Showing posts with label texture atlases. Show all posts
Showing posts with label texture atlases. Show all posts

Friday, July 19, 2013

Game Programming and 2d Art, Part 3 (Texture Atlases)

Welcome to the final part of my series on game programming with 2d art assets!

The previous 2 entries are here:
Part 1
Part 2

If you don't know already, a texture atlas (also known as a spritesheet) helps game developers to display neat 2d graphics in to their games.  There is usually some sort of organization sanity happening with them as well, for example, all of the frames of animation for a player character would be in one atlas and its file name could be "herowalking.png" or something like that.

Of course, this isn't limited in any way, I've often used atlases that are just a collection of User Interface components usually in a file called "gui.png" -- it has all the buttons, graphs, meters, check marks, and all sorts of doodads, all conveniently packed in to one GUI atlas file.

At any rate, assembling a texture atlas can be extremely tedious.  You have to make sure nothing overlaps anything else, that all your texture objects can fit, you will even need to remember where you put each object so that a game engine can subsequently extract each object.  It is so much planning and tracking!

Thankfully, there is a program out there called Texture Packer.  It is a commercial product, but all in all, it's a nice, convenient tool to have in your tool belt.  I'll even go so far to say that if you make 2d games commercially, you probably shouldn't be without it!  It's reasonably priced as well for how much time and money it would save you.

Let's put it this way, I spent about 2 weeks making a command line program to extract texture sizes and coordinates and it was a pain to deal with.  On top of that, I was still relying on manually entering texture coordinates in to our games from that program's output.  If an artist changed any graphics, it would be a nightmare changing things all over the place.

This program keeps track of all that stuff, and allows you to output all that relevant information in to various game engine formats; or for us, even a generic XML data format!

Below is a screencap of what it looks like:





Honestly, it's pretty good.  There are a couple of features that would be nice to have; like manually being able to move texture objects around (or swap places with each other), but what the tool does is automatically find a place for your sprites in the empty atlas for you, so you don't have to sit around with a magnifying glass lining pixels up manually!

There are quite a few neat features as well about it, like automatically generating different scaled versions of your atlas (click AutoSD) for catering to different resolutions, being able to specify atlas geometry (like powers of two, max width/height, etc), and it can even import SVG files.

It takes a little while getting use to, but all in all, it's a pretty useful tool and saves us quite a bit of time dealing with artwork.

I have noticed that the windows and linux ports are a little behind the mac port, and again, it is missing a couple neat features, but all in all, it is useable and useful.

They offer a trial version of the program also, so you can check it out without having to buy it first.

Friday, May 10, 2013

Game Programming and 2d Art, Part 2

Ok, so we finally have a graphic.  This is a raster graphic, preferably a PNG file, and we need to put it in to a game.

If you're not sure what I'm talking about, check the first part of this article: Game Programming and 2d Art

As a programmer, the first step to get this art in game is to load the png file in to memory and get to the raw RGB data.  This is ideally suited for libpng (google for tech examples how to do use this library).

Once you get the pixel data, you can load it in to your favorite graphics library (opengl for example) and start putting it on quads/triangles/whatever.  Of course, other problems can come up before you might actually see your graphic (like orthogonal viewport, etc).  Those concepts are beyond this article (if you're interested, check out nehe's website for their tutorials).

This is all well and good and ideally you can finally put some basic png file to direct use in a game.  Already this probably could be a rollercoaster of learning and complexities, but the fun doesn't stop there!

The "better" way of handling 2d graphics is to use texture atlases.  Or rather, a collection of individual png files crammed in to one larger png file.  If you've ever opened "skins" or texture packs for various games (quake, minecraft, etc), you may have noticed that the graphics are all over the place in a larger raster graphic file (png).  The face is upside down and is connected to the chest, which is in turn connected to their legs and maybe their shoes below that.  It basically looks like someone took a steamroller to a player or monster and flattened them all out in to one graphic file.

Welcome to the wonderful world of texture atlases.  Before we begin, let's talk about some considerations you should take in to account.

First, atlas dimensions and memory.

Not everyone is running a desktop, especially with amazing graphics cards.  More over, if you're going to deploy on a mobile device or tablet, this is a major problematic area.  That said, you need to consider how big your atlas is.

Powers of two (1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2056, etc) or PoT is a very critical concept to understand when it comes to texture memory.  Your texture atlases should always be in perfect power of two dimensions.  Specifically, if your atlas is 256 pixels tall, it should be 256 pixels wide.

Why?

Well, if you understand basic computer science, you should understand that computers work in base 2 (0, 1).  Powers of two are significant in that it aligns memory perfectly with memory offset techniques.  It's complicated, but it boils down to optimizing how a CPU and GPU process data.  More over, older graphics cards were completely unable to use Non-Powers of Two (nPoT) at all.  Trying to load graphic data with nPoT dimensions would result in garbled graphic data... usually like someone took the bottom of your graphic and ripped it sideways as it is rendered from top to bottom... if it renders anything at all other than a white box.

So, your PoT texture atlas is fine, but there's still a problem.  There are a lot of things that can go wrong when rendering graphic data, but a common issue is that you may have exceeded a maximum amount of memory (like try loading a 2056x2056 texture atlas), while it would be nice if your program told you when you exceeded a maximum, it will likely instead crash when trying to load or use the data.

Of course, it isn't this simple, some graphics cards and computer systems will load this just fine (dependent on hardware per device), leaving you very confused when your masterpiece of a game simply won't work on your friend's computer, but works fine on yours.  Worse, sometimes hardware may actually do some sort of complicated emulation or paging to force large texture data to work.  The major drawback here is that you will be swapping data in and out of the CPU/GPU so constantly that the performance of your game will suffer tremendously.

At the end of the day, working with large atlases can give you various scenarios.  Sometimes it will work, others will make your game run like terrible, and others will out right crash the program.

There really isn't any "best" answer here other than to select some maximum atlas size during your technical design phase and stick with it.  There are software strategies to attempt to figure out a device's max texture size and to parse that large atlas data in to smaller pixel data clumps (that likely need to also follow PoT rules), but again, that can be very complicated, but may be necessary if you want to be a serious game/graphics engine programmer.

The final result that you will want to work with isn't even the atlas itself, but rather the texture objects inside the atlas that you will want to use!  All this headache just to find there's even more to it!

There is a tool that simplifies this a bit, and I talk about it here in the last article.