Hi everyone,
I just want to ask something about drawing a lot of geometry efficiently.
I read that it would be better to use glMultiDrawElements, however I really don’t understand how.
Let’s assume we have different objects (3 for instance) , each of them is bound to a VAO.
1/How can we draw all of them at one, or what is the best way to draw them all without having any overload.
Usually we do this :
Bind VAO
Unbind VAO (or delete it).
But in this case how do we do ?
2/What do **indices stand for ( in this example is it an array of NULL) ??? ( I assume that I don’t need any offset in the indices):confused:

I recal : l glMultiDrawElements( GLenum mode,const GLsizei * count,GLenum type,const GLvoid ** indices,GLsizei primcount);

I think the rationale behind glMultiDraw is the following. If someone disagrees please correct me

Imagine that you have a single VAO that contains:

  • a big VBO with the geometry of your 3 objects and
  • a big index VBO with the indices like this: indices-of-object-0, indices-of-object-1, indices-of-object-2.

To draw them with glDrawElements you can do something like this:

bind VAO
glDrawElements(GL_TRIANGLES, object_0_indices_count, GL_UNSIGNED_SHORT, NULL);
glDrawElements(GL_TRIANGLES, object_1_indices_count, GL_UNSIGNED_SHORT, object_0_indices_count * sizeof(GLushort));
glDrawElements(GL_TRIANGLES, object_2_indices_count, GL_UNSIGNED_SHORT, (object_0_indices_count + object_1_indices_count) * sizeof(GLushort));

Now let’s assume that in your current frame you see 2 out of 3 objects (1st and 3rd). In that case you can use glMultiDrawElements.

GLsizei count[] = {object_0_indices_count, object_2_indices_count};
GLvoid* indices[] = {NULL, (object_0_indices_count + object_1_indices_count) * sizeof(GLushort)};
glMultiDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices, 2);

I think that your understading is alright.

However, I still don’t get one point.
If you have a lot of geometry to rendrer, is it better to pack all objects in one single VAO and use glMultiDrawElements or just use one VAO for each of them.

The driver can do some fancy optimizations inside glMultiDrawElements. For example it can create a new index buffer and issue a single draw call. The worst that can happen is do multiple calls of glDrawElements. I presume that overall the worst case scenario is to have the same performance as the multiple calls of glDrawElements but if the driver is smart enough glMultiDrawElements should be the faster way.