~~~~我的生活,我的點點滴滴!
!
大家都知道一個游戲里面會有大量的圖片。每一個圖片渲染是須要時間的,以下分析兩個類來加快渲染速度。加快游戲執行速度
一、SpriteBatchNode
1、先說下渲染批次:這是游戲引擎中一個比較重要的優化指標,指的是一次渲染凋用。也就是說。渲染的次數越少,游戲的執行效率越高。怎么看這個次數了?GL calls的值,以下會講到。
2、SpriteBatchNode就是cocos2d-x為了減少渲染批次而建立的一個專門管理精靈的類。
有人會問,怎么高速知道究竟渲染了多少次了,告訴你吧,游戲左下角有三行數據:
GL verts 表示給顯卡繪制的頂點數
GL calls 表示代表每一幀中OpenGL指令的調用次數
FPS 這個是幀率不多說
主要看第二個“GL calls”代表每一幀中OpenGL指令的調用次數。這個數字越小,程序的繪制性能就越好。我們有沒有法子讓他小點了,答案當然是yes
首先我們使用sprite創建100個精靈。看看這個值是多少
code:
for(int i = 0; i < 100; ++ i) { char name[15]; memset(name, 0, sizeof(name)); sprintf(name, "%d.png", i % 10); auto sp = Sprite::create(name); sp->setPosition(Point(i*5,i*5)); node->addChild(sp); } this->addChild(node);這個循環創建了100個精靈,顯示出來,看效果
看左下角紅色圈圈。有101次繪制,當中100個元素每一個元素繪制一次。多出來的一次是繪制這個左下角信息自己。
在來看看使用SpriteBatchNode
code:
auto spBatchNode = SpriteBatchNode::create("0.png"); spBatchNode->setPosition(Point::ZERO); this->addChild(spBatchNode); for(int i = 0; i < 100; ++ i) { count++; //float x = CCRANDOM_0_1() * visibleSize.width; //float y = CCRANDOM_0_1() * visibleSize.height; //log("x=%lf, y=%lf",x, y); char name[15]; memset(name, 0, sizeof(name)); sprintf(name, "%d.png", i % 10); auto sp = Sprite::createWithTexture(spBatchNode->getTexture()); sp->setPosition(Point(i*5,i*5)); spBatchNode->addChild(sp); }看效果圖
看到沒,立刻減到2了,這快了太多了。
這是一個提速。在3.x版本號里面已經自己主動實現了批渲染處理了。所以非常多時候SpriteBatchNode用不上了
在來看看SpriteFrameCache
二、SpriteFrameCache
首先我們使用合圖軟件,將這10張圖合成一張大圖和一個plist文件。
在使用CocoStudio導出時。選擇“使用大圖”就可以將小圖合成一張大圖。當然我們也能夠選擇TexturePacker這樣的專業的合圖軟件。合成的圖片分為“test.png”和“test.plist”兩部分,然后使用SpriteFrameCache。
code:
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("test.plist","test.png"); Node* node = Node::create(); char name[32]; for(int i = 0;i<100;++i) { char name[15]; memset(name, 0, sizeof(name)); //auto sprite = Sprite::create(name); auto sprite = Sprite::createWithSpriteFrameName(name); sprite->setPosition(Point(i*5,i*5)); node->addChild(sprite, 0); } this->addChild(node);這段代碼中,我們調用addSpriteFramesWithFile函數,將大圖加載到內存中,創建對象時,調用createWithSpriteFrameName從緩存紋理中加載圖片。
如此做我們全部的繪制調用都能夠合並到一次OpenGL指令中。這些繪制指令的計算與合並都由Cocos2d-x引擎完畢。編譯執行例如以下圖所看到的:
我們能夠很明顯的看到,優化后的程序“GL calls”依舊變成了2次。
另一種優化。就是當精靈超出屏幕后就剔除掉,這樣也能降低OpenGL指令。
三、繪制剔除
相對於上一種優化。這個要更easy理解。它是指當一個元素移動到屏幕之外,就不進行繪制。
code:
Node* node = Node::create(); for(int i = 0;i<100;++i) { char name[15]; memset(name, 0, sizeof(name)); sprintf(name, "%d.png",i%10); auto sprite = Sprite::create(name); //auto sprite = Sprite::createWithSpriteFrameName(name); sprite->setPosition(Point(i*5,i*5)); node->addChild(sprite, 0); } this->addChild(node); auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = [=](Touch *pTouch, Event *pEvent) { return true; }; listener->onTouchMoved = [=](Touch *pTouch, Event *pEvent) { node->setPosition(node->getPosition()+pTouch->getDelta()); }; Director::getInstance()->getEventDispatcher()-> addEventListenerWithSceneGraphPriority(listener, this); return true;}效果圖例如以下:
我們發現GL calls也變小了。這也是一種不錯的方法
四、小結
總的來說,這兩點優化能夠說是對程序性能有了極大提升。同一時候在開發的過程中,也使程序猿不必過多的糾結於渲染效率的優化。