Continuing with my extensions to Apple's
Texture2D class, this post is about extending it to render a sprite from a sprite sheet, which is basically just rendering only part of the texture. Sprite sheets are useful for storing all of the frames for an animated sprite, or simply for storing multiple images in a single texture. It's not only convenient, but can have a positive effect on performance as the texture does not need to be changed from one sprite to the next (although I haven't made this optimisation in the example code, which selects the texture each time).
This simple implementation requires all the sprites to be the same size, laid out from left-to-right and top-to-bottom in the texture. For example, the following sprite sheet was created using some sprites from Prince of Persia:
Each sprite here is 45x45 pixels, numbered 0 (top left sprite) to 12 (bottom-most sprite).
To render one of the sprites from this sprite sheet, the texture co-ordinates passed to the
glTexCoordPointer OpenGL call needs to be selected to bound the appropriate sprite. First, let's look at how
Texture2D renders an image.
Texture2D creates a texture large enough to fit the entire image - an OpenGL texture needs to be a power of 2, so for a 180x180 image, a texture size of 256x256 is used.
A rectangle with a bounding box starting from (0, 0) with a width of 1.0 and a height of 1.0 represents the full texture. To render part of the texture a smaller rectangle needs to be passed to
glTexCoordPointer before drawing the texture.
Texture2D keeps two variables representing the x and y scale of the original image to the texture size (
maxT), which it uses to render the image by passing
glTexCoordPointer a rectangle starting at (0, 0) with a width of
maxS and a height of
To render one of the sprites in the image, the origin and dimensions need to be determined. If we know how many sprites there are across (
dimx) and down (
dimy), and the index of the sprite to render (
index), then the bounding box can be determined as fractions of
x = maxS * (index % dimx) / dimx y = maxT * int(index / dimy) / dimy width = maxS / dimx height = maxT / dimy
Have a look at
MyTexture2D class in the code on github for a full implementation of this. The project also includes a small iOS demonstration app showing an animated figure using the sprite sheet from this post.