zoukankan      html  css  js  c++  java
  • iOS和android游戏纹理优化和内存优化(cocos2d-x)

    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。 


           这里还有一点需要说明,一般我们处理windows下的dds纹理的时候,都习惯将其按2的整次幂对其,虽然图片内容只有900*900,但是图片大小 却是1024*1024。那我们读取这个图片所消耗的内存就是4mb,按2的整次幂对其是有助于提高运行效率的,但是不是非常必须的。ios和 android的设备都支持非2的整次幂的纹理。所以如果是png图片,那么它该多大就多大。此时消耗的内存就只有900*900*4=3mb。 


    9、不要过于迷信所谓的去除alpha通道以节约内存。这个还要实际分析下具体结果。  我测试过(分别用cocos2d-x和鬼火3d引擎),rgba8888 和rgb888格式的png图片显示所消耗的内存是一样的。24位图片虽然读取的时候开辟的内存只有3mb(1024*1024*3,注意如果是用 CGImage读取的话,那这个值就是4mb),但是glTexImage2D提交给显卡后依然会增加4mb内存。可能跟显卡的数据对齐有关。 


         这里我测试还有一个诡异的地方,如果是用pvr的npot图片的话,rgb888要比rgba8888所消耗的内存要小,但是pot图片两者又是一样的(png图片两种情况都是一样的)。可能是powervr显卡有特殊处理。 


    10、rgb565和rgb5551的图片所消耗的内存是rgba8888的一半,如果没有透明渐变的话,视觉上也看不出什么区别。一些大的背景图可以优先选择这种格式。 


    11、pvr图片加载速度要比png和jpg快3~5倍(同样1024*1024 argb8888),png消耗的时间可能是700ms左右,但是pvr只需要100ms左右。如果是pvr.ccz压缩下,消耗的时间是200ms左 右。可见pvr在加载速度上还是有非常大的优势的。这个应该是因为png和jpg需要把图片数据还原为rgba,但是pvr可以直接把图片数据传递给显 卡。pvrtc4的图片是可以被powervr显卡直接支持的。 






    总结下: 


    1、最终决定图片占用内存的是它的像素格式和大小,与其扩展名无关。png8  png32 jpg pvr只要其像素格式都是argb8888,那么最终图片占用的内存是一样的。 


    2、如果不是pvrtc4的格式,那么不要扩展成2的整次幂,因为图片越小,占用内存越小 


    3、单单去除透明通道不会减少图片所消耗的内存,png和jpg图片也无法减少图片体积,所以不推荐rgb888的格式。替代选择rgb565和rgb5551。 


    5、小心加载图片时临时开辟的纹理数据造成的内存飙高,可以考虑加入内存池,及时的开辟和释放缓冲区。 


    6、如果是为了减少图片体积可以选择:1、jpg--压缩比最高,质量较好,但是不支 持半透明    2、png8--同样图片会比jpg略大一些,使用ImageAlpha进行转换,视觉上几乎看不出差别。    这两种图片格式都可以极大的减少图片体积(减少70%~80%),但是无助于减少内存 


    7、如果是为了减少内存可以选择:1、没有透明色的图片统一转换为rgb565格式, 这个时候无法使用png8了,所以png和pvr.ccz图片大小几乎相同,pvr.ccz速度更快,所以推荐pvr.ccz的rgb565格式    2、如果透明色仅仅是进行关键色标注,而没有渐变混合,那么推荐rgb5551 (r5_a1)的pvr.ccz格式 


    8、可以考虑写个打包系统,统一把资源文件打包,而不是单个文件用pvr.ccz进行zip压缩,这样可以获得更高的效率。(比如我封装了下暴雪的mpq打包,其读取速度与本地文件读取速度相当,这样就可以获得最佳的读取效率) 










    最后附上我测试的数据日志,图片是一张1024*1024的图片,实际图片内容大小为960*700。测试设备iphone4,png jpg等图片加载代码修改为windows版本。tex后面是图片的加载时间。 over后面的括号里面是图片加载所消耗的内存。 




    2012-12-27 14:28:54.614 HelloCpp[4939:707] cocos2d: surface size: 960x640 
    Cocos2d: cocos2d: cocos2d-2.1beta3-x-2.1.0 
    Cocos2d: cocos2d: GL_VENDOR:     Imagination Technologies 
    Cocos2d: cocos2d: GL_RENDERER:   PowerVR SGX 535 
    Cocos2d: cocos2d: GL_VERSION:    OpenGL ES 2.0 IMGSGX535-63.24 
    Cocos2d: cocos2d: GL_MAX_TEXTURE_SIZE: 2048 
    Cocos2d: cocos2d: GL_MAX_TEXTURE_UNITS: 8 
    Cocos2d: cocos2d: GL supports PVRTC: YES 
    Cocos2d: cocos2d: GL supports BGRA8888 textures: NO 
    Cocos2d: cocos2d: GL supports NPOT textures: YES 
    Cocos2d: cocos2d: GL supports discard_framebuffer: YES 
    Cocos2d: cocos2d: GL supports shareable VAO: YES 
    Cocos2d: cocos2d: compiled with Profiling Support: NO 
    tex   195    map_001_BG.pvr 
    map_001_BG.pvr 
        ---over   proess:11.0mb (4.0mb)   free:274.6mb 
    tex   159    map_001_BG_rgb.pvr 
    map_001_BG_rgb.pvr 
        ---over   proess:15.0mb (4.0mb)   free:270.6mb 
    tex   711    map_001_BG.jpg 
    map_001_BG.jpg 
        ---over   proess:19.1mb (4.1mb)   free:266.7mb 
    tex   653    map_001_BG_rgb.jpg 
    map_001_BG_rgb.jpg 
        ---over   proess:23.1mb (4.0mb)   free:262.6mb 
    tex   670    map_001_BG.png 
    map_001_BG.png 
        ---over   proess:27.1mb (4.1mb)   free:258.7mb 
    tex   739    map_001_BG_rgb.png 
    map_001_BG_rgb.png 
        ---over   proess:31.1mb (4.0mb)   free:254.3mb 
    tex   240    map_001_BG.pvr.ccz 
    map_001_BG.pvr.ccz 
        ---over   proess:35.1mb (4.0mb)   free:250.4mb 
    tex   204    map_001_BG_rgb.pvr.ccz 
    map_001_BG_rgb.pvr.ccz 
        ---over   proess:39.2mb (4.0mb)   free:246.5mb 
    tex   97    map_001_BG_rgb565.pvr 
    map_001_BG_rgb565.pvr 
        ---over   proess:41.2mb (2.0mb)   free:244.6mb 
    tex   710    map_001_BG_rgb565.png 
    map_001_BG_rgb565.png 
        ---over   proess:45.2mb (4.0mb)   free:241.1mb 
    tex   591    map_001_BG_rgba8888f.png 
    map_001_BG_rgba8888f.png 
        ---over   proess:47.8mb (2.6mb)   free:238.3mb 
    tex   484    map_001_BG_rgba8888f.jpg 
    map_001_BG_rgba8888f.jpg 
        ---over   proess:49.7mb (1.9mb)   free:236.5mb 
    tex   123    map_001_BG_rgba8888f.pvr 
    map_001_BG_rgba8888f.pvr 
        ---over   proess:52.4mb (2.7mb)   free:234.1mb 
    tex   589    map_001_BG_rgb888f.png 
    map_001_BG_rgb888f.png 
        ---over   proess:55.1mb (2.7mb)   free:231.2mb 
    tex   478    map_001_BG_rgb888f.jpg 
    map_001_BG_rgb888f.jpg 
        ---over   proess:57.0mb (1.9mb)   free:229.4mb 
    tex   92    map_001_BG_rgb888f.pvr 
    map_001_BG_rgb888f.pvr 
        ---over   proess:59.0mb (2.0mb)   free:227.8mb 
    (lldb) 




    第二个日志是ios版本的图片加载,其他与上一个相同,可以看到速度要比windows版本的png加载快一倍,但是内存消耗更高 




    2012-12-27 15:36:10.330 HelloCpp[4979:707] cocos2d: surface size: 960x640 
    Cocos2d: cocos2d: cocos2d-2.1beta3-x-2.1.0 
    Cocos2d: cocos2d: GL_VENDOR:     Imagination Technologies 
    Cocos2d: cocos2d: GL_RENDERER:   PowerVR SGX 535 
    Cocos2d: cocos2d: GL_VERSION:    OpenGL ES 2.0 IMGSGX535-63.24 
    Cocos2d: cocos2d: GL_MAX_TEXTURE_SIZE: 2048 
    Cocos2d: cocos2d: GL_MAX_TEXTURE_UNITS: 8 
    Cocos2d: cocos2d: GL supports PVRTC: YES 
    Cocos2d: cocos2d: GL supports BGRA8888 textures: NO 
    Cocos2d: cocos2d: GL supports NPOT textures: YES 
    Cocos2d: cocos2d: GL supports discard_framebuffer: YES 
    Cocos2d: cocos2d: GL supports shareable VAO: YES 
    Cocos2d: cocos2d: compiled with Profiling Support: NO 
    tex   196    map_001_BG.pvr 
    map_001_BG.pvr 
        ---over   proess:11.0mb (4.0mb)   free:275.8mb 
    tex   160    map_001_BG_rgb.pvr 
    map_001_BG_rgb.pvr 
        ---over   proess:15.0mb (4.0mb)   free:271.9mb 
    tex   130    map_001_BG.jpg 
    map_001_BG.jpg 
        ---over   proess:19.3mb (4.3mb)   free:267.6mb 
    tex   151    map_001_BG_rgb.jpg 
    map_001_BG_rgb.jpg 
        ---over   proess:23.5mb (4.2mb)   free:263.8mb 
    tex   344    map_001_BG.png 
    map_001_BG.png 
        ---over   proess:28.7mb (5.3mb)   free:258.7mb 
    tex   328    map_001_BG_rgb.png 
    map_001_BG_rgb.png 
        ---over   proess:34.0mb (5.3mb)   free:253.6mb 
    tex   237    map_001_BG.pvr.ccz 
    map_001_BG.pvr.ccz 
        ---over   proess:38.0mb (4.0mb)   free:249.6mb 
    tex   221    map_001_BG_rgb.pvr.ccz 
    map_001_BG_rgb.pvr.ccz 
        ---over   proess:42.0mb (4.0mb)   free:245.2mb 
    tex   98    map_001_BG_rgb565.pvr 
    map_001_BG_rgb565.pvr 
        ---over   proess:44.0mb (2.0mb)   free:243.2mb 
    tex   300    map_001_BG_rgb565.png 
    map_001_BG_rgb565.png 
        ---over   proess:48.9mb (4.9mb)   free:238.2mb 
    tex   293    map_001_BG_rgba8888f.png 
    map_001_BG_rgba8888f.png 
        ---over   proess:52.8mb (3.9mb)   free:234.2mb 
    tex   87    map_001_BG_rgba8888f.jpg 
    map_001_BG_rgba8888f.jpg 
        ---over   proess:55.7mb (2.9mb)   free:231.7mb 
    tex   143    map_001_BG_rgba8888f.pvr 
    map_001_BG_rgba8888f.pvr 
        ---over   proess:58.3mb (2.7mb)   free:228.8mb 
    tex   300    map_001_BG_rgb888f.png 
    map_001_BG_rgb888f.png 
        ---over   proess:62.2mb (3.9mb)   free:225.3mb 
    tex   87    map_001_BG_rgb888f.jpg 
    map_001_BG_rgb888f.jpg 
        ---over   proess:65.1mb (2.9mb)   free:222.7mb 
    tex   91    map_001_BG_rgb888f.pvr 
    map_001_BG_rgb888f.pvr 
        ---over   proess:67.0mb (1.9mb)   free:220.7mb 
    (lldb) 

  • 相关阅读:
    第一节:SpringMVC概述
    SpringMVC【目录】
    Windows 系统快速查看文件MD5
    (error) ERR wrong number of arguments for 'hmset' command
    hive使用遇到的问题 cannot recognize input
    Overleaf支持的部分中文字体预览
    Understanding and Improving Fast Adversarial Training
    Django2实战示例 第十三章 上线
    Django2实战示例 第十二章 创建API
    Django2实战示例 第十一章 渲染和缓存课程内容
  • 原文地址:https://www.cnblogs.com/ablansetaimeng/p/4218550.html
Copyright © 2011-2022 走看看