GeometryBuilder2D.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using Microsoft.Xna.Framework;
  4. using Microsoft.Xna.Framework.Graphics;
  5. namespace MonoGame.Extended.Graphics.Geometry
  6. {
  7. public class GeometryBuilder2D : GeometryBuilder<VertexPositionColorTexture, ushort>
  8. {
  9. public GeometryBuilder2D(int maximumVerticesCount, int maximumIndicesCount)
  10. : base(maximumVerticesCount, maximumIndicesCount)
  11. {
  12. }
  13. public void BuildSprite(int indexOffset, ref Matrix3x2 transformMatrix, Texture2D texture,
  14. ref Rectangle sourceRectangle,
  15. Color? color = null, FlipFlags flags = FlipFlags.None, float depth = 0)
  16. {
  17. if (texture == null)
  18. throw new ArgumentNullException(nameof(texture));
  19. var texelLeft = 0f;
  20. var texelTop = 0f;
  21. var texelRight = 1f;
  22. var texelBottom = 1f;
  23. if (sourceRectangle.Width > 0)
  24. {
  25. texelLeft = (float)sourceRectangle.X / texture.Width;
  26. texelTop = (float)sourceRectangle.Y / texture.Height;
  27. texelRight = (sourceRectangle.X + sourceRectangle.Width) / (float)texture.Width;
  28. texelBottom = (sourceRectangle.Y + sourceRectangle.Height) / (float)texture.Height;
  29. }
  30. else
  31. {
  32. sourceRectangle.Width = texture.Width;
  33. sourceRectangle.Height = texture.Height;
  34. }
  35. var color1 = color ?? Color.White;
  36. var vertices = Vertices;
  37. transformMatrix.Transform(0, 0, ref vertices[0].Position);
  38. vertices[0].Position.Z = depth;
  39. vertices[0].Color = color1;
  40. vertices[0].TextureCoordinate.X = texelLeft;
  41. vertices[0].TextureCoordinate.Y = texelTop;
  42. transformMatrix.Transform(sourceRectangle.Width, 0, ref vertices[1].Position);
  43. vertices[1].Position.Z = depth;
  44. vertices[1].Color = color1;
  45. vertices[1].TextureCoordinate.X = texelRight;
  46. vertices[1].TextureCoordinate.Y = texelTop;
  47. transformMatrix.Transform(0, sourceRectangle.Height, ref vertices[2].Position);
  48. vertices[2].Position.Z = depth;
  49. vertices[2].Color = color1;
  50. vertices[2].TextureCoordinate.X = texelLeft;
  51. vertices[2].TextureCoordinate.Y = texelBottom;
  52. transformMatrix.Transform(sourceRectangle.Width, sourceRectangle.Height, ref vertices[3].Position);
  53. vertices[3].Position.Z = depth;
  54. vertices[3].Color = color1;
  55. vertices[3].TextureCoordinate.X = texelRight;
  56. vertices[3].TextureCoordinate.Y = texelBottom;
  57. var flipDiagonally = (flags & FlipFlags.FlipDiagonally) != 0;
  58. var flipHorizontally = (flags & FlipFlags.FlipHorizontally) != 0;
  59. var flipVertically = (flags & FlipFlags.FlipVertically) != 0;
  60. if (flipDiagonally)
  61. {
  62. FloatHelper.Swap(ref vertices[1].TextureCoordinate.X, ref vertices[2].TextureCoordinate.X);
  63. FloatHelper.Swap(ref vertices[1].TextureCoordinate.Y, ref vertices[2].TextureCoordinate.Y);
  64. }
  65. if (flipHorizontally)
  66. if (flipDiagonally)
  67. {
  68. FloatHelper.Swap(ref vertices[0].TextureCoordinate.Y, ref vertices[1].TextureCoordinate.Y);
  69. FloatHelper.Swap(ref vertices[2].TextureCoordinate.Y, ref vertices[3].TextureCoordinate.Y);
  70. }
  71. else
  72. {
  73. FloatHelper.Swap(ref vertices[0].TextureCoordinate.X, ref vertices[1].TextureCoordinate.X);
  74. FloatHelper.Swap(ref vertices[2].TextureCoordinate.X, ref vertices[3].TextureCoordinate.X);
  75. }
  76. if (flipVertically)
  77. if (flipDiagonally)
  78. {
  79. FloatHelper.Swap(ref vertices[0].TextureCoordinate.X, ref vertices[2].TextureCoordinate.X);
  80. FloatHelper.Swap(ref vertices[1].TextureCoordinate.X, ref vertices[3].TextureCoordinate.X);
  81. }
  82. else
  83. {
  84. FloatHelper.Swap(ref vertices[0].TextureCoordinate.Y, ref vertices[2].TextureCoordinate.Y);
  85. FloatHelper.Swap(ref vertices[1].TextureCoordinate.Y, ref vertices[3].TextureCoordinate.Y);
  86. }
  87. VertexCount = 4;
  88. AddQuadrilateralIndices(indexOffset);
  89. IndexCount = 6;
  90. PrimitivesCount = 2;
  91. }
  92. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  93. private void AddQuadrilateralIndices(int indexOffset)
  94. {
  95. Indices[0] = (ushort)(0 + indexOffset);
  96. Indices[1] = (ushort)(1 + indexOffset);
  97. Indices[2] = (ushort)(2 + indexOffset);
  98. Indices[3] = (ushort)(1 + indexOffset);
  99. Indices[4] = (ushort)(3 + indexOffset);
  100. Indices[5] = (ushort)(2 + indexOffset);
  101. }
  102. }
  103. }