什么是压缩纹理

在实际应用特别是游戏中纹理占用了相当大的包体积,而且GPU无法直接解码目前流行的图片格式,图片必须转换为RGB等类型的格式才能上传到GPU内存,这显然增加了GPU内存的占用。为了处理这些问题于是出现了GPU支持的压缩纹理格式,在GPU中进行解码。压缩纹理属于有损压缩,更在意解码速度,而编码在程序运行之前,因此速度较慢。

压缩纹理的常见格式

基于OpenGL ES的压缩纹理有常见的如下几种实现:

1)ETC1(Ericsson texture compression)

2)ETC2(Ericsson texture compression)

3)PVRTC (PowerVR texture compression)

4)ATITC (ATI texture compression)

5)S3TC (S3 texture compression)

ETC1

ETC1格式是OpenGL ES图形标准的一部分,并且被所有的Android设备所支持。

扩展名为: GL_OES_compressed_ETC1_RGB8_texture,不支持透明通道,所以仅能用于不透明纹理。

且要求大小是2次幂。

当加载压缩纹理时,参数支持如下格式: GL_ETC1_RGB8_OES(RGB,每个像素0.5个字节)

ETC2

ETC2 是 ETC1 的扩展,压缩比率一样,但压缩质量更高,而且支持透明通道,能完整存储 RGBA 信息。ETC2 需要 OpenGL ES 3.0(对应 WebGL 2.0)环境,目前还有不少低端 Android 手机不兼容,iOS 方面从 iPhone5S 开始都支持 OpenGL ES 3.0。ETC2 和 ETC1 一样,长宽可以不相等,但要求是 2 的幂次方。

PVRTC

支持的GPU为Imagination Technologies的PowerVR SGX系列。

OpenGL ES的扩展名为: GL_IMG_texture_compression_pvrtc。

当加载压缩纹理时,参数支持如下几种格式: GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG (RGB,每个像素0.5个字节) GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG (RGB,每个像素0.25个字节) GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG (RGBA,每个像素0.5个字节) GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG (RGBA,每个像素0.25个字节)

ATITC

支持的GPU为Qualcomm的Adreno系列。

支持的OpenGL ES扩展名为: GL_ATI_texture_compression_atitc。

当加载压缩纹理时,参数支持如下类型的纹理: GL_ATC_RGB_AMD (RGB,每个像素0.5个字节) GL_ATC_RGBA_EXPLICIT_ALPHA_AMD (RGBA,每个像素1个字节) GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD (RGBA,每个像素1个字节)

S3TC

也被称为DXTC,在PC上广泛被使用,但是在移动设备上还是属于新鲜事物。支持的GPU为NVIDIA Tegra系列。

OpenGL ES扩展名为:

GL_EXT_texture_compression_dxt1和GL_EXT_texture_compression_s3tc。

当加载压缩纹理时,参数有如下几种格式: GL_COMPRESSED_RGB_S3TC_DXT1 (RGB,每个像素0.5个字节) GL_COMPRESSED_RGBA_S3TC_DXT1 (RGBA,每个像素0.5个字节) GL_COMPRESSED_RGBA_S3TC_DXT3 (RGBA,每个像素1个字节) GL_COMPRESSED_RGBA_S3TC_DXT5 (RGBA,每个像素1个字节)

压缩纹理相关API的使用

1) 获得GPU的型号

glGetString(GL_RENDERER)

2) 获得GPU的生产厂商

glGetString(GL_VENDOR);

3) 获取GPU支持哪些压缩纹理

string extensions = (const char*)glGetString(GL_EXTENSIONS);

4)判断是否支持ETC1格式的压缩纹理

return (extensions.find("GL_OES_compressed_ETC1_RGB8_texture")!= string::npos);

5) 判断是否支持DXT格式的压缩纹理

return (extensions.find("GL_EXT_texture_compression_dxt1")!= string::npos ||
extensions.find("GL_EXT_texture_compression_s3tc")!= string::npos);

6)判断是否支持PVRTC格式的压缩纹理

return (extensions.find("GL_IMG_texture_compression_pvrtc")!= string::npos);

7)判断是否支持ATITC格式的压缩纹理

return (extensions.find("GL_AMD_compressed_ATC_texture")!= string::npos ||
extensions.find("GL_ATI_texture_compression_atitc")!= string::npos);

8) 上传压缩纹理数据

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

internalformat即是压缩纹理格式的类型。

9)查看设备支持的texture压缩格式,可以使用如下代码获取:

