Cocos2d-x 3.x 开发(十八)10行代码看自动Batch,10行代码看自动剔除

1、概述

在游戏的运行过程中,图形的绘制是非常大的开销。对于良莠不齐的Android手机市场,绘制优化较好的游戏,可以在更多的手机上运行,因此也是优化的重中之重。图形方面的优化主要体现在减少GUP的绘制次数上。这里我们分别从自动优化渲染批次和绘制剔除两个方面来看新版本在绘制上的优化。

2、自动batch

在Cocos2d-x 3.x中,抛弃了先前手动编写BatchNode,采用自动管理的方式。说起BatchNode,就难免涉及到显卡底层的绘制原理。简单的说,每提交一条绘制指令到显卡都会产生消耗,因此尽量少的提交指令就可以优化性能。更具体的说,当整个场景绘制都放在同一条指令中时,是最佳的状态。

只介绍理论很难说明问题,我们动手写个Demo做测试。

创建一个新工程。更改init函数如下。

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    Node* node = Node::create();
    char name[32];
    for(int i  = 0;i<100;++i)
    {
        memset(name, 0, sizeof(name));
        sprintf(name, "%d.png",i%10);
		auto sprite = Sprite::create(name);
        sprite->setPosition(Point(i*5,i*5));
        node->addChild(sprite, 0);
    }
    this->addChild(node);
    return true;
}

这段代码创建了100个图片。我将示例工程中的按钮复制了9个,并将第三个按钮稍作了修改。这样程序会循环创建这10张图片。图片资源如下图所示。

编译运行程序,我们可以看到下面的运行画面。

我们关注的是左下角信息的第二行。“GL calls”代表每一帧中OpenGL指令的调用次数。这个数字越小,程序的绘制性能就越好。现在每有101次绘制,其中100个元素每个元素绘制一次,多出来的一次是绘制这个左下角信息自己。

接下来,我们使用合图软件,将这10张图合成一张大图和一个plist文件。在使用CocoStudio导出时,选择“使用大图”即可将小图合成一张大图。当然我们也可以选择TexturePacker这种专业的合图软件。合成的图片分为“test.png”和“test.plist”两部分,如上面的资源文件图片所示。

更改init代码如下。

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    CCSpriteFrameCache::getInstance()->addSpriteFramesWithFile("test.plist","test.png");
    Node* node = Node::create();
    char name[32];
    for(int i  = 0;i<100;++i)
    {
        memset(name, 0, sizeof(name));
        sprintf(name, "%d.png",i%10);
		//auto sprite = Sprite::create(name);
        auto sprite = Sprite::createWithSpriteFrameName(name);
        sprite->setPosition(Point(i*5,i*5));
        node->addChild(sprite, 0);
    }
    this->addChild(node);
    return true;
}

这段代码中,我们调用addSpriteFramesWithFile函数,将大图载入到内存中,创建对象时,调用createWithSpriteFrameName从缓存纹理中载入图片。如此做我们所有的绘制调用都可以合并到一次OpenGL指令中,这些绘制指令的计算与合并都由Cocos2d-x引擎完成。编译运行如下图所示。

我们可以非常明显的看到,优化后的程序“GL calls”变成了2次。

3、绘制剔除

另一方面优化是绘制剔除。相对于上一种优化,这个要更容易理解。它是指当一个元素移动到屏幕之外,就不进行绘制。

接着刚才的例子,我们测试一下这个特性。更改init函数如下。

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    //CCSpriteFrameCache::getInstance()->addSpriteFramesWithFile("test.plist","test.png");
    Node* node = Node::create();
    char name[32];
    for(int i  = 0;i<100;++i)
    {
        memset(name, 0, sizeof(name));
        sprintf(name, "%d.png",i%10);
		auto sprite = Sprite::create(name);
        //auto sprite = Sprite::createWithSpriteFrameName(name);
        sprite->setPosition(Point(i*5,i*5));
        node->addChild(sprite, 0);
    }
    this->addChild(node);

    auto listener = EventListenerTouchOneByOne::create();
    listener->onTouchBegan = [=](Touch *pTouch, Event *pEvent)
    {
        return true;
    };
    listener->onTouchMoved = [=](Touch *pTouch, Event *pEvent)
    {
        node->setPosition(node->getPosition()+pTouch->getDelta());
    };
    Director::getInstance()->getEventDispatcher()->
        addEventListenerWithSceneGraphPriority(listener, this);

    return true;
}

首先,我们将自动Batch的优化更改回来,否则无法进行测试。接下来,我们在场景中加入一个点击事件,点击拖动屏幕时,移动这100个元素。编译运行,运行效果如下图。

可以看到,当部分图片被移出屏幕时,“GL calls”的数量会下降。

4、小结

总的来说,这两点优化可以说是对程序性能有了极大提升。同时在开发的过程中,也使程序员不必过多的纠结于渲染效率的优化。

相关代码下载:http://download.csdn.net/detail/fansongy/7398941

PS:最近工作比较忙,博客更新的比较少了。忙过了这段,尽量多写些文章补上,以飨读者。

本篇博客出自阿修罗道,转载请注明出处,禁止用于商业用途:http://blog.csdn.net/fansongy/article/details/26968473

