I'm writing a simple scene graph, and I have a mesh class that keeps track of a vertex array object, vertex buffer object and an index buffer object.
When I initialize the mesh objects and populate them with data, it seems that the last created vertex buffer is the one being used when drawing, even when I bind a different vertex array object.
When rendering, if I only bind the vertex array, any meshes other than the last initialized one have the vertices of the last initialized mesh (but the correct indices, making them look wrong).
The only way I got it to work is to bind the vertex buffer object again right after I bind the vertex array object. This contradicts every documentation or comment I read anywhere.
// Geometry class
class Geometry
{
public override void Render()
{
this.Mesh.bind(); // bind mesh
this.Material.bind(); // bind shader. This also uses attribute locations stored in the shader object to enable vertex attributes
this.Data.Render();
this.Mesh.unbind(); // bind 0 to vertex array
this.Material.unbind(); // use program 0
}
}
// base mesh class
class Mesh
{
public override void init()
{
// ... truncated code for creating vertices ..
vertexArray = GL.GenVertexArray();
GL.BindVertexArray(vertexArray);
GL.GenBuffers(2, buffers);
GL.BindBuffer(BufferTarget.ArrayBuffer, buffers[0]);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * Vertex.SizeInBytes), vertices, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, buffers[1]);
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Count * sizeof(uint)), indices.ToArray(), BufferUsageHint.StaticDraw);
numPoints = vertices.Length;
numIndices = indices.Count;
GL.BindVertexArray(0);
}
public void bind()
{
GL.BindVertexArray(vertexArray);
// I had to add this line to make meshes render correctly
GL.BindBuffer(BufferTarget.ArrayBuffer, buffers[0]);
}
public void unbind()
{
GL.BindVertexArray(0);
}
public override void Render()
{
GL.DrawElements(PrimitiveType.Triangles, numIndices, DrawElementsType.UnsignedInt, IntPtr.Zero);
}
public override void Update(float t, float deltaT, int xDelta, int yDelta, int zDelta, MouseState mouse, KeyboardState keyboard)
{
}
}