Wednesday, November 17, 2010

Atlas Textures

When we first started with Call Connect we used the method for textures that I had been using for my OpenGL framework since I created it which was to have each visual item in it's own texture. And whilst this was working fine for the most part we discovered that there were a few visual abnormalities cropping up such as sprites not appearing to draw at exactly the right size as well as there being artifacts around the edges of some of the textures.

As OpenGL requires that all textures put loaded by it need to be at a power of two this meant that the majority of our images needed to be stretched or squashed into a power of two texture which OpenGL would then resize to the correct size when drawing.

  • An example of the stretched plug animation
 Greg noticed that when he resized the sprites to be saved out into power of two textures and then resized them back the textures would sometimes gain artifacts around the edges. As we could always notice these visual quirks when playing the game we decided something needed to be done.

That was when we came to Atlas Textures. I'd known about using atlas textures for a while but it was always the same thing of choosing between spending time going back and rewriting a bunch of code that worked already (for the most part) or writing new code for features of the game. The latter choice always won out but now that there were some real issues to be resolved we decided to spend the time to make it work properly.

If you don't know about atlas texturing the basic concept is to have one big texture that you put all of your various sprites and animations in, fitting them like a puzzle, and whenever you need to draw a specific sprite you only draw that section of the atlas texture.
The benefits of using this technique are twofold.
Firstly, you don't need to resize any of your sprites into textures of power of two as you can fit them into the atlas texture in their original form.
Secondly, the way OpenGL works is that it loads in each texture to the memory when it needs to draw it so therefore the more textures you have the more time OpenGL will spend swapping and loading in new textures each time the game draws. But if you use one atlas texture OpenGL just needs to load that one big texture at the start of the draw call and each sprite in the game will just draw it's own subsection from that texture. This can be a big performance boost in a sprite heavy game.

  • Here is the (unfinished) atlas texture we are using for Call Connect
 Once we had the atlas texture set up all that was needed was to reprogram the sprite and animation classes to handle drawing from the big atlas texture and to calculate the pixel positions for the top left and bottom right of each sprite.
Whilst the static sprites made the change quite easily the animations required a bit more mathematical rejiggering and after a few "WTF why isn't this working!" moments I managed to get it working as smoothly as it was before. The visual improvement on the static sprites was noticable straight away and the animations looked better too. This blog post is being written after when the atlas texture was implemented and before all the textures have been swapped over to their atlas texture version (I was keen to write this down!) so we shall the overall improvement when that process is complete.

And even though we probably won't see a performance boost in Call Connect due to it's relatively simple nature - in terms of processing and sprite drawing - we have set ourselves up to be able to create much more system intensive games in the future.

So I guess what I'm saying is: Use atlas textures, they'll be worth it in the long run.
Oh and there's some handy tools out there like this flash Atlas Texture creation thingy which you can also download:


No comments:

Post a Comment