Cocos2d-x优化中纹理优化_C/C++_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > C/C++ > Cocos2d-x优化中纹理优化

Cocos2d-x优化中纹理优化

 2014/11/11 21:26:56  关东升  程序员俱乐部  我要评论(0)
  • 摘要:1.纹理像素格式纹理优化工作的另一重要的指标是纹理像素格式,能够最大程度满足用户对保真度要求的情况下,选择合适的像素格式,可以大幅提高纹理的处理速度。而且纹理像素格式有与硬件有这密切的关系。下面我们先了解一下纹理像素的格式,主要的格式有:RGBA8888。32位色,它是默认的像素格式,每个通道8位(比特),每个像素4个字节。BGRA8888。32位色,每个通道8位(比特),每个像素4个字节。RGBA4444。16位色,每个通道4位(比特),每个像素2个字节。RGB888。24位色
  • 标签:优化

1.纹理像素格式
纹理优化工作的另一重要的指标是纹理像素格式,能够最大程度满足用户对保真度要求的情况下,选择合适的像素格式,可以大幅提高纹理的处理速度。而且纹理像素格式有与硬件有这密切的关系。
下面我们先了解一下纹理像素的格式,主要的格式有:
RGBA8888。32位色,它是默认的像素格式,每个通道8位(比特),每个像素4个字节。
BGRA8888。32位色,每个通道8位(比特),每个像素4个字节。
RGBA4444。16位色,每个通道4位(比特),每个像素2个字节。
RGB888。24位色,没有Alpha通道,所以没有透明度。每个通道8位(比特),每个像素3个字节。
RGB565。16位色,没有Alpha通道,所以没有透明度。R和B通道是各5位,G通道是6。
RGB5A1(或RGBA5551)。16位色,每个通道各4位,Alpha通道只用1位表示。
PVRTC4。4位PVR压缩纹理格式,PVR格式是专门为iOS设备上面的PowerVR图形芯片而设计的。它们在iOS设备上非常好用,因为可以直接加载到显卡上面,而不需要经过中间的计算转化。
PVRTC4A。具有Alpha通道的,4位PVR压缩纹理格式。
PVRTC2。2位PVR压缩纹理格式。
PVRTC2A。具有Alpha通道的,2位PVR压缩纹理格式。


此外,PVR格式在保存的时候还可以采用Gzip和zlib压缩格式进行压缩,对应的保存文件为pvr.gz和pvr.ccz。经过压缩文件会更小,加载的时候使用更少的内存!虽然是转化为纹理的时候,需要解压,但对于CPU影响很小。


2.纹理缓存异步加载
我们在启动游戏和进入场景时候,由于需要加载的资源过多就会比较“卡”,用户体验不好。我们可以采用纹理缓存(TextureCache)异步加载纹理图片,TextureCache类异步加载函数如下:
virtual void addImageAsync(const std::string &?filepath,
std::function< void(Texture2D *)> callback?
)?
其中第一个参数文件路径,第二参数是回调函数。下面我们通过一个实例介绍一下纹理缓存异步加载使用,有200张小图片,加载到纹理缓存,加载过程会有一个进度显式在界面上,如图20-25所示。

?纹理缓存异步加载实例

HelloWorldScene.cpp中主要代码如下:

