乐趣区

关于opengl-es:OpenGL-ES-压缩纹理

什么是压缩纹理

在理论利用特地是游戏中纹理占用了相当大的包体积,而且 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

退出移动版