diff --git a/Diamond/Util/ObjVertex.cs b/Diamond/Util/ObjVertex.cs index c168a09..16bd041 100644 --- a/Diamond/Util/ObjVertex.cs +++ b/Diamond/Util/ObjVertex.cs @@ -3,18 +3,39 @@ using OpenTK; namespace Diamond.Util { + /// + /// Vertex buffer data for Wavefront meshes + /// [VertexData] public struct ObjVertex { + /// + /// Vertex position (v) + /// [VertexPointer("position", 3)] + [VertexPointer("v", 3)] public Vector3 Position; + /// + /// UV coordinate (vt) + /// [VertexPointer("uv", 2)] + [VertexPointer("vt", 2)] public Vector2 UV; + /// + /// Vertex normal (vn) + /// [VertexPointer("normal", 3)] + [VertexPointer("vn", 3)] public Vector3 Normal; + /// + /// Create a new ObjVertex + /// + /// The vertex position (v) + /// The uv coordinate (vt) + /// The vertex normal (n) public ObjVertex(Vector3 position, Vector2 uv, Vector3 normal) { Position = position; diff --git a/Diamond/Util/SubArray.cs b/Diamond/Util/SubArray.cs index 91c9482..327f4c1 100644 --- a/Diamond/Util/SubArray.cs +++ b/Diamond/Util/SubArray.cs @@ -5,12 +5,32 @@ using System.Linq; namespace Diamond.Util { + /// + /// Provices access to a subset of an array + /// + /// public class SubArray : IEnumerable { - public T[] Array; - public int Offset; - public int Length; + /// + /// The array that this references + /// + public T[] Array { get; set; } + /// + /// The offset of this subarray + /// + public int Offset { get; set; } + + /// + /// The length of this subarray + /// + public int Length { get; } + + /// + /// By-ref access to the underlying array + /// + /// The index of the subarray to access + /// A reference to the offset position public ref T this[int i] { get @@ -21,28 +41,36 @@ namespace Diamond.Util } } - public SubArray(T[] array) : this(array, 0, array.Length) + /// + /// Create a subarray covering an entire array + /// + /// The array to cover + public SubArray(T[] array) + : this(array, 0, array.Length) { } + /// + /// Create a subarray from an array + /// + /// The array to cover + /// The offset of the subarray + /// The length of the subarray public SubArray(T[] array, int offset, int length) { + if (offset + length > array.Length) + throw new IndexOutOfRangeException($"Cannot create subarray with length {length}) of " + + $"array with length {array.Length} at index {offset}"); + Array = array; Offset = offset; Length = length; } - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - for (var i = 0; i < Length; i++) - yield return Array[Offset + i]; - } - + /// + /// Create a copy of the array within the bounds of the subarray + /// + /// A copied array from this subarray public T[] ToArray() { var arr = new T[Length]; @@ -50,6 +78,18 @@ namespace Diamond.Util return arr; } + /// + /// Create a copy of the array within the bounds of the subarray, and make this subarray cover that copy + /// + /// The new array that this subarray covers + public T[] Extract() + { + var arr = ToArray(); + Offset = 0; + Array = arr; + return arr; + } + public override string ToString() { if (Length == 0) @@ -57,16 +97,56 @@ namespace Diamond.Util return $"[{string.Join(", ", this)}]"; } + + #region IEnumerable + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// Enumerate over the array within the bounds of the subarray + /// + /// + public IEnumerator GetEnumerator() + { + for (var i = 0; i < Length; i++) + yield return Array[Offset + i]; + } + + #endregion } + /// + /// Class for static SubArray operations + /// public static class SubArray { - public static T[] Join(params SubArray[] subArrays) => Join((IEnumerable>)subArrays); + /// + /// Make multiple subArrays cover the same array + /// + /// The element type + /// The SubArrays to join + /// The new underlying array + public static T[] Join(params SubArray[] subArrays) => Join((IEnumerable>) subArrays); + /// + /// Make multiple subArrays cover the same array + /// + /// The element type + /// The SubArrays to join + /// The new underlying array public static T[] Join(IEnumerable> subArrays) { + // todo: this breaks in the case: Join(a, b); Join(b, c) + // possibly create "multiarray" class or similar which would manage these operations + // and prevent this case from arising + + var subArrList = subArrays.ToList(); // prevent multiple enumeration + HashSet uniqueArrays = new HashSet(); - foreach (var subArray in subArrays) + foreach (var subArray in subArrList) { uniqueArrays.Add(subArray.Array); } @@ -88,7 +168,7 @@ namespace Diamond.Util System.Array.ConstrainedCopy(uniqueArray, 0, array, offsets[uniqueArray], uniqueArray.Length); } - foreach (var subArray in subArrays) + foreach (var subArray in subArrList) { subArray.Offset = offsets[subArray.Array]; subArray.Array = array; @@ -96,6 +176,5 @@ namespace Diamond.Util return array; } - } } \ No newline at end of file diff --git a/Diamond/Util/TileData.cs b/Diamond/Util/TileData.cs index 2af7f99..9493a4d 100644 --- a/Diamond/Util/TileData.cs +++ b/Diamond/Util/TileData.cs @@ -3,20 +3,26 @@ using OpenTK; namespace Diamond.Util { + /// + /// Vertex buffer data for instanced rendering + /// [VertexData(Divisor = 1)] public struct TileData { + /// + /// The global position of the instance + /// [VertexPointer("glbpos", 3)] + [VertexPointer("global_pos", 3)] public Vector3 Position; + /// + /// Create a new TileData + /// + /// The global position of the instance public TileData(Vector3 position) { Position = position; } - - public override string ToString() - { - return $"{nameof(Position)}: {Position}"; - } } } \ No newline at end of file diff --git a/hexworld/res/obj.vs.glsl b/hexworld/res/obj.vs.glsl index adc6110..a12f233 100644 --- a/hexworld/res/obj.vs.glsl +++ b/hexworld/res/obj.vs.glsl @@ -1,22 +1,27 @@ #version 440 -in vec3 position; -in vec3 glbpos; -in vec2 uv; -in vec3 normal; +// Wavefront vertices +in vec3 v; +in vec2 vt; +in vec3 vn; -out vec2 vcoord; -out float light; +// Instance data +in vec3 global_pos; uniform mat4 view; uniform mat4 proj; +out vec2 vcoord; +out float light; + void main () { - mat4 pv = proj * view; - vec3 pos = glbpos + position; - gl_Position = pv * vec4(pos, 1); - vcoord = uv; + mat4 proj_view = proj * view; + vec3 pos = global_pos + v; + + gl_Position = proj_view * vec4(pos, 1); + + vcoord = vt; - light = dot(vec3(.2, .3, 1), normal) / 2 + .5; + light = dot(vec3(.2, .3, 1), vn) / 2 + .5; } \ No newline at end of file