States managed by a VAO

Started by
1 comment, last by Laval B 10 years, 10 months ago

Hello everyone.

My question is about OpenGL and i'm using version 3.2 to 4.1 core profile.

I have been reading about VAO and i must admit i'm a bit confused. Looking at the spec it is clear that all vertex attribute states are "stored" in the VAO : glVertexAttribPointer, glEnableVertexAttribArray, etc which is ok.

According to the spec,GL_ELEMENT_ARRAY_BUFFER binding is a VAO state but not GL_ARRAY_BUFFER binding. Does that mean binding a VAO will bind the index buffer but not the vertex buffer ? So in order to render the content of a VBO, i would need to bind the VAO and the VBO right ? If this is true i find it odd. Shouldn't it be the other way around ? I often have many index buffers for a single VBO.

I know there is plenty of posts on the net about this subject, but they almost all endup more confusing then anything because half of the people say one thing and the rest says the other.

We think in generalities, but we live in details.
- Alfred North Whitehead
Advertisement

You don't need to bind the VBO. The array buffer binding is part of the per-attrib array state that is captured in a VAO during your glVertexAttribPointer call so the correct VBO will be used when you come to issue your draw call.

Binding a VBO on it's own doesn't do much - all it does is specify that "this is the buffer we're going to use for future operations" - when you issue that glVertexAttribPointer call, that's the point at which the currently bound VBO is picked up and attached to the state used by the attrib array.

This is made more explicit by the documentation for glVertexAttribPointer where it's stated that "The buffer object binding (GL_ARRAY_BUFFER_BINDING) is saved as generic vertex attribute array state".

If you think about it, this makes sense. Consider the following hypothetical example:


glBindVertexArray (vao);

glBindBuffer (GL_ARRAY_BUFFER, vbo1);
glEnableVertexAttribArray (0);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

glBindBuffer (GL_ARRAY_BUFFER, vbo2);
glEnableVertexAttribArray (1);
glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, 0, NULL);

If the array buffer was not part of the attrib array states, how would the driver know which VBO to use for each attrib array? It can't. If the array buffer binding was saved in the VAO, which binding gets saved? You can't have two simultaneous array buffer bindings (there's only one binding point).

Clear as mud? Well, yes and no. Just think about it in terms of "the array buffer to use for each attrib array is part of the attrib array state, and the actual binding itself is not needed for this" if it helps.

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

Thank you for the clear answer smile.png

It makes sense indeed, i didn't pay attention when i read the glVertexAttribPointer/glEnableVertexAttribArray part and got confused when they say :

<array> is the vertex array object name. The resulting vertex array

object is a new state vector, comprising all the state values listed in
tables 6.6 (except for the CLIENT_ACTIVE_TEXTURE selector state), 6.7,
and 6.8 (except for the ARRAY_BUFFER_BINDING state).

Ref http://www.opengl.org/registry/specs/ARB/vertex_array_object.txt

I forgot that vertex attributes are not necessarily in the same vbo (over 95 % of my vbo are filled with interleaved data).

Now, index buffer will get bound when binding the VAO. I guess i can still bind the index buffer separately after binding the VAO (which will update the VAO state every time though). If i do this, i will have to make sure to bind index buffer 0 if I render a VAO with no index buffer. Would that be a problem ? You see, my code base pretty much separates the vertex (and the vertext attribute specification) from the index.

We think in generalities, but we live in details.
- Alfred North Whitehead

This topic is closed to new replies.

Advertisement