Suppose I set up two VAOs, using the new (as of OpenGL 4.3) glBindVertexBuffer mechanism:
glGenVertexArrays(1, &vaoIndex0);
glGenVertexArrays(1, &vao
All of these calls modify VAO state. So no, you cannot reuse these settings across VAOs. You can of course set them the same in multiple VAOs, but you have to make the necessary state setup calls once when you set up each VAO.
The bindingIndex0
and bindingIndex1
values you use in your code fragment don't have any special meaning. They just establish the connection between the buffer you bind to the binding index with glBindVertexBuffer()
, and the attributes you specify as using that binding index.
The only condition is that the binding index has to be smaller than the value you can query as MAX_VERTEX_ATTRIB_BINDINGS
, which is guaranteed to be at least 16. Since these calls modify per-VAO state, you absolutely can use the same binding indices for multiple VAOs.
One way of looking at these newer state setup calls is that they introduce a level of indirection that was not previously available:
glVertexAttribPointer()
while the desired buffer is bound.glVertexAttribBinding()
. The binding index is then connected to a buffer, which is established with glBindVertexBuffer()
.In other words, in old style the connection is:
attribute index --> buffer
new style with these 4.3+ calls:
attribute index --> buffer index --> buffer
One advantage of this new flexibility is that you can bind a new buffer to multiple attributes with a single call. As long as all these attributes have the same buffer index, you need just one call to glBindVertexBuffer()
to specify a new buffer for all the attributes.
The following is not official notation at all. I just made it up. But I thought it might be useful to define the relationships more formally, by writing down some pseudo data structures.
Let's say each VAO contains two arrays to capture the connections explained above:
struct VAO {
...
uint bufferIndexBindings[MAX_VERTEX_ATTRIB_BINDINGS];
uint attribBufferIndices[MAX_VERTEX_ATTRIBS];
}
The two calls discussed here would then modify this structure like this:
glBindVertexBuffer(uint bindingIndex, uint buffer, ...) {
CurrentVAO.bufferIndexBindings[bindingIndex] = buffer;
}
glVertexAttribBinding(uint attribIndex, uint bindingIndex) {
CurrentVAO.attribBufferIndices[attribIndex] = bindingIndex;
}
This state is then used to obtain the buffer for a given attribute with index attribIndex
as:
CurrentVAO.bufferIndexBindings[CurrentVAO.attribBufferIndices[attribIndex]]
This also illustrates the indirection I explained above, which shows up here as two levels of lookup into the state tables.