Simple Texture Atlas for SFML.NET

By Mark Smith | 2d, code, csharp, sfml
1 Jun 2013

I recently noticed Kyle Pulver mention SFML’s lack of texture atlases. After a quick bit of searching, I couldn’t find anyone that had implemented any sort of texture atlas in SFML, so I whipped up a very basic implementation in C#. Note that there’s currently no error handling of any kind.

This class works with texture atlases generated with the excellent TexturePacker, and requires Json.NET. Make sure to set a “Data Format” of “JSON (Array)” in TexturePacker.

The TextureAtlas class:

class TextureAtlas
{
    private Texture mTexture;
    private Dictionary<string, IntRect> mTextureRects;

    public TextureAtlas(string jsonFileName, string textureName, bool trimPaths = false)
    {
        // load in the texture atlas texture
        mTexture = new Texture(textureName);

        // load in the json data describing all frames in the atlas
        string fileContents = File.ReadAllText(jsonFileName);
        RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(fileContents);

        // parse location and size of each frame's sub-texture, keyed by name, where the data is the IntRect for the frame's sub-texture
        mTextureRects = new Dictionary<string, IntRect>(rootObject.frames.Count);
        foreach (Frame frame in rootObject.frames)
        {
            Frame2 frameData = frame.frame;
            string fileName = frame.filename;

            if (trimPaths)
            {
                fileName = fileName.Substring(fileName.LastIndexOf('/') + 1);
            }

            mTextureRects.Add(fileName, new IntRect(frameData.x, frameData.y, frameData.w, frameData.h));
        }
    }

    public Texture GetTexture()
    {
        return mTexture;
    }

    public IntRect GetTextureRect(string textureName)
    {
        IntRect textureRect;
        if (mTextureRects.TryGetValue(textureName, out textureRect))
        {
            return textureRect;
        }

        return new IntRect(); // invalid texture name // TODO: handle error!
    }

    public Sprite CreateSprite(string textureName)
    {
        IntRect textureRect;
        if (mTextureRects.TryGetValue(textureName, out textureRect))
        {
            return new Sprite(mTexture, textureRect);
        }

        return new Sprite(); // invalid texture name // TODO: handle error!
    }
}

Usage:

TextureAtlas atlas = new TextureAtlas("assets/img/spritesheet_enemies.json", "assets/img/spritesheet_enemies.png", true);

// create a new sprite that is set to a specific texture from the atlas
Sprite atlasSprite1 = atlas.CreateSprite("enemy_1");

// manually set the sprite's texture
atlasSprite1.TextureRect = atlas.GetTextureRect("enemy_2");

SFML Texture Atlas Example
Full source for TextureAtlas.cs which also has a bunch of classes for handling the JSON data that were generated by http://json2csharp.com/

Tags: , , ,

3 Comments

  1. Kyle Pulver says:

    Hey just curious, does this end up working if you use the repeat texture flag in SFML? I think in most cases the built in repeat will just repeat the entire atlas instead of the rect you specify, but I haven’t yet tested this in SFML yet.

  2. Mark Smith says:

    Just tried it out, and it repeats the entire atlas. Not sure how to get it to just repeat the specified rect, might have to use a RenderTexture instead?

  3. Kyle Pulver says:

    Yeah, looks like repeating will just have to be the old fashioned way of just rendering enough times to cover the window/texture.

Leave a Reply

Your email address will not be published. Required fields are marked *