NGUI(1) UIDrawCall

之前看过一个博主说,研究代码一开始不能思路铺的太开,一开始应该从最核心的部分看起,然后一层一层的向外围展开,一次只看一个类或一个方法,别想看A的时候又想看B,遇到不懂的时候可以先放着,特别时遇到很复杂的调用关系的代码时千万不要深陷其中。从最核心的一小部分开始着手,比如看DrawCall 类的时候完全不管Widget和Panel,只关心这个类对外开放什么接口,需要什么数据等等。

所以研究NGUI ,首先来看看UIDrawCall吧,在此之前,如果还完全对UIDrawCall没有一点了解的话可以先看看 NGUI 必读1 NGUI渲染基础机制

下面是UIDrawCall的关键方法的介绍:

  一.UpdateGeometry() 最核心最重要的方法, 通过顶点,UV,颜色,贴图等信息绘制UI图形,下面是部分关键的代码:

      1.if (mFilter == null) mFilter = gameObject.AddComponent<MeshFilter>();//获得MeshFilter组件

      2. mMesh = new Mesh(); //创建用来渲染的网格对象 

      3. mTriangles = (verts.size >> 1); //三角形数量=顶点数/2

      4.  mMesh.vertices = verts.buffer; //将顶点 UV 颜色信息赋值跟网格对象,将网格赋值给mFilter 

           mMesh.uv = uvs.buffer;

           mMesh.colors32 = cols.buffer;

           mFilter.mesh = mMesh;

       5.if (mRenderer == null) mRenderer = gameObject.GetComponent<MeshRenderer>();//获得MeshRenderer组件

        6.UpdateMaterials();//更新Material 完成一次drawcall

一句话解释UpdateGeometry() 就是:

        将顶点 UV 颜色信息赋值给网格对象,然后将网格赋值给MeshFilter,最后MeshRenderer得到网格和材质,进行渲染。 对于Mesh,和MeshFilter,以及MeshRenderer不了解可查看相关博客:Mesh renderer 和 Mesh 和 Mesh Filter

  二.UpdateMaterials()  更新Material

   void UpdateMaterials ()

   {

        //如没有材质或使用了裁剪,就需要重建材质

        if (mRebuildMat || mDynamicMat == null || mClipCount != panel.clipCount)

        {

             RebuildMaterial();

             mRebuildMat = false;

        }

        else if (mRenderer.sharedMaterial != mDynamicMat)

        {

             //将材质赋值给MeshRender组件 ,更新render

             mRenderer.sharedMaterials = new Material[] { mDynamicMat };

        }

   }

  

  

三.RebuildMaterial () 重新生成材质

     1. CreateMaterial(); // 创建新的材质对象

     2. if (mTexture != null) mDynamicMat.mainTexture = mTexture;//将纹理赋值给材质

     3. if (mRenderer != null) mRenderer.sharedMaterials = new Material[] { mDynamicMat };//将材质赋值给MeshRender组件 ,更新render

四.CreateMaterial()  创建新的材质

  

 1. string shaderName = (mShader != null) ? mShader.name :

     ((mMaterial != null) ? mMaterial.shader.name : "Unlit/Transparent Colored");//默认使用NGUI自带的shader

   2. 

      //如果裁剪数量不为0 获得裁剪相关的shader ,如果不需要裁剪,直接获得shader对象

      if (mClipCount != 0)

      {

           shader = Shader.Find("Hidden/" + shaderName + " " + mClipCount);

           if (shader == null) Shader.Find(shaderName + " " + mClipCount);

           // Legacy functionality

           if (shader == null && mClipCount == 1)

           {

                mLegacyShader = true;

                shader = Shader.Find(shaderName + soft);

            }

       }

       else shader = Shader.Find(shaderName);

    

    3. mDynamicMat.shader = shader; //将shader赋值给Material对象

  其实DrawCall类功能很单一,下面做一个小测试,测试后会发现:完全可以把DrawCall类分离出NGUI,不用管Panel和Widget类,只用一个DrawCall类就可以独立渲染出想要的图形。

  下面是DrawCall测试的步骤:

 1.新建一个CustomDrawCall类,把UIDrawCall的代码原封不动的复制过去,把部分的属性改为Public属性:

  public Texture mTexture;

  [HideInInspector]

  public int[] mIndices;

 2.注释掉OnWillRenderObject()方法

 3.在unity3d场景中新建一个空GameObject,命名为“DrawCallObject”,这个对象就是我们绘制的目标对象。然后给这个对象添加MeshFilder,MeshRender组件,再挂上一个CustomDrawCall脚本,随便找一张贴图,拖到CustomDrawCall面板赋值给MTexture属性

   

   

  4.创建一个脚本TestDrawCall,在Start方法添加代码如下:

    5.把TestDrawCall脚本挂到场景的Main Camera上去

    6.运行Uinty3d,切换到场景,就可以看到贴图被绘制出来了:

    

   总结:UIDraw类其实并不复杂,它并不关心谁调用了它,我们完全可以把它独立出来,只要外部传入顶点,UV,颜色,贴图等信息给它,就可以绘制图形了。

   测试代码的链接是http://pan.baidu.com/s/1i3GRbtb

原文链接:https://blog.csdn.net/cbbbc/article/details/70918719

推荐另一篇写的不错的关于UIDrawCall的文章:https://zhuanlan.zhihu.com/p/102890994

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值