[html]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
    class="dp-xml">
  1. bool?HelloWorld::init()??
  2. {??
  3. ????if?(?!Layer::init()?)??
  4. ????{??
  5. ????????return?false;??
  6. ????}??
  7. ??
  8. ??
  9. ????Size?visibleSize?=?Director::getInstance()->getVisibleSize();??
  10. ????Vec2?origin?=?Director::getInstance()->getVisibleOrigin();??
  11. ????auto?closeItem?=?MenuItemImage::create(??
  12. ????????"CloseNormal.png",??
  13. ????????"CloseSelected.png",??
  14. ????????CC_CALLBACK_1(HelloWorld::menuCloseCallback,?this));??
  15. ??
  16. ??
  17. ????closeItem->setPosition(Vec2(origin.x?+?visibleSize.width?-?closeItem->getContentSize().width/2?,??
  18. ????????origin.y?+?closeItem->getContentSize().height/2));??
  19. ????auto?menu?=?Menu::create(closeItem,?NULL);??
  20. ????menu->setPosition(Vec2::ZERO);??
  21. ????this->addChild(menu,?1);??
  22. ??
  23. ??
  24. ????_labelLoading?=?Label::createWithTTF?("loading...",?"fonts/Marker?Felt.ttf",?35);??
  25. ????_labelPercent?=?Label::createWithTTF?("0%%",?"fonts/Marker?Felt.ttf",?35);??
  26. ??
  27. ??
  28. ????_labelLoading->setPosition(Vec2(visibleSize.width?/?2,?visibleSize.height?/?2?-?20));??
  29. ????_labelPercent->setPosition(Vec2(visibleSize.width?/?2,?visibleSize.height?/?2?+?20));??
  30. ??
  31. ??
  32. ????this->addChild(_labelLoading);??
  33. ????this->addChild(_labelPercent);??
  34. ??
  35. ??
  36. ????_numberOfLoadedSprites?=?0;??
  37. ????_imageOffset?=?0;??
  38. ??
  39. ??
  40. ????auto?sharedFileUtils?=?FileUtils::getInstance();??
  41. ????std::string?fullPathForFilename???
  42. ????????????????=?sharedFileUtils->fullPathForFilename("ImageMetaData.plist");???????????????①??
  43. ??
  44. ??
  45. ????ValueVector?vec?=?FileUtils::getInstance()->getValueVectorFromFile(fullPathForFilename);?????②??
  46. ????_numberOfSprites?=?vec.size();??????????????????????????????????????????③??
  47. ????//加载纹理??
  48. ????for(?auto&?e?:?vec)?????????????????????????????????????????????????????④??
  49. ????{???
  50. ????????auto?row?=?e.asValueMap();??
  51. ????????auto?filename?=?"icons/"?+?row.at("filename").asString();?????????
  52. ????????Director::getInstance()->getTextureCache()->addImageAsync(filename,??
  53. ????????????????CC_CALLBACK_1(HelloWorld::loadingCallBack,?this));??????????????????⑤??
  54. ????}??
  55. ????return?true;??
  56. }??
  57. ??
  58. ??
  59. void?HelloWorld::loadingCallBack(Texture2D?*texture)????????????????????????????????⑥??
  60. {??
  61. ????++_numberOfLoadedSprites;??
  62. ????__String*?str?=?__String::createWithFormat("%d%%",???
  63. ????????????????????????(int)(((float)_numberOfLoadedSprites?/?_numberOfSprites)?*?100));???????⑦??
  64. ????_labelPercent->setString(str->getCString());??????????????????????????????????⑧??
  65. ??
  66. ??
  67. ????Size?visibleSize?=?Director::getInstance()->getVisibleSize();??
  68. ????int?i?=?++_imageOffset?*?60;??
  69. ??
  70. ??
  71. ????auto?sprite?=?Sprite::createWithTexture(texture);???????????????????????????????⑨??
  72. ????sprite->setAnchorPoint(Vec2(0,0));??
  73. ????addChild(sprite,?-1);??
  74. ????sprite->setPosition(Vec2(?i?%?(int)visibleSize.width,?(i?/?(int)visibleSize.width)?*?60));??
  75. ??
  76. ??
  77. ????if?(_numberOfLoadedSprites?==?_numberOfSprites)?????????????????????????????⑩??
  78. ????{??
  79. ????????_numberOfLoadedSprites?=?0;??
  80. ????}??
  81. }??



上述代码第①行代码是获得资源目录下ImageMetaData.plist 文件全路径,ImageMetaData.plist 文件是我们定义用来描述要加载图标文件名,文件内容如下:

[html]?view plaincopy在CODE上查看代码片派生到我的代码片 ?
  1. <?xml?version="1.0"?encoding="utf-8"?>??
  2. <!DOCTYPE?plist?PUBLIC?"-//Apple//DTD?PLIST?1.0//EN"???
  3. ????????????????"http://www.apple.com/DTDs/PropertyList-1.0.dtd">??
  4. <plist?version="1.0">??
  5. ??<array>??
  6. ????<dict>??
  7. ??????<key>filename</key>??
  8. ??????<string>01-refresh.png</string>??
  9. ????</dict>??
  10. ????<dict>??
  11. ??????<key>filename</key>??
  12. ??????<string>02-redo.png</string>??
  13. ????</dict>??
  14. ????<dict>??
  15. ??????<key>filename</key>??
  16. ??????<string>03-loopback.png</string>??
  17. ????</dict>??
  18. ????<dict>??
  19. ??????<key>filename</key>??
  20. ??????<string>04-squiggle.png</string>??
  21. ????</dict>??
  22. ???…?…????
  23. ??</array>??
  24. </plist>????



ImageMetaData.plist 文件是属性列表文件,内部结构是数组类型,我们可以通过第②行代码FileUtils 的getValueVectorFromFile函数读入到ValueVector类型变量vec中。第③行代码_numberOfSprites = vec.size()是获得数组的长度,然后赋值给成员变量_numberOfSprites为了能够计算加载进度。
第④行代码是循环遍历数组,数组结构中的每一个元素是键值对结构,取的键值对结构语句是auto row = e.asValueMap()。然后通过语句row.at("filename").asString()从键值对对象row中取出键为filename对应的值。
第⑤行代码是调用TextureCache的addImageAsync函数实现异步加载图片缓存,HelloWorld::loadingCallBack是回调函数,this参数表示回调函数的目标对象。
第⑥行是我们定义的回调函数实现。第⑦行代码在的表达式(int)(((float)_numberOfLoadedSprites / _numberOfSprites) * 100)可以计数出加装进度,"%d%%"可以显示百分号,其中的%d是格式化输出数字。%%是输出%,前面%起到转义作用。第⑧行代码_labelPercent->setString(str->getCString())是设置进度标签_labelPercent的内容。

第⑨行代码auto sprite = Sprite::createWithTexture(texture)是通过纹理对象texture创建精灵对象。第⑩行代码if (_numberOfLoadedSprites == _numberOfSprites)是判断是否完成任务,_numberOfLoadedSprites是已经加装的图片数,_numberOfSprites是要加装的全部图片数。

?

?

更多内容请关注国内第一本Cocos2d-x 3.2版本图书《Cocos2d-x实战:C++卷》 本书交流讨论网站:http://www.cocoagame.net
更多精彩视频课程请关注智捷课堂Cocos课程:http://v.51work6.com 欢迎加入Cocos2d-x技术讨论群:257760386 欢迎关注智捷iOS课堂微信公共平台

发表评论
用户名: 匿名