1.纹理像素格式
纹理优化工作的另一重要的指标是纹理像素格式,能够最大程度满足用户对保真度要求的情况下,选择合适的像素格式,可以大幅提高纹理的处理速度。而且纹理像素格式有与硬件有这密切的关系。
下面我们先了解一下纹理像素的格式,主要的格式有:
RGBA8888。32位色,它是默认的像素格式,每个通道8位(比特),每个像素4个字节。
BGRA8888。32位色,每个通道8位(比特),每个像素4个字节。
RGBA4444。16位色,每个通道4位(比特),每个像素2个字节。
RGB888。24位色,没有Alpha通道,所以没有透明度。每个通道8位(比特),每个像素3个字节。
RGB565。16位色,没有Alpha通道,所以没有透明度。R和B通道是各5位,G通道是6。
RGB5A1(或RGBA5551)。16位色,每个通道各4位,Alpha通道只用1位表示。
PVRTC4。4位PVR压缩纹理格式,PVR格式是专门为iOS设备上面的PowerVR图形芯片而设计的。它们在iOS设备上非常好用,因为可以直接加载到显卡上面,而不需要经过中间的计算转化。
PVRTC4A。具有Alpha通道的,4位PVR压缩纹理格式。
PVRTC2。2位PVR压缩纹理格式。
PVRTC2A。具有Alpha通道的,2位PVR压缩纹理格式。
此外,PVR格式在保存的时候还可以采用Gzip和zlib压缩格式进行压缩,对应的保存文件为pvr.gz和pvr.ccz。经过压缩文件会更小,加载的时候使用更少的内存!虽然是转化为纹理的时候,需要解压,但对于CPU影响很小。
2.纹理缓存异步加载
我们在启动游戏和进入场景时候,由于需要加载的资源过多就会比较“卡”,用户体验不好。我们可以采用纹理缓存(TextureCache)异步加载纹理图片,TextureCache类异步加载函数如下:
virtual void addImageAsync(const std::string & filepath,
std::function< void(Texture2D *)> callback
)
其中第一个参数文件路径,第二参数是回调函数。下面我们通过一个实例介绍一下纹理缓存异步加载使用,有200张小图片,加载到纹理缓存,加载过程会有一个进度显式在界面上,如图20-25所示。
HelloWorldScene.cpp中主要代码如下:
- bool HelloWorld::init()
- {
- if ( !Layer::init() )
- {
- return false;
- }
- Size visibleSize = Director::getInstance()->getVisibleSize();
- Vec2 origin = Director::getInstance()->getVisibleOrigin();
- auto closeItem = MenuItemImage::create(
- "CloseNormal.png",
- "CloseSelected.png",
- CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
- closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
- origin.y + closeItem->getContentSize().height/2));
- auto menu = Menu::create(closeItem, NULL);
- menu->setPosition(Vec2::ZERO);
- this->addChild(menu, 1);
- _labelLoading = Label::createWithTTF ("loading...", "fonts/Marker Felt.ttf", 35);
- _labelPercent = Label::createWithTTF ("0%%", "fonts/Marker Felt.ttf", 35);
- _labelLoading->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2 - 20));
- _labelPercent->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2 + 20));
- this->addChild(_labelLoading);
- this->addChild(_labelPercent);
- _numberOfLoadedSprites = 0;
- _imageOffset = 0;
- auto sharedFileUtils = FileUtils::getInstance();
- std::string fullPathForFilename
- = sharedFileUtils->fullPathForFilename("ImageMetaData.plist"); ①
- ValueVector vec = FileUtils::getInstance()->getValueVectorFromFile(fullPathForFilename); ②
- _numberOfSprites = vec.size(); ③
- //加载纹理
- for( auto& e : vec) ④
- {
- auto row = e.asValueMap();
- auto filename = "icons/" + row.at("filename").asString();
- Director::getInstance()->getTextureCache()->addImageAsync(filename,
- CC_CALLBACK_1(HelloWorld::loadingCallBack, this)); ⑤
- }
- return true;
- }
- void HelloWorld::loadingCallBack(Texture2D *texture) ⑥
- {
- ++_numberOfLoadedSprites;
- __String* str = __String::createWithFormat("%d%%",
- (int)(((float)_numberOfLoadedSprites / _numberOfSprites) * 100)); ⑦
- _labelPercent->setString(str->getCString()); ⑧
- Size visibleSize = Director::getInstance()->getVisibleSize();
- int i = ++_imageOffset * 60;
- auto sprite = Sprite::createWithTexture(texture); ⑨
- sprite->setAnchorPoint(Vec2(0,0));
- addChild(sprite, -1);
- sprite->setPosition(Vec2( i % (int)visibleSize.width, (i / (int)visibleSize.width) * 60));
- if (_numberOfLoadedSprites == _numberOfSprites) ⑩
- {
- _numberOfLoadedSprites = 0;
- }
- }
上述代码第①行代码是获得资源目录下ImageMetaData.plist 文件全路径,ImageMetaData.plist 文件是我们定义用来描述要加载图标文件名,文件内容如下:
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
- "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
- <plist version="1.0">
- <array>
- <dict>
- <key>filename</key>
- <string>01-refresh.png</string>
- </dict>
- <dict>
- <key>filename</key>
- <string>02-redo.png</string>
- </dict>
- <dict>
- <key>filename</key>
- <string>03-loopback.png</string>
- </dict>
- <dict>
- <key>filename</key>
- <string>04-squiggle.png</string>
- </dict>
- … …
- </array>
- </plist>
ImageMetaData.plist 文件是属性列表文件,内部结构是数组类型,我们可以通过第②行代码FileUtils 的getValueVectorFromFile函数读入到ValueVector类型变量vec中。第③行代码_numberOfSprites = vec.size()是获得数组的长度,然后赋值给成员变量_numberOfSprites为了能够计算加载进度。
第④行代码是循环遍历数组,数组结构中的每一个元素是键值对结构,取的键值对结构语句是auto row = e.asValueMap()。然后通过语句row.at("filename").asString()从键值对对象row中取出键为filename对应的值。
第⑤行代码是调用TextureCache的addImageAsync函数实现异步加载图片缓存,HelloWorld::loadingCallBack是回调函数,this参数表示回调函数的目标对象。
第⑥行是我们定义的回调函数实现。第⑦行代码在的表达式(int)(((float)_numberOfLoadedSprites / _numberOfSprites) * 100)可以计数出加装进度,"%d%%"可以显示百分号,其中的%d是格式化输出数字。%%是输出%,前面%起到转义作用。第⑧行代码_labelPercent->setString(str->getCString())是设置进度标签_labelPercent的内容。
第⑨行代码auto sprite = Sprite::createWithTexture(texture)是通过纹理对象texture创建精灵对象。第⑩行代码if (_numberOfLoadedSprites == _numberOfSprites)是判断是否完成任务,_numberOfLoadedSprites是已经加装的图片数,_numberOfSprites是要加装的全部图片数。
《Cocos2d-x实战 C++卷》现已上线,各大商店均已开售:
京东:http://item.jd.com/11584534.html
当当:http://product.dangdang.com/23606265.html
互动出版网:http://product.china-pub.com/3770734
《Cocos2d-x实战 C++卷》源码及样章下载地址:
源码下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1155&extra=page%3D1
样章下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1157&extra=page%3D1
相关推荐
Cocos2d-x的基本架构及渲染机制、纹理相关的知识、OpenGL ES 2.0渲染管线、计算机字体的绘制、多分辨率支持、事件分发、碰撞与物理引擎、游戏对象模型架构、Genius-x开源框架、脚本在游戏引擎中的架构等。...
Cocos2d-x的基本架构及渲染机制、纹理相关的知识、OpenGL ES 2.0渲染管线、计算机字体的绘制、多分辨率支持、事件分发、碰撞与物理引擎、游戏对象模型架构、Genius-x开源框架、脚本在游戏引擎中的架构等。
Cocos2d-x的基本架构及渲染机制、纹理相关的知识、OpenGL ES 2.0渲染管线、计算机字体的绘制、多分辨率支持、事件分发、碰撞与物理引擎、游戏对象模型架构、Genius-x开源框架、脚本在游戏引擎中的架构等。...
第1章 Cocos2D-X引擎的介绍 1 1.1 何为游戏引擎 1 1.1.1 游戏的核心—引擎 1 1.1.2 引擎的特点 2 1.1.3 知名的引擎介绍 4 1.1.4 引擎的分类 5 1.2 Cocos2D-X引擎的来历 8 1.3 引擎的版本 9 1.4 下载与安装 10 1.5 ...
Cocos2d-x_C++_3.4,48款游戏源码大合集,Demo 演示代码,简单实现:捕鱼达人,FlappyBird,2048,塔防,微信飞机,超级玛丽,坦克大战,刀塔传奇,防空-合金弹头,城市猎人(跑酷),封神,跑酷30,切水果,奇怪大冒险,翻牌效果,...
五子棋,小海豹,割绳子,数字游戏,俄罗斯方块,中国象棋,植物大战僵尸,按钮特效,心形进度条,赛车游戏,预测球的轨迹,愤怒的小鸟,ClippingNode,刀光效果,SLG,魂斗罗,天天过马路,橡皮擦效果,流体test,2d 光线,愤怒的小鸟2,...
cocos2d-x异步加载plist cocos2d-x v2.2.0
本文实践自 Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理...
一张纹理和与其对应的Plist在COCOS2D-X中使用
在第一篇《如何使用CCRenderTexture创建动态纹理》基础上,增加创建动态山丘,原文《How To Create A Game Like Tiny Wings with Cocos2D 2.X Part 1》,在这里继续以Cocos2d-x进行实现。有关源码、资源等在文章下面...
就是利用了shader,读取两块纹理,然后通过一定的算法计算出叠加后的色值,最后渲染出来。 我们了解到,渲染sprite的类是TriangleCommand,这个类只能渲染多个三角形,并且只能渲染一块纹理。因此,我们要使用...
(译)cocos2d里面如何用texture picker和像素格式来优化spritesheet.pdf (译)在cocos2d里如何制作各种按钮.pdf (译)如何使用cocos2d制作基于tilemap的游戏教程 第一部分.pdf (译)如何在cocos2d里面使用动画和...
3D 浏览器3D View 是一个实验项目,它将 Cocos2d-x 扩展为具有 3D 功能。目的该项目背后 3D Viewer 的主要动机是研究和学习 Cocos2d-x 的渲染管道和场景管理。 因此,此存储库中的文件主要演示如何实现 3D 渲染。...
Texpoly 是关于使用 cocos2d-x 和 box2d 进行纹理和多边形三角剖分的简短教程的 cocos2d-x 项目示例部分。 该教程可,视频演示可。 要求 cocos2d-x 2.2.1 安装使用 克隆 $YOUR_COCOS2D_ROOT/projects 中的 git 存储...
http://blog.csdn.net/liangneo/article/details/42582947 uv动画是指通过在程序运行时动态改变纹理坐标,实现动态效果的纹理动画,使用uv动画可以实现水流动,火焰燃烧等效果。
该文档中包含了在cocos2d中使用多线程opengl纹理的方法,包括如何关联opengl上线文,拷贝纹理,cocos中精灵sprite 中上传子线程的纹理。