using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Syntriax.Engine.Core; namespace Syntriax.Engine.Integration.MonoGame; public class TriangleBatch : ITriangleBatch { private readonly GraphicsDevice graphicsDevice; private VertexBuffer vertexBuffer = default!; private readonly VertexPositionColor[] vertices = new VertexPositionColor[1024]; private int verticesIndex = 0; private Matrix _view; private Matrix _projection; private readonly BasicEffect basicEffect; public TriangleBatch(GraphicsDevice graphicsDevice) { this.graphicsDevice = graphicsDevice; this.graphicsDevice.RasterizerState = new RasterizerState() { CullMode = CullMode.None }; basicEffect = new(graphicsDevice); basicEffect.VertexColorEnabled = true; } public void Draw(Triangle triangle, ColorRGBA colorRGBA) { if (verticesIndex + 3 >= vertices.Length) Flush(); Vector2 A = triangle.A.ToDisplayVector2(); Vector2 B = triangle.B.ToDisplayVector2(); Vector2 C = triangle.C.ToDisplayVector2(); Color color = colorRGBA.ToColor(); vertices[verticesIndex++] = new(new(A.X, A.Y, 0f), color); vertices[verticesIndex++] = new(new(B.X, B.Y, 0f), color); vertices[verticesIndex++] = new(new(C.X, C.Y, 0f), color); } public void Begin(Matrix? view = null, Matrix? projection = null) { if (view != null) _view = view.Value; else _view = Matrix.Identity; if (projection != null) _projection = projection.Value; else { Viewport viewport = graphicsDevice.Viewport; _projection = Matrix.CreateOrthographicOffCenter(viewport.X, viewport.Width, viewport.Height, viewport.Y, 0, 1); } } public void End() => Flush(); private void Flush() { basicEffect.Projection = _projection; basicEffect.View = _view; vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionColor), 1024, BufferUsage.WriteOnly); vertexBuffer.SetData(vertices); graphicsDevice.SetVertexBuffer(vertexBuffer); foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) pass.Apply(); graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, verticesIndex / 3); verticesIndex = 0; } }