zoukankan      html  css  js  c++  java
  • Cocos2d-x优化中纹理优化

    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是要加装的所有图片数。


    很多其它内容请关注最新Cocos图书《Cocos2d-x实战 C++卷》
    本书交流讨论站点:http://www.cocoagame.net
    很多其它精彩视频课程请关注智捷课堂Cocos课程:http://v.51work6.com
    欢迎增加Cocos2d-x技术讨论群:257760386


    《Cocos2d-x实战 C++卷》现已上线,各大商店均已开售:

    京东:http://item.jd.com/11584534.html

    亚马逊:http://www.amazon.cn/Cocos2d-x%E5%AE%9E%E6%88%98-C-%E5%8D%B7-%E5%85%B3%E4%B8%9C%E5%8D%87/dp/B00PTYWTLU

    当当: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

    欢迎关注智捷iOS课堂微信公共平台


  • 相关阅读:
    Zookeeper系列二:分布式架构详解、分布式技术详解、分布式事务
    Zookeeper系列一:Zookeeper介绍、Zookeeper安装配置、ZK Shell的使用
    Mysql系列九:使用zookeeper管理远程Mycat配置文件、Mycat监控、Mycat数据迁移(扩容)
    Mysql系列八:Mycat和Sharding-jdbc的区别、Mycat分片join、Mycat分页中的坑、Mycat注解、Catlet使用
    Mysql系列七:分库分表技术难题之分布式全局唯一id解决方案
    Mysql系列五:数据库分库分表中间件mycat的安装和mycat配置详解
    学习Mysql过程中拓展的其他技术栈:Docker入门介绍
    学习Mysql过程中拓展的其他技术栈:设置linux虚拟机的固定ip和克隆linux虚拟机
    Mysql系列四:数据库分库分表基础理论
    Mysql系列三:Centos6下安装Mysql和Mysql主从复制的搭建
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5055437.html
Copyright © 2011-2022 走看看