Realtime Texture Packer for swf assets in Haxe Flash and HTML5 targets

In my last two posts I demonstrated loading swf assets into a haxe project which targets flash and html5 and then adding basic tween animations to individual elements.

For my projects the next obvious step is to get these assets into a hardware accelerated framework like Away3d or Starling. A technique which I often use to achieve this is to convert layouts into sprite sheets / texture atlases in preperation for upload to the GPU. This can obviously be done manually, however if assets are continually changing through out development it can become quite tedious to have to re-export sprite sheets multiple times per day. So this is where a real time texture packer really comes in handy.

For this I use a small realtime texture packer library.

haxelib install texture-packer

or http://lib.haxe.org/p/texture-packer/

At the heart of this library, lies the TexturePacker class. The basic concept is to add openfl IBitmapDrawable objects via texturePacker.add(iBitmapDrawable); then call the texturePacker.pack(); method which will return an IAtlasPackage object containing a bitmapdata object with all the IBitmapDrawable objects packed into it along with an xml object describing the atlas layout.

In the below Haxe example we loop through Mc_Assets as seen in the image to the right and add all of it’s children to the TexturePacker. texturePacker.pack(); is then called, which in turn returns an IAtlasPackage object. The IAtlasPackage object can then be used to create a texture atlas.

texturepack

package net.peteshand.realtimeTexturePacker;
 
import com.imagination.texturePacker.api.IAtlasPackage;
import com.imagination.texturePacker.impl.TexturePacker;
import openfl.display.Bitmap;
import openfl.display.Sprite;
import openfl.Lib;
 
/**
 * ...
 * @author P.J.Shand
 */
class Main extends Sprite 
{
	private var placement:Float = 0;
 
	public function new() 
	{
		super();
 
		var clip:Sprite = new Mc_Assets();
 
		TexturePacker.TARGET_TEXTURE_SIZE.setTo(256, 256);
		TexturePacker.AUTO_INCREASE_TEXTURE_SIZE = true;
		TexturePacker.debug = true;
 
		var texturePacker = new TexturePacker();
		for (i in 0...clip.numChildren) 
		{
			texturePacker.add(clip.getChildAt(i));
		}
		var atlasPackage:IAtlasPackage = texturePacker.pack();
 
		showSpriteSheets(atlasPackage);
	}
 
	private function showSpriteSheets(atlasPackage:IAtlasPackage) 
	{
		var bitmap:Bitmap = new Bitmap(atlasPackage.bitmapData);
		bitmap.scaleX = bitmap.scaleY = 0.5;
		bitmap.x = placement;
		addChild(bitmap);
		placement += bitmap.width + 2;
 
		if (atlasPackage.next != null) {
			showSpriteSheets(atlasPackage.next);
		}
	}
}

The result of the above code can be viewed below in both the flash and html5 targets.

Flash Version

HTML5 Version

Along with a bitmapdata and xml atlas, if all the IBitmapDrawable objects aren’t able to fit on the one spritesheet, a second IAtlasPackage object will be created and linked via the “.next” property. If there are to many IBitmapDrawable objects to fit on 2 atlases yet another IAtlasPackage will be created and linked via the “.next” property of the 2nd IAtlasPackage, and so on.

Source code of this example can be downloaded from github.

In the next post view how to import these assets into Away3D.