I haven't done any benchmarking to compare but there's a relatively unknown feature introduced to core in 4.3 that might be of interest to you. glVertexAttribPointer
has somewhat silently been deprecated in favor of a new suite of functions:
In 4.4 there's also a compound version of the latter function, glBindVertexBuffers
, that does N consecutive binds at once (not necessarily consecutive vertex attribute locations!) to save you the call overhead.
In the common use case of drawing a lot of objects with the same vertex attributes but different buffers, this vastly simplifies the work you have to do (and potentially is faster!) Instead of keeping around a VAO for each object, you only need one for each different combination of vertex attributes.
Sample code is worth 1000 words, so here goes.
void buildVAO() {
glBindVertexArray(vao);
// layout(location = 0) in vec3 position;
glEnableVertexAttribArray(0);
glVertexAttribFormat(0, 3, GL_FLOAT, false, 0);
glVertexAttribBinding(0, 0); // bind to first vertex buffer
// layout(location = 2) in vec3 normal;
glEnableVertexAttribArray(2);
glVertexAttribFormat(2, 3, GL_FLOAT, false, 0);
glVertexAttribBinding(2, 1); // bind to second vertex buffer
glBindVertexArray(0);
}
The biggest difference you should notice here is that you no longer need a buffer bound to specify your vertex attributes. Hooray for decoupling!
struct Object {
GLuint buffers[2]; // first provides position, second provides normal
size_t offsets[2]; // beginning of vertex data in buffer
size_t strides[2]; // stride of entire element in buffer
unsigned int triangles;
};
void draw(unsigned int count, const struct Object *objects) {
glBindVertexArray(vao);
for(int i = 0; i < count; ++i) {
// consecutive vertex buffer binding points are used here
glBindVertexBuffers(0, 2, objects[i].buffers, objects[i].offsets, objects[i].strides);
glDrawArrays(GL_TRIANGLES, 0, objects[i].triangles*3);
}
glBindVertexArray(0);
}
Here you can see why vertex buffer binding points are useful. Even though they don't contribute to consecutive vertex attribute locations, we can still bind consecutive buffers into those locations.
One last thing to note: if you have a GPU that supports OpenGL 4.5 there is a DSA equivalent for each of these functions.