123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- using System.Collections.Generic;
- using UnityEngine;
- namespace FairyGUI
- {
- /// <summary>
- ///
- /// </summary>
- public sealed class VertexBuffer
- {
- /// <summary>
- ///
- /// </summary>
- public Rect contentRect;
- /// <summary>
- ///
- /// </summary>
- public Rect uvRect;
- /// <summary>
- ///
- /// </summary>
- public Color32 vertexColor;
- /// <summary>
- ///
- /// </summary>
- public Vector2 textureSize;
- /// <summary>
- ///
- /// </summary>
- public readonly List<Vector3> vertices;
- /// <summary>
- ///
- /// </summary>
- public readonly List<Color32> colors;
- /// <summary>
- ///
- /// </summary>
- public readonly List<Vector2> uvs;
- /// <summary>
- ///
- /// </summary>
- public readonly List<Vector2> uvs2;
- /// <summary>
- ///
- /// </summary>
- public readonly List<int> triangles;
- static public Vector2[] NormalizedUV = new Vector2[] {
- new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) };
- static public Vector2[] NormalizedPosition = new Vector2[] {
- new Vector2(0, 1), new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1) };
- internal bool _alphaInVertexColor;
- internal bool _isArbitraryQuad;
- static Stack<VertexBuffer> _pool = new Stack<VertexBuffer>();
- /// <summary>
- ///
- /// </summary>
- /// <returns></returns>
- public static VertexBuffer Begin()
- {
- if (_pool.Count > 0)
- {
- VertexBuffer inst = _pool.Pop();
- inst.Clear();
- return inst;
- }
- else
- return new VertexBuffer();
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="source"></param>
- public static VertexBuffer Begin(VertexBuffer source)
- {
- VertexBuffer vb = Begin();
- vb.contentRect = source.contentRect;
- vb.uvRect = source.uvRect;
- vb.vertexColor = source.vertexColor;
- vb.textureSize = source.textureSize;
- return vb;
- }
- private VertexBuffer()
- {
- vertices = new List<Vector3>();
- colors = new List<Color32>();
- uvs = new List<Vector2>();
- uvs2 = new List<Vector2>();
- triangles = new List<int>();
- }
- /// <summary>
- ///
- /// </summary>
- public void End()
- {
- _pool.Push(this);
- }
- /// <summary>
- ///
- /// </summary>
- public void Clear()
- {
- vertices.Clear();
- colors.Clear();
- uvs.Clear();
- uvs2.Clear();
- triangles.Clear();
- _isArbitraryQuad = false;
- _alphaInVertexColor = false;
- }
- /// <summary>
- ///
- /// </summary>
- public int currentVertCount
- {
- get
- {
- return vertices.Count;
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="position"></param>
- public void AddVert(Vector3 position)
- {
- position.y = -position.y;
- vertices.Add(position);
- colors.Add(vertexColor);
- if (vertexColor.a != 255)
- _alphaInVertexColor = true;
- uvs.Add(new Vector2(
- Mathf.Lerp(uvRect.xMin, uvRect.xMax, (position.x - contentRect.xMin) / contentRect.width),
- Mathf.Lerp(uvRect.yMax, uvRect.yMin, (-position.y - contentRect.yMin) / contentRect.height)));
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="position"></param>
- /// <param name="color"></param>
- public void AddVert(Vector3 position, Color32 color)
- {
- position.y = -position.y;
- vertices.Add(position);
- colors.Add(color);
- if (color.a != 255)
- _alphaInVertexColor = true;
- uvs.Add(new Vector2(
- Mathf.Lerp(uvRect.xMin, uvRect.xMax, (position.x - contentRect.xMin) / contentRect.width),
- Mathf.Lerp(uvRect.yMax, uvRect.yMin, (-position.y - contentRect.yMin) / contentRect.height)));
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="position"></param>
- /// <param name="color"></param>
- /// <param name="uv"></param>
- public void AddVert(Vector3 position, Color32 color, Vector2 uv)
- {
- position.y = -position.y;
- vertices.Add(position);
- uvs.Add(new Vector2(uv.x, uv.y));
- colors.Add(color);
- if (color.a != 255)
- _alphaInVertexColor = true;
- }
- /// <summary>
- ///
- /// 1---2
- /// | / |
- /// 0---3
- /// </summary>
- /// <param name="vertRect"></param>
- public void AddQuad(Rect vertRect)
- {
- AddVert(new Vector3(vertRect.xMin, vertRect.yMax, 0f));
- AddVert(new Vector3(vertRect.xMin, vertRect.yMin, 0f));
- AddVert(new Vector3(vertRect.xMax, vertRect.yMin, 0f));
- AddVert(new Vector3(vertRect.xMax, vertRect.yMax, 0f));
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="vertRect"></param>
- /// <param name="color"></param>
- public void AddQuad(Rect vertRect, Color32 color)
- {
- AddVert(new Vector3(vertRect.xMin, vertRect.yMax, 0f), color);
- AddVert(new Vector3(vertRect.xMin, vertRect.yMin, 0f), color);
- AddVert(new Vector3(vertRect.xMax, vertRect.yMin, 0f), color);
- AddVert(new Vector3(vertRect.xMax, vertRect.yMax, 0f), color);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="vertRect"></param>
- /// <param name="color"></param>
- /// <param name="uvRect"></param>
- public void AddQuad(Rect vertRect, Color32 color, Rect uvRect)
- {
- vertices.Add(new Vector3(vertRect.xMin, -vertRect.yMax, 0f));
- vertices.Add(new Vector3(vertRect.xMin, -vertRect.yMin, 0f));
- vertices.Add(new Vector3(vertRect.xMax, -vertRect.yMin, 0f));
- vertices.Add(new Vector3(vertRect.xMax, -vertRect.yMax, 0f));
- uvs.Add(new Vector2(uvRect.xMin, uvRect.yMin));
- uvs.Add(new Vector2(uvRect.xMin, uvRect.yMax));
- uvs.Add(new Vector2(uvRect.xMax, uvRect.yMax));
- uvs.Add(new Vector2(uvRect.xMax, uvRect.yMin));
- colors.Add(color);
- colors.Add(color);
- colors.Add(color);
- colors.Add(color);
- if (color.a != 255)
- _alphaInVertexColor = true;
- }
- static List<Vector4> helperV4List = new List<Vector4>(4) { Vector4.zero, Vector4.zero, Vector4.zero, Vector4.zero };
- internal List<Vector4> FixUVForArbitraryQuad()
- {
- //ref1 http://www.reedbeta.com/blog/quadrilateral-interpolation-part-1/
- //ref2 https://bitlush.com/blog/arbitrary-quadrilaterals-in-opengl-es-2-0
- Vector4 qq = Vector4.one;
- Vector2 a = vertices[2] - vertices[0];
- Vector2 b = vertices[1] - vertices[3];
- Vector2 c = vertices[0] - vertices[3];
- float cross = a.x * b.y - a.y * b.x;
- if (cross != 0)
- {
- float s = (a.x * c.y - a.y * c.x) / cross;
- if (s > 0 && s < 1)
- {
- float t = (b.x * c.y - b.y * c.x) / cross;
- if (t > 0 && t < 1)
- {
- qq.x = 1 / (1 - t);
- qq.y = 1 / s;
- qq.z = 1 / t;
- qq.w = 1 / (1 - s);
- }
- }
- }
- for (int i = 0; i < 4; i++)
- {
- Vector4 v = uvs[i];
- float q = qq[i];
- v.x *= q;
- v.y *= q;
- v.w = q;
- helperV4List[i] = v;
- }
- return helperV4List;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="value"></param>
- /// <param name="startIndex"></param>
- /// <param name="count"></param>
- public void RepeatColors(Color32[] value, int startIndex, int count)
- {
- int len = Mathf.Min(startIndex + count, vertices.Count);
- int colorCount = value.Length;
- int k = 0;
- for (int i = startIndex; i < len; i++)
- {
- Color32 c = value[(k++) % colorCount];
- colors[i] = c;
- if (c.a != 255)
- _alphaInVertexColor = true;
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="idx0"></param>
- /// <param name="idx1"></param>
- /// <param name="idx2"></param>
- public void AddTriangle(int idx0, int idx1, int idx2)
- {
- triangles.Add(idx0);
- triangles.Add(idx1);
- triangles.Add(idx2);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="idxList"></param>
- /// <param name="startVertexIndex"></param>
- public void AddTriangles(int[] idxList, int startVertexIndex = 0)
- {
- if (startVertexIndex != 0)
- {
- if (startVertexIndex < 0)
- startVertexIndex = vertices.Count + startVertexIndex;
- int cnt = idxList.Length;
- for (int i = 0; i < cnt; i++)
- triangles.Add(idxList[i] + startVertexIndex);
- }
- else
- triangles.AddRange(idxList);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="startVertexIndex"></param>
- public void AddTriangles(int startVertexIndex = 0)
- {
- int cnt = vertices.Count;
- if (startVertexIndex < 0)
- startVertexIndex = cnt + startVertexIndex;
- for (int i = startVertexIndex; i < cnt; i += 4)
- {
- triangles.Add(i);
- triangles.Add(i + 1);
- triangles.Add(i + 2);
- triangles.Add(i + 2);
- triangles.Add(i + 3);
- triangles.Add(i);
- }
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- public Vector3 GetPosition(int index)
- {
- if (index < 0)
- index = vertices.Count + index;
- Vector3 vec = vertices[index];
- vec.y = -vec.y;
- return vec;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="position"></param>
- /// <param name="usePercent"></param>
- /// <returns></returns>
- public Vector2 GetUVAtPosition(Vector2 position, bool usePercent)
- {
- if (usePercent)
- {
- return new Vector2(Mathf.Lerp(uvRect.xMin, uvRect.xMax, position.x),
- Mathf.Lerp(uvRect.yMax, uvRect.yMin, position.y));
- }
- else
- return new Vector2(Mathf.Lerp(uvRect.xMin, uvRect.xMax, (position.x - contentRect.xMin) / contentRect.width),
- Mathf.Lerp(uvRect.yMax, uvRect.yMin, (position.y - contentRect.yMin) / contentRect.height));
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="vb"></param>
- public void Append(VertexBuffer vb)
- {
- int len = vertices.Count;
- vertices.AddRange(vb.vertices);
- uvs.AddRange(vb.uvs);
- uvs2.AddRange(vb.uvs2);
- colors.AddRange(vb.colors);
- if (len != 0)
- {
- int len1 = vb.triangles.Count;
- for (int i = 0; i < len1; i++)
- triangles.Add(vb.triangles[i] + len);
- }
- else
- triangles.AddRange(vb.triangles);
- if (vb._alphaInVertexColor)
- _alphaInVertexColor = true;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="vb"></param>
- public void Insert(VertexBuffer vb)
- {
- vertices.InsertRange(0, vb.vertices);
- uvs.InsertRange(0, vb.uvs);
- uvs2.InsertRange(0, vb.uvs2);
- colors.InsertRange(0, vb.colors);
- int len = triangles.Count;
- if (len != 0)
- {
- int len1 = vb.vertices.Count;
- for (int i = 0; i < len; i++)
- triangles[i] += len1;
- }
- triangles.InsertRange(0, vb.triangles);
- if (vb._alphaInVertexColor)
- _alphaInVertexColor = true;
- }
- }
- }
|