天天看點

[Cocos2d-x v3.x官方文檔]紋理緩存 紋理緩存 概述

紋理緩存

概述

在遊戲中需要加載大量的紋理圖檔,這些操作都是很耗記憶體和資源的。

當遊戲中有個界面用到的圖檔非常多,第一次點進這界面時速度非常慢(因為要加載繪制很多圖檔)出現卡頓,我們可以使用TextureCache提前異步加載紋理,等加載結束,進入到這個界面再使用這些圖檔速度就會非常快。

Texture2D: 紋理,即圖檔加載入記憶體後供CPU和GPU操作的貼圖對象。

TextureCache(紋理緩存),用于加載和管理紋理。一旦紋理加載完成,下次使用時可使用它傳回之前加載的紋理,進而減少對GPU和CPU記憶體的占用。

常用的方法

當你建立一個精靈,你一般會使用Sprite::create(pszFileName)。假如你去看Sprite::create(pszFileName)的實作方式,你将看到它将這個圖檔增加到紋理緩存中去了,

Sprite* Sprite::create(const std::string& filename)
{
    Sprite *sprite = new Sprite();
    if (sprite && sprite->initWithFile(filename))
    {
        sprite->autorelease();
        return sprite;
    }
    _SAFE_DELETE(sprite);
    return nullptr;
}

bool Sprite::initWithFile(const std::string& filename)
{
    ASSERT(filename.size()>0, "Invalid filename for sprite");

    Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);
    if (texture)
    {
        Rect rect = Rect::ZERO;
        rect.size = texture->getContentSize();
        return initWithTexture(texture, rect);
    }

    // don't release here.
    // when load texture failed, it's better to get a "transparent" sprite then a crashed program
    // this->release();
    return false;
}
           

上面代碼顯示在控制加載紋理。一旦這個紋理被加載了,在下一時刻就會傳回之前加載的紋理引用,并且減少加載的時候瞬間增加的記憶體。(詳細API請看TextureCache API)

擷取TextureCache

在3.0版本中,TextureCache不再作為單例模式使用。作為Director的成員變量,通過以下方式擷取

Director::getInstance()->getTextureCache();
           

擷取紋理

如果檔案名以前沒有被加載時,它會建立一個新的Texture2D 對象,它會傳回它。它将使用檔案名作為key否則,它會傳回一個引用先前加載的圖像。 TextureCache屏蔽了加載紋理的許多細節; addImage函數會傳回一個紋理Texture2D的引用,可能是新加載到記憶體的,也可能是之前已經存在的;

Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);
           

也可以通過getTextureForKey方法來獲得這個key所對應的紋理緩存,如果這個Key對應的紋理不存在,那麼就傳回NULL

Texture2D *texture = Director::getInstance()->getTextureCache()->getTextureForKey(textureKeyName);
           

異步加載紋理

TextureCache類還支援異步加載資源的功能,利用addImageAsync方法。你可以很方面地給addImageAsync方法添加一個回調方法,這樣,當紋理異步加載結束的時候,可以得到通知。

你可以選擇異步加載方式,這樣你就可以為loading場景增加一個進度條。關鍵代碼如下:

TextureCacheTest::TextureCacheTest()
: _numberOfSprites(20)
, _numberOfLoadedSprites(0)
{
    auto size = Director::getInstance()->getWinSize();

    _labelLoading = Label::createWithTTF("loading...", "fonts/arial.ttf", 15);
    _labelPercent = Label::createWithTTF("%0", "fonts/arial.ttf", 15);

    _labelLoading->setPosition(Point(size.width / 2, size.height / 2 - 20));
    _labelPercent->setPosition(Point(size.width / 2, size.height / 2 + 20));

    this->addChild(_labelLoading);
    this->addChild(_labelPercent);

    // load textrues
    Director::getInstance()->getTextureCache()->addImageAsync("Images/HelloWorld.png", _CALLBACK_1(TextureCacheTest::loadingCallBack, this));
    Director::getInstance()->getTextureCache()->addImageAsync("Images/grossini.png", _CALLBACK_1(TextureCacheTest::loadingCallBack, this));
    Director::getInstance()->getTextureCache()->addImageAsync("Images/grossini_dance_01.png", _CALLBACK_1(TextureCacheTest::loadingCallBack, this));
    ....

}

void TextureCacheTest::loadingCallBack(cocos2d::Texture2D *texture)
{
    ++_numberOfLoadedSprites;
    char tmp[10];
    sprintf(tmp,"%%%d", (int)(((float)_numberOfLoadedSprites / _numberOfSprites) * 100));
    _labelPercent->setString(tmp);

    if (_numberOfLoadedSprites == _numberOfSprites)
    {
        this->removeChild(_labelLoading, true);
        this->removeChild(_labelPercent, true);
        addSprite();
    }
}
           

清理緩存

removeUnusedTextures則會釋放目前所有引用計數為1的紋理,即目前沒有被使用的紋理。比如新場景建立好後,使用此方法釋放沒有使用的紋理非常友善。

Director::getInstance()->getTextureCache()->removeUnusedTextures();
           

當沒有其它對象(比如sprite)持有紋理的引用的時候,紋理仍然會存在記憶體之間。基于這一點,我們可以立馬從緩存中移除出去,這樣,當紋理不存需要的時候,馬上就會從記憶體中釋放掉。如下代碼所示:

Director::getInstance()->getTextureCache()->removeTextureForKey("Images/grossinis_sister2.png");
           

當收到"Memory Warning"時,可以調用removeAllTextures()方法。在短期内: 它還将釋放一些資源,防止您的應用程式被殺害; 中期: 它将配置設定更多的資源;從長遠來看:它會是相同的。

Director::getInstance()->getTextureCache()->removeAllTextures();
           

來源網址:https://github.com/chukong/cocos-docs/blob/master/manual/framework/native/v3/texture-cache/zh.md