Added documentation comments, reorganized HexRender

This commit is contained in:
2017-02-26 02:19:59 -05:00
parent bc584c8f42
commit 7500e0e7a4
11 changed files with 178 additions and 91 deletions

View File

@@ -3,14 +3,45 @@ using OpenTK.Graphics.OpenGL4;
namespace Diamond.Buffers
{
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = true)]
/// <summary>
/// Marks a field as an attribute to be sent to a shader. Must be used on public fields of a struct.
/// </summary>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true)]
public sealed class VertexPointerAttribute : Attribute
{
/// <summary>
/// The attribute name that the values of this field should point to
/// </summary>
public string Name { get; }
/// <summary>
/// The number of elements in this attribute
/// Corresponds to the <code>size</code> parameter to <code>glVertexAttribPointer</code>.
/// </summary>
public int Size { get; }
/// <summary>
/// The element type of the attribute
/// Corresponds to the <code>type</code> parameter to <code>glVertexAttribPointer</code>
/// </summary>
public VertexAttribPointerType Type { get; set; } = VertexAttribPointerType.Float;
/// <summary>
/// Whether to normalize the values of this attribute
/// Corresponds to the <code>normalized</code> parameter to <code>glVertexAttribPointer</code>
/// </summary>
public bool Normalized { get; set; } = false;
/// <summary>
/// The divisor to Instanced draw calls
/// Corresponds to the <code>divisor</code> parameter to <code>glVertexAttribDivisor</code>
/// </summary>
public int Divisor { get; set; } = 0;
/// <summary>
/// The offset of this attribute within each element
/// Corresponds to the <code>offset</code> parameter to <code>glVertexAttribPointer</code>
/// </summary>
public int Offset { get; set; } = 0;
public VertexPointerAttribute(string name, int size)

View File

@@ -2,18 +2,35 @@
namespace Diamond
{
/// <summary>
/// Parent class for all gl Object wrappers.
/// </summary>
public abstract class GLObject : IDisposable
{
/// <summary>
/// The name of this object
/// </summary>
public uint Id { get; protected set; }
/// <summary>
/// Force all <code>GLObject</code>s to define their name.
/// </summary>
/// <param name="id">The name of this object</param>
protected GLObject(uint id)
{
Id = id;
}
/// <summary>
/// Called to free the name of this object. Usually corresponds to <code>glDelete*</code>.
/// </summary>
protected abstract void Delete();
private bool _disposed = false;
/// <summary>
/// Free the name of this object
/// </summary>
public void Dispose()
{
if (_disposed) return;

View File

@@ -9,7 +9,7 @@ namespace Diamond.Shaders
private Dictionary<string, int> uniforms = new Dictionary<string, int>();
private Dictionary<string, int> attributes = new Dictionary<string, int>();
public string Log => GL.GetProgramInfoLog((int) Id);
public string Log => GL.GetProgramInfoLog((int) Id).Trim();
public Program()
: base((uint) GL.CreateProgram())
@@ -23,7 +23,7 @@ namespace Diamond.Shaders
public void Attach(Shader shader) => GL.AttachShader(Id, shader.Id);
public bool LinkStatus
public bool Linked
{
get
{

View File

@@ -4,10 +4,19 @@ using OpenTK.Graphics.OpenGL4;
namespace Diamond.Shaders
{
/// <summary>
/// Wraps methods for GL Shader objects.
/// </summary>
public class Shader : GLObject
{
/// <summary>
/// The type of this shader.
/// </summary>
public readonly ShaderType Type;
/// <summary>
/// Gets and sets the shader source with <code>glShaderSource</code> and <code>glGetShaderSource</code>.
/// </summary>
public string Source
{
get
@@ -19,8 +28,14 @@ namespace Diamond.Shaders
set { GL.ShaderSource((int) Id, value); }
}
public string Log => GL.GetShaderInfoLog((int) Id);
/// <summary>
/// Retrieves this shader's compilation log with <code>glGetShaderInfoLog</code>.
/// </summary>
public string Log => GL.GetShaderInfoLog((int) Id).Trim();
/// <summary>
/// Checks the compilation status of this shader with <code>glGetShader</code>.
/// </summary>
public bool Compiled
{
get
@@ -30,29 +45,52 @@ namespace Diamond.Shaders
}
}
/// <summary>
/// Creates a wrapper for a gl Shader object.
/// </summary>
/// <param name="type">The type of the shader to create</param>
public Shader(ShaderType type)
: base((uint) GL.CreateShader(type))
{
Type = type;
}
/// <summary>
/// Frees this gl object. Called by <code>GLObject.Dispose()</code>.
/// </summary>
protected override void Delete()
{
GL.DeleteShader(Id);
}
/// <summary>
/// Compile the shader.
/// </summary>
/// <returns>Compilation success</returns>
public bool Compile()
{
GL.CompileShader(Id);
GL.GetShader(Id, ShaderParameter.CompileStatus, out int success);
return success != 0;
return Compiled;
}
/// <summary>
/// Creates and compiles a shader from a source file.
/// </summary>
/// <param name="path">Source file location</param>
/// <param name="type">Type of the shader</param>
/// <returns>The compiled shader</returns>
public static Shader FromFile(string path, ShaderType type)
{
return FromFile(path, type, out bool success);
}
/// <summary>
/// Creates and compiles a shader from a source file.
/// </summary>
/// <param name="path">Source file location</param>
/// <param name="type">Type of the shader</param>
/// <param name="success">Compilation success</param>
/// <returns>The compiled shader</returns>
public static Shader FromFile(string path, ShaderType type, out bool success)
{
var s = new Shader(type);

View File

@@ -3,6 +3,9 @@ using System.Runtime.Serialization;
namespace Diamond.Shaders
{
/// <summary>
/// Exception relating to <code>Shader</code> and <code>Program</code> operations.
/// </summary>
[Serializable]
public class ShaderException : Exception
{

View File

@@ -5,6 +5,9 @@ using PixelFormat = OpenTK.Graphics.OpenGL4.PixelFormat;
namespace Diamond.Textures
{
/// <summary>
/// Wrapper class for gl Textures.
/// </summary>
public class Texture : GLObject
{
public TextureTarget Target;

View File

@@ -1,23 +1,30 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using Diamond;
using Diamond.Buffers;
using Diamond.Shaders;
using Diamond.Textures;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL4;
namespace hexworld
{
public partial class HexRender : GameWindow
public class HexRender : GameWindow
{
private readonly VertexData[] _cubeVerts =
JsonConvert.DeserializeObject<VertexData[]>(File.ReadAllText("cube.json"));
private readonly TileData[] _tilesData =
JsonConvert.DeserializeObject<TileData[]>(File.ReadAllText("tiles.json"));
private Program _pgm;
private Texture _grass;
@@ -26,8 +33,10 @@ namespace hexworld
private Matrix4 _view;
private Matrix4 _proj;
private VBO<Tile> _tileVbo;
private VBO<Vertex> _cubeVbo;
private VBO<TileData> _tileVbo;
private VBO<VertexData> _cubeVbo;
private double _time;
public HexRender(int width, int height)
: base(width, height, new GraphicsMode(32, 24, 0, 0))
@@ -38,24 +47,24 @@ namespace hexworld
Y = (DisplayDevice.Default.Height - Height) / 2;
}
private double _t;
protected override void OnUpdateFrame(FrameEventArgs e)
{
base.OnUpdateFrame(e);
_t += e.Time;
_time += e.Time;
_view = Matrix4.LookAt(10 * Vector3.One, Vector3.Zero, Vector3.UnitZ);
_proj = Matrix4.CreateOrthographic(Width / 100f, Height / 100f, -100, 100);
// wavy blocks around perimeter
for (var i = 0; i < 16; i++)
{
var ti = tiles[i];
tiles[i].Position.Z = (float) (Math.Sin((_t + ti.Position.X - ti.Position.Y / 1.5) / 1.5) * .25);
var ti = _tilesData[i];
_tilesData[i].Position.Z = (float) (Math.Sin((_time + ti.Position.X - ti.Position.Y / 1.5) / 1.5) * .25);
}
_tileVbo.Bind();
GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr) (0), (IntPtr) (16 * 3 * sizeof(float)), tiles);
GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr) (0), (IntPtr) (16 * 3 * sizeof(float)), _tilesData);
VBO.Unbind();
}
@@ -63,42 +72,34 @@ namespace hexworld
{
base.OnLoad(e);
_cubeVbo = new VBO<Vertex>();
_cubeVbo.Data(cubeVerts, BufferUsageHint.StaticDraw);
_tileVbo = new VBO<Tile>();
_tileVbo.Data(tiles, BufferUsageHint.DynamicDraw);
using (var vs = Shader.FromFile("s.vs.glsl", ShaderType.VertexShader))
using (var fs = Shader.FromFile("s.fs.glsl", ShaderType.FragmentShader))
{
_pgm = Program.FromShaders(vs, fs);
if (!vs.Compiled | !fs.Compiled)
{
Console.Out.WriteLine("Failed to compile shaders:");
if (!vs.Compiled)
Console.Out.WriteLine("Vertex Shader:\n" + vs.Log.Trim());
if (!fs.Compiled)
Console.Out.WriteLine("Fragment Shader:\n" + fs.Log.Trim());
Console.Out.WriteLine("Press any key to exit.");
Console.ReadKey();
Debug.WriteLine("Failed to compile shaders:");
Debug.WriteLineIf(!vs.Compiled, $"Vertex Log:\n{vs.Log}");
Debug.WriteLineIf(!fs.Compiled, $"Fragment Log:\n{fs.Log}");
Exit();
return;
}
_pgm = Program.FromShaders(vs, fs);
if (!_pgm.Link())
{
Debug.WriteLine($"Failed to link program:\n{_pgm.Log}");
Exit();
return;
}
}
if (!_pgm.LinkStatus)
{
Console.Out.WriteLine("Failed to link program:");
Console.Out.WriteLine(_pgm.Log.Trim());
Console.Out.WriteLine("Press any key to exit.");
Console.ReadKey();
Exit();
return;
}
_cubeVbo = new VBO<VertexData>();
_cubeVbo.Data(_cubeVerts, BufferUsageHint.StaticDraw);
_cubeVbo.AttribPointers(_pgm);
_tileVbo = new VBO<TileData>();
_tileVbo.Data(_tilesData, BufferUsageHint.DynamicDraw);
_tileVbo.AttribPointers(_pgm);
_grass = Texture.FromBitmap(new Bitmap("grass.png"));
@@ -111,11 +112,11 @@ namespace hexworld
_pgm.Dispose();
_grass.Dispose();
_stone.Dispose();
_tileVbo.Dispose();
_cubeVbo.Dispose();
_grass.Dispose();
_stone.Dispose();
}
protected override void OnRenderFrame(FrameEventArgs e)

18
hexworld/TileData.cs Normal file
View File

@@ -0,0 +1,18 @@
using Diamond.Buffers;
using Newtonsoft.Json;
using OpenTK;
namespace hexworld
{
public struct TileData
{
[JsonProperty("pos")]
[VertexPointer("glbpos", 3, Divisor = 1)]
public Vector3 Position;
public TileData(Vector3 position)
{
Position = position;
}
}
}

View File

@@ -1,53 +1,28 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Diamond;
using Diamond.Buffers;
using Diamond.Buffers;
using Newtonsoft.Json;
using OpenTK;
namespace hexworld
{
public partial class HexRender
public struct VertexData
{
public struct Tile
[JsonProperty("pos")]
[VertexPointer("locpos", 3)]
public Vector3 Position;
[JsonProperty("uv")]
[VertexPointer("coord", 2)]
public Vector2 UV;
[JsonProperty("norm")]
[VertexPointer("norm", 3)]
public Vector3 Normal;
public VertexData(Vector3 position, Vector2 uv, Vector3 normal)
{
[JsonProperty("pos")]
[VertexPointer("glbpos", 3, Divisor = 1)]
public Vector3 Position;
public Tile(Vector3 position)
{
Position = position;
}
Position = position;
UV = uv;
Normal = normal;
}
public struct Vertex
{
[JsonProperty("pos")]
[VertexPointer("locpos", 3)]
public Vector3 Position;
[JsonProperty("uv")]
[VertexPointer("coord", 2)]
public Vector2 UV;
[JsonProperty("norm")]
[VertexPointer("norm", 3)]
public Vector3 Normal;
public Vertex(Vector3 position, Vector2 uv, Vector3 normal)
{
Position = position;
UV = uv;
Normal = normal;
}
}
private readonly Vertex[] cubeVerts = JsonConvert.DeserializeObject<Vertex[]>(File.ReadAllText("cube.json"));
private Tile[] tiles = JsonConvert.DeserializeObject<Tile[]>(File.ReadAllText("tiles.json"));
}
}

View File

@@ -51,9 +51,10 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="TileData.cs" />
<Compile Include="VertexData.cs" />
<Compile Include="Driver.cs" />
<Compile Include="HexRender.cs" />
<Compile Include="Driver.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 596 B

After

Width:  |  Height:  |  Size: 670 B