NGUI Drall原理分析
2016-03-10 23:52
411 查看
要想 理解NGUI Drall的原理,首先要理解UIPanel、UIWidget、UIDrawCall、UIGeometry之间的关系。
1、所有的UIWidget都需要一个UIPanel来管理和绘制;
2、每个UIWidget都有一个UIGeometry,UIGeometry就是对UIWidget的顶点vertices,uvs和color进行存储和更新,UIGeometry完全由UIWidget维护;
3、不是每个UIWidget都有UIDrawCall,因为NGUI会通过Batch合并来减少UIDrawCall;
4、UIDrawCall根据UIGeometry提供的数据由UIPanel统一指定渲染绘制;
在次借鉴DSQiu的一张图更说明他们之间的关系,他有一篇博客就是讲这个的,有兴趣的可以去看看:/content/2572577.html
好了他们之间的关系有了大概的了解那我们就开始进入正题吧。
先说说NGUI
DrawCall的大概的一个原理,然后我们再去看看源码吧。
原理:1、首先将UIPanel上的所有UIWidget按照Depth排序,若Depth相同就按照Material的ID进行排序;
2、然后遍历UIWidget将相同Material的合并到一个DrawCall里面;
OK,基本原理就是这样,那么再让我们来看看源码吧
这就是合并DrawCall的代码,其思路如下
1、清空DrawCall List表,声明Material mat、Texture tex、Shader sdr、UIDrawCall dc记录上一次循环的Material、Texture、Shader、UIDrawCall;
2、遍历UIWidget列表对Material、Texture、Shader与上一个是否相同进行判断:
1)如果不同先将上个UIDrawCall加入到DrawCall列表中,然后根据当前UIPanel、Material、Texture、Shader创建一个UIDrawCall;
2)相同则就改变UIDrawCall的depthStart和depthEnd两个变量值;
OK,就简单粗暴的写到这,有写的不到位请指正谢谢!!!
1、所有的UIWidget都需要一个UIPanel来管理和绘制;
2、每个UIWidget都有一个UIGeometry,UIGeometry就是对UIWidget的顶点vertices,uvs和color进行存储和更新,UIGeometry完全由UIWidget维护;
3、不是每个UIWidget都有UIDrawCall,因为NGUI会通过Batch合并来减少UIDrawCall;
4、UIDrawCall根据UIGeometry提供的数据由UIPanel统一指定渲染绘制;
在次借鉴DSQiu的一张图更说明他们之间的关系,他有一篇博客就是讲这个的,有兴趣的可以去看看:/content/2572577.html
好了他们之间的关系有了大概的了解那我们就开始进入正题吧。
先说说NGUI
DrawCall的大概的一个原理,然后我们再去看看源码吧。
原理:1、首先将UIPanel上的所有UIWidget按照Depth排序,若Depth相同就按照Material的ID进行排序;
2、然后遍历UIWidget将相同Material的合并到一个DrawCall里面;
OK,基本原理就是这样,那么再让我们来看看源码吧
/// <summary> /// Fill the geometry fully, processing all widgets and re-creating all draw calls. /// </summary> void FillAllDrawCalls () { for (int i = 0; i < drawCalls.Count; ++i) UIDrawCall.Destroy(drawCalls[i]); drawCalls.Clear(); Material mat = null; Texture tex = null; Shader sdr = null; UIDrawCall dc = null; int count = 0; if (mSortWidgets) SortWidgets(); for (int i = 0; i < widgets.Count; ++i) { UIWidget w = widgets[i]; if (w.isVisible && w.hasVertices) { Material mt = w.material; Texture tx = w.mainTexture; Shader sd = w.shader; if (mat != mt || tex != tx || sdr != sd) { if (dc != null && dc.verts.size != 0) { drawCalls.Add(dc); dc.UpdateGeometry(count); dc.onRender = mOnRender; mOnRender = null; count = 0; dc = null; } mat = mt; tex = tx; sdr = sd; } if (mat != null || sdr != null || tex != null) { if (dc == null) { dc = UIDrawCall.Create(this, mat, tex, sdr); dc.depthStart = w.depth; dc.depthEnd = dc.depthStart; dc.panel = this; } else { int rd = w.depth; if (rd < dc.depthStart) dc.depthStart = rd; if (rd > dc.depthEnd) dc.depthEnd = rd; } w.drawCall = dc; ++count; if (generateNormals) w.WriteToBuffers(dc.verts, dc.uvs, dc.cols, dc.norms, dc.tans); else w.WriteToBuffers(dc.verts, dc.uvs, dc.cols, null, null); if (w.mOnRender != null) { if (mOnRender == null) mOnRender = w.mOnRender; else mOnRender += w.mOnRender; } } } else w.drawCall = null; } if (dc != null && dc.verts.size != 0) { drawCalls.Add(dc); dc.UpdateGeometry(count); dc.onRender = mOnRender; mOnRender = null; } }
这就是合并DrawCall的代码,其思路如下
1、清空DrawCall List表,声明Material mat、Texture tex、Shader sdr、UIDrawCall dc记录上一次循环的Material、Texture、Shader、UIDrawCall;
2、遍历UIWidget列表对Material、Texture、Shader与上一个是否相同进行判断:
1)如果不同先将上个UIDrawCall加入到DrawCall列表中,然后根据当前UIPanel、Material、Texture、Shader创建一个UIDrawCall;
2)相同则就改变UIDrawCall的depthStart和depthEnd两个变量值;
OK,就简单粗暴的写到这,有写的不到位请指正谢谢!!!
相关文章推荐
- 如何设计好的UI控件
- java中String,StringBuffer,StringBuilder拼接效率对比
- 3.UIViewController详解
- tableView自定义背景图结合masonry毛玻璃特效
- A. Robot Sequence
- easyUI datagrid笔记
- UVA 12166 Equilibrium Mobile 修改天平
- Easy UI bug:iframe中请求页面而session失效时页面跳转问题
- poj 2478 Farey Sequence
- UESTC 1073 秋实大哥与线段树 线段树&&改值与区间和
- iOS边练边学--UIScrollView和xib文件实现简单分页+定时器初使用
- EasyUI DataGrid 相同连续列合并
- EasyUI DataGrid 相同连续列合并
- EasyUI DataGrid 相同连续列合并
- UITableView介绍 之下拉刷新原理
- iOS学习 UITableView 单选
- Android的UI框架汇总整理
- Android中Handler,Looper和MessageQueue工作原理解析
- 【leetcode】Array——Longest Consecutive Sequence(128)
- Android高阶UI之加入购物车选择颜色、尺码实现