关于cocos2d-x对etc1图片支持的分析

本文详细分析了cocos2d-x对ETC1图片的支持,包括其在内存占用、加载速度上的优势,以及在Android和Windows平台的处理方式。同时,文章探讨了ETC1图片对非2的整次幂尺寸的兼容性问题,透明图片的解决方案,并介绍了PremultipliedAlpha的理解及其在渲染中的影响。最后,作者分享了针对不同平台的渲染优化策略,特别是Shader的改进以消除锯齿问题。
摘要由CSDN通过智能技术生成

1、ETC1图片是android下通用的压缩纹理,几乎所有的android机器都支持,是opengles2.0的标准。不像pvrtc4只是部分powervr的显卡支持。

      ETC1图片不支持半透明(有替代方案可以使etc1图片兼容半透明显示),内存占用只有正常RGBA8888的八分之一(一个像素0.5个字节),并且具备极高的加载速度。ETC1的图片大小只跟图片尺寸相关,在大小上无法媲美jpg或者png8的图片。

2、cocos2d-x早期使用android提供的ETC1Util来加载纹理,后面经过一次优化,改变成直接读取文件的加载方式。 也就是说ETC1文件前面16个字节是文件头,包含文件宽高等信息。 除开这16个字节,剩下的就是图片像素数据,这些数据可以直接传递给显卡使用glCompressedTexImage2D来创建纹理。

3、同样在这次优化中,加入了软件解压ETC1的功能,这样windows等桌面平台也可以使用ETC1的图片了(虽然没有任何优势可言)。但是实现有一些bug,导致不兼容非2的整次幂的图片。修改如下

 //if it is not gles or device do not support ETC, decode texture by software
        int bytePerPixel = 3;
        GLenum fallBackType = GL_UNSIGNED_BYTE;
        
        /*bool fallBackUseShort = false;
        if(fallBackUseShort)
        {
            bytePerPixel = 2;
            fallBackType = GL_UNSIGNED_SHORT_5_6_5;
        }
        */
        unsigned int stride = _width * bytePerPixel;
        
        std::vector<unsigned char> decodeImageData(((stride + 3) &~ 3) * ((_height + 3) &~3));
        
        etc1_decode_image(etcFileData + ETC_PKM_HEADER_SIZE, &decodeImageData[0], _width, _height, bytePerPixel, ((stride + 3) &~ 3));
        
        //set decoded data to gl
        glGenTextures(1, &_name);
        glBindTexture(GL_TEXTURE_2D, _name);
        
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _width, _height, 0, GL_RGB, fallBackType, &decodeImageData[0]);

        glBindTexture(GL_TEXTURE_2D, 0);
        delete[] etcFileData;
        etcFileData = NULL;
        return true;

注意其中两句    

     std::vector<unsigned char> decodeImageData(((stride + 3) &~ 3) * ((_height + 3) &~3));

     etc1_decode_image(etcFileData + ETC_PKM_HEADER_SIZE, &decodeImageData[0], _width, _height, bytePerPixel, ((stride + 3) &~ 3));

     分配内存必须能够容纳下图片数据,而ETC1图片会进行4字节对齐(圆整),所以宽高不能直接使用原始图片数据。  当然,不修改的话对于2的整次幂的图片也是没有问题的,因为本身就是对齐的,不需要圆整了。


4、android下部分机器兼容非2的整次幂的etc1图片,但是同样也有部分机器不兼容。遇到非2的整次幂的图片会渲染错误甚至崩溃。所以android下使用etc1图片需要进行2的整次幂的扩展。如果大量零碎文件的话,考虑使用TexturePacker打包图片


评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值