找回密码
 立即注册
查看: 175|回复: 0

03 uGUI源码-VertexHelper.cs

[复制链接]
发表于 2022-11-22 17:20 | 显示全部楼层 |阅读模式
VertexHelper Class[1]

定义


  • A utility class that can aid in the generation of meshes for the UI.
    一个工具类,它可以帮助UI生成网格。
This class implements IDisposable to aid with memory management.
这个类实现了IDisposable来帮助内存管理。
字段及属性

private List<Vector3> m_Positions;  //顶点位置列表 private List<Color32> m_Colors;  //顶点颜色列表 private List<Vector2> m_Uv0S;  //网格的第一个纹理坐标集。默认情况下由UI元素使用。 private List<Vector2> m_Uv1S;  //网格的第二个纹理坐标集(如果存在)。 private List<Vector2> m_Uv2S;  //网格的第三个纹理坐标集(如果存在)。 private List<Vector2> m_Uv3S;  //网格的第四个纹理坐标集(如果存在)。 private List<Vector3> m_Normals;  //法线列表 private List<Vector4> m_Tangents;  //切线列表 private List<int> m_Indices;  //定义三角形的索引的列表,决定了MeshRenderer构造三角形的顶点顺序 private static readonly Vector4 s_DefaultTangent = new Vector4(1.0f, 0.0f, 0.0f, -1.0f);  //默认切线值 private static readonly Vector3 s_DefaultNormal = Vector3.back;  //默认法线值 private bool m_ListsInitalized = false;  //以上列表元素是否进行初始化  public int currentVertCount{    get {return m_Positions != null? m_Positions.Count : 0;} }  //返回当前Buffer中顶点个数 public int currentIndexCount{    get {return m_Indices != null? m_Indices.Count : 0;} }  //获取VertexHelper上设置的Indices数。
m_Indices的注意点:
Unity默认是只渲染物体的正面,背面是不渲染的。这里就涉及到构造三角形的顺序。在Unity中以顺时针方向构造三角形,这个三角形就是正面,就被会参与渲染的计算,逆时针就是背面,最终不会显示到屏幕上。
所以必须要注意m_Indices的元素存储顺序。
这也是VertexHelper.cs提供的的Example里vh.AddTriangle(0, 1, 2); vh.AddTriangle(2, 3, 0); 的原因。
UIVertex与以上列表字段的关系

UIVertex类描述


Canvas 用于管理顶点的 Vertex 类。
变量描述
color顶点颜色。
normal法线。
position顶点位置。
tangent切线。
uv0网格的第一个纹理坐标集。默认情况下由 UI 元素使用。
uv1网格的第二个纹理坐标集(如果存在)。
uv2网格的第三个纹理坐标集(如果存在)。
uv3网格的第四个纹理坐标集(如果存在)。

可见,UIVertex类与VertexHelper类存储的列表字段呈整体与局部的关系,一个UI顶点应当包含以上字段属性。
构造函数

public VertexHelper();  //内部实现为空。public VertexHelper(Mesh m)//初始化内部字段,并将Mesh中顶点的值赋给内部成员。成员函数

InitializeListIfRequired


若m_ListsInitalized为false则初始化内部属性,并将m_ListsInitalized标记为true。
private void InitializeListIfRequired();
这里可以注意的是,List的初始化并不是简单的new,而是使用了对象池ListPool<T>,避免了List<T>的重复创建与销毁。
Dispose


确定性清理分配的内存。
//先调用ListPool<T>.Release(T),再将各字段置null,//最后m_ListsInitalized置为falsepublic void Dispose();Clear


清空VertexHelper存储的所有结点。
public void Clear();PopulateUIVertex


用VertexHelper中各顶点属性List的第i个索引值填充一个UIVertex。
public void PopulateUIVertex(ref UIVertex vertex, int i);SetUIVertex


用一个UIVertex设置各顶点属性List的第i个索引值。
public void SetUIVertex(UIVertex vertex, int i);FillMesh


使用VertexHelper中的顶点数据填满一个给定的Mesh。
public void FillMesh(Mesh mesh){        InitializeListIfRequired();          //清空mesh        mesh.Clear();        //这里注意: mesh的顶点不能超过65000,Unity中顶点数量不能超过65000个        if (m_Positions.Count >= 65000)              throw new ArgumentException("Mesh can not have more than 65000 vertices");        mesh.SetVertices(m_Positions);        mesh.SetColors(m_Colors);        mesh.SetUVs(0, m_Uv0S);        mesh.SetUVs(1, m_Uv1S);        mesh.SetUVs(2, m_Uv2S);        mesh.SetUVs(3, m_Uv3S);        mesh.SetNormals(m_Normals);        mesh.SetTangents(m_Tangents);        mesh.SetTriangles(m_Indices, 0);        //从顶点重新计算网格的包围体。        //修改顶点之后,应调用此函数以确保包围体正确。        //分配三角形会自动重新计算包围体。        mesh.RecalculateBounds();}AddVert方法


向VertexHelper存储的数据流中添加一个单独的顶点数据。
public void AddVert(Vector3 position, Color32 color, Vector2 uv0, Vector2 uv1, Vector2 uv2, Vector2 uv3, Vector3 normal, Vector4 tangent);AddTriangle


向VertexHelper存储的数据流中添加一个三角形。
public void AddTriangle(int idx0, int idx1, int idx2){       InitializeListIfRequired();       m_Indices.Add(idx0);       m_Indices.Add(idx1);       m_Indices.Add(idx2);}AddUIVertexQuad


用新添加的Vertex数组前四位元素绘制四边形。
//实际上就是添加前4个顶点进Buffer后调用两次AddTriangle方法。public void AddUIVertexQuad(UIVertex[] verts);AddUIVertexStream


将自定义顶点与指示索引添加进VertexHelper存储的数据流中。
public void AddUIVertexStream(List<UIVertex> verts, List<int> indices);
这里用到了CanvasRenderer.AddUIVertexStream:
接受顶点流并将其拆分为相应的数组(positions、colors、uv0s、uv1s、normals 和 tangents)
public static void AddUIVertexStream (List<UIVertex> verts, List<Vector3> positions, List<Color32> colors, List<Vector2> uv0S, List<Vector2> uv1S, List<Vector3> normals, List<Vector4> tangents);
AddUIVertexTriangleStream


基本同AddUIVertexStream,indices由提供的UIVertex列表获取。
public void AddUIVertexTriangleStream(List<UIVertex> verts);
这里用到了CanvasRenderer.SplitUIVertexStreams:
与AddUIVertexStream不同的是,拆分的属性还多了indices。
GetUIVertexStream


通过VertexHelper存储的数据流获取一个UIVertex列表。
(与AddUIVertexTriangleStream相反)
public void GetUIVertexStream(List<UIVertex> stream);
这里用到了CanvasRenderer.CreateUIVertexStream:
将一组顶点分量转换为 UIVertex 流。
public static void CreateUIVertexStream (List<UIVertex> verts, List<Vector3> positions, List<Color32> colors, List<Vector2> uv0S, List<Vector2> uv1S, List<Vector3> normals, List<Vector4> tangents, List<int> indices);
<hr>


  • *参考:
    Unity_UGUI | 通向UGUI源码的入口VertexHelper
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-6-27 20:48 , Processed in 0.086898 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表