diff --git a/RecrownedAthenaeum/Camera/Camera2D.cs b/RecrownedAthenaeum/Camera/Camera2D.cs index ce37908..0f9a018 100644 --- a/RecrownedAthenaeum/Camera/Camera2D.cs +++ b/RecrownedAthenaeum/Camera/Camera2D.cs @@ -12,7 +12,7 @@ namespace RecrownedAthenaeum.Camera { public float Zoom; public Vector2 Position; - public Matrix TransformMatrix { get; private set; } + public Matrix Matrix { get; private set; } public GraphicsDevice graphicsDevice; public Camera2D(GraphicsDevice graphicsDevice) @@ -26,7 +26,7 @@ namespace RecrownedAthenaeum.Camera public void Update() { Rectangle bounds = graphicsDevice.Viewport.Bounds; - TransformMatrix = + Matrix = Matrix.CreateTranslation(new Vector3(-Position.X, -Position.Y, 0)) * Matrix.CreateScale(Zoom) * Matrix.CreateTranslation(new Vector3(bounds.Width * 0.5f, bounds.Height * 0.5f, 0f)); diff --git a/RecrownedAthenaeum/RecrownedAthenaeum.csproj b/RecrownedAthenaeum/RecrownedAthenaeum.csproj index 6f1069e..04fb4a9 100644 --- a/RecrownedAthenaeum/RecrownedAthenaeum.csproj +++ b/RecrownedAthenaeum/RecrownedAthenaeum.csproj @@ -68,6 +68,7 @@ + diff --git a/RecrownedAthenaeum/Render/PrimitiveBatch.cs b/RecrownedAthenaeum/Render/PrimitiveBatch.cs new file mode 100644 index 0000000..cb532b3 --- /dev/null +++ b/RecrownedAthenaeum/Render/PrimitiveBatch.cs @@ -0,0 +1,116 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using RecrownedAthenaeum.Camera; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RecrownedAthenaeum.Render +{ + public class PrimitiveBatch : IDisposable + { + VertexPositionColor[] vertices; + int MaxVertices { get { return vertices.Length; } } + int bufferPosition; + BasicEffect basicEffect; + PrimitiveType primitiveType; + int verticesPerPrimitive; + GraphicsDevice graphicsDevice; + bool began; + bool isDisposed; + + /// + /// Creates a batch used to draw primitives. + /// + /// The current graphics device being used. + /// The current camera being used. + /// The amount of vertices every batch can hold before flushing. Default is 450. + public PrimitiveBatch(GraphicsDevice graphicsDevice, Camera2D camera, int verticesPerBatch = 450) + { + this.graphicsDevice = graphicsDevice ?? throw new ArgumentNullException("Graphics device can't be null."); + + basicEffect = new BasicEffect(graphicsDevice); + basicEffect.VertexColorEnabled = true; + basicEffect.View = camera.Matrix; + + vertices = new VertexPositionColor[verticesPerBatch]; + } + + /// + /// Starts the batch. Batch cannot be started twice. + /// + /// The type of primitive this batch would be drawing. + public void Begin(PrimitiveType primitiveType) + { + if (began) throw new InvalidOperationException("Begin is being called twice before being ended."); + this.primitiveType = primitiveType; + this.verticesPerPrimitive = 0; + switch (primitiveType) + { + case PrimitiveType.LineList: verticesPerPrimitive = 2; break; + case PrimitiveType.TriangleList: verticesPerPrimitive = 3; break; + } + + basicEffect.CurrentTechnique.Passes[0].Apply(); + began = true; + } + + /// + /// Ends the batch. Begin needs to be called before end. + /// + public void End() + { + if (!began) throw new InvalidOperationException("Begin must be called before ending."); + Flush(); + } + + /// + /// Adds a vertex position for the primitive being drawn. The batch needs to have beens started before this. + /// + /// The vector that represents the vertex. + /// The color of that vertex. + public void AddVertex(Vector2 vertex, Color color) + { + if (!began) throw new InvalidOperationException("Begin needs to be called before adding vertex."); + if (bufferPosition + verticesPerPrimitive >= MaxVertices && (bufferPosition % MaxVertices == 0)) + { + Flush(); + } + + vertices[bufferPosition].Position = (new Vector3(vertex, 0)); + vertices[bufferPosition].Color = color; + + bufferPosition++; + } + + /// + /// Flushes the batch. Automatically called if required. + /// + public void Flush() + { + if (!began) throw new InvalidOperationException("Begin needs to be called before flushing."); + if (bufferPosition == 0) return; + + graphicsDevice.DrawUserPrimitives(primitiveType, vertices, 0, bufferPosition / verticesPerPrimitive); + + bufferPosition = 0; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + public void Dispose(bool disposing) + { + if (disposing && !isDisposed) + { + basicEffect.Dispose(); + isDisposed = true; + } + } + } +} diff --git a/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs b/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs index d3832e5..28544e8 100644 --- a/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs +++ b/RecrownedAthenaeum/ScreenSystem/ScreenManager.cs @@ -104,13 +104,13 @@ namespace RecrownedAthenaeum.ScreenSystem { graphics.GraphicsDevice.SetRenderTarget(previousScreenRenderTarget); graphics.GraphicsDevice.Clear(previousScreen.BackgroundColor); - spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, camera.TransformMatrix); + spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, camera.Matrix); previousScreen.Draw(spriteBatch); spriteBatch.End(); graphics.GraphicsDevice.SetRenderTarget(null); Screen.UpdatePreviousScreenFrame(previousScreenRenderTarget); } - spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, camera.TransformMatrix); + spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, camera.Matrix); Screen.Draw(spriteBatch); spriteBatch.End(); } diff --git a/RecrownedAthenaeum/UI/Modular/UIModuleGroup.cs b/RecrownedAthenaeum/UI/Modular/UIModuleGroup.cs index eb9c043..c5a23d8 100644 --- a/RecrownedAthenaeum/UI/Modular/UIModuleGroup.cs +++ b/RecrownedAthenaeum/UI/Modular/UIModuleGroup.cs @@ -33,7 +33,7 @@ namespace RecrownedAthenaeum.UI.Modular if (scissorBounds != null) { batch.End(); - batch.Begin(SpriteSortMode.Deferred, null, null, null, scissorRasterizer, null, Camera?.TransformMatrix); + batch.Begin(SpriteSortMode.Deferred, null, null, null, scissorRasterizer, null, Camera?.Matrix); scissorBounds.Width = bounds.Width; scissorBounds.Height = bounds.Height; scissorBounds.X = bounds.X; @@ -57,7 +57,7 @@ namespace RecrownedAthenaeum.UI.Modular { batch.GraphicsDevice.ScissorRectangle = scissorBounds; batch.End(); - batch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, Camera?.TransformMatrix); + batch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, Camera?.Matrix); } }