Files
Syntriax.Engine/Engine.Integration/Engine.Integration.MonoGame/MonoGameTriangleBatch.cs

75 lines
2.5 KiB
C#

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Engine.Core;
using Engine.Systems.Graphics;
namespace Engine.Integration.MonoGame;
public class MonoGameTriangleBatch : Behaviour, ITriangleBatch, IFirstFrameUpdate
{
private GraphicsDevice graphicsDevice = null!;
private VertexBuffer vertexBuffer = default!;
private readonly VertexPositionColor[] vertices = new VertexPositionColor[1024];
private int verticesIndex = 0;
private Matrix view = Matrix.Identity;
private Matrix projection = Matrix.Identity;
private BasicEffect basicEffect = null!;
private readonly RasterizerState rasterizerState = new() { CullMode = CullMode.None };
public void FirstActiveFrame()
{
GraphicsDevice graphicsDevice = Universe.FindRequiredBehaviour<MonoGameWindowContainer>().Window.GraphicsDevice;
this.graphicsDevice = graphicsDevice;
basicEffect = new(graphicsDevice);
basicEffect.VertexColorEnabled = true;
vertexBuffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionColor), 1024, BufferUsage.WriteOnly);
}
public void Draw(Triangle triangle, ColorRGBA colorRGBA)
{
if (verticesIndex + 3 >= vertices.Length)
Flush();
Vector2 A = triangle.A.ToVector2();
Vector2 B = triangle.B.ToVector2();
Vector2 C = triangle.C.ToVector2();
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(Matrix4x4? view = null, Matrix4x4? projection = null)
{
Viewport viewport = graphicsDevice.Viewport;
this.view = (view ?? Matrix4x4.Identity).Transposed.ToXnaMatrix();
this.projection = (projection ?? Matrix4x4.CreateOrthographicViewCentered(viewport.Width, viewport.Height)).Transposed.ToXnaMatrix();
}
public void End() => Flush();
private void Flush()
{
if (verticesIndex == 0)
return;
graphicsDevice.RasterizerState = rasterizerState;
basicEffect.Projection = projection;
basicEffect.View = view;
vertexBuffer.SetData(vertices);
graphicsDevice.SetVertexBuffer(vertexBuffer);
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
pass.Apply();
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, verticesIndex / 3);
verticesIndex = 0;
}
}