coco2d-x 纹理研究

本文详细介绍了cocos2d-x中纹理的使用和优化技巧,包括使用16-bit纹理减少内存占用,选择合适的纹理像素格式,如RGB565、RGBA4444,以及利用PVR格式和PVRTC压缩。文章强调了避免一次性加载大量纹理导致的内存峰值问题,提出了按纹理大小顺序加载和预加载纹理的方法。此外,还讨论了内存警告处理、纹理缓存管理、精灵帧缓存的影响,以及如何避免缓存特定的纹理。
摘要由CSDN通过智能技术生成

1.通常情况下用PVR格式的文件来进行图片显示的时候,在运行速度和内存消耗方面都要比PNG格式要快和小。一般情况下PVR消耗的内存比PNG消耗的内存小25%左右。PVR格式可以用ZWoptex导出。PVR是apple芯片能直接读取和显示的文件.

 

2.图片抗锯齿处理。

图片放大时的处理:

图片在放大的时候会出现锯齿。纹理类提供了setAntiAliasTexParameters()函数来处理抗锯齿。当图片放大的时候会使用相邻的四个像素进行混合运算。从而消除锯齿。但是会让图片产生模糊的感觉。

左边使用的就是setAntiAliasTexParameters()。和右边的图片相比无锯齿,但是有模糊的感觉.右边的图片使用的是setAliasTexParameters()。不模糊,但是有锯齿。

图片缩小时的抗锯齿处理:

使用minmap,缩小时效果会更好,左边使用minmap

 

    CCSprite *imgMipMap = CCSprite::create("Images/logo-mipmap.pvr");
    if( imgMipMap )
    {
        imgMipMap->setPosition(ccp( s.width/2.0f-100, s.height/2.0f));
        addChild(imgMipMap);

        // support mipmap filtering
        ccTexParams texParams = { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE };    
        imgMipMap->getTexture()->setTexParameters(&texParams);
    }

3.cocos2d-x的纹理类支持从多种格式的文件加载图片.包括:.png , .jpeg, .pvr, .gz, .webp, .tiff, .ccz等格式的文件 。

 

4.最大限度的通过一些方法和手段减小纹理对内存消耗.

(1) 通过CCTexture2D来修改纹理的像素格式,可以减少纹理占用的内存大小和渲染的速度。

使用16-bit纹理

最快速地减少纹理内存占用的办法就是把它们作为16位颜色深度的纹理来加载。cocos2d默认的纹理像素格式是32位颜色深度。如果把颜色深度减半,那么内存消耗也就可以减少一半。并且这还会带来渲染效率的提升,大约提高10%。

你可以使用CCTexture2D对象的类方法setDefaultAlphaPixelFormat来更改默认的纹理像素格式,代码如下:

  CCTexture2D::setDefaultAlphaPixelFormat(kCCTexture2DPixelFormat_RGB565);

这里有个问题:首先,纹理像素格式的改变会影响后面加载的所有纹理。因此,如果你想后面加载纹理使用不同的像素格式的话,必须再调用此方法,并且重新设置一遍像素格式。

其次,如果你的CCTexture2D设置的像素格式与图片本身的像素格式不匹配的话,就会导致显示严重失真。比如颜色不对,或者透明度不对等等。

有哪些比较有用的纹理像素格式呢?
generate 32-bit textures: kCCTexture2DPixelFormat_RGBA8888 (default)
generate 16-bit textures: kCCTexture2DPixelFormat_RGBA4444
generate 16-bit textures: kCCTexture2DPixelFormat_RGB5A1
generate 16-bit textures: kCCTexture2DPixelFormat_RGB565 (no alpha)


 

RGBA8888是默认的格式。对于16位的纹理来说,使用RGB565可以获得最佳颜色质量,因为16位全部用来显示颜色:总共有65536总颜色值。但是,这里有个缺点,除非图片是矩形的,并且没有透明像素。所以RBG565格式比较适合背景图片和一些矩形的用户控件。

RBG5A1格式使用一位颜色来表示alpha通道,因此图片可以拥有透明区域。只是,1位似乎有点不够用,它只能表示32768种可用颜色值。而且图片要么只能全部是透明像素,或者全部是不透明的像素。因为一位的alpha通道的缘故,所以没有中间值。但是你可以使用fade in/out动作来改变纹理的opacity属性。

如果你的图片包含有半透明的区域,那么RBGA4444格式很有用。它允许每一个像素值有127个alpha值,因此透明效率与RGBA8888格式的纹理差别不是很大。但是,由于颜色总量减少至4096,所以,RBGA4444是16位图片格式里面颜色质量最差的。

现在,你可以得到16位纹理的不足之处了:它由于颜色总量的减少,有一些图片显示起来可能会失真,而且可能会产生“梯度”。


 

(2)避免一个接一个地加载PNG和JPG纹理(他们之间至少等待一帧)

 

cocos2d里面纹理加载分为两个阶段:1.从图片文件中创建一个UIImage对象。2.以这个创建好的UIImage对象来创建CCTexture2D对象。这意味着,当一个纹理被加载的时候,在短时候内,它会消耗两倍于它本身内存占用的内存大小。(译注:为什么只是短时间内呢?因为autoRelease pool和引用计数的关系,临时创建的UIImage对象会被回收。)

当你在一个方法体内,接二连三地加载4个纹理的时候,这个内存问题会变得更加糟糕。因为在这个方法还没结束之前,每一个纹理都会消耗两倍于它本身的内存。

我不是很确定,现在的cocos2d是否仍然如此。或者这种情况是否只适用于手工引用计数管理,或许ARC不会如此呢?我习惯于按顺序加载纹理,但是在加载下一个纹理之前要等待一帧。这将会使得任何纹理加载的消耗对内存的压力降低。因为等待一帧,引用计数会把临时的UIImage对象释放掉,减少内存压力。此外,在后续的文章中,如果你想在背景线程中按序加载纹理的话,也可以采用这种方法。

 

(3)iphone中不要使用jpg来创建纹理对象

cocos2d-iphone使用JPG纹理的时候有一个问题。因为JPG纹理在加载的时候,会实时地转化为PNG格式的纹理。这意味着cocos2d-iphone加载纹理是非常慢的(这里有演示),而且JPG纹理将消耗三倍于本身内存占用大小的内存。

一个2048*2048大小的纹理会消耗16M的内存。当你加载它的时候,在短时间内,它将消耗32MB内存。现在,如果这个图片是JPG格式,你会看到这个数字会达到48MB,因为额外的UIImage对象的创建。虽然,最终内存都会降到16M,但是,那一个时刻的内存飙高,足以让os杀死你的游戏进程,造成crash,影响用户体验。

JPG不论在加载速度和内存消耗方面都很差。所以,千万不要使用JPG!

(4)忽视文件图片大小

这种情况,我见到很多。它乍听起来可能觉得有点荒诞,但事实如此,因为它需要关于文件格式的知识,而这些知识并不是每一个程序员都了解的。我经常听到的论断就是“嘿!我的程序不可能有内存警告,我所有的图片资源加起来还不到30MB!”。

怎么说呢,因为图片文件大小和纹理内存占用是两码事。假设他们是帐篷。图片文件就相当于帐篷被装在行李箱。但是,如果你想要使用帐篷的话,它必须被撑起来,被“膨胀”。

图片文件和纹理的关系与此类似。图片文件大多是压缩过的,它们被使用的话必须先解压缩,然后才能会GPU所处理,变成我们熟知的纹理。一个2048*2048的png图片,采用32位颜色深度编码,那么它在磁盘上占用空间只有2MB。但是,如果变成纹理,它将消耗16MB的内存!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值