CCImage作为cocos2dx texture的核心处理函数包含了丰富的底层API调用和纹理格式操作,我想以CCImage来作为切入点发散性地去做扩展可能更加容易加深我们对cocos2dx引擎的理解,话不多说。

#define CC_GL_ATC_RGB_AMD                                          0x8C92
#define CC_GL_ATC_RGBA_EXPLICIT_ALPHA_AMD                          0x8C93
#define CC_GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD                      0x87EE

CCImage的开始是这个3个宏定义,这3个宏定义其实是对于ATITC格式纹理的类型:

  • ATC_RGB_AMD (RGB textures)
  • ATC_RGBA_EXPLICIT_ALPHA_AMD (RGB textures using explicit alpha encoding)
  • ATC_RGBA_INTERPOLATED_ALPHA_AMD (RGBA textures using interpolated alpha encoding)

谈到这里我就先介绍下纹理压缩,现在的游戏绝大多数情况下我们都是通过贴图来丰富游戏场景,而贴图本身占用内存空间并且是以不压缩的形式存放在显存当中的,常见的贴图格式分为16bits、24bits和32bits,即使是16bits的1024X1024贴图在显存中的大小也高达2MB,为了加快渲染速度和减少图像的锯齿,可以使用Mipmap把贴图处理成由一系列被预先计算和优化过的图片组成的文件,当然Mipmap是需要占用一定的内存空间的。

我们常见的图片文件格式有

  • BMP: Windows标准图像文件格式,位映射存储格式,图像深度可选(lbit、4bit、8bit及24bit),不采用其他任何压缩;
  • TGA: 数字化图像,以及运用光线跟踪算法所产生的高质量图像的常用格式,支持压缩,使用不失真的压缩算法,可以带通道图,另外还支持行程编码压缩。特点是可以做出不规则形状的图形、图像文件,兼顾了BMP的图象质量的同时又兼顾了JPEG的体积优势;
  • JPG: 24位颜色存储单个位图,与平台无关的格式,支持最高级别的有损压缩,可以很好地压缩类似的色调,但不能很好地处理亮度的强烈差异或处理纯色区域,只支持YUV颜色模式的数据结构。
  • GIF: 基于LZW算法的连续色调的无损压缩格式,可变长度等压缩算法;
  • PNG: 位图文件(bitmap file)存储格式,8位、24位、32位三种形式。

要显示一张JPG格式的图片需要先解码加载(手持设备上还是比较耗电的),然后再解压缩成原始像素格式传递给显卡,在没有显卡硬件支持的前提下,使用压缩格式保存纹理是值得商榷的。正是因为现在游戏对贴图的依赖导致对显示总线造成巨大的压力,所以很多厂家都对硬件提供了实时解压缩的功能,不过可惜的是没有一个格式能够得到多个厂家的支持。OpenGL ES定义了一个标准的接口:

GL_API void           GL_APIENTRY glCompressedTexImage2D (GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid* data);

不过纹理数据的格式还是没有统一的标准,导致一旦使用了压缩纹理就无法实现跨平台。

之前的纹理优化已经介绍了常见的纹理格式RGB565,RGBA4444,RGBA5551,RGB888,RGBA8888等。这里我们应该能很好地明白文件格式和纹理格式的区别了,文件格式是图像为了存储信息而使用的对信息的特殊编码方式,它存储在磁盘中,或者内存中,但是并不能被GPU所识别,因为以向量计算见长的GPU对于这些复杂的计算无能为力。这些文件格式当被游戏读入后,还是需要经过cpu解压成像素格式,再传送到GPU端进行使用。而纹理格式就是能被GPU所识别的像素格式,能被快速寻址并采样。举个例子,DDS文件是游戏开发中常用的文件格式,它内部可以包含RGBA4444的纹理格式,也可以包含RGBA8888的纹理格式,甚至可以包含DXT1的纹理格式。在这里DDS文件有点容器的意味。

