原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/youxikaifa/2019/0130/369.html
常州手游开发培训-NGUI Drall原理分析
					要想理解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的一张图更说明他们之间的关系:
			
					好了他们之间的关系有了大概的了解那我们就开始进入正题吧。
				
					先说说NGUI DrawCall的大概的一个原理,然后我们再去看看源码吧。
				
					原理:
				
					1.首先将UIPanel上的所有UIWidget按照Depth排序,若Depth相同就按照Material的ID进行排序;
				
					2.然后常州微信公众平台遍历UIWidget将相同Material的合并到一个DrawCall里面;
				
						        /// <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两个常州网站开发建设变量值;
					上篇:上一篇:常州微信游戏开发-U3d 动态下载动画资源Animatio
下篇:下一篇:常州手游开发-Unity与HTML通信




