115 lines
4.4 KiB
C#
115 lines
4.4 KiB
C#
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
|
|
{
|
|
List<VertexPositionColor> vertices;
|
|
int maxVertices;
|
|
int bufferPosition;
|
|
BasicEffect basicEffect;
|
|
PrimitiveType primitiveType;
|
|
int verticesPerPrimitive;
|
|
GraphicsDevice graphicsDevice;
|
|
bool began;
|
|
bool isDisposed;
|
|
|
|
/// <summary>
|
|
/// Creates a batch used to draw primitives.
|
|
/// </summary>
|
|
/// <param name="graphicsDevice">The current graphics device being used.</param>
|
|
/// <param name="camera">The current camera being used.</param>
|
|
/// <param name="verticesPerBatch">The amount of vertices every batch can hold before flushing. Default is 450. Should be changed to be the most optimal number if possible. Especially if using strip primitive types.</param>
|
|
public PrimitiveBatch(GraphicsDevice graphicsDevice, Camera2D camera, int verticesPerBatch = 500)
|
|
{
|
|
this.graphicsDevice = graphicsDevice ?? throw new ArgumentNullException("Graphics device can't be null.");
|
|
maxVertices = verticesPerBatch;
|
|
basicEffect = new BasicEffect(graphicsDevice);
|
|
basicEffect.VertexColorEnabled = true;
|
|
basicEffect.View = camera.Matrix;
|
|
|
|
vertices = new List<VertexPositionColor>(verticesPerBatch);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts the batch. Batch cannot be started twice.
|
|
/// </summary>
|
|
/// <param name="primitiveType">The type of primitive this batch would be drawing.</param>
|
|
public void Begin(PrimitiveType primitiveType)
|
|
{
|
|
if (began) throw new InvalidOperationException("Begin is being called twice before being ended.");
|
|
this.primitiveType = primitiveType;
|
|
verticesPerPrimitive = 0;
|
|
switch (primitiveType)
|
|
{
|
|
case PrimitiveType.LineList: verticesPerPrimitive = 2; break;
|
|
case PrimitiveType.TriangleList: verticesPerPrimitive = 3; break;
|
|
default: verticesPerPrimitive = 1; break;
|
|
}
|
|
|
|
basicEffect.CurrentTechnique.Passes[0].Apply();
|
|
began = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ends the batch. Begin needs to be called before end.
|
|
/// </summary>
|
|
public void End()
|
|
{
|
|
if (!began) throw new InvalidOperationException("Begin must be called before ending.");
|
|
Flush();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a vertex position for the primitive being drawn. The batch needs to have beens started before this.
|
|
/// </summary>
|
|
/// <param name="vertex">The vector that represents the vertex.</param>
|
|
/// <param name="color">The color of that vertex.</param>
|
|
public void AddVertex(Vector2 vertex, Color color)
|
|
{
|
|
if (!began) throw new InvalidOperationException("Begin needs to be called before adding vertex.");
|
|
if (primitiveType != PrimitiveType.LineStrip && primitiveType != PrimitiveType.TriangleStrip && bufferPosition + verticesPerPrimitive >= maxVertices && (bufferPosition % maxVertices == 0))
|
|
{
|
|
Flush();
|
|
}
|
|
vertices[bufferPosition] = new VertexPositionColor(new Vector3(vertex, 0), color);
|
|
|
|
bufferPosition++;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Flushes the batch. Automatically called if required if using <see cref="PrimitiveType.LineList"/> or <see cref="PrimitiveType.TriangleList"/>. Otherwise, manual flushing is required.
|
|
/// </summary>
|
|
public void Flush()
|
|
{
|
|
if (!began) throw new InvalidOperationException("Begin needs to be called before flushing.");
|
|
if (bufferPosition == 0) return;
|
|
|
|
graphicsDevice.DrawUserPrimitives(primitiveType, vertices.ToArray(), 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;
|
|
}
|
|
}
|
|
}
|
|
}
|