It seems to play up sometimes and I'm not sure if this is due to the class itself or the way I'm using it. Can someone confirm that this is a 'good' implementation of a VertexArrayObject
class?
//The following code is public domain
public class VertexArray : GraphicsResource
{
protected readonly int ID;
DrawMode _drawMode;
VertexLayout _vertexType;
protected BufferUsageHint bufferUsage = BufferUsageHint.StaticDraw;
int vertexCount;
int vertexBufferID;
public DrawMode DrawMode
{
get { return _drawMode; }
set { _drawMode = value; }
}
public int VertexCount
{
get { return vertexCount; }
}
public BufferUsageHint BufferUsage
{
get { return bufferUsage; }
set { bufferUsage = value; }
}
public VertexArray()
: base()
{
ID = createVAO();
disposed = false;
}
public VertexArray(DrawMode drawMode)
: base()
{
_drawMode = drawMode;
ID = createVAO();
disposed = false;
}
int createVAO()
{
int id;
GL.GenBuffers(1, out vertexBufferID);
GL.GenVertexArrays(1, out id);
GL.BindVertexArray(id);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferID);
VenGFX.currentVAO = this;
return id;
}
public void Bind()
{
if (vertexCount == 0)
throw new Exception("Vertex buffer has no data, and therefore can't be used");
if (disposed)
throw new ObjectDisposedException(ToString());
GL.BindVertexArray(ID);
VenGFX.currentVAO = this;
}
public void SetData<T>(T[] Array) where T : struct, IVertex
{
GL.BindVertexArray(ID);
if (Array.Length > 0 && Array[0].Layout != _vertexType)
setVertexType(Array[0].Layout);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferID);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Array.Length * _vertexType.SizeInBytes), Array, bufferUsage);
vertexCount = Array.Length;
VenGFX.currentVAO = this;
}
public void SetData<T>(T[] Array, int length) where T : struct, IVertex
{
GL.BindVertexArray(ID);
if (Array != null && Array.Length > 0 && Array[0].Layout != _vertexType)
setVertexType(Array[0].Layout);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferID);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(length * _vertexType.SizeInBytes), Array, bufferUsage);
vertexCount = length;
VenGFX.currentVAO = this;
}
void setVertexType(VertexLayout layout)
{
_vertexType = layout;
layout.Set();
}
protected override void Release()
{
if (VenGFX.currentVAO == this)
{
GL.BindVertexArray(0);
VenGFX.currentVAO = null;
}
int id = ID;
GL.DeleteBuffers(1, ref vertexBufferID);
GL.DeleteVertexArrays(1, ref id);
}
}
To draw with it, I write
if (mesh.VertexCount == 0)
return;
if (currentVAO != mesh)
mesh.Bind();
GL.DrawArrays((BeginMode)(int)mesh.DrawMode, 0, mesh.VertexCount);