这里我们可能会疑问我们为什么不能把类似图片压缩格式的方法应用在纹理贴图上,其实这是因为显示芯片在存取贴图时,是一种「随机存取」的动作。也就是说,显示芯片通常会需要以任意的顺序存取贴图里的数据。一般的压缩方式如JPEG,都利用了行程长度的编码方法,简单的说,它们必需以一定的顺序才能解开。因此,不能用这种方式来压缩贴图。

纹理的压缩方式分为2种:

  • 改变颜色空间:例如3dfx公司的YAB格式,利用YAB,每个像点只需要8bits,就可以达到接近16bits的效果。不过,无论如何,这样都使颜色的数目减少。因此,整个贴图的色彩变化就受到了限制。
  • 调色盘:就是类似OpenGL的索引,利用一个256种颜色的调色盘,就可以把贴图以 8 bits 的方式储存。不过,虽然它的色彩空间较大(可以是24bits或32bits),但是总颜色数目还是不能超过256种。所以,它的应用范围仍然有限。

现在常用的贴图压缩方式,则是利用以区块为基础的方式。通常的做法是,把贴图切割成许多小区块,再对各个区块进行压缩。例如,S3TC就是把贴图切成4×4的小区块。利用这种做法,就可以对区块进行某种处理(通常就是vector quantization或是其变形),显示芯片也可以区块为单位,进行随机的存取动作。因此,这是适合用在贴图的方式。

不过,区块的大小会影响到压缩的效果。一般来说,区块愈大,就能有愈高的压缩比。不过,愈大的区块也会使额外的负担增加。因为显示芯片只能以区块为单位来读取贴图数据,如果区块愈大,则每个区块中就可能会有愈多的数据是不需要的。所以,也不能任意把区块的大小加大。

在基于已压缩纹理的渲染论文中,列举了纹理压缩四项的特点,使其不同于其他图像压缩技术。

  • 解压速度:由于最好能直接从已压缩的纹理直接渲染,为了尽可能地不影响性能,解压缩要尽可能快。
  • 随机访问:由于几乎不可能预测纹素被访问的顺序,任何纹理压缩算法必须允许对其中纹素的随机访问。所以几乎所有的纹理压缩算法都以块为单位压缩和存储纹素,当某一纹素被访问时,只有同一块中若干纹素被读取和解压缩。这项需求也排除了很多压缩率较高的图像压缩方式,例如JPEG和行程长度编码。
  • 压缩率和图像质量:由于人眼的不精确性,相比于其他应用领域,图像渲染更适宜使用有损数据压缩。
  • 编码速度:纹理压缩对压缩速度要求不高,因为绝大多数情况下,纹理只需要进行一次压缩。

由于其数据访问模式是事先知道的,纹理压缩常作为整个绘图管线的一部分,在绘制时对动态地已压缩数据进行解压缩。而反过来绘制管线也可以通过纹理压缩技术来降低对于
带宽和存储的需求。在纹理贴图中,已压缩纹理和没有经过压缩的纹理使用起来基本没有区别,都可以被用来存储颜色数据或其他数据,例如凹凸贴图或法线贴图,也都可以和Mipmapping或各向异性过滤等共同使用。

现在主流的移动cpu支持的纹理格式(ARM移动处理器其实是一种SoC片上系统,其内部整合了cpu单元和GPU单元甚至通讯单元。因此在讨论游戏兼容性时,cpu就等于GPU):

cpu GPU
德州仪器 Power VR系列
三星猎户座 Mail系列
高通 Adreno系列
NVIDIA Geforce系列
海思K3V2 Vivante GC
  • Imagination的PowerVR:PVRTC,ETC1
    • 代表机型:Apple iPhone、iPad,三星I9000、P3100
  • Qualcomm的Adreno系列:
    • Adreno 2xx系列:3Dc和ATITC(基于ATI)
    • Adreno 320:ETC,3Dc和ATITC(基于ATI),ETC2
    • 代表机型:HTC G10、G14,小米1、小米2
  • ARM的Mali系列:ETC
    • 300/400系列:
    • T600系列:ASTC
    • 代表机型:三星galaxy SII、galaxy SIII、galaxy Note1、galaxy Note2(亚版)
  • NVIDIA的Geforce系列:ETC,S3TC(DXT1、DXT3和DXT5)
    • Tegra 2:ATITC
    • Tegra K1:ASTC
    • 代表机型:Google Nexus 7,HTC One X
  • Vivante的GC系列:ETC,S3TC

