转自:https://blog.csdn.net/oqqQuZi1234567/article/details/41749599

图片文件大小和纹理内存占用是两码事。假设他们是帐篷。图片文件就相当于帐篷被装在行李箱。但是,如果你想要使用帐篷的话,它必须被撑起来,被“膨胀”。
图片文件和纹理的关系与此类似。图片文件大多是压缩过的,它们被使用的话必须先解压缩,然后才能会GPU所处理,变成我们熟知的纹理。一个2048*2048的png图片,采用32位颜色深度编码,那么它在磁盘上占用空间只有2MB。但是,如果变成纹理,它将消耗16MB的内存!
当然,减少纹理占用内存大小是有办法滴。

使用16-bit纹理
最快速地减少纹理内存占用的办法就是把它们作为16位颜色深度的纹理来加载。cocos2d默认的纹理像素格式是32位颜色深度。如果把颜色深度减半,那么内存消耗也就可以减少一半。并且这还会带来渲染效率的提升,大约提高10%。
你可以使用CCTexture2D对象的类方法setDefaultAlphaPixelFormat来更改默认的纹理像素格式,代码如下:
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGB5A1];
[[CCTextureCache sharedTextureCache] addImage:@"ui.png"];
这里有个问题:首先,纹理像素格式的改变会影响后面加载的所有纹理。因此,如果你想后面加载纹理使用不同的像素格式的话,必须再调用此方法,并且重新设置一遍像素格式。
其次,如果你的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位纹理的不足之处了:它由于颜色总量的减少,有一些图片显示起来可能会失真,而且可能会产生“梯度”。

使16位纹理看起来更棒
幸运的是,我们有TexturePacker.(后面简称TP)
TP有一个特性叫做“抖动”,它可以使得原本由于颜色数量减少而产生的失真问题得到改善。(TP里面有很多抖动算法,关于这些算法,读者可以参考我翻译的另一篇文章)。
特别是在拥有Retina显示的像素密度下,你几乎看不出16位与32位的纹理之间的显示差别。当然,前提是你需要采用“抖动”算法。
cocos2d默认的颜色深度将会把所有的纹理都渲染到16位的color framebuffer里面,然后再显示到你的设备屏幕上面。既然这样,我们为什么不把所有的纹理的格式都弄成16位呢,32位又有什么用呢?反正它本来就会渲染到16位的framebuffer上去的。这个问题有点太底层了,我不想深挖下去,而且我也不适合解释这个问题。(译者:哈哈,知之为知之,不知为不知)

使用NPOT纹理
NOPT是“non power of two”的缩写,译作“不是2的幂”。.在cocos2d1.x的时候,你必须在ccConfig.h文件中开启对NPOT的支持,但是,cocos2d 2.x就不需要了,它默认是支持NPOT的。所有3代(iphone 3GS)以后的ios设置都支持cocos2d 2.x(因为它们支持OpenGL ES2.0),所以也都能支持NPOT纹理。
如果纹理图集(texture atlas)使用NPOT的纹理,它将有一个具大的优势:它允许TP更好地压缩纹理。因此,我们会更少地浪费纹理图集的空白区域。而且,这样的纹理在加载的时候,会少使用1%到49%左右的内存。而且你可以使用TP强制生成NPOT的纹理。(你只需要勾选“allow free size”即可)
为什么要关心NPOT呢?因为苹果的OpenGL驱动有一个bug,导致如果使用POT的纹理,则会产生额外33%的内存消耗。

————————————————
版权声明:本文为CSDN博主「fnxiao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/oqqQuZi1234567/article/details/41749599

