Click here to Skip to main content
15,886,783 members
Articles / Mobile Apps / Android

Texture Atlas Maker

Rate me:
Please Sign up or sign in to vote.
4.94/5 (16 votes)
15 Feb 2012BSD6 min read 142.3K   7K   55  
A utility to create texture atlases for 2D OpenGL games
This is an old version of the currently published article.
e Image 1

Introduction

I've decided to open source our in-house texture atlas creation tool, because I think this will be useful for other independent game developers.

Features

  • Built for speed
Loads textures nearly 5 times faster than loading from PNG
  • One click operation
Streamlines the art pipeline. Can creates multiple atlases with multiple formats, all with one click.
  • Open source
Java source code provided, so you can modify the tool for your own needs.

What is a texture atlas?

A texture atlas bin-packs multiple images into a single texture. Because OpenGL textures have to be sized as power of 2, loading the images separately would require a lot of padding, which means wasted GPU memory. As well as that having all images in one texture allows draw-call batching: in other words several sprites can be drawn with one call.

Who is this for?

Although the tool was developed for the iPhone, it is useful for most platforms including Android and PC. The tool is written in java and runs on Windows, Mac and Linux.

A sample iPhone project is included, that demonstrates loading the texture atlas. The code is c++ and designed to be portable.

How to use

Download the file AtlasMaker_jar.zip and unzip. You will need java installed on your machine to use it. You may also need to install PVRTexTool, if you want to create PVR compressed textures.

settings3.png

  • Input folder

The source images for your project must be in PNG format and must be organised in directories according to file format. Select the location of the input folder and the directory structure will be shown. Then select the required file format for each directory

  • 32-bit Targa
This is the default option. Choose this for best quality. Note: targa files have RGB bytes in OpenGL order, so they load faster. This means the file will look odd if you open it on your PC, but it will look fine on the device.
  • 16-bit Targa
Choosing this option uses only 16-bits per pixel, but reduces the number of colours. Textures with subtle colour changes (i.e. gradients) will look bad.
  • PVR
Compressed PVR format. Uses either 2, or 4-bits per pixel. This format works better with "organic" images with no transparent borders. Note: a padding of 2 pixels is created around each image. This is to prevent pixels appearing from adjacent images (the PVR algorithm draws pixels outside of the image borders).
  • Output file

Select the name and location of the output file. The texture atlases will be saved to the same directory.

Advanced options

options.png

Click on the "Options..." button to open advanced options.

  • Alpha threshold
Transparent pixels are trimmed off all source images. The alpha threshold indicates what is considered to be transparent.
  • Location of PVRTexTool
This is the file location where you installed the PVRTexTool (PVRTexTool.exe)
  • PVR Options
When the PVR file format is selected, first the texture atlas will be created as a PNG, then the PVRTexTool will be called to convert it to PVR. This is a slow operation, so by default "Convert PVRs" is deselected.
Choose 2-bit for smaller memory use, but lower quality, or 4-bit for higher quality.

Output tabs

A tab is created for each texture. The tab icon hold a preview of the texture. For convenience, clicking anywhere in the texture will display the file name of the image clicked on.

Textures created

OpenGL textures must be have height and width dimension that are power-of-two. As well as that, PVR textures must be square. The iPhone limits the maximum texture size to 1024x1024.

The application tries to fit the images in the smallest texture size possible: i.e. first it tries to fit in 32x32, then 32x64, then 64x64, then 128x64... and so on till the maximum 1024x1024. If the images still don't fit, then a second texture will be created, and so on.

Each file will be named by the directory and an index number. E.g. if images are in the directory "images" then the following textures are created: images0.tga, images1.tga, images2.tga, etc.

Output XML file

The application creates an XML file, which contains all data for each image in each texture atlas, example:

XML
<atlas numImages="4">
  <texture file="testImages0.pvr">
    <image name="arch" x="0" y="0" width="89" height="71"/>
    <image name="prowlerBody0_1" x="36" y="342" width="43" height="34" yOffset="5" transWidth="46" transHeight="39"/>
  </texture>
  <texture file="dump0.pvr">
    <image name="arrowDownPressed" x="400" y="54" width="46" height="39"/>
    <image name="arrowUpPressed" x="448" y="54" width="46" height="37"/>
  </texture>
</atlas>

First, the "atlas" element tells you total images in atlas, so memory can be pre-allocated when loading.

Then each texture element has the file name and a list of image element.

Each image element contains the following data:

  • x, y, width, height
The position within the texture and size of image
  • xOffset, yOffset, transWidth, transHeight
Padding data for sprite animations. If we have sprite animations, each sprite needs to be padded so that the image doesn't "jump" around during animation, but we don't want to store the blank space in the texture and waste memory.
xOffset.png

Why PNG is unsuitable for games

PNG is a complex format and slow to decode. Here are some benchmarks, which show just how slow PNG is:

PNGTarga 32-bit*Targa 16-bit
Loading Windows *64 ms9 ms5 ms
Loading iPhone 3GS*385 ms83 ms
Size1.27 MB2.42 MB1.23 MB
Zipped size1.26 MB1.25 MB339 kB
Loading a 1024 x 1024 texture (complex image with transparency)

As you can see on the iPhone texture loading is 4.6 times slower than 32-bit Targa. Although the Targa file is twice as big it's the same size when zipped, so the package size will be the same. On top of that, if your images only need to be 16-bit quality you get double savings. PNG does not have any 16-bit option.

As you can see, using Targa is a no-brainer.

  • Notes:

PNG decoded on Windows using libpng.PNG decoded on iPhone using native iOS API (i.e. UIImage). Targa is compressed RLE Targa.

Demo iPhone project

Included is a xcode project that opens the generated textures and displays a sprite.

The following classes are used in the project:

  • Game
Main game object.
  • ResManager
Sets up OpenGL state and initialises all resources
  • AtlasMaster
Reads atlas xml file and creates the AtlasImage objects and textures and stores them in a map for retrieval.
  • XParser
Fast XML parser, with cut down functionality. Parses using forward-only method to avoid the overhead of creating a DOM.
  • TargaReader
Reads 32-bit and 16-bit Targa files
  • CommonBuffer
All texture files are loaded into a shared buffer, rather than creating and deleting each time
  • ImagePVR
Loads PVR textures.
  • AtlasImage
Creates a textured quad for each image.
Note: the project uses boost/unordered_map.hpp. You need to download boost and set the project include headers in xcode to point to where you installed boost. Alternatively, you can change the line: #define fmap boost::unordered_map, to #define fmap std:map in precompile.h

License

This application is released under the BSD license. This means both commercial and non-commercial entities can use it. Commercial and non-commercial third parties can also include it in their products for free. The only thing I ask is that the copyright notice remains in the About box and source code.

License

This article, along with any associated source code and files, is licensed under The BSD License


Written By
Software Developer Astronautz
Spain Spain
After working in the software industry for many years, I've started my own games company that specialises in strategy games for mobile platforms.

Comments and Discussions

Discussions on this specific version of this article. Add your comments on how to improve this article here. These comments will not be visible on the final published version of this article.