cocos2d-x 详解之 CCTexture2D(纹理图片)和 CCTextureCache(纹理缓存)

        精灵和动画都涉及到纹理图片的使用,所以在研究精灵与动画之前,我们先来了解一下纹理图片类CCTexture2D和纹理缓存CCTextureCache的原理:

        当一张图片被加载到内存后,它是以纹理的形式存在的。纹理是什么东西呢?纹理就是一块内存,这块内存中存放的是--按照指定的像素格式--填充的“图片像素信息”。它被最终作为三角面着色所依据的数据源。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

cocos2d-x中的libcocos2d库,其下有许多目录,找到textures展开,可以看到有CCTexture2D,CCTextureAtlas,CCTextureCache,CCTexturePVR四个类。

    ①CCTexture2D: 纹理,即图片加载入内存后供CPU和GPU操作的贴图对象。

    ②CCTexturePVR:处理PVR文件生成纹理的类,提示:微笑 大家可以用它解析愤怒的小鸟中的图片。

    ③CCTextureCache:纹理管理器,负责加载图片并对生成的纹理进行管理。通过“字典”来进行快速的查询。

    ④CCTextureAtlas:纹理块管理器,如果图片是由多个小图块组成的,则纹理块管理器用来存储这些小图块的相关信息,以方便绘制相应图块。

如果想了解引擎内部的实现原理,参考此处链接http://blog.csdn.net/ypfsoul/article/details/8909199


          我们重点分析CCTexture2D和CCTextureCache和使用:

         CCTexture2D

可以把它看成一个纹理,它是cocos2d-x渲染图形的重要参数,用来贴图。

纹理--知道如何将自己绘制到屏幕上。通过该类还可以设置纹理过滤、抗锯齿等参数。该类还提供了一个接口,将字符串创建成纹理。这里需要特别重提的两点是:cocos2d-x是使用OpenGL ES绘制2D图形的,它的尺寸是2N次方,因此该类所包含的纹理大小必须是2的幂次,纹理的大小不一定就等于图片的大小;另外,有别于CCImage,这是一张存在于显存中的纹理,实际上并不一定存在于内存中。

常用的是如下所示的3个接口:

//单例模型解决了纹理加载。一旦你的纹理被加载进来,下一次使用的时候它将会返回一个之前已经加载了的纹理的引用,而不是重新加载,这样就减少了GPU&CPU内存。
static CCTextureCache * sharedTextureCache();

CCTexture2D* addImage(const char* fileimage);

void removeUnusedTextures();//释放当前所有引用计数为1的纹理,即目前没有被使用的纹理.
/*实际上,我们很少需要调用removeUnusedTextures这个接口,因为引擎内部所有的纹理加载都是通过这个缓存进行。换句话说,载入的每一张图片都被缓存了,所以我们更需要关心什么时候清理缓存。引擎会在设备出现内存警告时自动清理缓存,但是这显然在很多情况下已经为时过晚了。一般情况下,我们应该在切换场景时清理缓存中的无用纹理,因为不同场景间使用的纹理是不同的。如果确实存在着共享的纹理,将其加入一个标记数组来保持其引用计数,以避免被清理了。*/

使用时:CCTexture2D* cache = CCTextureCache::sharedTextureCache()->addImage("hero.png");即可获得一个纹理对象。

addImage内部通过image的相对路径加载一张图片,如果已存在于内存中则直接返回引用,否则加载并返回纹理对象的引用。

注意:纹理图片只是一个贴图,而必须依赖可视化节点才能显示于视图中。


         CCTextureCache

CCTextureCache相当于CCTexture2D的容器,是一块内存池,用来缓存CCTexture2D对象。纹理缓存CCTextureCache,这里缓存的是加载到内存中的纹理资源,也就是图片资源。其原理是对加入缓存的纹理资源进行一次引用,使其引用计数加一,保持不被清除,而Cocos2d-x的渲染机制是可以重复使用同一份纹理在不同的场合进行绘制,从而达到重复使用,降低内存和GPU运算资源的开销的目的。

CCTextureCache里面有一个字典CCDictionary* m_pTextures; 该字典中key是图片的名称(相对路径),value是CCTexture2D。当CCTextureCache调用addImage函数,会先根据图片名称去内存中查找是否存在(和C++中map类似),是则取出直接返回。

CCTexture2D * CCTextureCache::addImage(const char * path)
{
CCTexture2D * texture = NULL;
std::string pathKey = path;
CCFileUtils::ccRemoveHDSuffixFromFile(pathKey);
/* ...... */

pathKey = CCFileUtils::fullPathFromRelativePath(pathKey.c_str());//获取图片的相对路径,也是在缓存池字典的关键字
texture = m_pTextures->objectForKey(pathKey);

std::string fullpath = pathKey; // (CCFileUtils::fullPathFromRelativePath(path));
if( ! texture )//判断是否已经加载到内存里了,否则加载
{
/** .... */
}

return texture;
} 