游戏内存优化之使用16位纹理/NPOT的更多相关文章

  1. 转 cocos2dx内存优化 (之二)

    一.cocos2dx之如何优化内存使用(高级篇) 本文由qinning199原创,转载请注明:http://www.cocos2dx.net/?p=93 一.内存优化原则 为了优化应用内存,你应该知道 ...

  2. cocos2dx内存优化

    纹理消耗了大量内存 在大部分情况下,是纹理(textures)消耗了游戏程序大量的内存.因此,纹理是我们首要考虑优化的对象 纹理加载 cocos2d里面纹理加载分为两个阶段:从图片文件中创建一个Ima ...

  3. 32位Windows7上8G内存使用感受+xp 32位下使用8G内存 (转)

    32位Windows7上8G内存使用感受+xp 32位下使用8G内存 博客分类: Windows XPWindowsIE企业应用软件测试  我推荐做开发的朋友:赶快加入8G的行列吧....呵呵..超爽 ...

  4. 转 iOS和android游戏纹理优化和内存优化(cocos2d-x)

    iOS和android游戏纹理优化和内存优化(cocos2d-x) (未完成) 1.2d游戏最占内存的无疑是图片资源. 2.cocos2d-x不同平台读取纹理的机制不同.ios下面使用CGImage, ...

  5. iOS和android游戏纹理优化和内存优化(cocos2d-x)(转载)

    转自http://blog.csdn.net/langresser_king/article/details/8426708 (未完成) 1.2d游戏最占内存的无疑是图片资源. 2.cocos2d-x ...

  6. iOS和android游戏纹理优化和内存优化(cocos2d-x)

    1.2d游戏最占内存的无疑是图片资源. 2.cocos2d-x不同平台读取纹理的机制不同.ios下面使用 CGImage,android和windows下是直接调用png库.我测试了下,使用png库直 ...

  7. OS和android游戏纹理优化和内存优化(cocos2d-x)

    注:原文地址不详! 1.2d游戏最占内存的无疑是图片资源. 2.cocos2d-x不同平台读取纹理的机制不同. ios以下使用CGImage,android和windows下是直接调用png库.我測试 ...

  8. Unity3D 游戏开发之内存优化

    项目的性能优化主要围绕CPU.GPU和内存三大方面进行. 无论是游戏还是VR应用,内存管理都是其研发阶段的重中之重. 然而,在我们测评过的大量项目中,90%以上的项目都存在不同程度的内存使用问题.就目 ...

  9. 转 cocos2d-x 优化(纹理渲染优化、资源缓存、内存优化)

    概述 包括以下5种优化:引擎底层优化.纹理优化.渲染优化.资源缓存.内存优化   引擎优化 2.0版本比1.0版本在算法上有所优化,效率更高.2.0版本使用OpenGl ES 2.0图形库,1.0版本 ...

  10. cocos2d-x项目过程记录(纹理和内存优化方面)

    1.参考资料:Cocos2d-x纹理优化的一些方案  cocos2d-x如何优化内存的应用  iOS和android游戏纹理优化和内存优化(cocos2d-x) 2.加载贴图集纹理 CCSpriteF ...

随机推荐

  1. 从各种点理解Unity中的协程

    这个写的很好,https://zhuanlan.zhihu.com/p/59619632

  2. Spark log4j 配置

    Spark的ml包提供了非常好用的调参功能,通过ParamGridBuilder构建待选参数(如:logistic regression的regParam),然后数据量小的时候可以用CrossVali ...

  3. mvc和ef如何连接

    1.一般加上ef步骤:引入ef包,新建自己的context并继承自DbContext,构造函数里写上链接字符串,属性都是表集合.如何使用:程序中UserContext un = new UserCon ...

  4. .NetCore自定义模板,发布Nuget

    1.创建模板项目框架 2.创建模板文件 在项目文件夹根目录创建.template.config文件夹,在文件夹下创建新的文件:template.json 内容如下 { "$schema&qu ...

  5. 城市间最短路径问题——R和Rcpp实现

    这里的最短路径问题也叫做相识问题,具体问题来自 https://www.math.pku.edu.cn/teachers/lidf/docs/Rbook/html/_Rbook/examples.ht ...

  6. 手把手XTTS_V4迁移

    最近公司Oracle升级,考虑到停机时间等综合因数,最终选择了xtts数据迁移方案. 为此我整理了一份操作手册,方便以后查阅. 关于xtts的介绍可以参见这篇文章: <XTTS,又一个值得你重视 ...

  7. List集合转换成数组

    我现在有个需求:将File集合转换成MultipartFile数组结构 然后我就开始在网上开启了List转换到数组之旅. 首先来看一个例子 ArrayList<String> list=n ...

  8. torch.squeeze函数解释,torch.FloatTensor()函数作用解释

    1. torch.squeeze(x,N)  主要对数据维度进行压缩 torch.squeeze(x,N) #也可以写为格式 x.squeeze(dim=N) 含义:当N未给定时,去掉x中所有维度为1 ...

  9. tidb自动处理僵尸进程脚本

    [root@host-2 wj]# vi kill_tidb_zombie.sh #!/bin/bash source /etc/profile cat /dev/null > /tmp/sql ...

  10. crontab执行不生效

    背景:不知道什么原因脚本手动执行:正常:crontab执行不生效: 1.将命令所属路径加入到 /etc/crontab中, 2.在shell脚本中加入 source /etc/profile