[SOLVED] Loading LibGDX / Spine Atlas

[SOLVED] Loading LibGDX / Spine Atlas
0.0 0


Hello guys,

I’m currently using spine in my project, and everything is going fine, except for one issue:
Instead of using TexturePacker, I’m trying to use Spine’s texture packer, as I have it’s license. The problem is that Spine generates a LibGDX Atlas format (plain text), which I can’t directly use with any Cocos2D sprite loading functions, as they require a plist. Since spine have the Atlas loader implemented, I tried to use it to load my atlas file, but it fails, with the debugger pointing to a fault address error…
First, let me post my code for the atlas loading:

// Load animations
    Constants::screechAnimation = CCAnimation::create();
    CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache();
    Atlas* atlas = Atlas_readAtlasFile(s_Powerup_FX_Screech_Atlas);
    AtlasRegion* region = atlas->regions;

    while(region) {
        CCSpriteFrame* sf = CCSpriteFrame::create(s_Powerup_FX_Screech_Image,
            CCRectMake(region->x, region->y, region->width, region->height),
            CCPointMake(region->offsetX, region->offsetY),
            CCSizeMake(region->originalWidth, region->originalHeight));
        cache->addSpriteFrame(sf, region->name);
        region = region->next;

    CCAnimationCache::sharedAnimationCache()->addAnimation(Constants::screechAnimation, s_Powerup_FX_ScreechAnimationName);

I’ve looked at spine runtime sources and found that these functions needs to be implemented for atlas loading to work, and are the cause of the faulty memory adress:

 * Functions that must be implemented:

void _AtlasPage_createTexture (AtlasPage* self, const char* path);
void _AtlasPage_disposeTexture (AtlasPage* self);
char* _Util_readFile (const char* path, int* length);

As they are needed in Atlas.cpp

But I’ve found them implemented in spine-cocos2dx.cpp:

void _AtlasPage_createTexture (AtlasPage* self, const char* path) {
    CCTexture2D* texture = CCTextureCache::sharedTextureCache()->addImage(path);
    CCTextureAtlas* textureAtlas = CCTextureAtlas::createWithTexture(texture, 4);
    self->rendererObject = textureAtlas;
    // Using getContentSize to make it supports the strategy of loading resources in cocos2d-x.
    // self->width = texture->getPixelsWide();
    // self->height = texture->getPixelsHigh();
    self->width = texture->getContentSize().width;
    self->height = texture->getContentSize().height;

void _AtlasPage_disposeTexture (AtlasPage* self) {

char* _Util_readFile (const char* path, int* length) {
    unsigned long size;
    char* data = reinterpret_cast(CCFileUtils::sharedFileUtils()->getFileData(
        CCFileUtils::sharedFileUtils()->fullPathForFilename(path).c_str(), "r", &size));
    *length = size;
    return data;

And, of couse, i’m importing spine-cocos2dx.h and compiling the whole extensions. So, any idea why this code is not being executed?

Thanks for your attention!

PS: The main reason for using spine texture packer is that i’ll be able to use options that are blocked in TexturePacker for free users, as trim, rotate and other , and have already paid for spine, I don’t want to pay for a feature spine already has…

— Edit:
Oh well, it turns out I was loading with the wrong filename…. Anyway, if someone needs to know how to use Spine’s Atlas loader, here it is :stuck_out_tongue: (i’ve edited my code as it was wrong)


Did you not have any issues with sprite rotation? I’ve noticed Cocos2d plist format rotates clockwise, libGDX on the other had handled counter-clockwise.

Here is a optional implementation that will handle both cocos2d plist and libGDX atlas format and use the correct 90 degree rotation:


I haven’t tried sprite rotation yet, but it’s nice to know there’s a solution already, thanks!


Hey Jason, I noticed that you’ve forgotten to implement the removeSpriteFramesFromAtlas function, which is also very handy, I can’t push it right now to your repo, but here it is:

    /** Removes multiple Sprite Frames from CCDictionary.
    * @since v0.99.5
    void removeSpriteFramesFromDictionary(CCDictionary* dictionary);

    /** Removes multiple Sprite Frames from Atlas.
    void removeSpriteFramesFromAtlas(Atlas* atlas);


void CCSpriteFrameCache::removeSpriteFramesFromFile(const char* plist)
    std::string fullPath = CCFileUtils::sharedFileUtils()->fullPathForFilename(plist);
    size_t extPos = string(plist).find_last_of("."); 
    int cmp = strcmp(&plist[extPos], ".atlas"); 

    if ( !cmp ) { 
        Atlas* atlas = Atlas_readAtlasFile(fullPath.c_str()); 
    } else {
        CCDictionary* dict = CCDictionary::createWithContentsOfFileThreadSafe(fullPath.c_str());


        // remove it from the cache
        set::iterator ret = m_pLoadedFileNames->find(plist);
        if (ret != m_pLoadedFileNames->end())

void CCSpriteFrameCache::removeSpriteFramesFromAtlas(Atlas* atlas)
    CCArray* keysToRemove = CCArray::create();
    AtlasRegion* region = atlas->regions; 
    do { 
        std::string spriteFrameName = region->name; 
        CCSpriteFrame* spriteFrame = (CCSpriteFrame*)m_pSpriteFrames->objectForKey(spriteFrameName); 
        if (spriteFrame) 
    } while ((region = region->next));



Thanks, posted the commit.


There’s just a small change needed for this code load an Atlas with multiple pages at addSpriteFramesWithAtlas:

        // create frame 
        spriteFrame = new CCSpriteFrame(); 
        CCTextureAtlas* texAtlas = static_cast(region->page->rendererObject); 

            CCRectMake(region->x, region->y, region->width, region->height), 
            CCPointMake(region->offsetX, region->offsetY), 
            CCSizeMake((float)region->originalWidth, (float)region->originalHeight) 
        // add sprite frame 

You can also remove the CCTexture2DpobTexture* as it won’t be needed anymore ;D