首页 > 代码库 > Cocos2d之Texture2D类详解之将文件加载成Texture2D对象
Cocos2d之Texture2D类详解之将文件加载成Texture2D对象
一、声明
笔者以cocos2d框架cocos2d-x-3.3rc0版本的源码做分析。本文为笔者原创,允许转载和分享,只要注明文章出处即可。
二、简介
Texture2D类简介
Texture2D类允许开发者用图像、文本信息和简单的数据来创建OpenGL2D纹理。被创建的纹理拥有两个维度。根据开发者创建Texture2D对象方式的不同,实际图像的尺寸可能比生成的纹理的尺寸要小,而且纹理的内容是倒置的。
像素格式
在计算机图形学中,人们用每个像素在内存中的总位数以及分别存储红、蓝、绿和alpha(阿尔法通道)分量的位数来定义一个像素格式。像素格式描述了像素数据在内存中的存储格式,也定义了像素在内存中的编码方式。
在Texture2D类中,用一个枚举类型 PixelFormat 来表示不同的像素格式。下面是像素格式枚举类型的定义。
enum class PixelFormat { //! auto detect the type AUTO, //! 32-bit texture: BGRA8888 BGRA8888, //! 32-bit texture: RGBA8888 RGBA8888, //! 24-bit texture: RGBA888 RGB888, //! 16-bit texture without Alpha channel RGB565, //! 8-bit textures used as masks A8, //! 8-bit intensity texture I8, //! 16-bit textures used as masks AI88, //! 16-bit textures: RGBA4444 RGBA4444, //! 16-bit textures: RGB5A1 RGB5A1, //! 4-bit PVRTC-compressed texture: PVRTC4 PVRTC4, //! 4-bit PVRTC-compressed texture: PVRTC4 (has alpha channel) PVRTC4A, //! 2-bit PVRTC-compressed texture: PVRTC2 PVRTC2, //! 2-bit PVRTC-compressed texture: PVRTC2 (has alpha channel) PVRTC2A, //! ETC-compressed texture: ETC ETC, //! S3TC-compressed texture: S3TC_Dxt1 S3TC_DXT1, //! S3TC-compressed texture: S3TC_Dxt3 S3TC_DXT3, //! S3TC-compressed texture: S3TC_Dxt5 S3TC_DXT5, //! ATITC-compressed texture: ATC_RGB ATC_RGB, //! ATITC-compressed texture: ATC_EXPLICIT_ALPHA ATC_EXPLICIT_ALPHA, //! ATITC-compresed texture: ATC_INTERPOLATED_ALPHA ATC_INTERPOLATED_ALPHA, //! Default texture format: AUTO DEFAULT = AUTO, NONE = -1 };
阿尔法通道 alpha
alpha是指一张图片的透明度和半透明度。阿尔法通道的值由像素值的某几位表示,比如说,一个16位像素可能使用5位保存红色、5为保存蓝色、5位保存绿色,以及最后一位保存阿尔法通量。这时候alpha的值只有1和0,意味着纹理要么透明,要么不透明。
阿尔法通道除了能够表示图形的透明度外,还关系到不同像素颜色融合的效果。
三、源码详解
笔者比较支持从源代码中寻找寻找框架接口的使用方法。笔者会在本文中通过家少cocos2d源代码来介绍如何将一个图形资源文件加载成为Texture2D对象。
Texture2D纹理能够用于生成精灵,接下来看一下Sprite类中运用Texture2D的例子。
bool Sprite::initWithFile(const std::string &filename, const Rect& rect){ CCASSERT(filename.size()>0, "Invalid filename"); Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename); if (texture) { return initWithTexture(texture, rect); } // don‘t release here. // when load texture failed, it‘s better to get a "transparent" sprite then a crashed program // this->release(); return false;}
上面这个函数中,Sprite类能够利用图像文件名和一个裁剪矩阵生成Texture2D纹理,从而生成精灵。生成纹理的函数是 Director::getInstance()->getTextureCache()->addImage(filename). 下面看一下这些函数的定义。
TextureCache* Director::getTextureCache() const{ return _textureCache;}
//texture cache belongs to this director TextureCache *_textureCache;
可见,在Director类中有一个TextureCache类型的 _textureCache 成员变量。TextureCache类中的addImage函数能够将一个图形文件加载成为Texture2D纹理。下面看addImage函数的定义。
/** Returns a Texture2D object given an filename. * If the filename was not previously loaded, it will create a new Texture2D * object and it will return it. It will use the filename as a key. * Otherwise it will return a reference of a previously loaded image. * Supported image extensions: .png, .bmp, .tiff, .jpeg, .pvr */ Texture2D* addImage(const std::string &filepath);
从addImage函数的声明中可以知道,addImage函数能够将给定文件名的图形文件加载成纹理。从中也可以看出TextureCache类的设计其实就是为了减少因生成纹理而多次多资源文件加载造成CPU和内存的开销。对于已经加载过的图形资源文件,TextureCache类不会再次加载,而是之间返回对资源文件的引用。
值得注意的一点是,开发者不用自行创建TextureCache对象,Director对形象持有一个TextureCache对象。
四、总结
笔者在本文中简单介绍了像素和阿尔法通量等一些计算机图形学的简单概念,以及跟踪源码寻找在cocos2d开发中如何将一个图形资源文件加载成纹理。下面将生成纹理的接口在总结一下。
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);
Cocos2d之Texture2D类详解之将文件加载成Texture2D对象