using System; using System.Collections.Generic; using System.Linq; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL4; namespace SM.OGL.Mesh { /// /// Represents a Vertex Buffer Object used for meshes. /// public class VBO : List { /// /// Specifies the expected usage pattern of the data store. /// public BufferUsageHint BufferUsageHint; /// /// Specifies the data type of each component in the array. /// public VertexAttribPointerType PointerType; /// /// Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4. /// public int PointerSize; /// /// Normalise floats? /// public bool Normalised; /// /// Specifies the byte offset between consecutive generic vertex attributes. /// public int PointerStride; /// /// Specifies a offset of the first component of the first generic vertex attribute in the array in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target. /// public int PointerOffset; /// /// Generates a VBO for inserting mesh data. /// /// Specifies the expected usage pattern of the data store. Default: StaticDraw /// Specifies the data type of each component in the array. Default: Float /// Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4. Default: 3 /// Specifies the byte offset between consecutive generic vertex attributes. Default: 0 /// Specifies a offset of the first component of the first generic vertex attribute in the array in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target. Default: 0 /// Normalise floats? Default: false public VBO(BufferUsageHint bufferUsageHint = BufferUsageHint.StaticDraw, VertexAttribPointerType pointerType = VertexAttribPointerType.Float, int pointerSize = 3, int pointerStride = 0, int pointerOffset = 0, bool normalised = false) { BufferUsageHint = bufferUsageHint; PointerType = pointerType; PointerSize = pointerSize; PointerStride = pointerStride; PointerOffset = pointerOffset; Normalised = normalised; } /// /// Adds two values to the VBO. /// public void Add(float x, float y) => AddRange(new[] {x,y}); /// /// Adds three values to the VBO. /// public void Add(float x, float y, float z) => AddRange(new[] {x,y,z}); /// /// Adds four values to the VBO. /// public void Add(float x, float y, float z, float w) => AddRange(new[] {x,y,z,w}); /// /// Adds a Vector2. /// public void Add(Vector2 vector) => Add(vector.X, vector.Y); /// /// Adds a Vector2 and a value. /// public void Add(Vector2 vector, float z) => Add(vector.X, vector.Y, z); /// /// Adds a Vector2 and two values. /// public void Add(Vector2 vector, float z, float w) => Add(vector.X, vector.Y, z, w); /// /// Adds a Vector3. /// public void Add(Vector3 vector) => Add(vector.X, vector.Y, vector.Z); /// /// Adds a Vector3 and a value. /// public void Add(Vector3 vector, float w) => Add(vector.X, vector.Y, vector.Z, w); /// /// Adds a vector4. /// /// public void Add(Vector4 vector) => Add(vector.X, vector.Y, vector.Z, vector.W); /// /// Adds a color. /// public void Add(Color4 color) => Add(color.R, color.G, color.B, color.A); /// /// Binds the buffer to the active VAO. /// /// The id for the attribute. internal void BindBuffer(int attribID) { float[] data = ToArray(); int buffer = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, buffer); GL.BufferData(BufferTarget.ArrayBuffer, data.Length * sizeof(float), data, BufferUsageHint); GL.VertexAttribPointer(attribID, PointerSize, PointerType, Normalised, PointerStride, PointerOffset); GL.EnableVertexAttribArray(attribID); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); } } }