cocos2dx-ui的渲染机制
来源:互联网 发布:网络很丑的女人的图片 编辑:程序博客网 时间:2024/06/05 00:18
渲染系统是游戏引擎里面最重要的一个模块之一了,如何遍历UI树,如何将UI合理的渲染在屏幕上,如何选择渲染的顺序,这是渲染系统最需要考虑的。其实遍历的顺序就决定了渲染的顺序。
Cocos2d-x的渲染函数是通过Node::visit来进行的,首先看看这个函数干了什么吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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);
bool
visibleByCamera = isVisitableByVisitingCamera();
int
i = 0;
if
(!_children.empty())
{
sortAllChildren();
// draw children zOrder < 0
for
( ; i < _children.size(); i++ )
{
auto node = _children.at(i);
if
(node && node->_localZOrder < 0)
node->visit(renderer, _modelViewTransform, flags);
else
break
;
}
// self draw
if
(visibleByCamera)
this
->draw(renderer, _modelViewTransform, flags);
for
(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
(*it)->visit(renderer, _modelViewTransform, flags);
}
else
if
(visibleByCamera)
{
this
->draw(renderer, _modelViewTransform, flags);
}
}
然后可以开始一步一步分析代码了,首先快速去掉不可见的元素,并且不绘制它的子元素。_visible的判断就干了这件事情。
然后判断子节点是否为空,子节点为空的判断是否在摄像机可视范围内,只有在可视范围内才进行绘制,如下:
1
2
3
4
else
if
(visibleByCamera)
{
this
->draw(renderer, _modelViewTransform, flags);
}
然后重点就是子节点非空的情况了,子节点非空的时候,先将所有子节点进行排序,根据什么排序呢?走进sortAllChildren函数看一看
1
2
3
4
5
6
7
8
void
Node::sortAllChildren()
{
if
(_reorderChildDirty)
{
std::sort(std::begin(_children), std::end(_children), nodeComparisonLess);
_reorderChildDirty =
false
;
}
}
还要继续深入nodeComparisonLess函数
1
2
3
4
5
6
bool
nodeComparisonLess(Node* n1, Node* n2)
{
return
( n1->getLocalZOrder() < n2->getLocalZOrder() ||
( n1->getLocalZOrder() == n2->getLocalZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )
);
}
可以看到它是根据LocalZOrder进行排序的,当LocalZOrder相同的情况下,根据加入UI树的顺序排序。那么LocalZOrder就是非常重要的元素了,排序好的子节点是基于LocalZOrder递增的。接下来看看子节点是如何进行绘制的。
1
2
3
4
5
6
7
8
9
10
// draw children zOrder < 0
for
( ; i < _children.size(); i++ )
{
auto node = _children.at(i);
if
(node && node->_localZOrder < 0)
node->visit(renderer, _modelViewTransform, flags);
else
break
;
}
首先绘制_localZOrder小于0的,然后绘制自身 最后绘制大于等于0的
1
2
3
4
5
6
// self draw
if
(visibleByCamera)
this
->draw(renderer, _modelViewTransform, flags);
for
(auto it=_children.cbegin()+i; it != _children.cend(); ++it)
(*it)->visit(renderer, _modelViewTransform, flags);
下面是一张图便于理解
所以UI树的遍历方法就是中序遍历的深度优先算法。总结如下:
1.遍历左边子节点
2.遍历根节点
3.遍历右边子节点
通过这样的方法,可以保证UI的绘制顺序可以通过_localZOrder 来调节,小于0的将被首先绘制,然后再绘制父节点。然后再绘制大于0的。
所以综上所述,_localZOrder 越小的元素将会被优先绘制
0 0
- cocos2dx-ui的渲染机制
- cocos2dx的渲染机制
- cocos2dx的渲染机制
- cocos2dx渲染机制
- cocos2dX 文字的渲染
- cocos2dx的渲染树
- cocos2dx-ui的分类与使用
- cocos2dx的UI
- UI渲染机制优化方面理解
- 浏览器的渲染机制
- 浏览器的渲染机制
- 浏览器的渲染机制
- 浏览器的渲染机制
- 浏览器的渲染机制
- 浏览器的渲染机制
- Unity的渲染机制
- Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析
- Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析
- [leetcode] 12.Integer to Roman
- 微信开发学习路线
- Eclipse注释模板
- old-boy_LINUX
- Trie树统计词频和指定前缀的单词个数
- cocos2dx-ui的渲染机制
- 决胜C++面试:堆、栈面面观
- centos6.5在VMware和Oracle VM VirtualBox下安装的区别
- JS数组
- Tomcat集群Cluster实现原理剖析
- HDU 2031 进制转换(进制转换)
- android 遇到TextView 没到末尾 自动换行 可能是 全角半角混合
- Java IO流->处理流->“随机访问” 的方式:RandomAccessFile
- Java单例你所不知道的事,与Volatile关键字有染