MeshBatcher.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /******************************************************************************
  2. * Spine Runtimes License Agreement
  3. * Last updated January 1, 2020. Replaces all prior versions.
  4. *
  5. * Copyright (c) 2013-2020, Esoteric Software LLC
  6. *
  7. * Integration of the Spine Runtimes into software or otherwise creating
  8. * derivative works of the Spine Runtimes is permitted under the terms and
  9. * conditions of Section 2 of the Spine Editor License Agreement:
  10. * http://esotericsoftware.com/spine-editor-license
  11. *
  12. * Otherwise, it is permitted to integrate the Spine Runtimes into software
  13. * or otherwise create derivative works of the Spine Runtimes (collectively,
  14. * "Products"), provided that each user of the Products must obtain their own
  15. * Spine Editor license and redistribution of the Products in any form must
  16. * include this license and copyright notice.
  17. *
  18. * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
  19. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
  24. * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *****************************************************************************/
  29. using System;
  30. using System.Collections.Generic;
  31. using Microsoft.Xna.Framework.Graphics;
  32. using Microsoft.Xna.Framework;
  33. namespace Spine {
  34. public struct VertexPositionColorTextureColor : IVertexType {
  35. public Vector3 Position;
  36. public Color Color;
  37. public Vector2 TextureCoordinate;
  38. public Color Color2;
  39. public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
  40. (
  41. new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
  42. new VertexElement(12, VertexElementFormat.Color, VertexElementUsage.Color, 0),
  43. new VertexElement(16, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
  44. new VertexElement(24, VertexElementFormat.Color, VertexElementUsage.Color, 1)
  45. );
  46. VertexDeclaration IVertexType.VertexDeclaration {
  47. get { return VertexDeclaration; }
  48. }
  49. }
  50. // #region License
  51. // /*
  52. // Microsoft Public License (Ms-PL)
  53. // MonoGame - Copyright � 2009 The MonoGame Team
  54. //
  55. // All rights reserved.
  56. //
  57. // This license governs use of the accompanying software. If you use the software, you accept this license. If you do not
  58. // accept the license, do not use the software.
  59. //
  60. // 1. Definitions
  61. // The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under
  62. // U.S. copyright law.
  63. //
  64. // A "contribution" is the original software, or any additions or changes to the software.
  65. // A "contributor" is any person that distributes its contribution under this license.
  66. // "Licensed patents" are a contributor's patent claims that read directly on its contribution.
  67. //
  68. // 2. Grant of Rights
  69. // (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
  70. // each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
  71. // (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3,
  72. // each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
  73. //
  74. // 3. Conditions and Limitations
  75. // (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
  76. // (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software,
  77. // your patent license from such contributor to the software ends automatically.
  78. // (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
  79. // notices that are present in the software.
  80. // (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
  81. // a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object
  82. // code form, you may only do so under a license that complies with this license.
  83. // (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees
  84. // or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent
  85. // permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular
  86. // purpose and non-infringement.
  87. // */
  88. // #endregion License
  89. //
  90. /// <summary>Draws batched meshes.</summary>
  91. public class MeshBatcher {
  92. private readonly List<MeshItem> items;
  93. private readonly Queue<MeshItem> freeItems;
  94. private VertexPositionColorTextureColor[] vertexArray = { };
  95. private short[] triangles = { };
  96. public MeshBatcher () {
  97. items = new List<MeshItem>(256);
  98. freeItems = new Queue<MeshItem>(256);
  99. EnsureCapacity(256, 512);
  100. }
  101. /// <summary>Returns a pooled MeshItem.</summary>
  102. public MeshItem NextItem (int vertexCount, int triangleCount) {
  103. MeshItem item = freeItems.Count > 0 ? freeItems.Dequeue() : new MeshItem();
  104. if (item.vertices.Length < vertexCount) item.vertices = new VertexPositionColorTextureColor[vertexCount];
  105. if (item.triangles.Length < triangleCount) item.triangles = new int[triangleCount];
  106. item.vertexCount = vertexCount;
  107. item.triangleCount = triangleCount;
  108. items.Add(item);
  109. return item;
  110. }
  111. private void EnsureCapacity (int vertexCount, int triangleCount) {
  112. if (vertexArray.Length < vertexCount) vertexArray = new VertexPositionColorTextureColor[vertexCount];
  113. if (triangles.Length < triangleCount) triangles = new short[triangleCount];
  114. }
  115. public void Draw (GraphicsDevice device) {
  116. if (items.Count == 0) return;
  117. int itemCount = items.Count;
  118. int vertexCount = 0, triangleCount = 0;
  119. for (int i = 0; i < itemCount; i++) {
  120. MeshItem item = items[i];
  121. vertexCount += item.vertexCount;
  122. triangleCount += item.triangleCount;
  123. }
  124. EnsureCapacity(vertexCount, triangleCount);
  125. vertexCount = 0;
  126. triangleCount = 0;
  127. Texture2D lastTexture = null;
  128. for (int i = 0; i < itemCount; i++) {
  129. MeshItem item = items[i];
  130. int itemVertexCount = item.vertexCount;
  131. if (item.texture != lastTexture || vertexCount + itemVertexCount > short.MaxValue) {
  132. FlushVertexArray(device, vertexCount, triangleCount);
  133. vertexCount = 0;
  134. triangleCount = 0;
  135. lastTexture = item.texture;
  136. device.Textures[0] = lastTexture;
  137. if (item.textureLayers != null) {
  138. for (int layer = 1; layer < item.textureLayers.Length; ++layer)
  139. device.Textures[layer] = item.textureLayers[layer];
  140. }
  141. }
  142. int[] itemTriangles = item.triangles;
  143. int itemTriangleCount = item.triangleCount;
  144. for (int ii = 0, t = triangleCount; ii < itemTriangleCount; ii++, t++)
  145. triangles[t] = (short)(itemTriangles[ii] + vertexCount);
  146. triangleCount += itemTriangleCount;
  147. Array.Copy(item.vertices, 0, vertexArray, vertexCount, itemVertexCount);
  148. vertexCount += itemVertexCount;
  149. }
  150. FlushVertexArray(device, vertexCount, triangleCount);
  151. }
  152. public void AfterLastDrawPass () {
  153. int itemCount = items.Count;
  154. for (int i = 0; i < itemCount; i++) {
  155. var item = items[i];
  156. item.texture = null;
  157. freeItems.Enqueue(item);
  158. }
  159. items.Clear();
  160. }
  161. private void FlushVertexArray (GraphicsDevice device, int vertexCount, int triangleCount) {
  162. if (vertexCount == 0) return;
  163. device.DrawUserIndexedPrimitives(
  164. PrimitiveType.TriangleList,
  165. vertexArray, 0, vertexCount,
  166. triangles, 0, triangleCount / 3,
  167. VertexPositionColorTextureColor.VertexDeclaration);
  168. }
  169. }
  170. public class MeshItem {
  171. public Texture2D texture = null;
  172. public Texture2D[] textureLayers = null;
  173. public int vertexCount, triangleCount;
  174. public VertexPositionColorTextureColor[] vertices = { };
  175. public int[] triangles = { };
  176. }
  177. }