RenderCache.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. using UnityEngine;
  2. using UnityEngine.EventSystems;
  3. using System.Collections.Generic;
  4. using UnityEngine.UI;
  5. namespace WXB
  6. {
  7. // 缓存渲染元素
  8. public partial class RenderCache
  9. {
  10. Owner mOwner;
  11. public RenderCache(Owner st)
  12. {
  13. mOwner = st;
  14. materials = new List<Texture>();
  15. }
  16. public abstract class BaseData
  17. {
  18. Rect m_Rect;
  19. public Rect rect
  20. {
  21. set { m_Rect = value; }
  22. get { return m_Rect; }
  23. }
  24. public NodeBase node = null;
  25. public Line line { get; protected set; } // 当前所处的行
  26. public bool isContain(Vector2 pos)
  27. {
  28. var rect = new Rect(m_Rect);
  29. rect.y = rect.y + line.y - rect.height;
  30. return rect.Contains(pos);
  31. }
  32. public virtual bool isAlignByGeometry
  33. {
  34. get { return false; }
  35. }
  36. public abstract void Render(VertexHelper vh, Rect area, Vector2 offset, float pixelsPerUnit);
  37. public virtual void OnMouseEnter() { }
  38. public virtual void OnMouseLevel() { }
  39. public virtual void OnMouseUp(PointerEventData eventData) { }
  40. public int subMaterial { get; set; }
  41. public override string ToString()
  42. {
  43. return string.Format("rect:{0}", m_Rect);
  44. }
  45. public virtual void Release()
  46. {
  47. node = null;
  48. line = null;
  49. OnRelease();
  50. }
  51. protected abstract void OnRelease();
  52. public virtual void OnAlignByGeometry(ref Vector2 offset, float pixelsPerUnit)
  53. {
  54. }
  55. public virtual void OnLineYCheck(float pixelsPerUnit)
  56. {
  57. }
  58. protected LineAlignment lineAlignment
  59. {
  60. get
  61. {
  62. return (node.lineAlignment == LineAlignment.Default ? node.owner.lineAlignment : node.lineAlignment);
  63. }
  64. }
  65. public virtual Vector2 GetStartLeftBottom(float unitsPerPixel)
  66. {
  67. if (line == null)
  68. {
  69. return new Vector2(rect.x, rect.y + rect.height);
  70. }
  71. Vector2 leftBottomPos = new Vector2(rect.x, rect.y + rect.height);
  72. var la = lineAlignment;
  73. switch (la)
  74. {
  75. case LineAlignment.Top:
  76. break;
  77. case LineAlignment.Center:
  78. {
  79. if (line.y == rect.height)
  80. {
  81. }
  82. else
  83. {
  84. float offset = ((line.y - rect.height) * 0.5f);
  85. leftBottomPos.y += offset;
  86. }
  87. }
  88. break;
  89. case LineAlignment.Bottom:
  90. leftBottomPos.y = rect.y + line.y;
  91. break;
  92. }
  93. return leftBottomPos;
  94. }
  95. }
  96. List<BaseData> DataList = new List<BaseData>();
  97. public List<Texture> materials { get; protected set; }
  98. public void Release()
  99. {
  100. materials.Clear();
  101. BaseData bd = null;
  102. for (int i = 0; i < DataList.Count; ++i)
  103. {
  104. bd = DataList[i];
  105. bd.Release();
  106. if (bd is TextData)
  107. {
  108. PoolData<TextData>.Free((TextData)bd);
  109. }
  110. else if (bd is SpriteData)
  111. {
  112. PoolData<SpriteData>.Free((SpriteData)bd);
  113. }
  114. }
  115. DataList.Clear();
  116. }
  117. public void cacheText(Line l, TextNode n, string text, Rect rect)
  118. {
  119. TextData td = PoolData<TextData>.Get();
  120. td.Reset(n, text, rect, l);
  121. DataList.Add(td);
  122. td.subMaterial = materials.IndexOf(n.d_font.material.mainTexture);
  123. if (td.subMaterial == -1)
  124. {
  125. td.subMaterial = materials.Count;
  126. materials.Add(n.d_font.material.mainTexture);
  127. }
  128. }
  129. public void cacheSprite(Line l, NodeBase n, Sprite sprite, Rect rect)
  130. {
  131. if (sprite != null)
  132. {
  133. SpriteData sd = PoolData<SpriteData>.Get();
  134. sd.Reset(n, sprite, rect, l);
  135. DataList.Add(sd);
  136. sd.subMaterial = materials.IndexOf(sprite.texture);
  137. if (sd.subMaterial == -1)
  138. {
  139. sd.subMaterial = materials.Count;
  140. materials.Add(sprite.texture);
  141. }
  142. }
  143. }
  144. public void cacheCartoon(Line l, NodeBase n, Cartoon cartoon, Rect rect)
  145. {
  146. if (cartoon != null)
  147. {
  148. CartoonData cd = PoolData<CartoonData>.Get();
  149. cd.Reset(n, cartoon, rect, l);
  150. DataList.Add(cd);
  151. }
  152. }
  153. public bool isEmpty
  154. {
  155. get { return DataList.Count == 0; }
  156. }
  157. struct Key
  158. {
  159. public int subMaterial;
  160. public bool isBlink;
  161. public bool isOffset;
  162. public Rect offsetRect;
  163. public bool IsEquals(BaseData bd)
  164. {
  165. return subMaterial == bd.subMaterial &&
  166. isBlink == bd.node.d_bBlink &&
  167. (
  168. (isOffset == false && bd.node.d_bOffset == false) ||
  169. (isOffset == bd.node.d_bOffset && offsetRect == bd.node.d_rectOffset)
  170. );
  171. }
  172. public List<BaseData> nodes;
  173. public DrawType drawType
  174. {
  175. get
  176. {
  177. if (isBlink)
  178. {
  179. if (isOffset)
  180. return DrawType.OffsetAndAlpha;
  181. return DrawType.Alpha;
  182. }
  183. if (isOffset)
  184. {
  185. return DrawType.Offset;
  186. }
  187. return DrawType.Default;
  188. }
  189. }
  190. public Draw Get(Owner owner, Texture texture)
  191. {
  192. long key = nodes[0].node.keyPrefix;
  193. key += texture.GetInstanceID();
  194. Draw draw = owner.GetDraw(drawType, key,
  195. (Draw d, object p) =>
  196. {
  197. d.texture = texture;
  198. if (d is OffsetDraw)
  199. {
  200. OffsetDraw od = d as OffsetDraw;
  201. od.Set((Rect)p);
  202. }
  203. }, offsetRect);
  204. return draw;
  205. }
  206. }
  207. static List<Key> s_keys = new List<Key>();
  208. Vector2 DrawOffset;
  209. public void OnAlignByGeometry(ref Vector2 offset, float pixelsPerUnit, float firstHeight)
  210. {
  211. for (int m = 0; m < DataList.Count; ++m)
  212. {
  213. if (DataList[m].rect.y > firstHeight)
  214. continue;
  215. if (!DataList[m].isAlignByGeometry)
  216. {
  217. offset = Vector2.zero;
  218. return;
  219. }
  220. DataList[m].OnAlignByGeometry(ref offset, pixelsPerUnit);
  221. }
  222. }
  223. // 行修正
  224. public void OnCheckLineY(float pixelsPerUnit)
  225. {
  226. for (int m = 0; m < DataList.Count; ++m)
  227. {
  228. DataList[m].OnLineYCheck(pixelsPerUnit);
  229. }
  230. }
  231. public void Render(VertexHelper vh, Rect rect, Vector2 offset, float pixelsPerUnit, Mesh workerMesh, Material defaultMaterial)
  232. {
  233. DrawOffset = offset /** pixelsPerUnit*/;
  234. s_keys.Clear();
  235. for (int m = 0; m < DataList.Count; ++m)
  236. {
  237. BaseData bd = DataList[m];
  238. int index = s_keys.FindIndex((Key k) =>
  239. {
  240. return k.IsEquals(bd);
  241. });
  242. if (index == -1)
  243. {
  244. Key k = new Key();
  245. k.subMaterial = bd.subMaterial;
  246. k.isOffset = bd.node.d_bOffset;
  247. k.isBlink = bd.node.d_bBlink;
  248. k.offsetRect = bd.node.d_rectOffset;
  249. k.nodes = ListPool<BaseData>.Get();
  250. s_keys.Add(k);
  251. k.nodes.Add(bd);
  252. }
  253. else
  254. {
  255. s_keys[index].nodes.Add(bd);
  256. }
  257. }
  258. vh.Clear();
  259. for (int i = 0; i < s_keys.Count; ++i)
  260. {
  261. Key key = s_keys[i];
  262. for (int m = 0; m < key.nodes.Count; ++m)
  263. {
  264. key.nodes[m].Render(vh, rect, offset, pixelsPerUnit);
  265. }
  266. if (vh.currentVertCount != 0)
  267. {
  268. Draw draw = key.Get(mOwner, materials[key.subMaterial]);
  269. vh.FillMesh(workerMesh);
  270. draw.FillMesh(workerMesh);
  271. vh.Clear();
  272. }
  273. ListPool<BaseData>.Release(key.nodes);
  274. }
  275. s_keys.Clear();
  276. }
  277. public BaseData Get(Vector2 pos)
  278. {
  279. BaseData bd = null;
  280. pos -= DrawOffset;
  281. for (int i = 0; i < DataList.Count; ++i)
  282. {
  283. bd = DataList[i];
  284. if (bd.isContain(pos))
  285. return bd;
  286. }
  287. return null;
  288. }
  289. public void Get(List<BaseData> bds, NodeBase nb)
  290. {
  291. BaseData bd = null;
  292. for (int i = 0; i < DataList.Count; ++i)
  293. {
  294. bd = DataList[i];
  295. if (bd.node == nb)
  296. bds.Add(bd);
  297. }
  298. }
  299. }
  300. }