纹理缓存(Texture Cache)讲解

2015年03月24日 15:34 0 点赞 0 评论 更新于 2025-11-21 18:28

简介

纹理缓存是一种将纹理数据存储在内存中的机制,其目的是为后续的绘制工作提供便利。在纹理缓存中,每个缓存图像的大小、颜色和区域范围都可以进行修改。借助纹理缓存,纹理数据无需在每次绘制时都重新发送给 GPU,从而提高了绘制效率。

CCTextureCache

Cocos2d 可通过调用 CCTextureCacheCCSpriteFrameCache 来缓存精灵的纹理。当精灵调用 CCTextureCacheCCSpriteFrameCache 的相关方法时,Cocos2d-x 会利用纹理缓存来创建 CCSprite。因此,开发者可以预先将纹理加载到缓存中,这样在场景中使用时会更加便捷。加载纹理的方式有多种,例如可以选择异步加载,通过这种方式还能为加载场景添加进度条。

下面来看 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 than a crashed program
// this->release();
return false;
}

上述代码展示了一个单例在控制纹理的加载过程。一旦纹理被加载,后续再次请求该纹理时,会直接返回之前加载的纹理引用,避免了重复加载,减少了加载时瞬间的内存增长。(详细 API 请参考 CCTextureCache API

CCSpriteFrameCache

CCSpriteFrameCache 单例用于缓存所有的精灵帧。通过使用精灵表(spritesheet)及其相关的 XML 文件,我们可以将大量的精灵帧加载到缓存中,之后就可以从该缓存中创建精灵对象。

与 XML 文件相关的纹理集通常是一张包含多个小纹理的大图片。以下是一个纹理集的示例:(此处可补充纹理集示例图片)

有三种方式可将纹理集加载到 CCSpriteFrameCache 中:

  1. 加载一个 XML(plist)文件。
  2. 加载一个 XML(plist)文件和一个纹理集。
  3. 通过 CCSpriteFrame 和一个精灵帧的名字。

具体完整 API 请参考 CCSpriteFrameCache API

示例代码如下:

CCSpriteFrameCache* cache = CCSpriteFrameCache::sharedSpriteFrameCache();
cache->addSpriteFramesWithFile("family.plist", "family.png");

使用缓存的主要原因是减少内存开销。当使用图片创建精灵时,如果该图片不在缓存中,会将其加载到缓存;若后续需要用相同图片创建新精灵,可直接从缓存中获取,无需重新分配内存。

CCSpriteFrameCache 与 CCSpriteBatchNode 的比较

在开发中,应尽可能使用精灵表(CCSpriteBatchNodes)。这种方式能够减少 draw 调用次数,因为 draw 调用是非常耗时的操作。每个 CCSpriteBatchNode 只需调用一次 draw 就能绘制其上的所有节点,而不是每个节点单独调用 draw

CCSpriteBatchNode 只需一次渲染操作就能处理所有子节点。这就是为什么要将精灵添加到 batch node 中的原因,因为可以统一进行渲染。但只有使用的纹理包含在 batch node 中的精灵才能添加到 batch node 上,因为 batch node 一次只能渲染相同的纹理集。

如果将精灵添加到其他节点上,每个精灵会单独调用自己的 draw 函数,此时 batch node 就无法发挥作用。

CCSpriteBatchNode 也是常用节点之一,可像其他节点一样从场景中移除。纹理集和精灵帧都缓存在 CCTextureCacheCCSpriteFrameCache 单例中。若要从内存中移除纹理集和精灵帧,需通过缓存类来完成。

作者信息

menghao

menghao

共发布了 3994 篇文章