The Spritebatcher: A Overview

Hey everyone,

I was thinking that we could get something going about Spritebatchers.
I’m seeing a lot of posts where people are asking about the best practices and honestly at the end of the day I want to know too.

So being the performance junkie I am, I was thinking we could get a list going about the things to keep in mind.

I’ll start out by explaining my understanding and update this as more info comes in.
I know there are a lot of different openGL implementations so I’ll try to cover everything in general

Now for the good stuff :smiley:

What is a SpriteBatcher?
A Spritebatcher is a nice little class or package that handles how your images get put on the screen.
The basic run down of a Spritebatcher can be thought as this:

  1. Prepare the Spritebatcher for all the images it needs to handle
  2. Get all the data (Vertex Positions, Color, Texture, etc) needed for each image or sprite.
    Put this data into a container (or directly into a VBO if you can use glMapBuffer*** calls)
  3. Prepare the Spritebatcher to render. Create the batch or batches to render from the data
  4. Send the batch off to the GPU to get rendered using a glDraw*** call

Why use a Spritebatcher?
The main reason for a Spritebatcher is performance.
When sending information off to the GPU its better to clump it all together, instead of a bunch of individual send off calls.
Basically, we want to keep our draw calls to a minimum.

When should we draw?
At some point we need to draw!
We need to call our method that sends everything off to the GPU, but when?
Really we should only draw when:

  1. We are out of space for our buffer or data container (Depends on the Spritebatcher implementation)
  2. We need to change Textures
  3. We need to change our Shader Program

Things to keep in mind
There are a lot of ways to make a Spritebatcher, but there are still a ton of common things to keep in mind!

  1. Minimize the number of glDraw*** calls. This will help performance and keep some heat off the GPU
  2. Use VBOs. Its not just good practice, but it also can give a performance increase.
    Plus some gl**** calls need them like glMapBuffer
  3. Set the VBO hint flag to GL_DYNAMIC_DRAW or GL_STREAM_DRAW when your vertex data changes often
  4. Use a IBO with the GL_STATIC_DRAW hint. Prefill the IBO with index data, since the indices will always be the same
  5. Use a Texture Atlas! Place as many images on a texture as you can. glBindTexture calls are expensive!
  6. If you’re using an openGL version that supports glMapBuffer or glMapBufferRange use one of those
    calls to fill your VBO. These calls give direct access to the VBO and can give you a nice performance increase
  7. If you can use glMapBufferRange, you can use the UNSYNCRONIZED flag when mapping to get a really nice performance increase.
    Riven has an awesome post on this! Link to post below
  8. If you have to use a FloatBuffer to transfer data to the GPU (Lower versions of openGL that don’t support glMap*** calls).
    When putting data into your FloatBuffer use the put method that accepts an Array. Individual puts calls are crazy slow :frowning:
    but the Array put is faster :smiley:
  9. Vertex data transformations can be done on the CPU side to keep some heat off the GPU

Links!

Rivens Post about Lightening Fast VBOs!
http://www.java-gaming.org/index.php?topic=28209.0

SharpDX’s Spritebatcher. Made in C# but it still has the basics and a solid layout!

Mattdesl’s Spreitebatcher implementation. A little old, but still solid!