0

Normally, when one loads the sprite frame cache from a file by calling:

SpriteFrameCache::getInstance()->addSpriteFramesWithFile(filename);

internally, the texture corresponding to that file is added to the texture cache by calling:

    Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(texturePath.c_str());

which is basically creating a Texture2D object from that image and storing it in an unordered_map.


This does not happen internally when I generate my texture on the fly, and add sprite frames to the frame cache by calling the code below within a loop:

I generate a texture on the fly, and add sprite frames to the SpriteFrameCache by doing:

   SpriteFrame* frame;

    if (!isRotated) {
        frame = SpriteFrame::createWithTexture(texture, rect, isRotated, offset, originalSize);
    }else{
        frame = SpriteFrame::createWithTexture(texture, rect, isRotated, offset, originalSize);
    }
    SpriteFrameCache::getInstance()->addSpriteFrame(frame, frameName);

It seems that no calls are made internally to addImage() in the texture cache, when I add frames this way (by calling addSpriteFrame()), even though all the sprite frames are using the same texture.

The counter on the bottom left that displays the number of openGL calls says there are only 2 calls, regardless of how many frames I add to the screen.

When calling

p Director::getInstance()->getTextureCache()->getCachedTextureInfo()

I get the output:

(std::__1::string) $0 = "\"/cc_fps_images\" rc=4 id=254 999 x 54 @ 16 bpp => 105 KB\nTextureCache dumpDebugInfo: 1 textures, for 105 KB (0.10 MB)\n"

Which is the texture that shows the fps rate.... so there is no sign of my texture, but at the same time there is no problem adding frames that use that texture.

So my question is: Will there be a performance problem later on because of this ? Should I add the texture to the texture cache manually ? Are there any other problems that I may encounter by adding my sprite frames this way ?

Also, my texture is created by using Texture2D* tex = new Texture2D(), and then initWithData(). So should I keep a reference to this pointer, and call delete later ? Or is it enough to just call removeUnusedTextures?

Rahul Iyer
  • 19,924
  • 21
  • 96
  • 190

1 Answers1

0

So my question is: Will there be a performance problem later on because of this ?

It depends how many times you'd be using this texture.

Should I add the texture to the texture cache manually ?

Again, it depends how many you'd use it. If it's created dynamically few or more times caching will improve performance as you don't have to recreate it again and again.

Are there any other problems that I may encounter by adding my sprite frames this way ?

I don't think so.

Also, my texture is created by using Texture2D* tex = new Texture2D(), and then initWithData(). So should I keep a reference to this pointer, and call delete later ?

Well if you just want to abandon tex (making it local variable), because you created sprite from it you can do it. But sprite simply has a pointer to this texture. If you'll release texture itself it'll disappear (probably will become a black rectangle).

Or is it enough to just call removeUnusedTextures?

This just clears TextureCache map. If your texture isn't here it won't release it.

You'd have to specify use case of this texture. If - let's imagine - you have a texture, which contains a bullet (which you created using initWithData), which is used frequently. You just can have one texture object stored in your scene and you have to create all bullet sprites from this one texture. Using TextureCache it won't be any faster. However you have to remember to release texture memory when you don't need it anymore (for example when you leave scene), because you create Texture2D using new keyword, not create principle (like Sprite::create, Texture2D doesn't have it), which auto manages memory.

Makalele
  • 7,431
  • 5
  • 54
  • 81
  • Thanks for your answer, but my problem is different: The texture for my sprite sheet is what is created dynamically - so all the frames in the texture are used many times during the scene. I create the texture just once at startup of a scene, and no longer need the texture in other scenes (so will need to unload it). I create sprite frames the way described above, and add it to the spriteframecache, but am not adding anything to the texture cache (should I ?). What is the purpose of the texture cache then? Do I even need it then? Because won't just the spriteframecache be sufficient? – Rahul Iyer Oct 16 '16 at 05:42
  • As far as I understand (and quick lookup in code proves that) SpriteFrameCache is something a level above TextureCache. TextureCache is simply a dictionary of pairs filename, texture. From the other hand SpriteFrameCache is useful for handling spritesheets. It's a dictionary of spriteFrame and it's name. It stores dictionary data of each frame from spritesheet. However textures are still stored in TextureCache. – Makalele Oct 17 '16 at 08:19
  • I still don't understand what I'm supposed to do - looking at the source code of SpriteFrameCache it doesn't add the texture to texture cache if you call createWithTexture(). – Rahul Iyer Oct 17 '16 at 10:55
  • In my opinion you don't need SpriteFrameCache at all. You don't use spritesheet here, because you're creating textures on the fly. You can have one big texture for spritesheet and few spriteframes, which uses the same texture, but also stores x, y, width and height, which makes it a part. – Makalele Oct 17 '16 at 14:03
  • Well how do you make use of autobatching then? Is it enough that all the sprite frames are created from the same texture ? – Rahul Iyer Oct 18 '16 at 04:48
  • It can't be more memory efficient. As for rendering you probably can optimise it somehow. As for autobatching you should ask on cocos2d-x forums. – Makalele Oct 18 '16 at 07:21