Vertex Array Objects - Driver bug or am I doing it wrong?

Started by
1 comment, last by 21st Century Moose 12 years ago
I'm transitioning some code to use VAOs and have run into a curious problem that I'm not certain is a driver bug or the result of a brain malfunction on my part. Basically, the first batch of drawing code I've transitioned works perfectly; the API works as described and expected. The second batch does not.

Here's the code that works: glGenVertexArrays (1, &vao1);
glBindVertexArray (vao1);

glEnableVertexAttribArray (0);
glEnableVertexAttribArray (1);
glEnableVertexAttribArray (2);

glBindBuffer (GL_ARRAY_BUFFER, vbo1);

glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, sizeof (vertextype1), (void *) 0);
glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, sizeof (vertextype1), (void *) 12);
glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, sizeof (vertextype1), (void *) 24);

glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, ibo1);

glBindVertexArray (0);

"vbo1" and "ibo1" are buffer objects that have already been successfully generated and confirmed to work without VAOs. "vbo1" has been created with GL_STATIC_DRAW, "ibo1" with GL_STREAM_DRAW.

And now here's the code that fails: glGenVertexArrays (1, &vao2);
glBindVertexArray (vao2);

glEnableVertexAttribArray (0);
glEnableVertexAttribArray (1);
glEnableVertexAttribArray (2);

glBindBuffer (GL_ARRAY_BUFFER, vbo2);

glVertexAttribPointer (0, 2, GL_FLOAT, GL_FALSE, sizeof (vertextype2), (void *) 0);
glVertexAttribPointer (1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof (vertextype2), (void *) 8);
glVertexAttribPointer (2, 2, GL_FLOAT, GL_FALSE, sizeof (vertextype2), (void *) 12);

glBindVertexArray (0);

Again, "vbo2" is a buffer object that has already been successfully generated and confirmed to work without VAOs. This time however it has been created with GL_STREAM_DRAW and there is no GL_ELEMENT_ARRAY_BUFFER in use.

In both cases the drawing code is essentially the same: bind the VAO and issue draw calls. In the working case glDrawRangeElements is used, in the non-working case glDrawArrays is used. In both cases glMapBufferRange is used for updating the GL_STREAM_DRAW buffers.

Checking in the debugger I see that both VAOs are successfully generated and are assigned non-zero names.

In the non-working case, however, I can make it work by just adding a "glBindBuffer (GL_ARRAY_BUFFER, vbo2)" call immediately before my glBindVertexArray call.

So in summary, works: glBindVertexArray (vao1);
glMapBufferRange (.....); glUnmapBuffer (.....);
glDrawRangeElements (......);


Doesn't work: glBindVertexArray (vao2);
glMapBufferRange (.....); glUnmapBuffer (.....);
glDrawArrays (......);


Works: glBindBuffer (GL_ARRAY_BUFFER, vbo2);
glBindVertexArray (vao2);
glMapBufferRange (.....); glUnmapBuffer (.....);
glDrawArrays (......);


Also works: glBindVertexArray (vao2);
glBindBuffer (GL_ARRAY_BUFFER, vbo2);
glMapBufferRange (.....); glUnmapBuffer (.....);
glDrawArrays (......);


The failure is just a black screen. Nothing is drawn. glGetError consistently returns GL_NO_ERROR. glGetIntegerv (GL_ARRAY_BUFFER_BINDING, ...) returns the wrong buffer name in both the working and non-working cases, glGetIntegerv (GL_ELEMENT_ARRAY_BUFFER_BINDING, ...) returns the correct buffer name in the working case.

If the buffer binding was not part of the VAO state it would explain everything, but according to http://www.opengl.or...ex_Array_Object it is.

The failure case occurs on an AMD 6490 M with Catalyst 12.3, Windows 7 x64, using a core GL3.3 profile. I haven't yet been able to test on other hardware.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Advertisement
Try doing the bind buffer after you've done the bind of the VA, rather than before.

Try doing the bind buffer after you've done the bind of the VA, rather than before.


? But I'm already doing that ?

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement