What is compressed texture

In practical applications, especially in games, texture occupies a considerable package volume, and GPU cannot decode the current popular image format directly. Images must be converted to RGB and other formats before uploading to GPU memory, which obviously increases the occupation of GPU memory. In order to deal with these problems, the compressed texture format supported by GPU appears, which is decoded in GPU. Compressed texture is lossy compression, which is more concerned with decoding speed, and encoding before the program runs, so it is slower.

Common format for compressed textures

There are several common implementations of compressed texture based on 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

The ETC1 format is part of the OpenGL ES graphics standard and is supported by all Android devices. The extension GL_OES_compressed_ETC1_RGB8_texture does not support transparent channels, so can only be used with opaque textures. And it has to be a power of two. When loading compressed textures, the parameters support the following format: GL_ETC1_RGB8_OES(RGB, 0.5 bytes per pixel)

ETC2

ETC2 is an extension of ETC1, with the same compression ratio, but higher compression quality, and transparent channel support, complete storage of RGBA information. ETC2 requires OpenGL ES 3.0 (corresponding to WebGL 2.0). Currently, there are many low-end Android phones that are not compatible with OpenGL ES 3.0. IOS supports OpenGL ES 3.0 from iPhone5S. ETC2, like ETC1, can be unequal in length and width, but it has to be a power of two.

PVRTC

The GPU supported is Imagination Technologies PowerVR SGX series. The extension of OpenGL ES is GL_IMG_texture_compression_pvrtc. When loading compressed textures, the parameters can be in the following formats: GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG (RGB, 0.5 bytes per pixel) GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG (RGB, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG (RGBA, 0.5 bytes per pixel) GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG (RGBA, 0.5 bytes per pixel) 0.25 bytes per pixel)

ATITC

Supported Gpus are Qualcomm’s Adreno series. The supported OpenGL ES extension is GL_ATI_texture_compression_atitc. When loading compressed textures, the parameters support the following types of textures: GL_ATC_RGB_AMD (RGB, 0.5 bytes per pixel) GL_ATC_RGBA_EXPLICIT_ALPHA_AMD (RGBA, 1 byte per pixel) GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD (RGBA, 1 byte per pixel)

S3TC

Also known as DXTC, it is widely used on PCS, but is a novelty on mobile devices. NVIDIA Tegra series GPU is supported. The OpenGL ES extensions are GL_EXT_texture_compression_dxt1 and GL_EXT_texture_compression_s3tc. When loading a compressed texture, the parameters have the following formats: GL_COMPRESSED_RGB_S3TC_DXT1 (RGB, 0.5 bytes per pixel) GL_COMPRESSED_RGBA_S3TC_DXT1 (RGBA, GL_COMPRESSED_RGBA_S3TC_DXT3 (RGBA, 1 byte per pixel) GL_COMPRESSED_RGBA_S3TC_DXT5 (RGBA, 1 byte per pixel)

Use of compression texture related apis

1) Get the GPU model

glGetString(GL_RENDERER)
Copy the code

2) Obtain the GPU manufacturer

glGetString(GL_VENDOR);
Copy the code

3) Obtain the compressed textures supported by the GPU

string extensions = (const char*)glGetString(GL_EXTENSIONS);
Copy the code

4) Determine whether ETC1 format compressed texture is supported

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

5) Determine whether the compressed texture in DXT format is supported

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

6) Determine whether the compressed texture in PVRTC format is supported

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

7) Determine whether ATITC format compressed texture is supported

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

8) Upload compressed texture data

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

Internalformat is the type of compressed texture format. 9) Check the texture compression format supported by the device. You can use the following code to get it:

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; } // Note that the filter mode of the PVRTC texture cannot be set to GL_LINEAR_MIPMAP_LINEAR, otherwise the loaded lines will display black, as mentioned here.Copy the code

10) The compression format specified in glTexImage can be used to compress uploaded textures to improve memory usage by setting intenalFormat to a value in the table. Image compression in this way increases the overhead of texture loading, but increases texture performance by using texture storage more efficiently. If for some reason the texture cannot be compressed, OpenGL uses the basic internal format listed in the table below and loads the uncompressed texture.

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
Copy the code

In addition to these compression formats, OpenGL has added some specific compression formats, namely GL_COMPRESSED_SIGNED_RED_RGTC1, GL_COMPRESSED_SIGNED_RED_RGTC2, And GL_COMPRESSED_SIGNED_RG_RGTC2, which are used for various single and dual color channel compression textures. They replace GL_LUMINANCE and GL_LUMINANCE_ALPHA in compatible versions. 11) Determine if the texture has been successfully compressed

GLint comFlag; 
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_COMPRESSED,&comFlag);
Copy the code

GlGetTexLevelParameteriv Supports the following parameters:

GL_TEXTURE_COMPRESSED: returns 1 if the texture is compressed, otherwise returns 0 GL_TEXTURE_COMPRESSED_IMAGE_SIZE: Returns the compressed texture size in bytes GL_TEXTURE_INTERNAL_FORMAT: GL_NUM_COMPRESSED_TEXTURE_FORMATS: Number of supported compression texture formats GL_COMPRESSED_TEXTURE_FORMATS: GL_TEXTURE_COMPRESSION_HINT: How to select a compression formatCopy the code

11) Specify how to select the compression format

glHint(GL_TEXTURE_COMPRESSION_HINT,GL_FASTEST); / / the fastest glHint (GL_TEXTURE_COMPRESSION_HINT GL_NICEST); GlHint (GL_TEXTURE_COMPRESSION_HINT,GL_DONT_CARE); // Select your ownCopy the code

Compressed texture tool

Each texture compression tool and the corresponding vendor provide a texture compression tool, including visual tools and command line tools, can be downloaded

1) Imagination Technologies PowerVR

PVETextTool

2) Qualcomm Adreno

Adreno Texture Tool

3) ARM Mali

Mail Texture Compression Tool

4) nVIDIA prototypes

DirectX Texture Tool