using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; namespace RecrownedAthenaeum.Render { /// /// Renders rectangles using the . /// public class RectangleRenderer { /// /// The used. Needs to be disposed. /// public readonly PrimitiveBatch primitiveBatch; private bool began; private bool filling; /// /// Creates a rectangle renderer with the given . /// /// public RectangleRenderer(PrimitiveBatch primitiveBatch) { this.primitiveBatch = primitiveBatch; } /// /// Begins the render batch. /// /// Whether or not to fill the rectangle. public void Begin(bool filled) { filling = filled; if (began) throw new InvalidOperationException("Cannot begin twice."); primitiveBatch.Begin(filled ? PrimitiveType.TriangleStrip : PrimitiveType.LineStrip); began = true; } /// /// Ends the batch. /// public void End() { 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 DrawRectangle(int x, int y, int width, int height, Color color, double rotation = 0) { 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); } } } }