TexturePacker的学习笔记

首先转载地球人己阻止不了程序猿们学习cocos2d-x了 (第一篇)

不过我们最终的目标是把遊戏放到 iOS 或 Android 机子上玩, 所以我们不能不考虑一下有关OpenGL ES 优化的问题, 两大关键问题就是内存(显存)运用和速度.

先看一下内存问题, OpenGL ES  纹理的宽和高都要是2的倍数, 以刚才的例子来说, 虽然 Background.png 本身是 480x320, 但在载入内存後, 它其实会被变成一张 512x512 的纹理, 而Grass Block.png 则由 101x131 变成 128x256, 我们可以看到如此这样会造成不少浪费.

再看看关於渲染速度方面, OpenGL ES 上来说我们应该尽量减少渲染时切换纹理和 glDrawArray 的呼叫, 刚才的例子每画一个图像都会切换一次纹理并呼叫一次 glDrawArray , 我们这里只画3样东西, 所以不会看到有什麽问题, 但如果我们要渲染几十个甚至几百个图像 , 速度上就会被拖慢. 很明显这并不是我们所想要的.

那我们应该怎麽解决这些问题呢? 答案就是利用纹理地图(texture atlas), 比如下面这张纹理就是把我们想用的图像都合併在一起, 而它的大小正好是 512x512:

 


如果人手去做这个合併工作就太痛苦了, 这里要向大家推荐一个十分好用的工具: TexturePacker! (http://www.texturepacker.com/) 这个工具直接支持 cocos2d, 实在是太方便了!

首先我们把想要用的图像都放到一个目录里, 再用TexturePacker 的 "Add Folder"  功能把目录加进去, TexturePacker 的默认输出格式就是 cocos2d:
  

为了节省位置, 我们可以把Border padding 和Shape Padding 都设为1, 而选了 Allow rotation 可以让 TexturePacker 更为有效率的摆放图像在纹理里:


 

在键入了输出的档案名字後, 我们就可以用 Publish 把纹理输出.

接下来, 我们把输出的两个档案(我们这里的例子是images.plist 和 images.png) 放到 Resources 里, 就可以在程序里用 CCSpriteFrameCache 把纹理和有关资料载入:

CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();
        cache->addSpriteFramesWithFile("images.plist", "images.png");	//将其加入到缓存
        // Get window size and place the label upper.
        CCSize size = CCDirector::sharedDirector()->getWinSize();
        CCSprite* pSprite = CCSprite::spriteWithSpriteFrameName("Background.png");
        CC_BREAK_IF(! pSprite);
        pSprite->setPosition(ccp(size.width/2, size.height/2));
        this->addChild(pSprite, 0);
        pSprite = CCSprite::spriteWithSpriteFrameName("Grass Block.png");
        CC_BREAK_IF(! pSprite);
        pSprite->setPosition(ccp(size.width/2, size.height/2));
        this->addChild(pSprite, 0);
        pSprite = CCSprite::spriteWithSpriteFrameName("p8.png");
        CC_BREAK_IF(! pSprite);
        CCSize dim = pSprite->getContentSize();
        pSprite->setPosition(ccp(size.width/2, size.height/2+dim.height/2));
        this->addChild(pSprite, 0);

来到这里, 我们已经逹到了节省内存和减少纹理切换, 最後一个我们想做的优化是减少 glDrawArray 的次数, 而我们所运用的技巧, 就是批次渲染(Batch Rendering), cocos2d 提供了CCSpriteBatchNode 来方便大家做有关的处理, CCSpriteBatchNode 里的CCSprite 都是要用同一个纹理的, 所以我们在建立一个 CCSpriteBatchNode 是要给它一个纹理, 再把它加到 Layer 里 :

CCSpriteFrameCache *cache = CCSpriteFrameCache::sharedSpriteFrameCache();
        cache->addSpriteFramesWithFile("images.plist", "images.png");
        CCTexture2D *texture = CCTextureCache::sharedTextureCache()->textureForKey("images.png");
        CCSpriteBatchNode *spriteBatch = CCSpriteBatchNode::batchNodeWithTexture(texture);//减少 glDrawArray 的次数,批次渲染
        addChild(spriteBatch);
        // Get window size and place the label upper.
        CCSize size = CCDirector::sharedDirector()->getWinSize();
//我们如常的建立各个 CCSprite, 但不同的地方是我们不把它们加在 Layer 里而是把它们直接加到 CCSpriteBatchNode 上:
        CCSprite* pSprite = CCSprite::spriteWithSpriteFrameName("Background.png");
        pSprite->setPosition(ccp(size.width/2, size.height/2));
        spriteBatch->addChild(pSprite, 0);
        pSprite = CCSprite::spriteWithSpriteFrameName("Grass Block.png");
        pSprite->setPosition(ccp(size.width/2, size.height/2));
        spriteBatch->addChild(pSprite, 0);
        pSprite = CCSprite::spriteWithSpriteFrameName("p8.png");
        CCSize dim = pSprite->getContentSize();
        pSprite->setPosition(ccp(size.width/2, size.height/2+dim.height/2));
        spriteBatch->addChild(pSprite, 0);


 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值