recrownedathenaeum/RecrownedAthenaeum/Render/RectangleRenderer.cs

93 lines
3.8 KiB
C#

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using RecrownedAthenaeum.Camera;
using System;
namespace RecrownedAthenaeum.Render
{
/// <summary>
/// Renders rectangles using the <see cref="PrimitiveBatch"/>.
/// </summary>
public class RectangleRenderer : IDisposable
{
private bool disposed;
/// <summary>
/// The <see cref="PrimitiveBatch"/> used. Needs to be disposed.
/// </summary>
private readonly PrimitiveBatch primitiveBatch;
/// <summary>
/// Creates a rectangle renderer with the given <see cref="PrimitiveBatch"/>.
/// </summary>
/// <param name="camera">Camera to use for <see cref="PrimitiveBatch"/>. Default will use <see cref="Configuration"/>.</param>
/// <param name="graphicsDevice">Graphics device to use. Default will use <see cref="Configuration"/>.</param>
public RectangleRenderer(Camera2D camera = null, GraphicsDevice graphicsDevice = null)
{
primitiveBatch = new PrimitiveBatch(camera, graphicsDevice, 4);
}
/// <summary>
/// Disposes the rectangle renderer.
/// </summary>
public void Dispose()
{
Dispose(true);
}
/// <summary>
/// Overridable for dispose.
/// </summary>
/// <param name="disposing">True when its a player calling the dispose.</param>
public virtual void Dispose(bool disposing)
{
if (disposed) throw new ObjectDisposedException(GetType().Name);
if (disposing)
{
primitiveBatch.Dispose();
}
disposed = true;
}
/// <summary>
/// Draws a basic rectangle given bottom left and top right.
/// </summary>
/// <param name="x">X coordinate of bottom left.</param>
/// <param name="y">Y coordinate of bottom left.</param>
/// <param name="width">Width of rectangle.</param>
/// <param name="height">Height of rectangle.</param>
/// <param name="color">Color of all vertices of this rectangle.</param>
/// <param name="rotation">Rotation of rectangle. Default is 0 radians.</param>
/// <param name="filled">If this rectangle should be filled.</param>
public void Draw(int x, int y, int width, int height, Color color, double rotation = 0, bool filled = false)
{
primitiveBatch.Begin(filled ? PrimitiveType.TriangleStrip : PrimitiveType.LineStrip);
Vector2[] corners = new Vector2[4];
double topRightAngleFromOrig = Math.Atan((double)height / width);
corners[0] = new Vector2(x, y);
corners[1] = new Vector2(x + (float)Math.Cos(rotation) * width, y + (float)Math.Sin(rotation) * 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((Math.PI / 2f) - rotation) * height), y + (float)(Math.Sin((Math.PI / 2f) - rotation) * height));
if (filled)
{
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);
}
primitiveBatch.End();
}
}
}