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

1、概述

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

2、自动batch

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

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

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

[cpp] view plaincopyprint?

  1. bool HelloWorld::init()
  2. {
  3. //////////////////////////////
  4. // 1. super init first
  5. if ( !Layer::init() )
  6. {
  7. return false;
  8. }
  9. Node* node = Node::create();
  10. char name[32];
  11. for(int i  = 0;i<100;++i)
  12. {
  13. memset(name, 0, sizeof(name));
  14. sprintf(name, "%d.png",i%10);
  15. auto sprite = Sprite::create(name);
  16. sprite->setPosition(Point(i*5,i*5));
  17. node->addChild(sprite, 0);
  18. }
  19. this->addChild(node);
  20. return true;
  21. }

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

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

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

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

更改init代码如下。

[cpp] view plaincopyprint?

  1. bool HelloWorld::init()
  2. {
  3. //////////////////////////////
  4. // 1. super init first
  5. if ( !Layer::init() )
  6. {
  7. return false;
  8. }
  9. CCSpriteFrameCache::getInstance()->addSpriteFramesWithFile("test.plist","test.png");
  10. Node* node = Node::create();
  11. char name[32];
  12. for(int i  = 0;i<100;++i)
  13. {
  14. memset(name, 0, sizeof(name));
  15. sprintf(name, "%d.png",i%10);
  16. //auto sprite = Sprite::create(name);
  17. auto sprite = Sprite::createWithSpriteFrameName(name);
  18. sprite->setPosition(Point(i*5,i*5));
  19. node->addChild(sprite, 0);
  20. }
  21. this->addChild(node);
  22. return true;
  23. }


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

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

3、绘制剔除

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

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

[cpp] view plaincopyprint?

  1. bool HelloWorld::init()
  2. {
  3. //////////////////////////////
  4. // 1. super init first
  5. if ( !Layer::init() )
  6. {
  7. return false;
  8. }
  9. //CCSpriteFrameCache::getInstance()->addSpriteFramesWithFile("test.plist","test.png");
  10. Node* node = Node::create();
  11. char name[32];
  12. for(int i  = 0;i<100;++i)
  13. {
  14. memset(name, 0, sizeof(name));
  15. sprintf(name, "%d.png",i%10);
  16. auto sprite = Sprite::create(name);
  17. //auto sprite = Sprite::createWithSpriteFrameName(name);
  18. sprite->setPosition(Point(i*5,i*5));
  19. node->addChild(sprite, 0);
  20. }
  21. this->addChild(node);
  22. auto listener = EventListenerTouchOneByOne::create();
  23. listener->onTouchBegan = [=](Touch *pTouch, Event *pEvent)
  24. {
  25. return true;
  26. };
  27. listener->onTouchMoved = [=](Touch *pTouch, Event *pEvent)
  28. {
  29. node->setPosition(node->getPosition()+pTouch->getDelta());
  30. };
  31. Director::getInstance()->getEventDispatcher()->
  32. addEventListenerWithSceneGraphPriority(listener, this);
  33. return true;
  34. }

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

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

4、小结

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

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

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

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

时间: 2024-10-09 08:45:04

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

unity3D游戏开发十八之NGUI动画

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

【Cocos2D研究院之游戏开发】

http://www.xuanyusong.com/archives/category/ios/cocos2d_game 分类目录归档:[Cocos2D研究院之游戏开发] 201211-19 Cocos2D研究院之打开全新ViewController与返回(八) 雨松MOMO [Cocos2D研究院之游戏开发] 围观5745次 17条评论          之前cocos2d的文章都是由魏凯同学维护,从今天开始我也会抽时间写点cocos2d的文章.最近在研究如何将IOS游戏与软件结合起来.通常游

实习模块vue+java小型全栈开发(三)

实习模块vue+java小型全栈开发(三) --dx 背景 首先,先给自己一个答案:这篇博客我定义为(三),因为之前的两个模块页面,内容都是一样的,但是被改了几次需求,就一直拖着没有上传. 今天是真正意义上的全栈开发,用的都是当前市面上的最新的框架前端是vuejs,后端springBoot全家桶,知识点很全,而我正好勉强的把前端知识赶完,然后进行的这次模块开发,并且这次模块开发给了我很大的惊喜. 全栈果然很神奇. 模块简介:点击考勤之后,调到一个页面,完成这个页面的所用功能. 完成之后的页面:我

从零开始学ios开发(十八):Storyboards(下)

这篇我们完成Storyboards的最后一个例子,之前的例子中没有view之间的切换,这篇加上这个功能,使Storyboards的功能完整呈现.在Storyboards中负责view切换的东西叫做“segue”,只需对它进行简单的设置即可,一切都是傻瓜式的,无需繁琐的代码.好了,开始我们的例子吧. 1)Create a Simple Storyboard创建一个project,左边选择Application,右边选择Empty Application template(我们这里不使用Single

【转】cocos2d-x游戏开发(十四)用shader使图片背景透明

转自:http://blog.csdn.net/dawn_moon/article/details/8631783 好吧,终于抽时间写这篇文章了. 手头上有很多人物行走图,技能特效图等,但这些图都有个纯黑色背景,怎么样将内容显示出来,让背景透明呢?前段时间搞了一下,感谢群里的童鞋们,提供了思路和方法. 这里用shader处理了像素,使黑色背景透明,直接上代码 ShaderSprite.h 1 #ifndef __TestShader__ShaderSprite__ 2 #define __Tes

从零开始学ios开发(八):Autorotation and Autosizing

不好意思,这一篇间隔的时间有点长,最近实在是事情太多,耽搁了,好了,长话短说,下面继续学习ios. 这次学习的内容是Autorotation和Autosizing,Autorotation就是屏幕内容自动旋转,因为iphone有重力感应系统(陀螺仪???),屏幕的内容会随着用户手握iphone的方式(竖着握Portrait.横着握Landscape)而改变,这个相信大家都已经有所体会,Autosizing是指当iphone的屏幕旋转后,屏幕里面控件的大小和位置也会自动改变.好了,下面跟着例子继续

企业搜索引擎开发之连接器connector(二十八)

通常一个SnapshotRepository仓库对象对应一个DocumentSnapshotRepositoryMonitor监视器对象,同时也对应一个快照存储器对象,它们的关联是通过监视器管理对象DocumentSnapshotRepositoryMonitorManagerImpl实现的 DocumentSnapshotRepositoryMonitorManagerImpl类要实现那些行为,先查看其实现接口DocumentSnapshotRepositoryMonitorManager定义

企业搜索引擎开发之连接器connector(十八)(待编辑)

创建并启动连接器实例之后,连接器就会基于Http协议向指定的数据接收服务器发送xmlfeed格式数据,我们可以通过配置http代理服务器抓取当前基于http协议格式的数据(或者也可以通过其他网络抓包工具抓取) // 设置代理 /Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("IP地址", "端口")); synchronized (this) { uc = (HttpURLConnect

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

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