注意:当需要一次加载多张图片时,可以先把图片加载到CCTextureCache中,这样使用图片时的速度就会很快了。




MagicTools引擎,括3d场景,材质,d3d与opengles两个渲染器,max导出插件,集成了cocos2d作为ui。 引擎架构如下: 1.MtFoundation:底层数学库、字符串处理、操作系统和编译器宏定义等底层封装库。这些功能放在了MtFoundation.dll中,这个库可以以后单独提取出来提供其他项目使用。 2.MtKernel:提供资源管理器、文件系统、场景树管理。所以资源均提供引用计数、加载卸载计数、资源可以按组进行预加载。同一资源可以属于多个资源组,资源组在做rpg游戏切换房间的时候比较有用,可将一个房间的资源列表做一个组进行加载,若已存在的资源会增加其加载计数,而不用重新加载。 3.MtSceneQuery:场景查询模块。场景查询是一个相对独立的模块,可以替换掉。主要做一些算法的工作,比如射线查询、视锥剔除。把它独立处理就是希望这些cpu计算工作可以与渲染分离,便于放到一个独立的线程中。 4.MtGraphic:3d引擎模块,提供网格定义、材质定义,骨骼动画和蒙皮、贴图资源、渲染设备封装等。此处对渲染设备功能做了抽象,将具体渲染调用放到了d3d9renderer和glesrenderer中去。这里的材质在d3d下直接使用d3dxeffect,并使用宏控制编译。gles下使用固定管线控制。 d3d环境下定义了自己的材质和材质模板格式,材质模板主要用于定义effect中可用的宏,这些宏的可选取值,effect代码本身等。材质文件则引用材质模板文件,并定义宏的取值,还有uniform参数值。图形模块提供effect的uniform参数与场景中光源和物体本身材质参数的绑定。 gles环境下定了一个简单的脚本,控制固定功能渲染中的diffuse、specular和第一层纹理的参数 自定义了模型网格、骨骼、动画、材质、渲染实体等文件格式,这些文件格式说明放在了fileformats目录下。 渲染实体(Model)定义了网格与材质的组合关系,目前一个子网格只能有一个材质,但能扩展成一个子网格绑定多个材质。这样可以方便制作材质的过渡效果。 5.MtGraphic2d:这个模块是将cocos2dx0.99.4的底层替换成自己封装的渲染器实现的。cocos2dx原本是使用opengles1.0作为渲染api,在windows系统下使用powervr的模拟器运行。现在可以在d3d下或是opengles下运行。并将其更新流程合并到MtGraphic中,使得cocos2d可以正常的渲染在3d场景的前方。cocos2d的大部分功能已测试完成。可以在d3d下正常运行。 6.MtEngine:对上面几个模块的统一封装,这里负责动态的加载上面的几个模块,这里可以选择使用d3d还是gles进行渲染。还提供了建议场景逻辑控制,支持加载一个xml定义的场景脚本文件。直接使用EgnObject(EngineObject的简写)对场景模型进行控制可以省去操作底层场景树和模型材质创建的流程。 7.sampler:测试项目,用于测试上述功能。加载一个xml场景(里面全是茶壶。。。等编辑器出来就可以摆场景了),cocos2d界面渲染。鼠标键盘的输入控制。(wasd控制移动、鼠标控制方向) 材质文件说明: efm(effect material):d3d专用,里面会引用mtpl(material template)文件。 mtpl:材质模板文件,里面定义可选的宏和可选取值,还有d3dxeffect的代码。 ffm(fixed function material):d3d和gles通用,固定渲染管线材质。gles下只能用这个。 工程里带的导出插件目前只能导出网格,材质需要自己动手配置.(材质的编辑打算放到编辑器里做,然后在编辑器中绑定网格和材质,这也是cryengine和《古域》的做法,这样可以保证编辑的材质和游戏最终运行时的效果一样。)编译max导出插件需要max2010的sdk,安装插件后就可以导出单个模型。一次导出一个模型,做好一个mesh后选择max的export菜单,然后选择导出成“MtEngine Mesh File”(*.mmesh)就可以。 写了这么最后解释下为啥做这个东西吧。之前在做了两年多ogre引擎的开发,ogre确实很牛x,它的代码风格、封装程度、还有大量的算法工具都很不错,降低了3d开发的门槛,在用过的引擎中它门槛是最低的,说明他的封装做的好,但其内部结构过于复杂,不适合做灵活的修改。比如一个entity只能给一个材质,材质缺乏层的概念,不利于叠加临时效果。渲染与场景管理的代码结合得太紧,不能分离。比如没渲染一次场景都得做一次renderable排序加一次八叉树遍历,一帧里的多次渲染按理这些流程应该有所优化,但ogre
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值