I needed a simple texture packer for FreeType to pack my glyphs, so i retrofitted our old ImagePacker code to work with Pixmap’s and be able to generate TextureAtlases. This means you can now generate TextureAtlases on the fly, with the caveat that the packing might not be 100% optimal (no rotation, as with Nate’s TexturePacker). The packer supports padding and border pixel duplication and multi-page packing in case your pixmaps don’t fit onto a single page. It uses the infamous Black Pawn packing algorithm.
The packer supports incremental, asynchronous inserts, meaning you don’t have to pack all images at once. This is useful if you want to fetch thumbnails from the web on a separate thread for example. In case of font rendering it will allow me to create a glyph cache, so scripts like Arabic or Chinese can be better supported eventually, with some caveats.
You can of course also just use it the old fashioned way, throw Pixmaps at it, generate a TextureAtlas and call it a day. Here is some example code for the two use cases.
// 512x512 pixel pages, RGB565 format, 2 pixels of padding, border duplication PixmapPacker packer = new PixmapPacker(512, 512, Format.RGB565, 2, true); packer.pack("First", pixmap1); packer.pack("Second", pixap2); TextureAtlas atlas = packer.generateTextureAtlas(TextureFilter.Linear, TextureFilter.Linear);
To dispose of the resources, simply dispose the generated TextureAtlas.
In the incremental scenario, you pack images whenever you have something new to pack, then update a TextureAtlas you allocated.
// 512x512 pixel pages, RGB565 format, 2 pixels of padding, no border duplication PixmapPacker packer = new PixmapPacker(512, 512, Format.RGB565, 2, false); TextureAtlas incrementalAtlas = new TextureAtlas(); // potentially on a separate thread, e.g. downloading thumbnails, preparing glyphs packer.pack("thumbnail", thumbnail); // on the rendering thread, every frame packer.updateTextureAtlas(incrementalAtlas, TextureFilter.Linear, TextureFilter.Linear); // once the atlas is no longer needed, make sure you get the final additions. This might // be more elaborate depending on your threading model. packer.updateTextureAtlas(incrementalAtlas, TextureFilter.Linear, TextureFilter.Linear); incrementalAtlas.dispose();
Finally, you can also use the packer without generating an atlas. In that case you will most likely be interested in the Array
PixmapPacker packer = new PixmapPacker(512, 512, Format.RGB565, 2, true); packer.pack("First", pixmap1); packer.pack("Second", pixap2); // do something interesting here packer.dispose();
And that’s it. I myself hate preprocessing tools, especially when i’m still developing. The PixmapPacker should ease your pain a tiny little bit when it comes to packing images during your development. I suggest using the offline packer tools once you finalize your app/game as packing Pixmaps on the fly does cost some computational power.