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