rectangle renderer now has correct corner calculations; switched to vertex buffer for primitive batch. still wip.

This commit is contained in:
Harrison Deng 2019-02-13 07:43:35 -06:00
parent de93e35b07
commit 68345ada3c
2 changed files with 34 additions and 18 deletions

View File

@ -13,15 +13,19 @@ namespace RecrownedAthenaeum.Render
{ {
VertexPositionColor[] vertices; VertexPositionColor[] vertices;
int bufferPosition; int bufferPosition;
int maxVertices; VertexBuffer vertexBuffer;
BasicEffect basicEffect; BasicEffect basicEffect;
PrimitiveType primitiveType; PrimitiveType primitiveType;
int verticesPerPrimitive; /// <summary>
/// Sets the vertices per primitive. Default is dependent on the primitive type. Lists will generally satisfy the amount of vertices they need, while strips should be set or it will all be interconnected.
/// </summary>
public int verticesPerPrimitive;
GraphicsDevice graphicsDevice; GraphicsDevice graphicsDevice;
bool began; bool began;
bool disposed; bool disposed;
bool changed;
Camera3D camera; Camera3D camera;
/// <summary> /// <summary>
@ -36,8 +40,8 @@ namespace RecrownedAthenaeum.Render
this.camera = camera ?? (Configuration.Camera2D); this.camera = camera ?? (Configuration.Camera2D);
basicEffect = new BasicEffect(this.graphicsDevice); basicEffect = new BasicEffect(this.graphicsDevice);
basicEffect.VertexColorEnabled = true; basicEffect.VertexColorEnabled = true;
vertices = new VertexPositionColor[verticesPerBatch+1]; vertices = new VertexPositionColor[verticesPerBatch];
maxVertices = verticesPerBatch; vertexBuffer = new VertexBuffer(this.graphicsDevice, typeof(VertexPositionColor), verticesPerBatch, BufferUsage.WriteOnly);
} }
/// <summary> /// <summary>
@ -56,11 +60,9 @@ namespace RecrownedAthenaeum.Render
case PrimitiveType.TriangleList: verticesPerPrimitive = 3; break; case PrimitiveType.TriangleList: verticesPerPrimitive = 3; break;
default: verticesPerPrimitive = 1; break; default: verticesPerPrimitive = 1; break;
} }
basicEffect.World = camera.worldMatrix; basicEffect.World = camera.worldMatrix;
basicEffect.View = camera.ViewMatrix; basicEffect.View = camera.ViewMatrix;
basicEffect.Projection = camera.projectionMatrix; basicEffect.Projection = camera.projectionMatrix;
basicEffect.CurrentTechnique.Passes[0].Apply();
began = true; began = true;
} }
@ -82,20 +84,24 @@ namespace RecrownedAthenaeum.Render
/// <param name="color">The color of that vertex.</param> /// <param name="color">The color of that vertex.</param>
public void AddVertex(Vector2 vertex, Color color) public void AddVertex(Vector2 vertex, Color color)
{ {
changed = true;
if (!began) throw new InvalidOperationException("Begin needs to be called before adding vertex."); if (!began) throw new InvalidOperationException("Begin needs to be called before adding vertex.");
if (disposed) throw new ObjectDisposedException(this.GetType().Name); if (disposed) throw new ObjectDisposedException(this.GetType().Name);
if (primitiveType != PrimitiveType.LineStrip && primitiveType != PrimitiveType.TriangleStrip) if (primitiveType != PrimitiveType.LineStrip && primitiveType != PrimitiveType.TriangleStrip)
{ {
if (bufferPosition + verticesPerPrimitive > maxVertices && (bufferPosition % maxVertices == 0)) if (bufferPosition + verticesPerPrimitive >= vertices.Length)
{ {
Flush(); if ((bufferPosition % vertices.Length == 0))
} {
else Flush();
{ }
throw new InvalidOperationException("Buffer size doesn't match with primitive type."); else
{
throw new InvalidOperationException("Buffer size doesn't match with primitive type.");
}
} }
} }
else if (bufferPosition + verticesPerPrimitive > maxVertices) else if (bufferPosition + verticesPerPrimitive > vertices.Length)
{ {
throw new InvalidOperationException("Buffer size isn't large enough."); throw new InvalidOperationException("Buffer size isn't large enough.");
} }
@ -109,10 +115,20 @@ namespace RecrownedAthenaeum.Render
/// </summary> /// </summary>
public void Flush() public void Flush()
{ {
if (changed)
{
changed = false;
vertexBuffer.SetData(vertices);
}
graphicsDevice.SetVertexBuffer(vertexBuffer);
if (!began) throw new InvalidOperationException("Begin needs to be called before flushing."); if (!began) throw new InvalidOperationException("Begin needs to be called before flushing.");
if (disposed) throw new ObjectDisposedException(this.GetType().Name); if (disposed) throw new ObjectDisposedException(this.GetType().Name);
if (bufferPosition == 0) return; if (bufferPosition == 0) return;
graphicsDevice.DrawUserPrimitives(primitiveType, vertices, 0, bufferPosition / verticesPerPrimitive); foreach (EffectPass effectPass in basicEffect.CurrentTechnique.Passes)
{
effectPass.Apply();
graphicsDevice.DrawPrimitives(primitiveType, 0, bufferPosition/verticesPerPrimitive);
}
bufferPosition = 0; bufferPosition = 0;
} }

View File

@ -64,12 +64,12 @@ namespace RecrownedAthenaeum.Render
Vector2[] corners = new Vector2[4]; Vector2[] corners = new Vector2[4];
double topRightAngleFromOrig = Math.Atan((double)height / width);
corners[0] = new Vector2(x, y); corners[0] = new Vector2(x, y);
corners[1] = new Vector2(x + (float)Math.Cos(rotation) * width, y + (float)Math.Sin(rotation) * width); 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));
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[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); corners[3] = new Vector2(x - (float)(Math.Cos((Math.PI / 2f) - rotation) * height), y + (float)(Math.Sin((Math.PI / 2f) - rotation) * height));
if (filled) if (filled)
{ {