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 (maxS
and 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 maxT
.
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 maxS
and maxT
:
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.
Post a comment