现在主流的纹理压缩标准:

  • ETC1:OpenGL ES2.0基本的纹理压缩标准,大部分移动GPU都会支持的纹理标准,不支持Alpha通道,只能用于压缩不透明的材质,几乎所有的安卓设备都可以支持ETC压缩的GPU加速;
  • ETC2:OpenGL ES 3.0引入的纹理压缩格式,还在改进中,除了高通的Adreno 320之外还没有移动GPU支持,补全了ETC1不支持Alpha通道的缺陷,支持更高质量的RGBA(RGB+Alpha)压缩;
  • PVRTC:
  • S3TC:也被称为DXTn或者DXTC,就是常见的DDS压缩纹理,无论压缩速度还是压缩比都不错,也支持GPU加速,而且是桌面显卡通用的压缩格式;
  • EAC:主要用于1-2信道数据的情况;
  • ASTC:压缩速度和质量上比S3TC要好;

未完待续…

纹理压缩的更多相关文章

  1. ios – AFNetworking启用GZIP

    我在AFNetworking网站上查看支持GZIP压缩“服务器响应的Gzip解压缩已经内置在AFNetworking中,因为NSURLConnection将使用content-encoding:gzipHTTP头自动解压缩响应.”–AFNetworking常见问题如何启用GZIP压缩,以便我可以从服务器压缩数据或已经默认为谢谢!

  2. android – 如何“安装”Action Bar Sherlock?

    我应该安装哪个库?解决方法没有听到包含动作栏的兼容性库,几天前我已经下载了最后一个.无论如何,它很简单,解压缩文件IN(!!

  3. 利用Java实现zip压缩/解压缩

    Java1.1实现了I/O数据流与网络数据流的单一接口,因此数据的压缩、网络传输和解压缩的实现比较容易,下面介绍利用ZipEntry、ZipInputStream和ZipOutputStream三个Java类实现zip数据压缩方式的编程方法。zip压缩文件结构:一个zip文件由多个entry组成,每个entry有一个唯一的名称,entry的数据项存储压缩数据。与zip文件有关的几个Java类·类ZipEntrypublicZipEntry;name为指定的数据项名。·类ZipOutputStreamZip

  4. PHP 实现文件压缩解压操作的方法

    这篇文章主要介绍了PHP 实现压缩解压操作的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  5. Java实现文件压缩为zip和解压zip压缩包

    这篇文章主要为大家介绍了Java如何实现将文件压缩为zip以及解压zip压缩包,文中的示例代码讲解详细,感兴趣的小伙伴可以动手尝试一下

  6. Node.js实现压缩与解压数据

    这篇文章介绍了Node.js实现压缩与解压数据的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  7. JavaScript 如何在线解压 ZIP 文件

    本文将介绍浏览器解压和服务器解压两种在线解压ZIP文件的方案。帮助大家用JavaScript实现在线解压,感兴趣的朋友可以参考下

  8. PHP解压ZIP文件到指定文件夹的方法

    这篇文章主要介绍了PHP解压ZIP文件到指定文件夹的方法,结合实例形式分析了php实现的zip操作类及相应使用技巧,需要的朋友可以参考下

  9. php利用ZipArchive类操作文件的实例

    在本篇文章里小编给大家整理了关于php利用ZipArchive类实现文件压缩与解压实例代码内容,需要的朋友们学习下。

  10. Java对zip,rar,7z文件带密码解压实例详解

    在日常业务中,会遇到一些琐碎文件需要打包到一个压缩包中上传,业务方在后台接收到压缩包后自行解压,然后解析相应文件。而且可能涉及安全保密,因此会在压缩时带上密码,要求后台业务可以指定密码进行解压。本文将用Java解决这一问题,需要的可以参考一下

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部