1
\$\begingroup\$

Optimizing modern OpenGL relies on aggressive batching, which is done by calls like glMultiDrawElementsIndirect. Although glMultiDrawElementsIndirect can render a large number of different meshes, it makes the assumption that all these meshes are made of the same primitives (eg. GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_POINTS).

In order to most efficiently batch rendering, is it wise to force everything to be GL_TRIANGLES (while ignoring possible optimizations with GL_TRIANGLE_STRIP or GL_TRIANGLE_FAN) in order to make it possible to group more meshes together?

This though comes from reading the Approaching Zero Driver Overhead slides, which suggests to draw everything (or, presumably, as much as possible) in a single glMultiDrawElementsIndirect call.

\$\endgroup\$
  • \$\begingroup\$ That depends on so many factors, it could vary from driver to driver, hardware to hardware, scene to scene.. The only way to know for sure is profiling. \$\endgroup\$ – bogglez Jun 22 '14 at 12:13
  • \$\begingroup\$ GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN are counter-productive if you are trying to group meshes together. You have to insert degenerate triangles or primitive restart indices in order to do that. In reality, the primary benefit of strips (cache efficiency) can be achieved just by using an indexed list of triangles in that order. Of course if you used strip order verbatim you would have winding issues, it is not the vertex order that you need to duplicate but the triangle order. \$\endgroup\$ – Andon M. Coleman Jun 22 '14 at 13:07
2
\$\begingroup\$

You don't need that fancy glMultiDrawElementsIndirect, you can just use glDrawArraysInstanced.

Batching is just about lowering draw calls as much as possible.

Triangle strips and triangle fans are used to lower your bandwidth. This means that by using a more memory efficient representation of geometry, you can send less data to the GPU. Please note that this does not mean you send less batches, it just means that your batches can be smaller.

In general for hobbyists and the like draw calls are quite likely going to be the major performance bottleneck in your game, if you have any performance problems at all. I don't think it would be very common for many games to require bandwidth optimizations.

However, as a programmer it might make it simpler for you to lower your draw call count (batch count) if your meshes are all in a similar format.

|improve this answer|||||
\$\endgroup\$
  • 1
    \$\begingroup\$ Triangle strips / fans are about more than just reducing the number of vertices that need to be uploaded to the GPU. They re-use vertices in an ordered pattern, which makes them much more cache friendly and that ultimately translates to fewer redundant vertex shader invocations because the post-T&L cache hit rate is higher. You do not need an actual strip primitive to take advantage of this, just supply a list of indices in that order. It is not as big a deal on modern hardware, but back in the day properly supplying vertices in strip-order was hugely important for performance. \$\endgroup\$ – Andon M. Coleman Jun 22 '14 at 13:02
  • \$\begingroup\$ The inspiration for using glMultiDrawElementsIndirect comes from the Approaching Zero Driver Overhead slides, which suggest submitting everything in a single multi-draw. glDrawArraysInstanced will allow instancing, but does not allow submitting multiple arbitrary (different) draw calls at the same time. \$\endgroup\$ – Nicolas Louis Guillemot Jun 22 '14 at 20:40

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.