SpriteAtlas Made Easy

Well this is not quite as easy as actually packing things before hand, (and not as fast) but is great for prototyping and adding stuff without having to repack every time. I made these classes when I made my Atlas engine which is crap but it was nice not having to deal with json/xml and still get atlases.

Here is the paste bin for the 3 classes.

http://pastebin.java-gaming.org/7718c134177 <---- Atlas class
http://pastebin.java-gaming.org/718c3214777 <---- BufferedImageUtils class
http://pastebin.java-gaming.org/18c3137477c <---- TextureRegion class.

Loads images onto a BufferedImage via java2d and a given name for the image. It will save the region coordinates of each image. Once all images are added, it will create a texture from the BufferedImage. You can then grab any region that was loaded. Here is example usage.


		Atlas a1 = new Atlas(1024, 1024, "a1");
		a1.addTexStrip(BufferedImageUtils.loadImageStrip("res/bloodSplat.png", 2, 2, 4, 128, 128), "bloodSplash");
		a1.addTex(BufferedImageUtils.loadImage("res/player/idle.png", true), "playerTopIdle");
		a1.addTex(BufferedImageUtils.loadImage("res/player/botIdle.png", true), "playerBotIdle");
		a1.addTex(BufferedImageUtils.loadImage("res/player/fire1.png", true), "playerFire1");
		a1.addTex(BufferedImageUtils.loadImage("res/player/fire2.png", true), "playerFire2");
		a1.set();

//later in code
                TextureRegion topIdle,botIdle,fire1,fire2;
		topIdle = a1.getTexRegion("playerTopIdle"); 
		botIdle = a1.getTexRegion("playerBotIdle");
		fire1 = a1.getTexRegion("playerFire1");
		fire2 = a1.getTexRegion("playerFire2");
//loading a strip of images into an array of TextureRegions
		FxBloodSplat b = new FxBloodSplat(l.x + Rnd.random(1), l.y + Rnd.random(1), a1.getRegion("bloodSplash", 3), (int) a); 

//rendering. 
	public static void drawImage(float x, float y, float w, float h, TextureRegion tex, Vector4f color)
	{
		glBindTexture(GL_TEXTURE_2D, tex.texID);
		glBegin(GL_QUADS);
		{
			glColor4f(color.x, color.y, color.z, color.w);
			glTexCoord2f(tex.region[0], tex.region[1]);
			glVertex2f(x - w / 2, y - h / 2);
			glTexCoord2f(tex.region[2], tex.region[3]);
			glVertex2f(x + w / 2, y - h / 2);
			glTexCoord2f(tex.region[4], tex.region[5]);
			glVertex2f(x + w / 2, y + h / 2);
			glTexCoord2f(tex.region[6], tex.region[7]);
			glVertex2f(x - w / 2, y + h / 2);
		}
		glEnd();
	}

This is quick and dirty and can very much be improved. It is fast enough for smaller games but for a larger project, use libGDX with their oh so nice texture packer. This should be an easy introduction for people looking to play with texture atlases before delving into libGDX or their own versions. I use it a bunch for my non-libgdx stuff as I am too damn lazy to use all the fancy texture packers.

:slight_smile:

I did a java compiler “addon” a while back, to do just something like this. You specify all the single images in your code and at compile-time a texture atlass is created automaticly by the compiler.

take a look, perhaps you will like it :):

I remember reading when you first posted that and was like, “I am not quite sure how that works.” Now I am like, “Hot reloading images? **** yeah!” I may look into that lib in the feature. I am not a huge fan of annotations (probably from lack of experience). I like specifying all resources before hand which is what your lib does but not in the actually code.

+1 btw.

If you specify the same resource twice, will it load it twice?

        @InjectResource(file = "resources/textures/ball.png")
        private TextureAtlasElement normal;
        @InjectResource(file = "resources/textures/ball.png")
        private TextureAtlasElement glow;

The thing is, I created a very flexible resource system. You can extend it very easily with your own file formats, caches, processors(like the atlass creation) and own hot reload functionality.

I did the AutoAtlas in just 1 hour and it was only intended as a proof of concept, take a look at the source. Beside the Atlass stuff I “stole” from libgdx, the whole project is only some couple lines of code.

Every resource gets process only once(by every registered resource processor). How many times a resource is loaded on runtime depends on your caching strategy.

You could probably implement the same thing for your Texture Atlas implementation in a couple of lines too.

ps: the annotations are the only way in Java to hook yourself into the compiler. Take a look at annotation processing if you are interested. I btw hid as much as possible of the complexity of this.

FWIW and a bit off topic from the OP, libgdx has AssetManager which does ref counting of assets, assets can have dependencies, and assets can do loading on the GL thread, a separate thread, or both (which enables a loading screen to be shown while loading assets). It was a huge pain to get right, but it works well.