Cocos2d-x 3.x 开发(十八)10行代码看自动Batch,10行代码看自动剔除,布布扣,bubuko.com

时间: 2024-10-09 18:44:14

Cocos2d-x 3.x 开发(十八)10行代码看自动Batch,10行代码看自动剔除的相关文章

unity3D游戏开发十八之NGUI动画

我们先来看下帧动画,顾名思义,就是一帧帧的图片组成的动画,我们须要用到UISprite Animation组件,它的属性例如以下: Framerate:播放速率,也就是每秒钟播放的帧数 Name Prefix:图片名字的前缀,能够用来过滤图片集中的图片,从而指定你须要的图片 Loop:循环 依照前面文章创建UI的步骤,我们创建一个sprite,一个button,通过点击button来控制动画的播放和暂停.OK,首先我们创建一个Atlas,把我们的须要的素材放进去,例如以下图: 点击Create创

Android基础笔记(十八)- Fragment

博客的感悟终点-开始 什么是Fragment 添加fragment到Activity的两种方式 Fragment的生命周期 Fragment的向下兼容 Fragment之间的通信 博客的感悟,终点-开始 这个是基础的最后一篇博客了,学习了很多,也有很多感触. 就在这里大致总结一下. 坚持往往很难,完美的坚持下去更难.这是写这十八篇博客的感悟. 时间流失的很快,总是感觉时间不够用.慢慢的就会让自己博客的质量下降.今天反思了一下,我这样不就是在制造"破窗户"吗?(破窗户理论不知道的可以去看

实习小白::(转) Cocos2d-x 3.x 开发(十八)10行代码看自动Batch,10行代码看自动剔除 --------其实就是渲染图片机制

1.概述 在游戏的运行过程中,图形的绘制是非常大的开销.对于良莠不齐的Android手机市场,绘制优化较好的游戏,可以在更多的手机上运行,因此也是优化的重 中之重.图形方面的优化主要体现在减少GPU的绘制次数上.这里我们分别从自动优化渲染批次和绘制剔除两个方面来看新版本在绘制上的优化. 2.自动batch 在Cocos2d-x 3.x中,抛弃了先前手动编写BatchNode,采用自动管理的方式.说起BatchNode,就难免涉及到显卡底层的绘制原理.简单的说,每提交一条 绘制指令到显卡都会产生消

QT开发(三十八)——Model/View框架编程

QT开发(三十八)--Model/View框架编程 一.自定义模型 1.自定义只读模型 QAbstractItemModel为自定义模型提供了一个足够灵活的接口,能够支持数据源的层次结构,能够对数据进行增删改操作,还能够支持拖放.QT提供了 QAbstarctListModel和QAbstractTableModel两个类来简化非层次数据模型的开发,适合于结合列表和表格使用. 自定义模型需要考虑模型管理的的数据结构适合的视图的显示方式.如果模型的数据仅仅用于列表或表格的显示,那么可以使用QAbs

QT开发(四十八)——数据库SQL接口层

QT开发(四十八)--数据库SQL接口层 SQL接口层提供了对数据库的访问,主要类包括Qt SQL模块中的QSqlDatabase.QSqlQuery.QSqlError.QSqlField.QSqlIndex和QSqlRecord.QSqlDatabase类用于创建数据库连接,QSqlQuery用于使用SQL语句实现与数据库交互. 一.QSqlDatabase 1.QSqlDatabase简介 QSqlDatabase类提供了通过连接访问数据库的接口,QSqlDatabase对象本身代表一个连

使用 C# 开发智能手机软件:推箱子(十八)

这是"使用 C# 开发智能手机软件:推箱子" 系列文章的第十八篇.在这篇文章中.介绍 Window/SelectLevelDlg.cs 源程序文件. 这个源程序文件包括 SelectLevelDlg 类,该类继承自 System.Windows.Forms.Form 类.表示推箱子的"选关"对话框.例如以下图所看到的: 以下是 Window/SelectLevelDlg.Designer.cs 的源程序的部分代码: namespace Skyiv.Ben.PushB

QT开发(二十八)——QT常用类(二)

QT开发(二十八)--QT常用类(二) 一.QDir 1.QDir简介 QDir提供对目录结构及其内容的访问. QDir通过相对或绝对路径指向一个文件. 2.QDir成员函数 QDir主要成员函数如下: QDir::QDir ( const QDir & dir ) QDir::QDir ( const QString & path = QString() ) Dir::QDir ( const QString & path, const QString & nameFil

Python开发【第十八篇】:MySQL(二)

Python开发[第十八篇]:MySQL(二) 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. SELECT * FROM ( SELECT nid, NAME FROM tb1 WHERE nid > 2 ) AS A WHERE A. NAME > 'alex'; 临时表搜索 1.创建视图 --格式:CREATE VIEW 视图名称 AS SQL语句 CREATE VIEW v

Android开发实战(十八):Android Studio 优秀插件:GsonFormat

原文:Android开发实战(十八):Android Studio 优秀插件:GsonFormat Android Studio 优秀插件系列: Android Studio 优秀插件(一):GsonFormat ------------------------------------------------------------------------------------------------------- 这几天没有活,于是乎整理了一些代码,顺便把一些一直在使用的东西也整理下,然后学