cocos源码分析--绘制顺序LocalZOrder、GlobalZOrder、OrderOfArrival
使用规则
节点的渲染顺序跟节点的三个成员变量有关(_localZOrder、_globalZOrder、_orderOfArrival)分别对应三个设置函数setLocalZOrder、setGlobalZOrder、setOrderOfArrival。无论是_localZOrder、_globalZOrder、_orderOfArrival都是越大的越后渲染,越小的越先渲染,而且有_globalZOrder的优先级大于_localZOrder的优先级大于_orderOfArrival的优先级。所以我们判断节点间的渲染(绘制)顺序时应先对比他们的_globalZOrder值,如若相等,再对比他们的_localZOrder值,如若相等,再对比他们的_orderOfArrival值。其中,_orderOfArrival值在调用addChild函数是自动给出,一般我们不调用setOrderOfArrival函数去更改节点间的渲染(绘制)顺序。
当采用LocalZOrder作为节点渲染(绘制)顺序的判断值时,父节点的LocalZOrder不与子节点的LocalZOrder值作比较。子节点中LocalZOrder值小于0的节点作为以父节点为根节点的树的左子树的根节点,大于0的作为右子树的根节点。所以在中序遍历下,先(渲染)绘制子节点中LocalZOrder值小于0的子节点,再渲染(绘制)父节点,再渲染LocalZOrder值大于0的子节点。
代码原理
localZOrder和orderOfArrival在visit里面
void Node::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags)
{
// quick return if not visible. children won't be drawn.
if (!_visible)
{
return;
} uint32_t flags = processParentFlags(parentTransform, parentFlags); // IMPORTANT:
// To ease the migration to v3.0, we still support the Mat4 stack,
// but it is deprecated and your code should not rely on it
/*
为了便于迁移到v3.0,我们仍然支持Mat4堆栈,
但它已被弃用,您的代码不应该依赖它
*/
Director* director = Director::getInstance();
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
//把刚生产的模型视图矩阵加入到顶部的modeview【对scene来说,执行下面代码之前,里面已经有3个modelview】
//这个代码针对2.0的,对3.1没啥意义了
director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform); int i = ; if(!_children.empty())
{
sortAllChildren();
// draw children zOrder < 0
for( ; i < _children.size(); i++ )
{
auto node = _children.at(i); if ( node && node->_localZOrder < )
node->visit(renderer, _modelViewTransform, flags);
else
break;
}
// self draw
this->draw(renderer, _modelViewTransform, flags); for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
(*it)->visit(renderer, _modelViewTransform, flags);
}
else
{
this->draw(renderer, _modelViewTransform, flags);
} /*
画完了就退出战,是兼容2.0的时候,现在不需要这个了
矩阵的转换都在GPU的shader中了
*/
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); // FIX ME: Why need to set _orderOfArrival to 0??
// Please refer to https://github.com/cocos2d/cocos2d-x/pull/6920
// reset for next frame
// _orderOfArrival = 0;
}
void Node::sortAllChildren()
{
if( _reorderChildDirty ) {
std::sort( std::begin(_children), std::end(_children), nodeComparisonLess );
_reorderChildDirty = false;
}
}
bool nodeComparisonLess(Node* n1, Node* n2)
{
return( n1->getLocalZOrder() < n2->getLocalZOrder() ||
( n1->getLocalZOrder() == n2->getLocalZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
);
}
通过排序之后,然后遍历,加入到 command命令中
globalZOrder在CCRender中进行排序,代码如下:
void RenderQueue::sort()
{
// Don't sort _queue0, it already comes sorted
//不对queue0的在进行排序,他们是 按照localQueue排序的
std::sort(std::begin(_queueNegZ), std::end(_queueNegZ), compareRenderCommand);
std::sort(std::begin(_queuePosZ), std::end(_queuePosZ), compareRenderCommand);
}
所以globalZOrder在LocalZOrder之前。
cocos源码分析--绘制顺序LocalZOrder、GlobalZOrder、OrderOfArrival的更多相关文章
- cocos源码分析--LayerColor的绘制过程
1开始,先创建一个LayerColor Scene *scene=Scene::create(); director->runWithScene(scene); //目标 auto layer ...
- cocos源码分析--ClippingNode绘图原理
在OpenGL 绘制过程中,与帧缓冲有关的是模版,深度测试,混合操作.模版测试使应用程序可以定义一个遮罩,在遮罩内的片段将被保留或者丢弃,在遮罩外的片段操作行为则相反.深度测试用来剔除那些被场景遮挡的 ...
- cocos源码分析--Sprite绘图原理
精灵是2D游戏中最重要的元素,可以用来构成游戏中的元素,如人物,建筑等,用Sprite类表示,他将一张纹理的一部分或者全部矩形区域绘制到屏幕上.我们可以使用精灵表来减少OpenGL ES 绘制的次数, ...
- cocos源码分析--RenderTexture
cocos中RenderTexture主要用来实现截屏,然后把截取出来的图片保存到磁盘中,除了保存图片和渲染纹理,它还可以得到一些预渲染结果,并将这些结果作为一种纹理数据. 例如我们可以用RGB5_A ...
- cocos源码分析--SpriteBatchNode绘图原理
SpriteBatchNode继承Node,并实现了TextureProtocol接口,重写了Node的addChild()方法,visit()方法以及draw()方法. addChild()方法限制 ...
- cocos源码分析--用Sprite加载自定义着色器
本文写一个使用动态更新属性变量的自定义着色器.在这个例子中,小图标的位置根据手指的触摸而移动,以屏幕重点为参照物,屏幕中向下的部分根据手指的点击乘以一个绿色的颜色值,向上的部分乘以一个红色的颜色值. ...
- Android应用层View绘制流程与源码分析
1 背景 还记得前面<Android应用setContentView与LayoutInflater加载解析机制源码分析>这篇文章吗?我们有分析到Activity中界面加载显示的基本流程原 ...
- 一个由正则表达式引发的血案 vs2017使用rdlc实现批量打印 vs2017使用rdlc [asp.net core 源码分析] 01 - Session SignalR sql for xml path用法 MemCahe C# 操作Excel图形——绘制、读取、隐藏、删除图形 IOC,DIP,DI,IoC容器
1. 血案由来 近期我在为Lazada卖家中心做一个自助注册的项目,其中的shop name校验规则较为复杂,要求:1. 英文字母大小写2. 数字3. 越南文4. 一些特殊字符,如“&”,“- ...
- springboot Properties加载顺序源码分析
关于properties: 在spring框架中properties为Environment对象重要组成部分, springboot有如下几种种方式注入(优先级从高到低): 1.命令行 java -j ...
随机推荐
- [转]ConcurrentHashMap原理分析
一.背景: 线程不安全的HashMap 因为多线程环境下,使用Hashmap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap. 效率低下的Has ...
- perventDefault, stopPropagation, stopImmediatePropagation 三者的区别
event有三种特别容易混淆的方法, 用来阻止默认事件的发生 1. e.preventDefault(); 2. e.stopPropagation(); 3. e.stopImmediatePro ...
- gets_s()函数的参数太少,strcpy_s():形参和实参 2 的类型不同,等c函数在Visual Studio上出现的问题, get()函数和scanf()读取字符串的区别,栈的随机性
首先,这些C函数,在VS上要加_s后缀的原因是,这些函数存在字符串越界等问题,可以参考这篇文章,https://blog.csdn.net/silleyj/article/details/854540 ...
- Springboot配置文件映射
添加类和配置文件的映射: 1.定义映射类 @Component @PropertySource("classpath:config/XX.properties") public c ...
- 维护贴--验证可用--mysql给root开启远程访问权限,修改root密码(转)
1.MySql-Server 出于安全方面考虑只允许本机(localhost, 127.0.0.1)来连接访问. 这对于 Web-Server 与 MySql-Server 都在同一台服务器上的网站架 ...
- NET设计模式 第三部分 结构型模式(7):适配器模式(Adapter Pattern)
适配器模式(Adapter Pattern) ——.NET设计模式系列之八 Terrylee,2006年2月 概述 在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但 ...
- FireDAC内部初探
procedure TForm1.Button1Click(Sender: TObject); var FCommIntf: IFDPhysCommand; //FireDAC.Phys.Intf F ...
- Linux下批处理文件编写
linux下的批处理文件,基本就是shell脚本文件. 一.最简单的脚本书写方法为: 1.新建一个文件,名字为test(自己定义的名字) touch test.sh 2.在里面编写脚本 程序必须以下面 ...
- jQuery 筛选器 链式编程操作
$('#i1').next() 下一个标签$('#i1').nextAll() 兄弟标签中,所有下一个标签$('#i1').nextUntil('#ii1') 兄弟标签中,从下一个标签到id为ii1的 ...
- 安装老版本redis .NET 客户端
https://github.com/ServiceStackV3/ServiceStackV3 PM> Install-Package ServiceStack -Version 3.9.71 ...