Cocos2d-x 学习笔记(26) 从源码学习 DrawCall 的降低方法
本文链接:https://www.cnblogs.com/deepcho/p/cocos2dx-drawcall-glcalls.html
1. 屏幕左下角
我们通常在Cocos2d-x项目运行前,在AppDelegate::applicationDidFinishLaunching()方法中,执行
director->setDisplayStats(true);
用于开启屏幕左下角的数据显示,数据一共三行,分别是:
第一行GL verts表示此时绘制的顶点数。
第二行GL calls表示此时DrawCall数量。
第三行表示此时的FPS。
我们研究第二行的GL calls,也就是DrawCall的相关知识。
2. bool _displayStats
左下角数据通过Director的setDisplayStats方法控制显示与否。该方法仅改变了Director的_displayStats变量,我们可以猜测是该变量控制了数据显示。该变量默认为false,所以要开启数据显示的话,需要手动修改该变量。
另外,Director::setDefaultValues(void)方法也会修改_displayStats。下面看setDefaultValues方法的被调用过程。
在程序入口Application::run()方法调用的AppDelegate::applicationDidFinishLaunching()方法的第一行,执行了:
Configuration::getInstance()->loadConfigFile("configs/config-example.plist");
可以猜测该行是加载了一个plist配置文件,因为其执行的位置很靠前,应该是设置了Cocos2d-x项目的一些重要变量。
打开该plist发现刚才的预测正确。该plist文件如下:
loadConfigFile方法仅设置了Configuration单例对象的几个变量。在该方法最后,执行了:
Director::getInstance()->getEventDispatcher()->dispatchEvent(_loadedEvent);
该行表面看是分发了一个我们自定义的事件,实际上重要的是,这是Director在程序内的初始化位置。
因为此时不存在Director单例对象,所以执行Director::init()方法。在init方法第一行,执行了:
setDefaultValues();
该方法是对刚才的Configuration单例对象plist文件内与Director和图像纹理相关的内容进行设置,包括这几个内容:
_oldAnimationInterval _animationInterval(1.0/fps)
_displayStats
_projection (3d、2d、CUSTOM)
Texture2D::setDefaultAlphaPixelFormat(Texture2D::PixelFormat::RGBA8888)
Image::setPVRImagesHavePremultipliedAlpha(pvr_alpha_premultiplied)
所以,这是在我们手动调用setDisplayStats方法之前对_displayStats的一次设置,这次设置是通过在setDefaultValues方法中加载plist配置文件进行的。
3. ssize_t _drawnBatches
在帧循环内的Director::drawScene()方法中,会对_displayStats进行判断,为true时分别执行showStats()方法和calculateMPF()方法。
showStats()方法是直接输出三行数据到屏幕左下角。其中DrawCall的值是Renderer成员变量_drawnBatches。
DrawCall的值就是_drawnBatches的值,_drawnBatches的增加仅在Renderer::drawBatchedTriangles()方法中进行,如下:
/************** 3: Draw *************/
for (int i=; i<batchesTotal; ++i)
{
CC_ASSERT(_triBatchesToDraw[i].cmd && "Invalid batch");
_triBatchesToDraw[i].cmd->useMaterial();
glDrawElements(GL_TRIANGLES, (GLsizei) _triBatchesToDraw[i].indicesToDraw, GL_UNSIGNED_SHORT, (GLvoid*) (_triBatchesToDraw[i].offset*sizeof(_indices[])) );
_drawnBatches++;
_drawnVertices += _triBatchesToDraw[i].indicesToDraw;
}
所以,表面上看想办法降低batchesTotal的值就能降低DrawCall的值。
从上篇文章对Renderer渲染的学习中可以总结出降低DrawCall的大致思路:
同GlobalZOrder的元素中,元素被添加到节点的顺序就是渲染命令的添加顺序。当两个命令相邻且同材质ID的情况下,这两个命令的索引是被添加到同一个_triBatchesToDraw的索引中,而_triBatchesToDraw的索引是在被GL一次绘制,_triBatchesToDraw的数量决定了batchesTotal的值,也就是DrawCall的值。所以,我们要想实现一次DrawCall中绘制多个元素,就要尽可能让不同元素添加到节点的顺序是相邻的且不被打断,并且它们的材质ID一致,从而这些元素顶点索引被整合到一起,在一次glDrawElements方法中被绘制。
本文链接:https://www.cnblogs.com/deepcho/p/cocos2dx-drawcall-glcalls.html
Cocos2d-x 学习笔记(26) 从源码学习 DrawCall 的降低方法的更多相关文章
- Hadoop学习笔记(10) ——搭建源码学习环境
Hadoop学习笔记(10) ——搭建源码学习环境 上一章中,我们对整个hadoop的目录及源码目录有了一个初步的了解,接下来计划深入学习一下这头神象作品了.但是看代码用什么,难不成gedit?,单步 ...
- memcached学习笔记——存储命令源码分析下篇
上一篇回顾:<memcached学习笔记——存储命令源码分析上篇>通过分析memcached的存储命令源码的过程,了解了memcached如何解析文本命令和mencached的内存管理机制 ...
- memcached学习笔记——存储命令源码分析上篇
原创文章,转载请标明,谢谢. 上一篇分析过memcached的连接模型,了解memcached是如何高效处理客户端连接,这一篇分析memcached源码中的process_update_command ...
- Laravel学习笔记之Session源码解析(上)
说明:本文主要通过学习Laravel的session源码学习Laravel是如何设计session的,将自己的学习心得分享出来,希望对别人有所帮助.Laravel在web middleware中定义了 ...
- Sping学习笔记(一)----Spring源码阅读环境的搭建
idea搭建spring源码阅读环境 安装gradle Github下载Spring源码 新建学习spring源码的项目 idea搭建spring源码阅读环境 安装gradle 在官网中下载gradl ...
- mybatis源码学习(一) 原生mybatis源码学习
最近这一周,主要在学习mybatis相关的源码,所以记录一下吧,算是一点学习心得 个人觉得,mybatis的源码,大致可以分为两部分,一是原生的mybatis,二是和spring整合之后的mybati ...
- 框架源码系列十一:事务管理(Spring事务管理的特点、事务概念学习、Spring事务使用学习、Spring事务管理API学习、Spring事务源码学习)
一.Spring事务管理的特点 Spring框架为事务管理提供一套统一的抽象,带来的好处有:1. 跨不同事务API的统一的编程模型,无论你使用的是jdbc.jta.jpa.hibernate.2. 支 ...
- JUC.Lock(锁机制)学习笔记[附详细源码解析]
锁机制学习笔记 目录: CAS的意义 锁的一些基本原理 ReentrantLock的相关代码结构 两个重要的状态 I.AQS的state(int类型,32位) II.Node的waitStatus 获 ...
- [Golang学习笔记] 03 库源码文件
库源码文件:不能被直接运行的源码文件,它仅用于存放程序实体,这些程序实体可以被其他代码使用. 代码包声明的基本规则: 1. 同目录下的源码文件的代码包声明语句要一致.也就是说,它们要同属于一个代码包( ...
随机推荐
- Visual Studio Code安装Python环境
如何在全宇宙最强编辑器安装Python运行环境 (雾 首先安装Python2和Python3,如果只需要用到一个的话,直接安装即可运行,不存在转换问题. 安装Python扩展,直接搜索安装即可. 更改 ...
- 是时候让大家看看你用django写出来的博客了(内含部署教程视频)
作者:HelloGitHub-追梦人物 文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 博客的基础功能已经开发的差不多了,虽然还有很多地方可以完善,但我们还是希望早点把博客部 ...
- 6.Sentinel源码分析—Sentinel是如何动态加载配置限流的?
Sentinel源码解析系列: 1.Sentinel源码分析-FlowRuleManager加载规则做了什么? 2. Sentinel源码分析-Sentinel是如何进行流量统计的? 3. Senti ...
- 002:CSS基础
注意:蓝色 重要:红色 目录: 1. 学会使用CSS选择器: 9大选择器.交集选择器.并集选择器.后代选择器.子代选择器.伪类选择器. 2.font.color.横向竖向居中.文本修饰.首行缩进. f ...
- Kubernetes 从懵圈到熟练:集群服务的三个要点和一种实现
作者 | 声东 阿里云售后技术专家 文章来源:Docker,点击查看原文. 以我的经验来讲,理解 Kubernetes 集群服务的概念,是比较不容易的一件事情.尤其是当我们基于似是而非的理解,去排查服 ...
- Spring——依赖注入(DI)详解
声明:本博客仅仅是一个初学者的学习记录.心得总结,其中肯定有许多错误,不具有参考价值,欢迎大佬指正,谢谢!想和我交流.一起学习.一起进步的朋友可以加我微信Liu__66666666 这是简单学习一遍之 ...
- [VB.NET Tips]Try...Catch...End Try的另一种用法
有时在调用一个方法时,会进行异常处理.但是当方法内部出现错误时,无法快速定位到是哪一行代码有问题. 下面介绍一下Try的另一个用法: Try...Catch ex As Exception When ...
- 关于java属性字段命名
最近项目定义vo的时候,boolean类型数据定义成isProperty类型的,导致系统间数据交互过程中报错. 网上爬了良久: JavaBean命名规范里面规定,对于primitive和自定义类类型的 ...
- Spring 梳理-跨重定向请求传递数据-Flash
Spring MVC Flash Attribute 的讲解与使用示例 1. Spring MVC 3.1版本加了一个很有用的特性,Flash属性,它能解决一个长久以来缺少解决的问题,一个POST/R ...
- Spring 梳理-webApplicationContext 与servletContext
1.WebApplicationContext的研究 ApplicationContext是spring的核心,Context通常解释为上下文环境,用“容器”来表述更容易理解一些,Applicatio ...