Saturday, June 13, 2015

What state is stored in an OpenGL Vertex Array Object (VAO) and how do I use the VAO correctly?


I was wondering what state is stored in an OpenGL VAO. I've understood that a VAO contains state related to the vertex specifications of buffered vertices (what attributes are in the buffers, and what buffers are bound, ... ). To better understand the correct usage of VAO's, I'd like to know exactly what state they hold.






From simple examples, I've understood that correct usage of VAO's is as follows:


Setup


Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO


Rendering


Bind VAO
---- Draw
Unbind VAO

From this, I assume that at least the vertex buffer bindings and the vertex attribute specifications are stored in the VAO. I'm unsure however how this usage pattern extends to situations where (multiple) textures and (multiple) shader programs come into play. Is the active shader program stored in the VAO? And are the texture bindings (with their sampling/ wrapping settings) stored in the VAO as well? Ditto for uniforms?




Therefore, my questions are:




  • What exact state is stored in an OpenGL VAO? (VBO bindings, attribute specifications, active shader program, texture bindings, texture sampling/wrapping settings, uniforms ... ?)

  • How do I correctly use VAO's in a more complex rendering setup where (multiple) textures with associated sampling/wrapping settings, (multiple) shader programs and uniforms are involved?



Answer



VAO stores data about vertex attribute locations. (And some other data related to them.)
"VBO bindings, active shader program, texture bindings, texture sampling/wrapping settings, uniforms" are completely unrelated to it.


You may ask why it doesn't remember VBO binding. Because you don't need to bind VBO to draw something, you only need to bind it when creating VAO: When you call glVertexAttribPointer(...), VAO remembers what VBO is currently bound. And VAO will take attributes from these VBOs when you draw it, even if these VBOs are not bound currently.




Also, VAOs and VBOs must be used slighty differently:


This will not work



Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO

because you need to bind VBO to specify attribute locations.



So, you should do it like this:


Generate VAO
BindVAO
Generate VBO's
BindVBO's
Specify vertex attributes

You can change VBO's data whenever you want, but you must bind it before.


And drawing should look like this:


Bind VAO

Draw


As you may noticed, I removed unbind calls from your lists. They are almost completely useless and they will slightly slow down your program, so I see no reason to call them.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...