Cocos2d-x優化中紋理優化

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所示。

html

 紋理緩存異步加載實例數組

HelloWorldScene.cpp中主要代碼以下:
緩存

[html] view plaincopy在CODE上查看代碼片派生到個人代碼片微信

  1. bool HelloWorld::init()  app

  2. {  異步

  3.     if ( !Layer::init() )  函數

  4.     {  oop

  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課堂微信公共平臺

相關文章
相關標籤/搜索