Using a VAO to draw hundreds of disconnected quads


#1

I’m working on a sprite renderer right now. My goal is to be able to draw every sprite in one draw call using a VAO, each sprite is supposed to be rendered using GL_TRIANGLE_STRIP with 4 points,


|P2\     P4|
|   \      |
|    \     |
|     \    |
|      \   |
|P1     \P3|

I would like to put each of these sprites into a VAO and draw them all using one call. I have two problems that I would like help with. First, is it possible to increase the number of sprites drawn by the VAO with this method (increase the size of the VBO). And second, is there a way to draw each sprite on its own using one draw call.


#2

I think concerning the first point, you could maybe use transorm feedback to copy the data into an VBO of different size. Concerning the second point, glMultiDrawArrays or glDrawArraysInstanced might help…


#3

You may be better off using glDrawElements(GL_TRIANGLES). That doesn’t require any more vertices, but does require an element array.

You can’t “extend” a buffer object, i.e. increase the size while retaining the existing data. You can use glBufferData() to replace the data store with a larger one, but that will discard any existing data. If possible, create the buffer with a large enough store to start with (you don’t have to use all of it initially). If that isn’t possible, create a new buffer object and copy the data over. Unless you have a good reason to do otherwise, the size should be doubled each time (the smaller the increase at each step, the more steps required to reach a given size, and the more data copied in total).

You can draw multiple triangle strips in one call with e.g. glMultiDrawArrays() (requires OpenGL 2.0, so works with any version having VAOs), or by using glDrawElements() with glEnable(GL_PRIMITIVE_RESTART) and glPrimitiveRestartIndex() (requires OpenGL 3.1), or with glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX) (requires OpenGL 4.3).

But glMultiDrawArrays() (or similar) might be inefficient with many small groups. Implementations tend to optimise for typical usage, and two triangles per group isn’t very typical. You’d need to check on specific hardware to be sure.