int num_formats;
glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_formats);
std::cout<<"Texture extensions: "<<num_formats<<std::endl; int *formats = (int*)alloca(num_formats * sizeof(int));
glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
for(int i=0; i<num_formats; i++)
{
std::cout<<i<<" 0x"<<hex<<formats[i]<<dec<<std::endl;
} //注意使用PVRTC格式纹理时,纹理的filter mode不能设置为 GL_LINEAR_MIPMAP_LINEAR,
//否则的话加载出来的画线显示黑色, 这里有提到。

10)glTexImage中指定压缩格式可以对上传的纹理进行压缩以改善内存使用,通过设置intenalFormat为表中一个值实现。通过这种方式进行图像压缩增加了纹理加载的开销,但却能够通过更有效地使用纹理存储空间来增加纹理性能,如果由于某些原因无法对纹理进行压缩,OpenGL就会使用下表中所列出的基本内部格式,并加载未经压缩的纹理。

GL_COMPRESSED_RGB : GL_RGB
GL_COMPRESSED_RGBA : GL_RGBA
GL_COMPRESSED_SRGB : GL_SRGB
GL_COMPRESSED_SRGB_ALPHA : GL_RGBA
GL_COMPRESSED_RED : GL_RED
GL_COMPRESSED_RG : GL_RG

除了这些压缩格式外,OpenGL中还加入了一些特定的压缩格式,即GL_COMPRESSED_SIGNED_RED_RGTC1,GL_COMPRESSED_SIGNED_RED_RGTC2,和GL_COMPRESSED_SIGNED_RG_RGTC2,它们用于各种单颜色通道和双颜色通道压缩纹理,他们代替了兼容版本中GL_LUMINANCE和GL_LUMINANCE_ALPHA的功能

11)判断纹理是否被成功压缩

GLint comFlag;
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_COMPRESSED,&comFlag);

glGetTexLevelParameteriv第三参数支持的有:

GL_TEXTURE_COMPRESSED:如果纹理被压缩返回1,否则返回0
GL_TEXTURE_COMPRESSED_IMAGE_SIZE:获取压缩后的纹理大小(以字节为单位)
GL_TEXTURE_INTERNAL_FORMAT:所使用的压缩格式
GL_NUM_COMPRESSED_TEXTURE_FORMATS:支持的压缩纹理格式数量
GL_COMPRESSED_TEXTURE_FORMATS:支持的压缩纹理格式数组
GL_TEXTURE_COMPRESSION_HINT: 选择压缩格式的方式

11)指定选择压缩格式的方式

glHint(GL_TEXTURE_COMPRESSION_HINT,GL_FASTEST); //最快
glHint(GL_TEXTURE_COMPRESSION_HINT,GL_NICEST); //质量最好
glHint(GL_TEXTURE_COMPRESSION_HINT,GL_DONT_CARE); //自行选择

压缩纹理工具

每种压缩纹理以及相应的厂商都提供了压缩纹理的工具,包括可视化工具和命令行工具,可自行下载

1)Imagination Technologies PowerVR

PVETextTool

2)Qualcomm Adreno

Adreno Texture Tool

3)ARM Mali

Mail Texture Compression Tool

4)nVIDIA Tegra

DirectX Texture Tool

