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 ...
随机推荐
- MySQL联结查询和组合查询
联结查询 1.关系表 主键:一列或一组列,能够唯一区分表中的每一行,用来表示一个特定的行 外键:为某个表中的一列,包含另一个表的主键,定义量表的关系. 2.创建联结 规定要连接的表和他们如何关联即可 ...
- TypeScript 之 模块
https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/Modules.html 外部模块简写 外部模块简写:declare ...
- centos7 pptp 安装
1 安装 ppp yum install -y ppp 2 安装 pptpd yum install -y pptpd 3 编辑/etc/pptpd.conf 在最后 添加 localip 192. ...
- jmeter---将回应数据写入到文件
jmeter---将回应数据写入到文件 JMeterPlugins (插件监听器)Flexible File Writer:这个插件允许你灵活记录测试结果 Filename:结果记录的地方 Overw ...
- 如何在linux服务器上使用hanlp
关于如何在linux服务器上使用hanlp也有分享过一篇,但分享的内容与湘笑的这篇还是不同的.此处分享一下湘笑的这篇hanlp在linux服务器上使用的文章,供新手朋友学习之用. 本文主要工作是在li ...
- 多线程中的Lock小结
出处:http://www.cnblogs.com/DarrenChan/p/6528578.html#undefined 1.lock和synchronized的区别 1)Lock不是Java语言内 ...
- centos添加额外测源,解决:No package openvpn available.
centos添加额外测源,解决:No package openvpn available. ##添加额外的repositories,安装openvpn yum install epel-release ...
- minicom的安装及配置
1. sudo apt-get install minicom 2. 配置 (1). sudo minicom –s (2). (3). 按“A”配置设备,再按回车保存.按”F”,把留空改为NO.回车 ...
- hyperledge fabric里order-kafka过程分析
Broadcast主要接收Peer的数据并在Orderer里面生成一系列数据块,主要流程见下图: Broadcast过程分析:Peer(客户端)通过GRPC发起通信,与Orderer连接成功之后,便可 ...
- oracle rac的启动与停止
引言:这写篇文章的出处是因为我的一名学生最近在公司搭建RAC集群,但对其启动与关闭的顺序和原理不是特别清晰,我在教学工作中也发现了很多学员对RAC知识了解甚少,因此我在这里就把RAC里面涉及到的最常用 ...