but on my GeForce 9300M, glBufferData() overwrites vertex data with indices if invoked on the same buffer object twice. Whatever was filled in last stays in even though I bind buffers correctly.
Of course it does. It’s a buffer object.
Buffer object memory is not broken into parts based on attachment points. It’s just an array of memory, just like you would get if you called malloc or new. Calling glBufferData is like calling malloc.
Here is a condensed version of what you’re doing in GL terms.
GLuint SetupMyVertexAndIndexData(...)
{
GLuint buffer = 0;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BINDING, buffer);
glBufferData(GL_ARRAY_BINDING, numVertices * vertexSize, <vertex data>);
glBindBuffer(GL_ELEMENT_ARRAY_BINDING, buffer);
glBufferData(GL_ELEMENT_ARRAY_BINDING, numIndices * indexSize, <index data>);
return buffer;
}
And here’s the equivalent in C:
BufferObject *vertexBuffer = NULL;
BufferObject *indexBuffer = NULL;
BufferObject SetupMyVertexAndIndexData(...)
{
BufferObject myBuffer;
vertexBuffer = &myBuffer;
vertexBuffer->data = malloc(numVertices * vertexSize);
//Fill vertexBuffer->data with vertex data.
vertexBuffer = NULL;
indexBuffer = &myBuffer;
free(indexBuffer->data);
indexBuffer->data = malloc(numIndices * indexSize);
//Fill indexBuffer->data with index data.
return myBuffer;
}
Do you see the problem?
If you want to put vertex and index data in the same buffer object, they have to go into different parts of the buffer object:
GLuint SetupMyVertexAndIndexData(...)
{
GLuint buffer = 0;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BINDING, buffer);
glBufferData(GL_ARRAY_BINDING, (numVertices * vertexSize) + (numIndices * indexSize), NULL);
glBufferSubData(GL_ARRAY_BINDING, (numVertices * vertexSize), 0, <vertex data>);
glBufferSubData(GL_ARRAY_BINDING, (numIndices * indexSize), (numVertices * vertexSize), <index data>);
return buffer;
}
Whenever you want to use the index data, in a glDrawElements call, you must provide an offset of (numVertices * vertexSize).
Binding a buffer to a different binding point does not change the contents of the buffer. It does not cause the buffer to have both a “vertex portion” and an “index portion”. The buffer is always a single 1-dimensional array of bytes.
So if you want two things in a single buffer object, you must put them in different places within that 1D array of bytes.