I am implementing an instanced rendering system in my engine.
I use VAO’s in my entity render code to bind the vertex buffer and element buffer for each different model.
My instancing code uses GL_ARB_instanced_arrays to setup a mat4 attribute. There is a VBO that I populate with an array of transformation matrices for each instance. I use glVertexAttribDivisorARB to make the attribute “become” each instance’s transformation matrix as it iterates through the VBO of matrices in the glDrawElementsInstancedARB call.
So here’s the question:
If I bind the matrix array VBO, then bind the model’s vertex/element VAO after, would the matrix VBO still be bound, or would the VAO’s bindings override (and unbind) the binding of the matrix array VBO.
I want to bind the matrix array before the VAO because I don’t want the matrix array to become a part of the model’s VAO. I am guessing that if I bind and unbind the matrix VBO while the VAO is bound, it would add significant overhead by modifying the VAO unnecessarily.
VAOs do not encapsulate what is bound to the GL_ARRAY_BUFFER target. However, that is only because rendering does not care about what is bound to GL_ARRAY_BUFFER.
VAOs encapsulate all of the state used for rendering with arrays of vertices to OpenGL. When you bind one, the results of all prior gl*Pointer calls are discarded. Also, all glEnable/Disables for attributes are discarded.
I am guessing that if I bind and unbind the matrix VBO while the VAO is bound, it would add significant overhead by modifying the VAO unnecessarily.
Overhead to what? The point of VAOs is to encapsulate the state needed to render something. The only reason you wouldn’t want it to be part of the VAO would be if you were changing which buffer to use. And if you are, then that’s what you’re doing, and you’ve already accepted any penalty you’re going to get based solely on that.
Ok, I think I understand.
I always use the same buffer object for my matrices. So as long as my “geometry binding” always uses VAO, then I can optimize it to only do the EnableVertexArrays + VertexAttribPointer the first time I render with each VAO, and trust that the VAO state will “capture” the instancing matrix attribute buffer pointer. Right?
I did some searching in the the draw_instanced and vertex_array_object documents, and I did not see either of them mention whether VertexAttribDivisor is captured in the VAO. I have a feeling it must be capturing it, can anyone confirm or deny it?
Yes, EnableVertexArrays + VertexAttribPointer + VertexAttribDivisor are “captured” by VAOs, so yes, it is part of the VAOs state.
As you mentioned, you only have to execute this combo once for every VAO and then you’re ready to go.