6
\$\begingroup\$

I'm trying to wrap my head around how batching is done in a 2D sprite-based game. My understanding is I'd get the vertices that represent each sprite I want to draw and stuff them all into a single mesh. That way I'd only need a single draw call to render everything.

Does this apply when the sprites I render are different between frames, or when some sprites are moving? Because it sounds like I'd then have to recreate my batch mesh each frame, using either glDrawArrays/glDrawElements or a streaming VBO I assume. Does this sound correct?

\$\endgroup\$
2
  • \$\begingroup\$ Sprite batching is simply reducing the overhead by transmitting the data all at once, not to reduce memory needed or something. So making everything in a CPU array and then uploading it is fine. \$\endgroup\$
    – API-Beast
    Dec 2, 2012 at 21:40
  • 1
    \$\begingroup\$ You can update a VBO if only parts of it have changed but I find that the overhead of checking what has changed often doesn't outweigh recreating the VBO entirely. \$\endgroup\$
    – Roy T.
    Dec 2, 2012 at 21:56

1 Answer 1

8
\$\begingroup\$

Yes, that's correct. Take all sprites that use the same material (share the same atlas) and draw them using a single dynamic:/steaming VBO.

If you have static sprites, it may be more efficient to put all those in one VBO, and the dynamic ones in another. If you have a large number of sprites, it may also be advantageous to use more than one VBO and split your batches up to reduce the size and amount of geometry you send in each draw call.

As with all optimizations, profile and check what is faster rather than assuming or taking advice off the Internet at face value.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Would +2 for the last paragraph, if it would let me. \$\endgroup\$ Dec 2, 2012 at 23:29
  • 2
    \$\begingroup\$ Regarding dynamic VBO usage, it sometimes gives people the heebeegeebies to think that they need to resend the data each frame and they can easily fall into the trap of only resending things that change, which leads to overly complex code and lots of tiny updates (which GPUs hate). Remember that in the days before VBOs this was always done for everything anyway, and things ran well enough then - it's not a problem; slower than having all-static data for sure, but not that much slower. \$\endgroup\$ Dec 2, 2012 at 23:43
  • \$\begingroup\$ Thank you. The way I've drawn sprites in the past was having a single static VBO representing a 1x1 quad that gets redrawn for each sprite, the MVP matrix and texture parameters set appropriately. I was interested how batching worked exactly to see if it'd be a technique worth switching to. \$\endgroup\$
    – Aaron
    Dec 3, 2012 at 22:12
  • 1
    \$\begingroup\$ You actually can do that efficiently using geometry instancing, but that's a more advanced technique and requires using a larger version of GL/D3D. In that case though you're still generating a dynamic buffer every frame with all the matrices and texture coords for each sprite; only the geometry buffer would be static. \$\endgroup\$ Dec 3, 2012 at 22:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .