Game Development Reference
In-Depth Information
The usual usage pattern of a sprite batcher looks like this:
batcher.beginBatch(texture);
// call batcher.drawSprite() as often as needed, referencing regions in the texture
batcher.endBatch();
The call to
SpriteBatcher.beginBatch()
tells the batcher two things: it should clear its buffer,
and it should use the texture we pass in. We will bind the texture within this method for
convenience.
Next, we render as many sprites that reference regions within this texture as we need. This will
fill the buffer, adding four vertices per sprite.
The call to
SpriteBatcher.endBatch()
signals to the sprite batcher that we are done rendering
the batch of sprites and that it should now upload the vertices to the GPU for actual rendering.
We are going to use indexed rendering with a
Vertices
instance, so we also need to specify
the indices, in addition to the vertices in the float array buffer. However, since we are always
rendering rectangles, we can generate the indices beforehand once in the constructor of the
SpriteBatcher
. For this, we need to know how many sprites the batcher can draw per batch.
By putting a hard limit on the number of sprites that can be rendered per batch, we don't need
to grow any arrays of other buffers; we can just allocate these arrays and buffers once in the
constructor.
The general mechanics are rather simple. The
SpriteBatcher.drawSprite()
method may seem
like a mystery, but it's not a big problem (if we leave out rotation and scaling for a moment).
All we need to do is calculate the vertex positions and texture coordinates, as defined by the
parameters. We have done this manually already in previous examples—for instance, when we
defined the rectangles for the cannon, the cannonball, and Bob. We can do more or less the
same in the
SpriteBatcher.drawSprite()
method, only automatically, based on the parameters
of the method. So let's check out the
SpriteBatcher
. Listing 8-17 shows the code.
Listing 8-17. Excerpt from SpriteBatcher.java, Without Rotation and Scaling
package
com.badlogic.androidgames.framework.gl;
import
javax.microedition.khronos.opengles.GL10;
import
android.util.FloatMath;
import
com.badlogic.androidgames.framework.impl.GLGraphics;
import
com.badlogic.androidgames.framework.math.Vector2;
public class
SpriteBatcher {
final float
[] verticesBuffer;
int
bufferIndex;
final
Vertices vertices;
int
numSprites;
We look at the members first. The member
verticesBuffer
is the temporary float array in which
we store the vertices of the sprites of the current batch. The member
bufferIndex
indicates
where in the float array we should start to write the next vertices. The member
vertices
is