Android 使用压缩纹理( 三 )

3.ASTC由ARM & AMD研发 。ASTC同样是基于block的压缩方式,但块的大小却较支持多种尺寸,比如从基本的4x4到12x12;每个块内的内容用128bits来进行存储 , 因而不同的块就对应着不同的压缩率;相比ETC , ASTC不要求长宽是2的幂次方 。

Android 使用压缩纹理

文章插图
// ASTC 魔数const unsigned char ASTC_MAGIC_NUMBER[] = {0x13, 0xAB, 0xA1, 0x5C};// ASTC header declarationtypedef struct{    unsigned char  magic[4];    unsigned char  blockdim_x;    unsigned char  blockdim_y;    unsigned char  blockdim_z;    unsigned char  xsize[3];   /* x-size = xsize[0] + xsize[1] + xsize[2] */    unsigned char  ysize[3];   /* x-size, y-size and z-size are given in texels */    unsigned char  zsize[3];   /* block count is inferred */} AstcHeader;static const bool IsAstcTexture(unsigned char* buffer) {    return memcmp(buffer, ASTC_MAGIC_NUMBER, sizeof(ASTC_MAGIC_NUMBER)) == 0;}static const CompressedTextureInfo ParseAstcTexture(unsigned char *data, GLenum internal_format) {    CompressedTextureInfo textureInfo;    textureInfo.is_valid = false;    if (internal_format < GL_COMPRESSED_RGBA_ASTC_4x4_KHR        || internal_format > GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) {        LogE("parseAstcTexture: invalid internal_format=%d", internal_format);        return textureInfo;    }    if (!IsAstcTexture(data)) {        LogE("parseAstcTexture: not a astc file.");        return textureInfo;    }    // 映射为 ASTC 头    AstcHeader* astc_data_ptr = (AstcHeader*) data;    int x_size = astc_data_ptr->xsize[0] + (astc_data_ptr->xsize[1] << 8) + (astc_data_ptr->xsize[2] << 16);    int y_size = astc_data_ptr->ysize[0] + (astc_data_ptr->ysize[1] << 8) + (astc_data_ptr->ysize[2] << 16);    int z_size = astc_data_ptr->zsize[0] + (astc_data_ptr->zsize[1] << 8) + (astc_data_ptr->zsize[2] << 16);    int x_blocks = (x_size + astc_data_ptr->blockdim_x - 1) / astc_data_ptr->blockdim_x;    int y_blocks = (y_size + astc_data_ptr->blockdim_y - 1) / astc_data_ptr->blockdim_y;    int z_blocks = (z_size + astc_data_ptr->blockdim_z - 1) / astc_data_ptr->blockdim_z;    unsigned int n_bytes_to_read = x_blocks * y_blocks * z_blocks << 4;    textureInfo.is_valid = true;    textureInfo.internal_format = internal_format;    textureInfo.width = x_size;    textureInfo.height = y_size;    textureInfo.size = n_bytes_to_read;    textureInfo.data = data;    return textureInfo;}得到CompressedTextureInfo对象后 , 即可进行压缩纹理的显示了:

推荐阅读