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 RectangleBatch : IDisposable { public readonly PrimitiveBatch primitiveBatch; private bool disposed; private bool began; private bool filling; public RectangleBatch(PrimitiveBatch primitiveBatch) { this.primitiveBatch = primitiveBatch; } public RectangleBatch(GraphicsDevice graphicsDevice, Camera2D camera) : this(new PrimitiveBatch(graphicsDevice, camera, 4)) { } public void Begin(bool filled) { filling = filled; if (disposed) throw new ObjectDisposedException(typeof(PrimitiveBatch).Name); if (began) throw new InvalidOperationException("Cannot begin twice."); primitiveBatch.Begin(filled ? PrimitiveType.TriangleStrip : PrimitiveType.LineStrip); began = true; } public void End() { if (disposed) throw new ObjectDisposedException(typeof(PrimitiveBatch).Name); if (!began) throw new InvalidOperationException("Cannot end before beginning."); primitiveBatch.End(); began = false; } /// /// Draws a basic rectangle given bottom left and top right. /// /// X coordinate of bottom left. /// Y coordinate of bottom left. /// Width of rectangle. /// Height of rectangle. /// Color of all vertices of this rectangle. /// Rotation of rectangle. Default is 0 radians. public void Rectangle(int x, int y, int width, int height, Color color, double rotation = 0) { if (disposed) throw new ObjectDisposedException(typeof(PrimitiveBatch).Name); if (!began) throw new InvalidOperationException("Renderer must be started by calling Begin."); Vector2[] corners = new Vector2[4]; corners[0] = new Vector2(x, y); corners[1] = new Vector2(x + (float)Math.Cos(rotation) * width, y + (float)Math.Sin(rotation) * width); double topRightAngleFromOrig = Math.Atan(height / (double)width); float origDiagonalHypotenuse = (float)Math.Sqrt(width * width * height * height); corners[2] = new Vector2(x + (float)Math.Cos(topRightAngleFromOrig + rotation) * origDiagonalHypotenuse, y + (float)Math.Sin(topRightAngleFromOrig + rotation) * origDiagonalHypotenuse); corners[3] = new Vector2(x + (float)Math.Cos(rotation + Math.PI / 4f) * height, y + (float)Math.Sin(rotation) * height); if (filling) { primitiveBatch.AddVertex(corners[1], color); primitiveBatch.AddVertex(corners[2], color); primitiveBatch.AddVertex(corners[0], color); primitiveBatch.AddVertex(corners[3], color); } else { primitiveBatch.AddVertex(corners[0], color); primitiveBatch.AddVertex(corners[1], color); primitiveBatch.AddVertex(corners[2], color); primitiveBatch.AddVertex(corners[3], color); } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } public void Dispose(bool disposing) { if (!disposed && disposing) { if (primitiveBatch != null) { primitiveBatch.Dispose(); } } else { if (disposed) throw new ObjectDisposedException(typeof(PrimitiveBatch).Name); } } } }