Android 使用压缩纹理( 二 )

CompressedTextureInfo对象 。
1.ETC1ETC1格式是OpenGL ES图形标准的一部分,并且被所有的Android设备所支持 。扩展名为: GL_OES_compressed_ETC1_RGB8_texture,不支持透明通道,所以仅能用于不透明纹理 。且要求大小是2次幂 。当加载压缩纹理时,参数支持如下格式: GL_ETC1_RGB8_OES(RGB,每个像素0.5个字节)ETC1 压缩纹理的加载,主要参考了Android源码:etc1.cpp解析 ETC1 纹理:
// 解析 ETC1 纹理static const CompressedTextureInfo ParseETC1Texture(unsigned char* data) {    CompressedTextureInfo textureInfo;    textureInfo.is_valid = false;    const etc1::etc1_byte *header = data;    if (!etc1::etc1_pkm_is_valid(header)) {        LogE("LoadTexture: etc1_pkm is not valid");        return textureInfo;    }    unsigned int width = etc1::etc1_pkm_get_width(header);    unsigned int height = etc1::etc1_pkm_get_height(header);    GLuint size = 8 * ((width + 3) >> 2) * ((height + 3) >> 2);    GLvoid *texture_data = data + ETC1_PKM_HEADER_SIZE;    textureInfo.is_valid = true;    textureInfo.width = width;    textureInfo.height = height;    textureInfo.size = size;    textureInfo.internal_format = GL_ETC1_RGB8_OES;    textureInfo.data = texture_data;    return textureInfo;}2.ETC2ETC2 是 ETC1 的扩展,压缩比率一样,但压缩质量更高,而且支持透明通道,能完整存储 RGBA 信息 。ETC2 需要 OpenGL ES 3.0(对应 WebGL 2.0)环境,目前还有不少低端 Android 手机不兼容,iOS 方面从 iPhone5S 开始都支持 OpenGL ES 3.0 。ETC2 和 ETC1 一样,长宽可以不相等,但要求是 2 的幂次方 。
首先定义好 ETC2 的 Header:
// etc2_texture.hclass Etc2Header {public:    Etc2Header(const unsigned char *data);    unsigned short getWidth(void) const;    unsigned short getHeight(void) const;    unsigned short getPaddedWidth(void) const;    unsigned short getPaddedHeight(void) const;    GLsizei getSize(GLenum internalFormat) const;private:    unsigned char paddedWidthMSB;    unsigned char paddedWidthLSB;    unsigned char paddedHeightMSB;    unsigned char paddedHeightLSB;    unsigned char widthMSB;    unsigned char widthLSB;    unsigned char heightMSB;    unsigned char heightLSB;};// etc2_texture.cppEtc2Header::Etc2Header(const unsigned char *data) {    paddedWidthMSB  = data[8];    paddedWidthLSB  = data[9];    paddedHeightMSB = data[10];    paddedHeightLSB = data[11];    widthMSB        = data[12];    widthLSB        = data[13];    heightMSB       = data[14];    heightLSB       = data[15];}unsigned short Etc2Header::getWidth() const {    return (widthMSB << 8) | widthLSB;}unsigned short Etc2Header::getHeight() const {    return (heightMSB << 8) | heightLSB;}unsigned short Etc2Header::getPaddedWidth() const {    return (paddedWidthMSB << 8) | paddedWidthLSB;}unsigned short Etc2Header::getPaddedHeight() const {    return (paddedHeightMSB << 8) | paddedHeightLSB;}GLsizei Etc2Header::getSize(GLenum internalFormat) const {    if (internalFormat != GL_COMPRESSED_RG11_EAC        && internalFormat != GL_COMPRESSED_SIGNED_RG11_EAC        && internalFormat != GL_COMPRESSED_RGBA8_ETC2_EAC        && internalFormat != GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC) {        return (getPaddedWidth() * getPaddedHeight()) >> 1;    }    return (getPaddedWidth() * getPaddedHeight());}

经验总结扩展阅读