I'm considering two different approaches to vertex buffer management in my OpenGL game engine. The first one seems to be pretty usual, but I haven't seen the second one being proposed or used anywhere.
Buffer rebinding
This is the more obvious approach I've seen before. The vertex buffers are bound to VAO on demand, before draw calls.
// VAO creation
// Some attribute setup here
// Constant buffer-attribute bindings
glVertexArrayAttribBinding( vao, 0, 0 );
glVertexArrayAttribBinding( vao, 1, 1 );
glVertexArrayAttribBinding( vao, 2, 2 );
Then, when drawing:
for ( const auto &mesh : scene )
{
for ( int i = 0; i < mesh.buffer_count; i++ )
glVertexArrayVertexBuffers( vao, 0, mesh.buffer_count, mesh.buffers, mesh.offsets, mesh.strides );
// glDrawArrays()
}
Binding switching
In this approach, each mesh binds its vertex buffers to the VAO during initialization.
// VAO creation
// Some attribute setup here
// Each mesh binds its buffers to the VAO
// with glVertexArrayVertexBuffers()
int count = 0;
for ( auto &mesh : scene )
{
glVertexArrayVertexBuffers( vao, count, mesh.buffer_count, mesh.buffers, mesh.offsets, mesh.strides );
mesh.first_binding = count;
count += mesh.buffer_count;
}
Then, when drawing, only attribute bindings are altered and no buffers are bound. There are, however, many more glVertexArrayAttribBinding()
calls.
for ( const auto &mesh : scene )
{
for ( int i = 0; i < mesh.buffer_count; i++ )
glVertexArrayAttribBinding( vao, i, mesh.first_binding + i );
// glDrawArrays()
}
I'd seem that only changing where buffers feed their data might be more efficient than replacing buffers each frame. Is it really though? What are other advantages and disadvantages? Which way should I choose?
Also, is there any limit of buffers bound to VAO? I couldn't find any relevant GL_MAX_*
argument for glGet()
.
Thank you