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());}解析 ETC2 数据:
// ETC2 魔数static const char kMagic[] = { 'P', 'K', 'M', ' ', '2', '0' };static const bool IsEtc2Texture(unsigned char *data) { return memcmp(data, kMagic, sizeof(kMagic)) == 0;}static const CompressedTextureInfo ParseETC2Texture(unsigned char *data, GLenum internal_format) { CompressedTextureInfo textureInfo; textureInfo.is_valid = false; if (!IsEtc2Texture(data)) { LogE("ParseETC2Texture: not a etc2 texture"); return textureInfo; } Etc2Header etc2Header(data); textureInfo.is_valid = true; textureInfo.width = etc2Header.getWidth(); textureInfo.height = etc2Header.getHeight(); textureInfo.size = etc2Header.getSize(internal_format); textureInfo.internal_format = internal_format; textureInfo.data = data + ETC2_PKM_HEADER_SIZE; return textureInfo;}
推荐阅读
- 手把手教你玩转 Gitea|使用 Docker 安装 Gitea
- 26 《吐血整理》高级系列教程-吃透Fiddler抓包教程-Fiddler如何抓取Android7.0以上的Https包-上篇
- 苹果手机怎么使用超级截屏(苹果手机超级截屏在哪里)
- DirectX 使用 Vortice 从零开始控制台创建 Direct2D1 窗口修改颜色
- 为什么阿里Java开发手册不推荐使用Timestamp
- VMware安装Win11+WSA子系统和使用教程
- 支付宝取消自动续费怎么取消? 支付宝取消自动续费怎么取消
- 宝马3系320Li的使用日记 宝马3系320li价格
- 晚上避光使用了果酸面霜,为什么脸色还是变黑了
- 手镯变黑怎么恢复 银手镯变黑怎么清洗变亮