OpenGL ES 压缩纹理的更多相关文章

  1. 2.x最终照着教程,成功使用OpenGL ES 绘制纹理贴图,添加了灰度图

    在之前成功绘制变色的几何图形之后,今天利用Openg ES的可编程管线绘制出第一张纹理. 学校时候不知道OpenGL的重要性,怕晦涩的语法.没有跟老师学习OpenGL的环境配置,现在仅仅能利用coco ...

  2. Android OpenGL ES(八)----纹理编程框架

    1.把纹理载入进OpenGL中 我们的第一个任务就是把一个图像文件的数据载入到一个OpenGL的纹理中. 作为開始.让我们又一次舍弃第二篇的框架.又一次创建一个程序,新建一个util工具包,在该包下创 ...

  3. Opengl ES之纹理贴图

    纹理可以理解为一个二维数组,它可以存储大量的数据,这些数据可以发送到着色器上.一般情况下我们所说的纹理是表示一副2D图,此时纹理存储的数据就是这个图的像素数据. 所谓的纹理贴图,就是使用Opengl将 ...

  4. 【AR实验室】OpenGL ES绘制相机(OpenGL ES 1.0版本)

    0x00 - 前言 之前做一些移动端的AR应用以及目前看到的一些AR应用,基本上都是这样一个套路:手机背景显示现实场景,然后在该背景上进行图形学绘制.至于图形学绘制时,相机外参的解算使用的是V-SLA ...

  5. OpenGL ES教程系列(经典合集)

    为了搞透播放器的开发,花了些时间收集这些资料,虽然我已经搞定opengles渲染视频的内容,但是想玩玩opengles,往深里玩,图像处理这块是个好的方向,所以opengles是值得好好学的.   O ...

  6. OpenGL ES: (5) OpenGL的基本概念、OpenGL ES 在屏幕产生图片的过程、OpenGL管线(pipeline)

    一. OpenGL的基本概念 OpenGL 的结构可以从逻辑上划分为下面 3 个部分: 图元(Primitives) 缓冲区(Buffers) 光栅化(Rasterize) 图元(Primitives ...

  7. Opengl ES之VBO和VAO

    前言 本文主要介绍了什么是VBO/VAO,为什么需要使用VBO/VAO以及如何使用VBO和VAO. VBO 什么是VBO VBO(vertex Buffer Object):顶点缓冲对象.是在显卡存储 ...

  8. Opengl ES之FBO

    FBO介绍 FBO帧缓冲对象,它的主要作用一般就是用作离屏渲染,例如做Camera相机图像采集进行后期处理时就可能会用到FBO.假如相机出图的是OES纹理,为了方便后期处理, 一般先将OES纹理通过F ...

  9. OpenGL ES学习笔记(三)——纹理

    首先申明下,本文为笔者学习<OpenGL ES应用开发实践指南(Android卷)>的笔记,涉及的代码均出自原书,如有需要,请到原书指定源码地址下载. <OpenGL ES学习笔记( ...

随机推荐

  1. EFCore之增删改查

    1. 连接数据库 通过依赖注入配置应用程序,通过startup类的ConfigureService方法中的AddDbContext将EFCore添加到依赖注入容器 public void Config ...

  2. [Java] 数据分析--数据预处理

    数据结构 键-值对:HashMap 1 import java.io.File; 2 import java.io.FileNotFoundException; 3 import java.util. ...

  3. 联想 lenove 3750 M4服务器更改启动项和管理口IP

    联想 lenove 3750 M4服务器更改启动项和管理口IP 注: 因为在机房拍照的原因,再加上工作比较忙:整理成文档的时候有的过程已经忘记了,所以有的步骤可能会缺失,里面的选项都已经用中文方式表达 ...

  4. Linux进阶之Git分布式版本控制系统篇

    一.Git介绍 Git(读音为/gɪt/.)是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理. Git 是 Linus Torvalds 为了帮助管理 Linux 内核 ...

  5. [翻译] 预览 C# 10 的新东西

    原文: [Introducing C# 10] 作者: Ken Bonny ​ 本周早些时候(译注:原文发表于5月1日),我关注了 Mads Torgersen 在 DotNet SouthWest ...

  6. MyBatis执行器

    Mybatis的执行器 下面先展示一张图,用来说明一下Mybatis执行器的整体架构 SimpleExecutor 首先SimpleExecutor是我们最常使用的一个执行器,无论我们执行什么方法默认 ...

  7. 实用程序包utils - 基于Rollup打包输出各模块文件(二)

    上一次,我们讲到了如何去搭建一个前端工具库的工程,那么今天我们来聊一聊如何去将其打包输出. 需求 事情是这个样子的.我有一个这样的需求,或者是我发现有这么一个需求.就是有时候吧,我也不想搞的那么复杂, ...

  8. App自动化测试之Appium环境安装(涉及雷电模拟器和真机)

    1.安装Microsoft .NET Framework 4.5 及以上版本 2.安装Appium 官方网站地址:http://appium.io/ 我装了1.17.0版本 3.安装JDK 1.8及以 ...

  9. 『动善时』JMeter基础 — 37、将JMeter测试结果写入Excel

    目录 1.环境准备 (1)引入操作Excel文件的基础JAR包 (2)引入封装自定义操作Excel文件的JAR包 2.准备测试需要的数据 3.测试结果写入Excel演示 (1)测试计划内包含的元件 ( ...

  10. Angel图算法

    Angel图算法 [2.0]CommonFriends 计算两个好友的共同好友数,某种程度上可以刻画两个节点之间的紧密程度. 输入 输入数据路径:输入文件所在路径,无权网络数据, 数据格式为两列 sr ...