background image

 

iOS

       

   

    android

 

     

游戏纹理优化和内存优化

 

 

1、2d 游戏最占内存的无疑是图片资源。
2、cocos2d-x 不同平台读取纹理的机制不同。ios 下面使用 CGImage,android 和 windows 下是
直接调用

png 库。我测试了下,使用 png 库直接读取 png 会比 CGImage 还要节约 1mb 左右

内存(图片所占内存

4mb)但是速度要比 CGImage 慢一倍。时间和空间如何取舍就看实际

情况了。不过最佳的选择似乎是

pvr(即使 android 版本,即使不使用 pvrtc4)。

3、一般来说,我们可以直接使用 w * h * bpp 得到一张纹理所占的内存,比如一张
1024*1024 格式为 argb8888,那么他所占的内存就是 1024*1024*4=4mb。之前看到有博客提

jpg 会开辟 3 倍与此的内存(先转换为 png,然后解析 png),但是新的 ios 系统似乎没有

这个问题。

jpg 与 png 所消耗的内存几乎相同,并且 jpg 解析速度更快(几乎都是 4mb 解析

+4mb 纹理数据,而 jpg 解析时间是 png 的一半),但是这样反而很怪异,因为 jpg 是没有
透明色的,一个像素最多

3 字节,而 png 一个像素 4 字节,jpg 纹理应该占用内存更小才对,

后来看了下

cocos2d 的 ios 加载图片的代码,它把所有纹理转换成 rgba8888 格式,所以无论

jpg 还是 png,占用的都是 4 字节。正因 cocos2d 对其他纹理支持不够好,pvr 才会显得那

么高效。
4、pvr 格式可以被显卡所认可,而不需要开辟临时内存来读取,所以即便同为 argb8888 格
式的图片,

pvr 也会比 png 有效率,虽然不会节约程序稳定运行时的内存,但是会避免加载

大量图片时的内存暴涨。

 并且如果是 ios 设备的话,可以使用 pvrtc4 格式的图片,这个格式

相当于

windows 下的 dds 图片,是可以被显卡直接支持的。它是有损压缩,一个像素只占 4

位,不过如果不是有渐变半透明色的话,一般效果可以接受,而其节约的内存和

cpu 时间

非常非常显著。
5、pvr 也不是万金油。android 设备下虽然可以使用 pvr 格式,但是不能使用 pvrtc4,希望通

pvr 像 ios 设备上一样真正减少游戏内存是不太可行的。

6、pvr.ccz 其实就是 pvr 图片 zip 打包下,程序读的时候还是先解压出 pvr 资源,然后再读取
pvr。不过由于压缩下可以极大的减小图片体积,所以虽然多了解压过程也不会有特别多的
cpu 消耗。
7、一张 jpg 图片实际加载过程内存消耗,以一张 1024*1024 argb8888 500k 的 jpg 图片为例:

 

a.读取图片文件(消耗图片大小内存,500k) b、解析 jpg 数据(cgimage, 4mb) c、释放 500k
的图片内存

 d、opengl 纹理数据(4mb) e、释放 cgimage 的 4mb 内存。 注意,这个过程不是必然

的顺序执行,释放

cgimage 内存的实际是有系统决定的,会很快,但是不一定是立即执行。

 

所以内存会瞬间飙升

9mb 左右,然后减少 5mb,稳定到 4mb 左右

png 图片的加载过程与此相同
pvr 图片可以节约解析图片数据到纹理这一步的消耗。也就是说读取 pvr 图片资源(等价于
解压

pvr.ccz 到内存,如果是 1024*1024 argb8888 格式的话,那么图片大小就是 4mb,ccz

压缩后图片

1mb 左右)消耗 4mb,将 pvr 图片数据提交给显卡消耗 4mb。然后释放文件数据

4mb。这么看似乎跟 Png 从内存占用上相比也不是非常有优势。(注意这里说的 pvr 是指 pvr
封装的

argb8888,与 pvrtc4 的性能有天壤之别)

8、由于最终消耗内存的都是纹理数据,所以只要纹理数据格式是一定的,无论图片是什么
格式消耗的内存都是一样的。比如使用

Png8 图片,体积会减少 70%,但是内存占用与

png24/png32 是等价的(读取的时候会内部把调色板还原成真彩色,也就是说,虽然 png8 是
一个像素只占

8 位,但是读取到内存中的时候会将调色板颜色还原,依然需要开辟

1024*1024*4 字节的空间存放纹理数据)。 当然有无透明色,cocos2d 的处理还是有区别的。
如果是无透明色,可以使用

png24,那么所需开辟的纹理空间就是 3mb。