Compare commits
No commits in common. "afa6ed4f4c2e5ac77cc819c92e8be28caa1406b4" and "95cc1648b2b7c13aa36c7b408219d3e223cc236f" have entirely different histories.
afa6ed4f4c
...
95cc1648b2
@ -1,4 +1,3 @@
|
|||||||
using System.Diagnostics.Contracts;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using OpenTK.Graphics.OpenGL;
|
using OpenTK.Graphics.OpenGL;
|
||||||
@ -225,243 +224,4 @@ namespace Dashboard.Drawing.OpenGL
|
|||||||
public int CmdIndex;
|
public int CmdIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A customizable immediate mode draw call queue, for the modern OpenGL user.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TCall">The call info type.</typeparam>
|
|
||||||
/// <typeparam name="TVertex">The vertex structure.</typeparam>
|
|
||||||
public abstract class DrawCallRecorder<TCall, TVertex> : IGLDisposable, IInitializer
|
|
||||||
where TVertex : unmanaged
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The vertex array for this queue.
|
|
||||||
/// </summary>
|
|
||||||
public int Vao { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The vertex buffer for this queue.
|
|
||||||
/// </summary>
|
|
||||||
public int Vbo { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Number of calls recorded in this queue.
|
|
||||||
/// </summary>
|
|
||||||
public int CallCount => Calls.Count;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The number of total vertices recorded.
|
|
||||||
/// </summary>
|
|
||||||
public int TotalVertices => Vertices.Count;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The latest draw call info.
|
|
||||||
/// </summary>
|
|
||||||
public ref TCall CurrentCall => ref _currentCall;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The latest vertex emitted.
|
|
||||||
/// </summary>
|
|
||||||
public ref TVertex CurrentVertex => ref _currentVertex;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// True if currently recording a draw call.
|
|
||||||
/// </summary>
|
|
||||||
public bool InCall => _primitiveMode != 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Size of one vertex.
|
|
||||||
/// </summary>
|
|
||||||
protected int VertexSize => Unsafe.SizeOf<TVertex>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The list of draw calls.
|
|
||||||
/// </summary>
|
|
||||||
protected List<DrawCall> Calls { get; } = new List<DrawCall>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The list of all vertices.
|
|
||||||
/// </summary>
|
|
||||||
protected List<TVertex> Vertices { get; } = new List<TVertex>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The value to write for the draw call info at the start of a call.
|
|
||||||
/// </summary>
|
|
||||||
[Pure] protected virtual TCall DefaultCall => default(TCall);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The value to write for last vertex at the start of a call.
|
|
||||||
/// </summary>
|
|
||||||
[Pure] protected virtual TVertex DefaultVertex => default;
|
|
||||||
|
|
||||||
private int _start = 0;
|
|
||||||
private int _count = 0;
|
|
||||||
private int _primitiveMode = 0;
|
|
||||||
private TCall _currentCall;
|
|
||||||
private TVertex _currentVertex;
|
|
||||||
|
|
||||||
protected DrawCallRecorder()
|
|
||||||
{
|
|
||||||
_currentCall = DefaultCall;
|
|
||||||
_currentVertex = DefaultVertex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Record a draw call directly.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The primitive type to use.</param>
|
|
||||||
/// <param name="callInfo">The call info structure to use</param>
|
|
||||||
/// <param name="vertices">The list of vertices to use.</param>
|
|
||||||
/// <exception cref="InvalidOperationException">You attempted to use this function during another draw call.</exception>
|
|
||||||
public void DrawArrays(PrimitiveType type, in TCall callInfo, ReadOnlySpan<TVertex> vertices)
|
|
||||||
{
|
|
||||||
if (InCall)
|
|
||||||
throw new InvalidOperationException("Cannot use draw arrays in the middle of an ongoing immediate-mode call.");
|
|
||||||
|
|
||||||
DrawCall call = new DrawCall()
|
|
||||||
{
|
|
||||||
Type = type,
|
|
||||||
Start = Vertices.Count,
|
|
||||||
Count = vertices.Length,
|
|
||||||
CallInfo = callInfo,
|
|
||||||
};
|
|
||||||
|
|
||||||
Vertices.AddRange(vertices);
|
|
||||||
Calls.Add(call);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Start a draw call.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The primitive type for the call.</param>
|
|
||||||
public void Begin(PrimitiveType type) => Begin(type, DefaultCall);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Start a draw call.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type">The primitive type for the call.</param>
|
|
||||||
/// <param name="callInfo">The call info.</param>
|
|
||||||
/// <exception cref="InvalidOperationException">You attempted to create a draw call within a draw call.</exception>
|
|
||||||
public void Begin(PrimitiveType type, TCall callInfo)
|
|
||||||
{
|
|
||||||
if (InCall)
|
|
||||||
throw new InvalidOperationException("Attempt to begin new draw call before finishing previous one.");
|
|
||||||
|
|
||||||
_primitiveMode = (int)type;
|
|
||||||
_start = Vertices.Count;
|
|
||||||
_count = 0;
|
|
||||||
CurrentCall = callInfo;
|
|
||||||
CurrentVertex = DefaultVertex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Emit the latest or modified vertex.
|
|
||||||
/// </summary>
|
|
||||||
public void Vertex()
|
|
||||||
{
|
|
||||||
Vertex(CurrentVertex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Emit a vertex.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="vertex">The vertex to emit.</param>
|
|
||||||
public void Vertex(in TVertex vertex)
|
|
||||||
{
|
|
||||||
Vertices.Add(CurrentVertex = vertex);
|
|
||||||
_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// End the current call.
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="InvalidOperationException">You tried to end a call that you didn't begin recording.</exception>
|
|
||||||
public void End()
|
|
||||||
{
|
|
||||||
if (!InCall)
|
|
||||||
throw new InvalidOperationException("Attempt to end draw call before starting one.");
|
|
||||||
|
|
||||||
Calls.Add(new DrawCall()
|
|
||||||
{
|
|
||||||
Start = _start,
|
|
||||||
Count = _count,
|
|
||||||
Type = (PrimitiveType)_primitiveMode,
|
|
||||||
CallInfo = CurrentCall,
|
|
||||||
});
|
|
||||||
|
|
||||||
_primitiveMode = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called by the execution engine before a draw call is executed.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="call">The call to prepare.</param>
|
|
||||||
protected abstract void PrepareCall(in TCall call);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the vertex format for the <see cref="Vao"/> and <see cref="Vbo"/> created by the recorder.
|
|
||||||
/// </summary>
|
|
||||||
protected abstract void SetVertexFormat();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Execute all the recorded draw calls.
|
|
||||||
/// </summary>
|
|
||||||
public void Execute()
|
|
||||||
{
|
|
||||||
GL.BindVertexArray(Vao);
|
|
||||||
GL.BindBuffer(BufferTarget.ArrayBuffer, Vbo);
|
|
||||||
|
|
||||||
ReadOnlySpan<TVertex> vertices = CollectionsMarshal.AsSpan(Vertices);
|
|
||||||
GL.BufferData(BufferTarget.ArrayBuffer, Vertices.Count * VertexSize, vertices, BufferUsage.DynamicDraw);
|
|
||||||
|
|
||||||
foreach (DrawCall call in Calls)
|
|
||||||
{
|
|
||||||
PrepareCall(call.CallInfo);
|
|
||||||
GL.DrawArrays(call.Type, call.Start, call.Count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clear the draw call queue.
|
|
||||||
/// </summary>
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
Vertices.Clear();
|
|
||||||
Calls.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose(bool safeExit)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsInitialized { get; private set; }
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
if (IsInitialized)
|
|
||||||
return;
|
|
||||||
IsInitialized = true;
|
|
||||||
|
|
||||||
Vao = GL.CreateVertexArray();
|
|
||||||
Vbo = GL.CreateBuffer();
|
|
||||||
|
|
||||||
GL.BindVertexArray(Vao);
|
|
||||||
GL.BindBuffer(BufferTarget.ArrayBuffer, Vbo);
|
|
||||||
|
|
||||||
SetVertexFormat();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected struct DrawCall
|
|
||||||
{
|
|
||||||
public PrimitiveType Type;
|
|
||||||
public int Start;
|
|
||||||
public int Count;
|
|
||||||
public TCall CallInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -23,20 +23,4 @@ namespace Dashboard.Drawing.OpenGL
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
event Action Disposed;
|
event Action Disposed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Extension interface for GL contexts in a DPI-aware environment.
|
|
||||||
/// </summary>
|
|
||||||
public interface IDpiAwareGLContext : IGLContext
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Dpi for current context.
|
|
||||||
/// </summary>
|
|
||||||
public float Dpi { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Scale for the current context. This will be used to scale drawn geometry.
|
|
||||||
/// </summary>
|
|
||||||
public float Scale { get; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,6 @@ namespace Dashboard.Drawing
|
|||||||
int sz = ToVlq(cmdIndex, cmd);
|
int sz = ToVlq(cmdIndex, cmd);
|
||||||
sz += ToVlq(param.Length, cmd[sz..]);
|
sz += ToVlq(param.Length, cmd[sz..]);
|
||||||
_commandStream.Write(cmd[..sz]);
|
_commandStream.Write(cmd[..sz]);
|
||||||
_commandStream.Write(param);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -7,11 +7,10 @@ namespace Dashboard.Drawing
|
|||||||
{
|
{
|
||||||
public class TextExtension : DrawExtension
|
public class TextExtension : DrawExtension
|
||||||
{
|
{
|
||||||
public TextCommand TextCommand { get; }
|
public TextCommand TextCommand { get; } = new TextCommand();
|
||||||
|
|
||||||
private TextExtension() : base("DB_Text", new [] { FontExtension.Instance, BrushExtension.Instance })
|
private TextExtension() : base("DB_Text", new [] { FontExtension.Instance, BrushExtension.Instance })
|
||||||
{
|
{
|
||||||
TextCommand = new TextCommand(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly TextExtension Instance = new TextExtension();
|
public static readonly TextExtension Instance = new TextExtension();
|
||||||
@ -20,17 +19,12 @@ namespace Dashboard.Drawing
|
|||||||
public class TextCommand : IDrawCommand<TextCommandArgs>
|
public class TextCommand : IDrawCommand<TextCommandArgs>
|
||||||
{
|
{
|
||||||
public string Name { get; } = "Text";
|
public string Name { get; } = "Text";
|
||||||
public IDrawExtension Extension { get; }
|
public IDrawExtension Extension { get; } = TextExtension.Instance;
|
||||||
public int Length { get; } = -1;
|
public int Length { get; } = -1;
|
||||||
|
|
||||||
public TextCommand(TextExtension ext)
|
|
||||||
{
|
|
||||||
Extension = ext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int WriteParams(DrawQueue queue, TextCommandArgs obj, Span<byte> param)
|
public int WriteParams(DrawQueue queue, TextCommandArgs obj, Span<byte> param)
|
||||||
{
|
{
|
||||||
int size = Unsafe.SizeOf<Header>() + obj.Text.Length * sizeof(char) + sizeof(char);
|
int size = Unsafe.SizeOf<Header>() + obj.Text.Length + sizeof(char);
|
||||||
|
|
||||||
if (param.Length < size)
|
if (param.Length < size)
|
||||||
return size;
|
return size;
|
||||||
@ -58,7 +52,7 @@ namespace Dashboard.Drawing
|
|||||||
Header header = MemoryMarshal.Cast<byte, Header>(param[0..Unsafe.SizeOf<Header>()])[0];
|
Header header = MemoryMarshal.Cast<byte, Header>(param[0..Unsafe.SizeOf<Header>()])[0];
|
||||||
ReadOnlySpan<char> text = MemoryMarshal.Cast<byte, char>(param[Unsafe.SizeOf<Header>()..]);
|
ReadOnlySpan<char> text = MemoryMarshal.Cast<byte, char>(param[Unsafe.SizeOf<Header>()..]);
|
||||||
|
|
||||||
if (header.BorderBrush != -1 && header.BorderRadius != 0)
|
if (header.BorderBrush == -1 || header.BorderRadius == 0)
|
||||||
{
|
{
|
||||||
return new TextCommandArgs(
|
return new TextCommandArgs(
|
||||||
(IFont)queue.Resources[header.Font],
|
(IFont)queue.Resources[header.Font],
|
||||||
|
Loading…
Reference in New Issue
Block a user