6
\$\begingroup\$

I have been learning OpenGL 2.1 but using shaders, VBOs, IBOs, etc. I have gotten a rendering engine that can load and draw meshes, materials, forward lighting (no shadows yet), SceneNodes, and NodeComponents. There are no optimizations yet (for obvious reasons) such as occlusion culling, only Face culling at the moment.

A mesh (simplified) class looks like this:

struct Mesh
{
    GLuint vbo;
    GLuint ibo;
    GLuint size;

    void draw(Program* shaderProgram) const
    {
        glEnableVertexAttribArray(shaderProgram->attrib("vertPos"));
        glEnableVertexAttribArray(shaderProgram->attrib("vertTexCoord"));
        ...

        glBindBuffer(GL_ARRAY_BUFFER, vbo);

        glVertexAttribPointer(shaderProgram->attrib("vertPos"), 3, GL_FLOAT, false, 
                              sizeof(Vertex), (const GLvoid*)(0 * sizeof(float)));
        ...

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
        glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

        glDisableVertexAttribArray(shaderProgram->attrib("vertPos"));
        ...
    }
}

When I have been drawing multiple objects with the same mesh (or multiple meshes), I notice a frame drop compared to a single mesh with the same number of triangles.

Stanford Models were used.
(1 Face = Triangle)
| Model  | Num Models  | Total Faces | With Lighting | Without Lighting |
| -      | -           | -           | ms / frame    | ms / frame       |
|--------|-------------|-------------|---------------|------------------|
|        | 0 (control) |        0    |  0.47         |  0.41            |
| bunny  | 1           |    69630    |  1.2          |  0.64            |
| bunny  | 14          |   974820    | 12.4          |  3.50            |
| buddha | 1           |  1087474    |  7.87         |  2.89            |
| buddha | 10          | 10874740    | 71.4          | 23.8             |

I does look like that time/frame is ~O(n). However, drawing one vbo with 12% more faces, the frame time is decreased by 37%.

So my questions are:

  • Is drawing multiple VBOs actually worse than drawing one big one?
  • How would I combine these VBOs and IBOs into one big one if this is true?
\$\endgroup\$
4
\$\begingroup\$

Yes, doing several draw calls is slower than one. This is why state changes are expensive. There are techniques (like instancing) that fight this, but they're still more expensive than simply doing a single draw call.

To combine several VBOs into one, they must have the same state (i.e, same shader, same textures, etc), and they must be static (i.e, not moving independently). Then simply transform the vertex data into the same space (for instance world space, or possibly the object space of a reference object) and handle the result as a single object.

The first question you have to ask, however, is whether all of this is worth it. First make it work, then make it fast.

\$\endgroup\$
  • \$\begingroup\$ Thank you for the quick reply. So what you are saying is when creating a scene/world, index the meshes, combine all the meshes that use the same state and then place them into a VBO? I know many games can use dozens of millions of faces (I remember Voodoo cards (years ago) advertizing 30M faces) but do they render them in such a way that only 100s of thousands of faces are being draw? I know I'm probably too early to optimize (and I know early optimization is bad!!!) but I'm still learning all this (in 2D, optimization was easy). \$\endgroup\$ – Xplane Sep 11 '14 at 11:13
  • \$\begingroup\$ Well, basically you could combine everything into single static meshes, but there are always cases where things aren't that simple, for instance visibility optimization like you mention. \$\endgroup\$ – Jari Komppa Sep 11 '14 at 11:20
  • \$\begingroup\$ Note that if you're using a (sane) artist pipeline, you can just combine the meshes in the modelling package before exporting. \$\endgroup\$ – Jari Komppa Sep 11 '14 at 11:21
  • \$\begingroup\$ I am using a (sane-ish) artist pipeline, but in any scene, there can be 100s of meshes. For many surfaces, I've been using normal mapping and parallax mapping to reduce faces but some models need those faces. Again, thank you very much! \$\endgroup\$ – Xplane Sep 11 '14 at 11:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.