精灵和动画都涉及到纹理图片的使用,所以在研究精灵与动画之前,我们先来了解一下纹理图片类CCTexture2D和纹理缓存CCTextureCache的原理:
当一张图片被加载到内存后,它是以纹理的形式存在的。纹理是什么东西呢?纹理就是一块内存,这块内存中存放的是--按照指定的像素格式--填充的“图片像素信息”。它被最终作为三角面着色所依据的数据源。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cocos2d-x中的libcocos2d库,其下有许多目录,找到textures展开,可以看到有CCTexture2D,CCTextureAtlas,CCTextureCache,CCTexturePVR四个类。
①CCTexture2D: 纹理,即图片加载入内存后供cpu和GPU操作的贴图对象。
②CCTexturePVR:处理PVR文件生成纹理的类,提示:大家可以用它解析愤怒的小鸟中的图片。
③CCTextureCache:纹理管理器,负责加载图片并对生成的纹理进行管理。通过“字典”来进行快速的查询。
④CCTextureAtlas:纹理块管理器,如果图片是由多个小图块组成的,则纹理块管理器用来存储这些小图块的相关信息,以方便绘制相应图块。
如果想了解引擎内部的实现原理,参考此处链接http://www.jb51.cc/article/p-uieygxfx-gw.html
我们重点分析CCTexture2D和CCTextureCache和使用:
CCTexture2D
可以把它看成一个纹理,它是cocos2d-x渲染图形的重要参数,用来贴图。
纹理--知道如何将自己绘制到屏幕上。通过该类还可以设置纹理过滤、抗锯齿等参数。该类还提供了一个接口,将字符串创建成纹理。这里需要特别重提的两点是:cocos2d-x是使用OpenGL ES绘制2D图形的,它的尺寸是2的N次方,因此该类所包含的纹理大小必须是2的幂次,纹理的大小不一定就等于图片的大小;另外,有别于CCImage,这是一张存在于显存中的纹理,实际上并不一定存在于内存中。
常用的是如下所示的3个接口:
- //单例模型解决了纹理加载。一旦你的纹理被加载进来,下一次使用的时候它将会返回一个之前已经加载了的纹理的引用,而不是重新加载,这样就减少了GPU&cpu内存。
- staticCCTextureCache*sharedTextureCache();
- CCTexture2D*addImage(constchar*fileimage);
- voidremoveUnusedTextures();//释放当前所有引用计数为1的纹理,即目前没有被使用的纹理.
- /*实际上,我们很少需要调用removeUnusedTextures这个接口,因为引擎内部所有的纹理加载都是通过这个缓存进行。换句话说,载入的每一张图片都被缓存了,所以我们更需要关心什么时候清理缓存。引擎会在设备出现内存警告时自动清理缓存,但是这显然在很多情况下已经为时过晚了。一般情况下,我们应该在切换场景时清理缓存中的无用纹理,因为不同场景间使用的纹理是不同的。如果确实存在着共享的纹理,将其加入一个标记数组来保持其引用计数,以避免被清理了。*/
使用时:CCTexture2D* cache = CCTextureCache::sharedTextureCache()->addImage("hero.png");即可获得一个纹理对象。
注意:纹理图片只是一个贴图,而必须依赖可视化节点才能显示于视图中。
CCTextureCache
CCTextureCache相当于CCTexture2D的容器,是一块内存池,用来缓存CCTexture2D对象。纹理缓存CCTextureCache,这里缓存的是加载到内存中的纹理资源,也就是图片资源。其原理是对加入缓存的纹理资源进行一次引用,使其引用计数加一,保持不被清除,而Cocos2d-x的渲染机制是可以重复使用同一份纹理在不同的场合进行绘制,从而达到重复使用,降低内存和GPU运算资源的开销的目的。
CCTextureCache里面有一个字典CCDictionary* m_pTextures; 该字典中key是图片的名称(相对路径),value是CCTexture2D。当CCTextureCache调用addImage函数,会先根据图片名称去内存中查找是否存在(和C++中map类似),是则取出直接返回。