Change over draw call propagation in the vertex generator.

This commit is contained in:
H. Utku Maden 2022-08-18 13:58:03 +03:00
parent 7c0c6d9a75
commit a0473d9e83
2 changed files with 47 additions and 45 deletions

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
namespace Quik.VertexGenerator
{
@ -75,6 +76,8 @@ namespace Quik.VertexGenerator
/// </summary>
public int ElementCount => _elementBufferPointer;
public List<QuikDrawCall> DrawCalls { get; } = new List<QuikDrawCall>();
public float CurveGranularity { get; set; } = 0.2f;
public QuikContext Context { get; }
@ -168,76 +171,69 @@ namespace Quik.VertexGenerator
_vertexBufferPointer = 0;
_elementBufferPointer = 0;
DrawCalls.Clear();
}
private QuikDrawCall _call;
public QuikDrawCall CallTemplate;
public event VertexGeneratorCommandHandler HandleCommand;
protected virtual void OnHandleCommand(QuikVertexGenerator generator, QuikCommand command, ref QuikDrawCall? call)
protected virtual bool OnHandleCommand(QuikVertexGenerator generator, QuikCommand command)
{
HandleCommand?.Invoke(generator, command, ref call);
bool anyCalls = false;
HandleCommand?.Invoke(generator, command, ref anyCalls);
return anyCalls;
}
public QuikDrawCall? ConsumeCommand(QuikCommand command)
public void ConsumeCommand(QuikCommand command)
{
_call.Target = _renderStencilMask ? QuikRenderTarget.Stencil : QuikRenderTarget.Color;
QuikDrawCall call = _call;
CallTemplate.Target = _renderStencilMask ? QuikRenderTarget.Stencil : QuikRenderTarget.Color;
switch (command.Type)
{
case QuikCommandType.Mask:
_call.Bounds = ((QuikCommandMask)command).Bounds;
CallTemplate.Bounds = ((QuikCommandMask)command).Bounds;
break;
case QuikCommandType.StencilMaskClear:
_call.ClearStencil = true;
CallTemplate.ClearStencil = true;
break;
case QuikCommandType.StencilMaskBegin:
_renderStencilMask = true;
_call.Target = QuikRenderTarget.Stencil;
CallTemplate.Target = QuikRenderTarget.Stencil;
break;
case QuikCommandType.StencilMaskEnd:
_renderStencilMask = false;
_call.Target = QuikRenderTarget.Color;
CallTemplate.Target = QuikRenderTarget.Color;
break;
case QuikCommandType.Line:
RenderLine(ref call, command as QuikCommandLine);
RenderLine(command as QuikCommandLine);
goto exit_with_call;
case QuikCommandType.Lines:
RenderLine(ref call, command as QuikCommandLines);
RenderLine(command as QuikCommandLines);
goto exit_with_call;
case QuikCommandType.Bezier:
RenderBezier(ref _call, command as QuikCommandBezier);
RenderBezier(command as QuikCommandBezier);
goto exit_with_call;
case QuikCommandType.Rectangle:
RenderRectangles(ref call, command as QuikCommandRectangle);
RenderRectangles(command as QuikCommandRectangle);
goto exit_with_call;
case QuikCommandType.Rectangles:
RenderRectangles(ref call, command as QuikCommandRectangles);
RenderRectangles(command as QuikCommandRectangles);
goto exit_with_call;
default:
{
QuikDrawCall? subcall = null;
OnHandleCommand(this, command, ref subcall);
if (subcall.HasValue)
{
call = subcall.Value;
if (OnHandleCommand(this, command))
goto exit_with_call;
}
else
{
goto exit_without_call;
break;
}
}
}
exit_without_call:
return null;
return;
exit_with_call:
_call.ClearStencil = false;
return call;
CallTemplate.ClearStencil = false;
}
#region Lines & Beziers
@ -563,7 +559,7 @@ namespace Quik.VertexGenerator
/// </summary>
/// <param name="call">The draw call to generate.</param>
/// <param name="line">The line to draw.</param>
private void RenderLine(ref QuikDrawCall call, QuikCommandLine line)
private void RenderLine(QuikCommandLine line)
{
// Skip over stipple patterns for now.
QuikStrokeStyle style = line.Style ?? Context.DefaultStroke;
@ -582,8 +578,10 @@ namespace Quik.VertexGenerator
GenerateEndCap(baseVertex, line.Line.End, normal, style.Width, endCapResolution, (short) (startOffset + 2),(short)
(startOffset + 3));
QuikDrawCall call = CallTemplate;
call.Offset = (short) (startOffset * 2);
call.Count = (short) (_elementBufferPointer - startOffset);
DrawCalls.Add(call);
}
/// <summary>
@ -591,7 +589,7 @@ namespace Quik.VertexGenerator
/// </summary>
/// <param name="call">The draw call to generate.</param>
/// <param name="lines">The lines command.</param>
private void RenderLine(ref QuikDrawCall call, QuikCommandLines lines)
private void RenderLine(QuikCommandLines lines)
{
// Skip over stipple patterns for now.
QuikStrokeStyle style = lines.Style ?? Context.DefaultStroke;
@ -644,11 +642,13 @@ namespace Quik.VertexGenerator
lastStartIndex = lineStartIndex;
}
QuikDrawCall call = CallTemplate;
call.Offset = (short) (startOffset * 2);
call.Count = (short) (_elementBufferPointer - startOffset);
DrawCalls.Add(call);
}
private void RenderBezier(ref QuikDrawCall call, QuikCommandBezier bezier)
private void RenderBezier(QuikCommandBezier bezier)
{
QuikStrokeStyle style = bezier.Style ?? Context.DefaultStroke;
QuikVertex baseVertex = new QuikVertex() { Color = style.Color };
@ -715,8 +715,10 @@ namespace Quik.VertexGenerator
lastEndNegative = endNegative;
}
QuikDrawCall call = CallTemplate;
call.Offset = (short) (startOffset * 2);
call.Count = (short) (_elementBufferPointer - startOffset);
DrawCalls.Add(call);
}
private void GenerateBezierSegment(
@ -780,7 +782,7 @@ namespace Quik.VertexGenerator
#region Rectangles
private void RenderRectangles(ref QuikDrawCall call, QuikCommandRectangle rectangle)
private void RenderRectangles(QuikCommandRectangle rectangle)
{
QuikStrokeStyle stroke = rectangle.StrokeStyle ?? Context.DefaultStroke;
QuikFillStyle fill = rectangle.FillStyle ?? Context.DefaultFill;
@ -789,8 +791,10 @@ namespace Quik.VertexGenerator
GenerateRectangle(rectangle.Rectangle, stroke, fill, rectangle.CornerRadius);
QuikDrawCall call = CallTemplate;
call.Offset = (short) (start * 2);
call.Count = (short) (_elementBufferPointer - start);
DrawCalls.Add(call);
}
private void GenerateRectangle(QuikRectangle rectangle, QuikStrokeStyle stroke, QuikFillStyle fill, float cornerRadius)
@ -1370,7 +1374,7 @@ namespace Quik.VertexGenerator
);
}
private void RenderRectangles(ref QuikDrawCall call, QuikCommandRectangles rectangles)
private void RenderRectangles(QuikCommandRectangles rectangles)
{
QuikStrokeStyle stroke = rectangles.StrokeStyle ?? Context.DefaultStroke;
QuikFillStyle fill = rectangles.FillStyle ?? Context.DefaultFill;
@ -1382,14 +1386,16 @@ namespace Quik.VertexGenerator
GenerateRectangle(rectangles.Rectangles[i], stroke, fill, rectangles.CornerRadius);
}
QuikDrawCall call = CallTemplate;
call.Offset = (short) (start * 2);
call.Count = (short) (_elementBufferPointer - start);
DrawCalls.Add(call);
}
#endregion
}
public delegate void VertexGeneratorCommandHandler(QuikVertexGenerator generator, QuikCommand command, ref QuikDrawCall? call);
public delegate void VertexGeneratorCommandHandler(QuikVertexGenerator generator, QuikCommand command, ref bool anyCalls);
public enum QuikRenderTarget
{

@ -114,7 +114,6 @@ void main()
loc = GL.GetUniformLocation(sp, "matrix");
List<QuikDrawCall> calls = new List<QuikDrawCall>();
int i = 0;
QuikStrokeStyle strokeBorder = new QuikStrokeStyle()
@ -203,29 +202,26 @@ void main()
QuikCommand command;
while (context.Draw.Commands.TryDequeue(out command))
{
QuikDrawCall? call = gen.ConsumeCommand(command);
if (call.HasValue) calls.Add(call.Value);
gen.ConsumeCommand(command);
}
GL.BufferData(BufferTarget.ArrayBuffer, gen.VertexCount * QuikVertex.Stride, ref gen.VertexBuffer[0], BufferUsageHint.StreamDraw);
GL.BufferData(BufferTarget.ElementArrayBuffer, gen.ElementCount * 2, ref gen.ElementBuffer[0], BufferUsageHint.StreamDraw);
foreach (QuikDrawCall call in calls)
foreach (QuikDrawCall call in gen.DrawCalls)
{
GL.DrawElements(BeginMode.Triangles, call.Count, DrawElementsType.UnsignedShort, call.Offset);
}
int callCount = gen.DrawCalls.Count;
gen.Clear();
calls.Clear();
if (++i % 60 == 0)
{
Console.WriteLine("Vertex Usage: {0} ; Element Usage: {1}", gen.VertexUsage, gen.ElementUsage);
Console.WriteLine("Vertex Usage: {0} ; Element Usage: {1} Calls: {2}", gen.VertexUsage, gen.ElementUsage, callCount);
}
window.Context.SwapBuffers();
}
}
}