【amazing cocos2d-x 3.0之十四】內存管理(2):紋理緩存(Texture Cache)

1. 介紹


紋理緩存是將紋理緩存起來,之後的繪製工作就能減少內存。每一個緩存圖像的大小,顏色和區域範圍都是可以被修改的。這些信息都是存儲在內存中,不用在每一次繪製的時候都發送給GPU。


2. CCTextureCache


Cocos2d通過調用CCTextureCache或者CCSpriteFrameCache來緩存精靈的紋理。

當這個精靈調用CCTextureCache 或 CCSpriteFrameCache的方法的時候,cocos2dx將使用紋理緩存來創建一個CCSprite。所以你可以預先將紋理加載到緩存中,這樣你在場景中使用的時候就非常方便了。怎麼樣加載這些紋理就看你自己的想法。例如,你可以選擇異步加載方式,這樣你就可以爲loading場景增加一個進度條。

當你創建一個精靈,你一般會使用CCSprite::create(pszFileName)。假如你去看CCSprite::create(pszFileName)的實現方式,你將看到它將這個圖片增加到紋理緩存中去了:

bool CCSprite::initWithFile(const char *pszFilename)
{
    CCAssert(pszFilename != NULL, "Invalid filename for sprite");
    CCTexture2D *pTexture = CCTextureCache::sharedTextureCache()->addImage(pszFilename);

    if (pTexture)
    {
        CCRect rect = CCRectZero;
        rect.size = pTexture->getContentSize();
        return initWithTexture(pTexture, rect);
    }

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

上面代碼顯示一個單例在控制加載紋理。一旦這個紋理被加載了,在下一時刻就會返回之前加載的紋理引用,並且減少加載的時候瞬間增加的內存。(詳細API請看CCTextureCache API)


3. CCSpriteFrameCache


CCSpriteFrameCache單例是所有精靈幀的緩存。使用spritesheet和與之相關的xml文件,我們可以加載很多的精靈幀到緩存中,那麼之後我們就可以從這個緩存中創建精靈對象了。

和這個xml相關的紋理集一般是一個很大的圖片,裏面包含了很多小的紋理。下面就是一個紋理集的例子:

有三種方式來加載紋理集到CCSpriteFrameCache中:
(1)加載一個xml(plist)文件
(2)加載一個xml(plist)文件和一個紋理集
(3)通過CCSpriteFrame和一個精靈幀的名字

具體完整API請看CCSpriteFrameCache API。

樣例:

CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache(); 

cache->addSpriteFramesWithFile(“hello.plist”, “hello.png”); 

使用緩存的原因就是減少內存,因爲當你使用一個圖片創建一個精靈的時候,如果這個圖片不在緩存中,那麼就會將他加載到緩存中,當你需要用相同的圖片來新建精靈的時候,就可以直接從緩存中取得,而不用再去新分配一份內存空間。


4. CCSpriteFrameCache 對比 CCSpriteBachNode


(1) 最好是儘可能的使用spritesheets (CCSpriteBatchNodes)。這樣的方式是減少draw的調用次數。Draw的調用是非常耗時的。每一個batchnode調用一次draw就可以繪製上面所有的節點,而不是每一個節點的draw都單獨調用一次,


(2) CCSpriteBatchNode渲染所有的子節點只需要一次,只需要調用一次draw。那就是爲什麼你需要把精靈加載batch node的原因,因爲可以統一一起渲染。但是隻有這個精靈使用的紋理包含在batch node中的纔可以添加到batch node上,因爲batch node一次只渲染這相同的紋理集。


(3) 假如你把精靈添加到其他的節點上。那麼每一個精靈就會調用自己的draw函數,batch node就沒起作用了。


(4) CCSpriteBatchNode也是一個常用節點。你可以從場景中像其他節點一樣移除掉。紋理集和精靈幀都被緩存在CCTextureCache 和 CCSpriteFrameCache單例中。假如你想要從內存中移除紋理集和精靈幀,那麼你不得不通過緩存類來完成這個工作。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章