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對象后 , 即可進行壓縮紋理的顯示了:

推薦閱讀