PDA

View Full Version : VBOs seem to overwrite each other's data



hoshi55
12-13-2011, 03:10 PM
Hi all, I've gone back to some openGL programming after a long hiatus and am trying my hand on VBOs for the first time. I'm only doing dead simple stuff here - drawing a textured quad containing 4 vertices.

I have exactly one VBO and index buffer to go with it per renderable object (of which I want to have a few, each with different tex coords). With allocating only one VBO/IBO pairing, everything works just fine. When i create a second or more pairing, the last VBO/IBO I've set up overrides all texture and vertex coordinate data!

This is my code to create my vertex data:



// (Example data, varies from one instance of the renderable to the next)
GLfloat data[] =
{
0, 0, 0, 0, 0,
0, 1, 0, 0, 1,
1, 0, 0, 1, 0,
1, 1, 0, 1, 1
};

GLubyte indices[] = { 0, 1, 2, 3 };

glGenBuffers(1, &m_quadVBO);
glBindBuffer(GL_ARRAY_BUFFER, m_quadVBO);

const GLsizeiptr dataSize = sizeof( data );

// Copy vertexData into VBO
glBufferData(GL_ARRAY_BUFFER, dataSize, data, GL_STATIC_DRAW);

// Set vertex format
glVertexPointer(3, GL_FLOAT, 5 * 4, (GLvoid*)((char*)NULL));
glTexCoordPointer(2, GL_FLOAT, 5 * 4, (GLvoid*)((char*)NULL+(3*4)));

// Create index buffer
glGenBuffers(1, &m_quadIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), indices, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);


each renderable object is a class instance, so m_quadVBO and m_quadIBO are different instances of GLuint for each of my renderables (they are not static, either). I have checked.

This is how I draw stuff:



glEnable( GL_TEXTURE_2D );

glBindBuffer(GL_ARRAY_BUFFER, m_quadVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadIBO);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (GLvoid*)((char*)NULL));


As mentioned, it looks exactly like the last call to glVertexPointer/glTexCoordPointer I make sets the data for all my buffers. Can anyone see anything wrong with the way I'm doing things? I have no idea what else I could try. I can't even poke around in memory as I have no idea at what address openGL stores the vertex data (probably on the GPU?)

Thanks in advance!

Chroohn
12-13-2011, 06:23 PM
Maybe you should try to use 'glVertexPointer' & 'glTexCoordPointer'
every time before 'glDrawElements' call.

hoshi55
12-14-2011, 08:05 AM
That works indeed, thanks!

I don't quite understand why though. glVertexPointer and glTexCoordPointer don't explicitly set any data pointers, I was under the impression that they merely set the data format for the currently bound buffer, but there's obviously more stuff going on behind the scenes.

In any case, cheers for your help.

arekkusu
12-14-2011, 09:40 AM
The Pointer API explicitly set the buffer binding (GL_VERTEX_ARRAY_BUFFER_BINDING, etc) in the current VAO. The pointer/offset passed into DrawArrays/Elements is relative to the buffer. So they really are effectively setting the data pointer.

If you have a couple of different vertex array setups that never change, you can avoid re-setting all of the pointers and data types by creating a couple of VAOs at init. Then bind the appropriate VAO before drawing.

V-man
12-15-2011, 05:28 AM
What VAO? GL 1.5 did not have VAO.

arekkusu
12-15-2011, 10:02 AM
It did on the Mac; VAO has been around for almost ten years (http://www.opengl.org/registry/specs/APPLE/vertex_array_object.txt).