diff --git a/Dashboard.Drawing.OpenGL/CommandInfo.cs b/Dashboard.Drawing.OpenGL/CommandInfo.cs
deleted file mode 100644
index 2e14aa4..0000000
--- a/Dashboard.Drawing.OpenGL/CommandInfo.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-using System.Numerics;
-using System.Runtime.InteropServices;
-
-namespace Dashboard.Drawing.OpenGL
-{
- public enum SimpleDrawCommand : int
- {
- Point = 1,
- Line = 2,
- Rect = 3,
-
- ///
- /// Make sure your custom commands have values higher than this if you plan on using the default command
- /// buffer.
- ///
- CustomCommandStart = 4096
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 64)]
- public struct CommandInfo
- {
- [FieldOffset(0)]
- public SimpleDrawCommand Type;
-
- [FieldOffset(4)]
- public int Flags;
-
- [FieldOffset(8)]
- public float Arg0;
- [FieldOffset(12)]
- public float Arg1;
-
- [FieldOffset(16)]
- public int FgGradientIndex;
- [FieldOffset(20)]
- public int FgGradientCount;
- [FieldOffset(24)]
- public int BgGradientIndex;
- [FieldOffset(28)]
- public int BgGradientCount;
-
- [FieldOffset(32)]
- public Vector4 FgColor;
-
- [FieldOffset(48)]
- public Vector4 BgColor;
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/ContextExecutor.cs b/Dashboard.Drawing.OpenGL/ContextExecutor.cs
deleted file mode 100644
index 5ecb66b..0000000
--- a/Dashboard.Drawing.OpenGL/ContextExecutor.cs
+++ /dev/null
@@ -1,184 +0,0 @@
-using System.Drawing;
-using Dashboard.Drawing.OpenGL.Executors;
-using Dashboard.OpenGL;
-using OpenTK.Mathematics;
-
-namespace Dashboard.Drawing.OpenGL
-{
- public interface ICommandExecutor
- {
- IEnumerable Extensions { get; }
- IContextExecutor Executor { get; }
-
- void SetContextExecutor(IContextExecutor executor);
-
- void BeginFrame();
-
- void BeginDraw();
-
- void EndDraw();
-
- void EndFrame();
-
- void ProcessCommand(ICommandFrame frame);
- }
-
- public interface IContextExecutor : IInitializer, IGLDisposable
- {
- GLEngine Engine { get; }
- IGLContext Context { get; }
- ContextResourcePool ResourcePool { get; }
- TransformStack TransformStack { get; }
- }
-
- public class ContextExecutor : IContextExecutor
- {
- public GLEngine Engine { get; }
- public IGLContext Context { get; }
- public ContextResourcePool ResourcePool { get; }
- public TransformStack TransformStack { get; } = new TransformStack();
- protected bool IsDisposed { get; private set; } = false;
- public bool IsInitialized { get; private set; } = false;
-
- private readonly List _executorsList = new List();
-
- private readonly Dictionary _executorsMap = new Dictionary();
-
- public ContextExecutor(GLEngine engine, IGLContext context)
- {
- Engine = engine;
- Context = context;
-
- ResourcePool = Engine.ResourcePoolManager.Get(context);
- ResourcePool.IncrementReference();
-
- AddExecutor(new BaseCommandExecutor());
- AddExecutor(new TextCommandExecutor());
- }
-
- ~ContextExecutor()
- {
- DisposeInvoker(true, false);
- }
-
- public void AddExecutor(ICommandExecutor executor, bool overwrite = false)
- {
- if (IsInitialized)
- throw new Exception("This context executor is already initialized. Cannot add new command executors.");
-
- IInitializer? initializer = executor as IInitializer;
-
- if (initializer?.IsInitialized == true)
- throw new InvalidOperationException("This command executor has already been initialized, cannot add here.");
-
- if (!overwrite)
- {
- foreach (string extension in executor.Extensions)
- {
- if (_executorsMap.ContainsKey(extension))
- throw new InvalidOperationException("An executor already handles this extension.");
- }
- }
-
- foreach (string extension in executor.Extensions)
- {
- _executorsMap[extension] = executor;
- }
- _executorsList.Add(executor);
-
- executor.SetContextExecutor(this);
- }
-
- public void Initialize()
- {
- if (IsInitialized)
- return;
- IsInitialized = true;
-
- foreach (ICommandExecutor executor in _executorsList)
- {
- if (executor is IInitializer initializer)
- initializer.Initialize();
- }
- }
-
- public virtual void BeginFrame()
- {
- foreach (ICommandExecutor executor in _executorsList)
- executor.BeginFrame();
- }
-
- protected virtual void BeginDraw()
- {
- foreach (ICommandExecutor executor in _executorsList)
- executor.BeginDraw();
- }
-
- protected virtual void EndDraw()
- {
- foreach (ICommandExecutor executor in _executorsList)
- executor.EndDraw();
- }
-
- public virtual void EndFrame()
- {
- ResourcePool.Collector.Dispose();
- TransformStack.Clear();
-
- foreach (ICommandExecutor executor in _executorsList)
- executor.EndFrame();
- }
-
- public void Draw(DrawQueue drawqueue) => Draw(drawqueue, new RectangleF(new PointF(0f,0f), Context.FramebufferSize));
-
- public virtual void Draw(DrawQueue drawQueue, RectangleF bounds, float scale = 1.0f)
- {
- BeginDraw();
-
- if (scale != 1.0f)
- TransformStack.Push(Matrix4.CreateScale(scale, scale, 1));
-
- foreach (ICommandFrame frame in drawQueue)
- {
- if (_executorsMap.TryGetValue(frame.Command.Extension.Name, out ICommandExecutor? executor))
- executor.ProcessCommand(frame);
- }
-
- EndDraw();
- }
-
- private void DisposeInvoker(bool safeExit, bool disposing)
- {
- if (!IsDisposed)
- return;
-
- IsDisposed = true;
-
- if (disposing)
- GC.SuppressFinalize(this);
-
- Dispose(safeExit, disposing);
- }
-
- protected virtual void Dispose(bool safeExit, bool disposing)
- {
- if (disposing)
- {
- foreach (ICommandExecutor executor in _executorsList)
- {
- if (executor is IGLDisposable glDisposable)
- glDisposable.Dispose(safeExit);
- else if (executor is IDisposable disposable)
- disposable.Dispose();
- }
-
- if (ResourcePool.DecrementReference())
- Dispose();
- }
- }
-
- public void Dispose() => DisposeInvoker(true, true);
-
- public void Dispose(bool safeExit) => DisposeInvoker(safeExit, true);
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/ContextResourcePool.cs b/Dashboard.Drawing.OpenGL/ContextResourcePool.cs
deleted file mode 100644
index e408f2a..0000000
--- a/Dashboard.Drawing.OpenGL/ContextResourcePool.cs
+++ /dev/null
@@ -1,133 +0,0 @@
-using Dashboard.OpenGL;
-
-namespace Dashboard.Drawing.OpenGL
-{
- public class ContextResourcePoolManager
- {
- private readonly Dictionary _unique = new Dictionary();
- private readonly Dictionary _shared = new Dictionary();
-
- public ContextResourcePool Get(IGLContext context)
- {
- if (context.ContextGroup == -1)
- {
- if (!_unique.TryGetValue(context, out ContextResourcePool? pool))
- {
- pool = new ContextResourcePool(this, context);
- _unique.Add(context, pool);
- }
-
- return pool;
- }
- else
- {
- if (!_shared.TryGetValue(context.ContextGroup, out ContextResourcePool? pool))
- {
- pool = new ContextResourcePool(this, context.ContextGroup);
- _shared.Add(context.ContextGroup, pool);
- }
-
- return pool;
- }
- }
-
- internal void Disposed(ContextResourcePool pool)
- {
- // TODO:
- }
- }
-
- public class ContextResourcePool : IGLDisposable, IArc
- {
- private int _references = 0;
- private bool _isDisposed = false;
- private readonly Dictionary _managers = new Dictionary();
-
- public ContextResourcePoolManager Manager { get; }
- public IGLContext? Context { get; private set; } = null;
- public int ContextGroup { get; private set; } = -1;
- public int References => _references;
- public ContextCollector Collector { get; } = new ContextCollector();
-
- internal ContextResourcePool(ContextResourcePoolManager manager, int contextGroup)
- {
- Manager = manager;
- ContextGroup = contextGroup;
- }
-
- internal ContextResourcePool(ContextResourcePoolManager manager, IGLContext context)
- {
- Manager = manager;
- Context = context;
- }
-
- public T GetResourceManager(bool init = true) where T : IResourceManager, new()
- {
- int index = ManagerAtom.Atom;
-
- if (!_managers.TryGetValue(index, out IResourceManager? resourceClass))
- {
- _managers[index] = resourceClass = new T();
- }
-
- if (init && resourceClass is IInitializer initializer)
- {
- initializer.Initialize();
- }
-
- return (T)resourceClass;
- }
-
- ~ContextResourcePool()
- {
- Dispose(true, false);
- }
-
- public void Dispose() => Dispose(true, false);
-
- public void Dispose(bool safeExit) => Dispose(safeExit, true);
-
- private void Dispose(bool safeExit, bool disposing)
- {
- if (_isDisposed)
- return;
- _isDisposed = true;
-
- Manager.Disposed(this);
-
- if (disposing)
- {
- foreach ((int _, IResourceManager manager) in _managers)
- {
- if (manager is IGLDisposable glDisposable)
- glDisposable.Dispose(safeExit);
- else if (manager is IDisposable disposable)
- disposable.Dispose();
- }
- GC.SuppressFinalize(this);
- }
- }
-
- public void IncrementReference()
- {
- Interlocked.Increment(ref _references);
- }
-
- public bool DecrementReference()
- {
- return Interlocked.Decrement(ref _references) == 0;
- }
-
-
- private class ManagerAtom
- {
- private static int _counter = -1;
-
- protected static int Acquire() => Interlocked.Increment(ref _counter);
- }
- private class ManagerAtom : ManagerAtom where T : IResourceManager
- {
- public static int Atom { get; } = Acquire();
- }
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/Dashboard.Drawing.OpenGL.csproj b/Dashboard.Drawing.OpenGL/Dashboard.Drawing.OpenGL.csproj
deleted file mode 100644
index 824110c..0000000
--- a/Dashboard.Drawing.OpenGL/Dashboard.Drawing.OpenGL.csproj
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
- net10.0
- enable
- enable
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Dashboard.Drawing.OpenGL/DrawCallRecorder.cs b/Dashboard.Drawing.OpenGL/DrawCallRecorder.cs
deleted file mode 100644
index 10f410d..0000000
--- a/Dashboard.Drawing.OpenGL/DrawCallRecorder.cs
+++ /dev/null
@@ -1,468 +0,0 @@
-using System.Diagnostics.Contracts;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Dashboard.OpenGL;
-using OpenTK.Graphics.OpenGL;
-using OpenTK.Mathematics;
-using Vector2 = System.Numerics.Vector2;
-using Vector3 = System.Numerics.Vector3;
-
-namespace Dashboard.Drawing.OpenGL
-{
- public class DrawCallRecorder : IGLDisposable, IInitializer
- {
- private int _vao = 0;
- private int _vbo = 0;
- private readonly List _vertices = new List();
- private readonly List _calls = new List();
-
- private int _start = 0;
- private int _count = 0;
- private int _primitives = 0;
- private Vector3 _charCoords;
- private int _cmdIndex;
- private int _texture0, _texture1, _texture2, _texture3;
- private TextureTarget _target0, _target1, _target2, _target3;
- private Matrix4 _transforms = Matrix4.Identity;
-
- public int CommandModulus = 64;
- public int CommandBuffer = 0;
- public int CommandSize = 64;
-
- private int CommandByteSize => CommandModulus * CommandSize;
-
- public int TransformsLocation { get; set; }
-
- public void Transforms(in Matrix4 transforms)
- {
- _transforms = transforms;
- }
-
- public void Begin(PrimitiveType type)
- {
- if (_primitives != 0)
- throw new InvalidOperationException("Attempt to begin new draw call before finishing previous one.");
-
- _primitives = (int)type;
- _start = _vertices.Count;
- _count = 0;
- }
-
- public void TexCoords2(Vector2 texCoords)
- {
- _charCoords = new Vector3(texCoords, 0);
- }
-
- public void CharCoords(Vector3 charCoords)
- {
- _charCoords = charCoords;
- }
-
- public void CommandIndex(int index)
- {
- _cmdIndex = index;
- }
-
- public void Vertex3(Vector3 vertex)
- {
- _vertices.Add(new DrawVertex()
- {
- Position = vertex,
- CharCoords = _charCoords,
- CmdIndex = _cmdIndex % CommandModulus,
- });
- _count++;
- }
-
- public void End()
- {
- if (_primitives == 0)
- throw new InvalidOperationException("Attempt to end draw call before starting one.");
-
- _calls.Add(
- new DrawCall()
- {
- Type = (PrimitiveType)_primitives,
- Start = _start,
- Count = _count,
- CmdIndex = _cmdIndex,
- Target0 = _target0,
- Target1 = _target1,
- Target2 = _target2,
- Target3 = _target3,
- Texture0 = _texture0,
- Texture1 = _texture1,
- Texture2 = _texture2,
- Texture3 = _texture3,
- Transforms = _transforms,
- });
-
- _primitives = 0;
- }
-
- public void BindTexture(TextureTarget target, int texture) => BindTexture(target, 0, texture);
-
- public void BindTexture(TextureTarget target, int unit, int texture)
- {
- switch (unit)
- {
- case 0:
- _texture0 = 0;
- _target0 = target;
- break;
- case 1:
- _texture1 = 0;
- _target1 = target;
- break;
- case 2:
- _texture2 = 0;
- _target2 = target;
- break;
- case 3:
- _texture3 = 0;
- _target3 = target;
- break;
- default:
- throw new ArgumentOutOfRangeException(nameof(unit), "I did not write support for more than 4 textures.");
- }
- }
-
- public void DrawArrays(PrimitiveType type, int first, int count)
- {
- throw new NotImplementedException();
- }
-
- public void Execute()
- {
- GL.BindVertexArray(_vao);
- GL.BindBuffer(BufferTarget.ArrayBuffer, _vbo);
-
- ReadOnlySpan vertices = CollectionsMarshal.AsSpan(_vertices);
- GL.BufferData(BufferTarget.ArrayBuffer, _vertices.Count * Unsafe.SizeOf(), vertices, BufferUsage.DynamicDraw);
-
- foreach (DrawCall call in _calls)
- {
- GL.BindBufferRange(BufferTarget.UniformBuffer, 0, CommandBuffer, call.CmdIndex / CommandModulus * CommandByteSize, CommandByteSize);
- GL.ActiveTexture(TextureUnit.Texture0);
- GL.BindTexture(call.Target0, call.Texture0);
- GL.ActiveTexture(TextureUnit.Texture1);
- GL.BindTexture(call.Target1, call.Texture1);
- GL.ActiveTexture(TextureUnit.Texture2);
- GL.BindTexture(call.Target2, call.Texture2);
- GL.ActiveTexture(TextureUnit.Texture3);
- GL.BindTexture(call.Target3, call.Texture3);
-
- Matrix4 transforms = call.Transforms;
- GL.UniformMatrix4f(TransformsLocation, 1, true, ref transforms);
- GL.DrawArrays(call.Type, call.Start, call.Count);
- }
- }
-
- 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);
-
- GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 32, 0);
- GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 32, 16);
- GL.VertexAttribIPointer(2, 1, VertexAttribIType.Int, 32, 28);
- GL.EnableVertexAttribArray(0);
- GL.EnableVertexAttribArray(1);
- GL.EnableVertexAttribArray(2);
- }
-
- private struct DrawCall
- {
- public PrimitiveType Type;
- public int Start;
- public int Count;
- public int CmdIndex;
-
- public int Texture0;
- public int Texture1;
- public int Texture2;
- public int Texture3;
-
- public TextureTarget Target0;
- public TextureTarget Target1;
- public TextureTarget Target2;
- public TextureTarget Target3;
-
- public Matrix4 Transforms;
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 32)]
- private struct DrawVertex
- {
- [FieldOffset(0)]
- public Vector3 Position;
- [FieldOffset(16)]
- public Vector3 CharCoords;
- [FieldOffset(28)]
- public int CmdIndex;
- }
- }
-
- ///
- /// A customizable immediate mode draw call queue, for the modern OpenGL user.
- ///
- /// The call info type.
- /// The vertex structure.
- public abstract class DrawCallRecorder : IGLDisposable, IInitializer
- where TVertex : unmanaged
- {
- ///
- /// The vertex array for this queue.
- ///
- public int Vao { get; private set; }
-
- ///
- /// The vertex buffer for this queue.
- ///
- public int Vbo { get; private set; }
-
- ///
- /// Number of calls recorded in this queue.
- ///
- public int CallCount => Calls.Count;
-
- ///
- /// The number of total vertices recorded.
- ///
- public int TotalVertices => Vertices.Count;
-
- ///
- /// The latest draw call info.
- ///
- public ref TCall CurrentCall => ref _currentCall;
-
- ///
- /// The latest vertex emitted.
- ///
- public ref TVertex CurrentVertex => ref _currentVertex;
-
- ///
- /// True if currently recording a draw call.
- ///
- public bool InCall => _primitiveMode != 0;
-
- ///
- /// Size of one vertex.
- ///
- protected int VertexSize => Unsafe.SizeOf();
-
- ///
- /// The list of draw calls.
- ///
- protected List Calls { get; } = new List();
-
- ///
- /// The list of all vertices.
- ///
- protected List Vertices { get; } = new List();
-
- ///
- /// The value to write for the draw call info at the start of a call.
- ///
- [Pure] protected virtual TCall DefaultCall => default(TCall);
-
- ///
- /// The value to write for last vertex at the start of a call.
- ///
- [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;
- }
-
- ///
- /// Record a draw call directly.
- ///
- /// The primitive type to use.
- /// The call info structure to use
- /// The list of vertices to use.
- /// You attempted to use this function during another draw call.
- public void DrawArrays(PrimitiveType type, in TCall callInfo, ReadOnlySpan 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);
- }
-
- ///
- /// Start a draw call.
- ///
- /// The primitive type for the call.
- public void Begin(PrimitiveType type) => Begin(type, DefaultCall);
-
- ///
- /// Start a draw call.
- ///
- /// The primitive type for the call.
- /// The call info.
- /// You attempted to create a draw call within a draw call.
- 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;
- }
-
- ///
- /// Emit the latest or modified vertex.
- ///
- public void Vertex()
- {
- Vertex(CurrentVertex);
- }
-
- ///
- /// Emit a vertex.
- ///
- /// The vertex to emit.
- public void Vertex(in TVertex vertex)
- {
- Vertices.Add(CurrentVertex = vertex);
- _count++;
- }
-
- ///
- /// End the current call.
- ///
- /// You tried to end a call that you didn't begin recording.
- 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;
- }
-
- ///
- /// Called by the execution engine before a draw call is executed.
- ///
- /// The call to prepare.
- protected abstract void PrepareCall(in TCall call);
-
- ///
- /// Set the vertex format for the and created by the recorder.
- ///
- protected abstract void SetVertexFormat();
-
- ///
- /// Execute all the recorded draw calls.
- ///
- public void Execute()
- {
- GL.BindVertexArray(Vao);
- GL.BindBuffer(BufferTarget.ArrayBuffer, Vbo);
-
- ReadOnlySpan 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);
- }
- }
-
- ///
- /// Clear the draw call queue.
- ///
- 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;
- }
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/Executors/BaseCommandExecutor.cs b/Dashboard.Drawing.OpenGL/Executors/BaseCommandExecutor.cs
deleted file mode 100644
index dd54eb1..0000000
--- a/Dashboard.Drawing.OpenGL/Executors/BaseCommandExecutor.cs
+++ /dev/null
@@ -1,333 +0,0 @@
-using System.Drawing;
-using OpenTK.Graphics.OpenGL;
-using System.Numerics;
-using Dashboard.OpenGL;
-using OTK = OpenTK.Mathematics;
-
-namespace Dashboard.Drawing.OpenGL.Executors
-{
- public class BaseCommandExecutor : IInitializer, ICommandExecutor
- {
- private int _program = 0;
- private readonly MappableBumpAllocator _commands = new MappableBumpAllocator();
- private readonly DrawCallRecorder _calls = new DrawCallRecorder();
-
- public bool IsInitialized { get; private set; }
- public IEnumerable Extensions { get; } = new[] { "DB_base" };
- public IContextExecutor Executor { get; private set; } = null!;
-
- public void Initialize()
- {
- if (IsInitialized) return;
-
- if (Executor == null)
- throw new Exception("Executor has not been set.");
-
- IsInitialized = true;
-
- LoadShaders();
- }
-
- public void SetContextExecutor(IContextExecutor executor)
- {
- Executor = executor;
- }
-
- public void BeginFrame()
- {
- }
-
- public void BeginDraw()
- {
- _commands.Initialize();
- _calls.Initialize();
-
- Size size = Executor.Context.FramebufferSize;
-
- Executor.TransformStack.Push(OTK.Matrix4.CreateOrthographicOffCenter(
- 0,
- size.Width,
- size.Height,
- 0,
- 1,
- -1));
-
- GL.Viewport(0, 0, size.Width, size.Height);
- }
-
- public void EndDraw()
- {
- _commands.Unmap();
- GL.UseProgram(_program);
- _calls.CommandBuffer = _commands.Handle;
- _calls.Execute();
- }
-
- public void EndFrame()
- {
- _commands.Clear();
- _calls.Clear();
- }
-
- public void ProcessCommand(ICommandFrame frame)
- {
- switch (frame.Command.Name)
- {
- case "Point":
- DrawBasePoint(frame);
- break;
- case "Line":
- DrawBaseLine(frame);
- break;
- case "RectF":
- case "RectS":
- case "RectFS":
- DrawRect(frame);
- break;
- }
- }
-
- private void DrawBasePoint(ICommandFrame frame)
- {
- ref CommandInfo info = ref _commands.Take(out int index);
-
- PointCommandArgs args = frame.GetParameter();
-
- info = new CommandInfo()
- {
- Type = SimpleDrawCommand.Point,
- Arg0 = args.Size,
- };
-
- SetCommandCommonBrush(ref info, args.Brush, args.Brush);
-
- _calls.Transforms(Executor.TransformStack.Top);
- _calls.Begin(PrimitiveType.Triangles);
- _calls.CommandIndex(index);
- DrawPoint(args.Position, args.Depth, args.Size);
- _calls.End();
- }
-
- private void DrawPoint(Vector2 position, float depth, float diameter)
- {
- // Draw a point as a isocles triangle.
- const float adjust = 1.1f;
- const float cos30 = 0.8660254038f;
- Vector2 top = adjust * new Vector2(0, -cos30);
- Vector2 left = adjust * new Vector2(-cos30, 0.5f);
- Vector2 right = adjust * new Vector2(cos30, 0.5f);
-
- _calls.TexCoords2(top);
- _calls.Vertex3(new Vector3(position + top * diameter, depth));
- _calls.TexCoords2(left);
- _calls.Vertex3(new Vector3(position + left * diameter, depth));
- _calls.TexCoords2(right);
- _calls.Vertex3(new Vector3(position + right * diameter, depth));
- }
-
- private void DrawBaseLine(ICommandFrame frame)
- {
- ref CommandInfo info = ref _commands.Take(out int index);
-
- LineCommandArgs args = frame.GetParameter();
-
- info = new CommandInfo()
- {
- Type = SimpleDrawCommand.Line,
- Arg0 = 0.5f * args.Size / (args.End - args.Start).Length(),
- };
-
- SetCommandCommonBrush(ref info, args.Brush, args.Brush);
-
- _calls.Transforms(Executor.TransformStack.Top);
- _calls.Begin(PrimitiveType.Triangles);
-
- _calls.CommandIndex(index);
-
- DrawLine(args.Start, args.End, args.Depth, args.Size);
-
- _calls.End();
- }
-
- private void DrawLine(Vector2 start, Vector2 end, float depth, float width)
- {
- float radius = 0.5f * width;
- Vector2 segment = end - start;
- float length = segment.Length();
- float ratio = radius / length;
- Vector2 n = ratio * segment;
- Vector2 t = new Vector2(-n.Y, n.X);
-
- Vector2 t00 = new Vector2(-ratio, -ratio);
- Vector2 t10 = new Vector2(1+ratio, -ratio);
- Vector2 t01 = new Vector2(-ratio, +ratio);
- Vector2 t11 = new Vector2(1+ratio, +ratio);
-
- Vector3 x00 = new Vector3(start - n - t, depth);
- Vector3 x10 = new Vector3(end + n - t, depth);
- Vector3 x01 = new Vector3(start - n + t, depth);
- Vector3 x11 = new Vector3(end + n + t, depth);
-
- _calls.TexCoords2(t00);
- _calls.Vertex3(x00);
- _calls.TexCoords2(t01);
- _calls.Vertex3(x01);
- _calls.TexCoords2(t11);
- _calls.Vertex3(x11);
-
- _calls.TexCoords2(t00);
- _calls.Vertex3(x00);
- _calls.TexCoords2(t11);
- _calls.Vertex3(x11);
- _calls.TexCoords2(t10);
- _calls.Vertex3(x10);
- }
-
- private void DrawRect(ICommandFrame frame)
- {
- ref CommandInfo info = ref _commands.Take(out int index);
-
- RectCommandArgs args = frame.GetParameter();
-
- Vector2 size = Vector2.Abs(args.End - args.Start);
- float aspect = size.X / size.Y;
- float border = args.StrikeSize;
- float normRad = args.StrikeSize / size.Y;
- float wideRad = aspect * normRad;
-
- int flags = 0;
-
- switch (frame.Command.Name)
- {
- case "RectF":
- flags |= 1;
- break;
- case "RectS":
- flags |= 2;
- break;
- case "RectFS":
- flags |= 3;
- break;
- }
-
- switch (args.BorderKind)
- {
- case BorderKind.Inset:
- flags |= 2 << 2;
- break;
- case BorderKind.Outset:
- flags |= 1 << 2;
- break;
- }
-
- info = new CommandInfo()
- {
- Type = SimpleDrawCommand.Rect,
- Flags = flags,
- Arg0 = aspect,
- Arg1 = normRad,
- };
-
- SetCommandCommonBrush(ref info, args.FillBrush, args.StrikeBrush);
-
- _calls.Transforms(Executor.TransformStack.Top);
- _calls.Begin(PrimitiveType.Triangles);
-
- _calls.CommandIndex(index);
-
- Vector2 t00 = new Vector2(-wideRad, -normRad);
- Vector2 t10 = new Vector2(1+wideRad, -normRad);
- Vector2 t01 = new Vector2(-wideRad, 1+normRad);
- Vector2 t11 = new Vector2(1+wideRad, 1+normRad);
-
- Vector3 x00 = new Vector3(args.Start.X - border, args.Start.Y - border, args.Depth);
- Vector3 x10 = new Vector3(args.End.X + border, args.Start.Y - border, args.Depth);
- Vector3 x01 = new Vector3(args.Start.X - border, args.End.Y + border, args.Depth);
- Vector3 x11 = new Vector3(args.End.X + border, args.End.Y + border, args.Depth);
-
- _calls.TexCoords2(t00);
- _calls.Vertex3(x00);
- _calls.TexCoords2(t01);
- _calls.Vertex3(x01);
- _calls.TexCoords2(t11);
- _calls.Vertex3(x11);
-
- _calls.TexCoords2(t00);
- _calls.Vertex3(x00);
- _calls.TexCoords2(t11);
- _calls.Vertex3(x11);
- _calls.TexCoords2(t10);
- _calls.Vertex3(x10);
-
- _calls.End();
- }
-
- protected void SetCommandCommonBrush(ref CommandInfo info, IBrush? fill, IBrush? border)
- {
- switch (fill?.Kind.Name)
- {
- case "DB_Brush_solid":
- SolidBrush solid = (SolidBrush)fill;
- Vector4 color = new Vector4(solid.Color.R/255f, solid.Color.G/255f, solid.Color.B/255f, solid.Color.A/255f);
- info.FgColor = color;
- break;
- case "DB_Brush_gradient":
- GradientBrush gradient = (GradientBrush)fill;
- GradientUniformBuffer gradients = Executor.ResourcePool.GetResourceManager();
- gradients.Initialize();
- GradientUniformBuffer.Entry entry = gradients.InternGradient(gradient.Gradient);
- info.FgGradientIndex = entry.Offset;
- info.FgGradientCount = entry.Count;
- break;
- case null:
- // Craete a magenta brush for this.
- info.FgColor = new Vector4(1, 0, 1, 1);
- break;
- }
-
- switch (border?.Kind.Name)
- {
- case "DB_Brush_solid":
- SolidBrush solid = (SolidBrush)border;
- Vector4 color = new Vector4(solid.Color.R/255f, solid.Color.G/255f, solid.Color.B/255f, solid.Color.A/255f);
- info.BgColor = color;
- break;
- case "DB_Brush_gradient":
- GradientBrush gradient = (GradientBrush)border;
- GradientUniformBuffer gradients = Executor.ResourcePool.GetResourceManager();
- gradients.Initialize();
- GradientUniformBuffer.Entry entry = gradients.InternGradient(gradient.Gradient);
- info.BgGradientIndex = entry.Offset;
- info.BgGradientCount = entry.Count;
- break;
- case null:
- // Craete a magenta brush for this.
- info.BgColor = new Vector4(1, 0, 1, 1);
- break;
- }
- }
-
- private void LoadShaders()
- {
- using Stream vsource = FetchEmbeddedResource("Dashboard.Drawing.OpenGL.Executors.simple.vert");
- using Stream fsource = FetchEmbeddedResource("Dashboard.Drawing.OpenGL.Executors.simple.frag");
- int vs = ShaderUtil.CompileShader(ShaderType.VertexShader, vsource);
- int fs = ShaderUtil.CompileShader(ShaderType.FragmentShader, fsource);
- _program = ShaderUtil.LinkProgram(vs, fs, new []
- {
- "a_v3Position",
- "a_v2TexCoords",
- "a_iCmdIndex",
- });
- GL.DeleteShader(vs);
- GL.DeleteShader(fs);
-
- GL.UniformBlockBinding(_program, GL.GetUniformBlockIndex(_program, "CommandBlock"), 0);
- }
-
- private static Stream FetchEmbeddedResource(string name)
- {
- return typeof(BaseCommandExecutor).Assembly.GetManifestResourceStream(name)!;
- }
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/Executors/TextCommandExecutor.cs b/Dashboard.Drawing.OpenGL/Executors/TextCommandExecutor.cs
deleted file mode 100644
index bcd94d1..0000000
--- a/Dashboard.Drawing.OpenGL/Executors/TextCommandExecutor.cs
+++ /dev/null
@@ -1,243 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-using BlurgText;
-using Dashboard.OpenGL;
-using OpenTK.Graphics.OpenGL;
-using OpenTK.Mathematics;
-
-namespace Dashboard.Drawing.OpenGL.Executors
-{
- public class TextCommandExecutor : ICommandExecutor, IInitializer
- {
- public IEnumerable Extensions { get; } = new[] { "DB_Text" };
- public IContextExecutor Executor { get; private set; }
- // private BlurgEngine Engine => Executor.ResourcePool.GetResourceManager();
- public bool IsInitialized { get; private set; }
-
- private DrawCallRecorder _recorder;
- private int _program = 0;
- private int _transformsLocation = -1;
- private int _atlasLocation = -1;
- private int _borderWidthLocation = -1;
- private int _borderColorLocation = -1;
- private int _fillColorLocation = -1;
-
- public TextCommandExecutor()
- {
- Executor = null!;
- _recorder = new DrawCallRecorder(this);
- }
-
- public void Initialize()
- {
- if (IsInitialized)
- return;
- IsInitialized = true;
-
- Assembly self = typeof(TextCommandExecutor).Assembly;
-
- using Stream vsource = self.GetManifestResourceStream("Dashboard.Drawing.OpenGL.Executors.text.vert")!;
- using Stream fsource = self.GetManifestResourceStream("Dashboard.Drawing.OpenGL.Executors.text.frag")!;
- int vs = ShaderUtil.CompileShader(ShaderType.VertexShader, vsource);
- int fs = ShaderUtil.CompileShader(ShaderType.FragmentShader, fsource);
- _program = ShaderUtil.LinkProgram(vs, fs, new []
- {
- "a_v3Position",
- "a_v2TexCoords",
- });
- GL.DeleteShader(vs);
- GL.DeleteShader(fs);
-
- _transformsLocation = GL.GetUniformLocation(_program, "m4Transforms");
- _atlasLocation = GL.GetUniformLocation(_program, "txAtlas");
- _borderWidthLocation = GL.GetUniformLocation(_program, "fBorderWidth");
- _borderColorLocation = GL.GetUniformLocation(_program, "v4BorderColor");
- _fillColorLocation = GL.GetUniformLocation(_program, "v4FillColor");
-
- _recorder.Initialize();
- }
-
- public void SetContextExecutor(IContextExecutor executor)
- {
- Executor = executor;
- }
-
- public void BeginFrame()
- {
- }
-
- public void BeginDraw()
- {
- _recorder.Clear();
- }
-
- public void EndDraw()
- {
- GL.UseProgram(_program);
- GL.Enable(EnableCap.Blend);
- GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
- _recorder.Execute();
- GL.Disable(EnableCap.Blend);
- }
-
- public void EndFrame()
- {
- }
-
- public void ProcessCommand(ICommandFrame frame)
- {
- switch (frame.Command.Name)
- {
- case "Text":
- DrawText(frame);
- break;
- }
- }
-
- private void DrawText(ICommandFrame frame)
- {
- TextCommandArgs args = frame.GetParameter();
- // DbBlurgFont font = Engine.InternFont(args.Font);
-
- BlurgColor color;
- switch (args.TextBrush)
- {
- case SolidBrush solid:
- color = new BlurgColor()
- {
- R = solid.Color.R,
- G = solid.Color.G,
- B = solid.Color.B,
- A = solid.Color.A,
- };
- break;
- default:
- color = new BlurgColor() { R = 255, G = 0, B = 255, A = 255 };
- break;
- }
-
- //BlurgResult? result = Engine.Blurg.BuildString(font.Font, font.Size, color, args.Text);
-
- // if (result == null)
- // return;
- //
- // Vector3 position = new Vector3(args.Position.X, args.Position.Y, args.Position.Z);
- // ExecuteBlurgResult(result, position);
- //
- // result.Dispose();
- }
-
- private void ExecuteBlurgResult(BlurgResult result, Vector3 position)
- {
- Matrix4 transforms = Executor.TransformStack.Top;
-
- for (int i = 0; i < result.Count; i++)
- {
- BlurgRect rect = result[i];
-
- int texture = (int)rect.UserData;
- Vector4 color = new Vector4(rect.Color.R / 255f, rect.Color.G / 255f, rect.Color.B / 255f,
- rect.Color.A / 255f);
-
- if (i == 0)
- {
- _recorder.Begin(PrimitiveType.Triangles, new Call()
- {
- Texture = texture,
- FillColor = color,
- Transforms = transforms,
- });
- }
- else if (
- _recorder.CurrentCall.Texture != texture ||
- _recorder.CurrentCall.FillColor != color)
- {
- _recorder.End();
- Call call = new Call()
- {
- Texture = texture,
- FillColor = color,
- Transforms = transforms,
- };
- _recorder.Begin(PrimitiveType.Triangles, call);
- }
-
- Vector3 p00 = new Vector3(rect.X, rect.Y, 0) + position;
- Vector3 p10 = p00 + new Vector3(rect.Width, 0, 0);
- Vector3 p11 = p00 + new Vector3(rect.Width, rect.Height, 0);
- Vector3 p01 = p00 + new Vector3(0, rect.Height, 0);
-
- Vector2 uv00 = new Vector2(rect.U0, rect.V0);
- Vector2 uv10 = new Vector2(rect.U1, rect.V0);
- Vector2 uv11 = new Vector2(rect.U1, rect.V1);
- Vector2 uv01 = new Vector2(rect.U0, rect.V1);
-
- _recorder.Vertex(p00, uv00);
- _recorder.Vertex(p10, uv10);
- _recorder.Vertex(p11, uv11);
-
- _recorder.Vertex(p00, uv00);
- _recorder.Vertex(p11, uv11);
- _recorder.Vertex(p01, uv01);
- }
- _recorder.End();
- }
-
- private struct Call
- {
- public Matrix4 Transforms = Matrix4.Identity;
- public int Texture = 0;
- public float BorderWidth = 0f;
- public Vector4 FillColor = Vector4.One;
- public Vector4 BorderColor = new Vector4(0,0,0,1);
-
- public Call()
- {
- }
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 8 * sizeof(float))]
- private struct Vertex
- {
- [FieldOffset(0)]
- public Vector3 Position;
- [FieldOffset(4 * sizeof(float))]
- public Vector2 TexCoords;
- }
-
- private class DrawCallRecorder : DrawCallRecorder
- {
- private TextCommandExecutor Executor { get; }
-
- public DrawCallRecorder(TextCommandExecutor executor)
- {
- Executor = executor;
- }
-
- public void Vertex(Vector3 position, Vector2 texCoords)
- {
- Vertex(new Vertex(){Position = position, TexCoords = texCoords});
- }
-
- protected override void PrepareCall(in Call call)
- {
- Matrix4 transforms = call.Transforms;
- GL.UniformMatrix4f(Executor._transformsLocation, 1, true, ref transforms);
- GL.Uniform1f(Executor._borderWidthLocation, call.BorderWidth);
- GL.Uniform4f(Executor._borderColorLocation, 1, in call.BorderColor);
- GL.Uniform4f(Executor._fillColorLocation, 1, in call.FillColor);
- GL.Uniform1i(Executor._atlasLocation, 0);
- GL.ActiveTexture(TextureUnit.Texture0);
- GL.BindTexture(TextureTarget.Texture2d, call.Texture);
- }
-
- protected override void SetVertexFormat()
- {
- GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, VertexSize, 0);
- GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, VertexSize, 4*sizeof(float));
- GL.EnableVertexAttribArray(0);
- GL.EnableVertexAttribArray(1);
- }
- }
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/Executors/gradient.glsl b/Dashboard.Drawing.OpenGL/Executors/gradient.glsl
deleted file mode 100644
index 3d16e53..0000000
--- a/Dashboard.Drawing.OpenGL/Executors/gradient.glsl
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _GRADIENT_GLSL_
-#define _GRADIENT_GLSL_
-
-#define DB_GRADIENT_MAX 16
-
-struct Gradient_t {
- float fPosition;
- float pad0;
- float pad1;
- float pad2;
- vec4 v4Color;
-};
-
-uniform GradientBlock
-{
- Gradient_t vstGradientStops[DB_GRADIENT_MAX];
-};
-
-vec4 getGradientColor(float position, int index, int count)
-{
- position = clamp(position, 0, 1);
-
- int i0 = 0;
- float p0 = vstGradientStops[index + i0].fPosition;
-
- int i1 = count - 1;
- float p1 = vstGradientStops[index + i1].fPosition;
-
- for (int i = 0; i < count; i++)
- {
- float px = vstGradientStops[index + i].fPosition;
-
- if (px > p0 && px <= position)
- {
- p0 = px;
- i0 = i;
- }
-
- if (px < p1 && px >= position)
- {
- p1 = px;
- i1 = i;
- }
- }
-
- vec4 c0 = vstGradientStops[index + i0].v4Color;
- vec4 c1 = vstGradientStops[index + i1].v4Color;
-
- float l = p1 - p0;
- float w = (l > 0) ? (position - p0) / (p1 - p0) : 0;
-
- return mix(c0, c1, w);
-}
-
-#endif
diff --git a/Dashboard.Drawing.OpenGL/Executors/simple.frag b/Dashboard.Drawing.OpenGL/Executors/simple.frag
deleted file mode 100644
index 9271218..0000000
--- a/Dashboard.Drawing.OpenGL/Executors/simple.frag
+++ /dev/null
@@ -1,224 +0,0 @@
-#version 140
-
-#define DB_GRADIENT_MAX 16
-#define DB_COMMAND_MAX 64
-
-#define CMD_POINT 1
-#define CMD_LINE 2
-#define CMD_RECT 3
-
-#define STRIKE_CENTER 0
-#define STRIKE_OUTSET 1
-#define STRIKE_INSET 2
-
-in vec3 v_v3Position;
-in vec2 v_v2TexCoords;
-flat in int v_iCmdIndex;
-
-out vec4 f_Color;
-
-uniform sampler2D txForeground;
-uniform sampler2D txBackground;
-
-struct Gradient_t {
- float fPosition;
- float pad0;
- float pad1;
- float pad2;
- vec4 v4Color;
-};
-
-uniform GradientBlock
-{
- Gradient_t vstGradientStops[DB_GRADIENT_MAX];
-};
-
-vec4 getGradientColor(float position, int index, int count)
-{
- position = clamp(position, 0, 1);
-
- int i0 = 0;
- float p0 = vstGradientStops[index + i0].fPosition;
-
- int i1 = count - 1;
- float p1 = vstGradientStops[index + i1].fPosition;
-
- for (int i = 0; i < count; i++)
- {
- float px = vstGradientStops[index + i].fPosition;
-
- if (px > p0 && px <= position)
- {
- p0 = px;
- i0 = i;
- }
-
- if (px < p1 && px >= position)
- {
- p1 = px;
- i1 = i;
- }
- }
-
- vec4 c0 = vstGradientStops[index + i0].v4Color;
- vec4 c1 = vstGradientStops[index + i1].v4Color;
-
- float l = p1 - p0;
- float w = (l > 0) ? (position - p0) / (p1 - p0) : 0;
-
- return mix(c0, c1, w);
-}
-
-struct CommandInfo_t {
- int iCommand;
- int iFlags;
- float fArg0;
- float fArg1;
-
- int iFgGradientIndex;
- int iFgGradientCount;
- int iBgGradientIndex;
- int iBgGradientCount;
-
- vec4 v4FgColor;
- vec4 v4BgColor;
-};
-
-uniform CommandBlock
-{
- CommandInfo_t vstCommandInfo[DB_COMMAND_MAX];
-};
-
-CommandInfo_t getCommandInfo()
-{
- return vstCommandInfo[v_iCmdIndex];
-}
-
-vec4 fgColor()
-{
- return getCommandInfo().v4FgColor;
-}
-
-vec4 bgColor()
-{
- return getCommandInfo().v4BgColor;
-}
-
-void Point(void)
-{
- vec4 fg = fgColor();
-
- if (dot(v_v2TexCoords, v_v2TexCoords) <= 0.25)
- f_Color = fg;
- else
- discard;
-}
-
-#define LINE_NORMALIZED_RADIUS(cmd) cmd.fArg0
-void Line(void)
-{
- vec4 fg = fgColor();
- CommandInfo_t cmd = getCommandInfo();
-
- float t = clamp(v_v2TexCoords.x, 0, 1);
- vec2 dv = v_v2TexCoords - vec2(t, 0);
- float d = dot(dv, dv);
-
- float lim = LINE_NORMALIZED_RADIUS(cmd);
- lim *= lim;
-
- if (d <= lim)
- f_Color = fg;
- else
- discard;
-}
-
-#define RECT_ASPECT_RATIO(cmd) (cmd.fArg0)
-#define RECT_BORDER_WIDTH(cmd) (cmd.fArg1)
-#define RECT_FILL(cmd) ((cmd.iFlags & (1 << 0)) != 0)
-#define RECT_BORDER(cmd) ((cmd.iFlags & (1 << 1)) != 0)
-#define RECT_STRIKE_MASK 3
-#define RECT_STRIKE_SHIFT 2
-#define RECT_STRIKE_KIND(cmd) ((cmd.iFlags & RECT_STRIKE_MASK) >> RECT_STRIKE_SHIFT)
-void Rect(void)
-{
- vec4 fg = fgColor();
- vec4 bg = bgColor();
-
- CommandInfo_t cmd = getCommandInfo();
- float aspect = RECT_ASPECT_RATIO(cmd);
- float border = RECT_BORDER_WIDTH(cmd);
- int strikeKind = RECT_STRIKE_KIND(cmd);
-
- vec2 p = abs(2*v_v2TexCoords - vec2(1));
- p.x = p.x/aspect;
-
- float m0;
- float m1;
- if (!RECT_BORDER(cmd))
- {
- m0 = 1;
- m1 = 1;
- }
- else if (strikeKind == STRIKE_OUTSET)
- {
- m0 = 1;
- m1 = border;
- }
- else if (strikeKind == STRIKE_INSET)
- {
- m0 = 1-border;
- m1 = 1;
- }
- else // strikeKind == STRIKE_CENTER
- {
- float h = 0.5 * border;
- m0 = 1-border;
- m1 = 1+border;
- }
-
- if (p.x > m1*aspect || p.y > m1)
- {
- discard;
- }
-
- if (RECT_FILL(cmd))
- {
- if (p.x <= 1 && p.y <= 1)
- {
- f_Color = fg;
- }
- }
-
- if (RECT_BORDER(cmd))
- {
- float x = clamp(p.x, aspect*m0, aspect*m1);
- float y = clamp(p.y, m0, m1);
-
- if (p.x == x || p.y == y)
- {
- f_Color = bg;
- }
- }
-}
-
-void main(void)
-{
- switch (getCommandInfo().iCommand)
- {
- case CMD_POINT:
- Point();
- break;
- case CMD_LINE:
- Line();
- break;
- case CMD_RECT:
- Rect();
- break;
-
- default:
- // Unimplemented value.
- f_Color = vec4(1, 0, 1, 1);
- break;
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/Executors/simple.vert b/Dashboard.Drawing.OpenGL/Executors/simple.vert
deleted file mode 100644
index 89248f0..0000000
--- a/Dashboard.Drawing.OpenGL/Executors/simple.vert
+++ /dev/null
@@ -1,21 +0,0 @@
-#version 140
-
-in vec3 a_v3Position;
-in vec2 a_v2TexCoords;
-in int a_iCmdIndex;
-
-out vec3 v_v3Position;
-out vec2 v_v2TexCoords;
-flat out int v_iCmdIndex;
-
-uniform mat4 m4Transforms;
-
-void main(void)
-{
- vec4 position = vec4(a_v3Position, 1) * m4Transforms;
- gl_Position = position;
- v_v3Position = position.xyz/position.w;
-
- v_v2TexCoords = a_v2TexCoords;
- v_iCmdIndex = a_iCmdIndex;
-}
diff --git a/Dashboard.Drawing.OpenGL/Executors/text.frag b/Dashboard.Drawing.OpenGL/Executors/text.frag
deleted file mode 100644
index 9914b22..0000000
--- a/Dashboard.Drawing.OpenGL/Executors/text.frag
+++ /dev/null
@@ -1,21 +0,0 @@
-#version 140
-
-in vec3 v_v3Position;
-in vec2 v_v2TexCoords;
-
-out vec4 f_Color;
-
-uniform sampler2D txAtlas;
-uniform float fBorderWidth;
-uniform vec4 v4BorderColor;
-uniform vec4 v4FillColor;
-
-void main() {
- // For now just honor the fill color
-
- vec4 color = texture(txAtlas, v_v2TexCoords) * v4FillColor;
-
- if (color.a <= 0.1)
- discard;
- f_Color = color;
-}
diff --git a/Dashboard.Drawing.OpenGL/Executors/text.vert b/Dashboard.Drawing.OpenGL/Executors/text.vert
deleted file mode 100644
index 27ae926..0000000
--- a/Dashboard.Drawing.OpenGL/Executors/text.vert
+++ /dev/null
@@ -1,18 +0,0 @@
-#version 140
-
-in vec3 a_v3Position;
-in vec2 a_v2TexCoords;
-
-out vec3 v_v3Position;
-out vec2 v_v2TexCoords;
-
-uniform mat4 m4Transforms;
-
-void main(void)
-{
- vec4 position = vec4(a_v3Position, 1) * m4Transforms;
- gl_Position = position;
- v_v3Position = position.xyz/position.w;
-
- v_v2TexCoords = a_v2TexCoords;
-}
diff --git a/Dashboard.Drawing.OpenGL/GLEngine.cs b/Dashboard.Drawing.OpenGL/GLEngine.cs
deleted file mode 100644
index 99641eb..0000000
--- a/Dashboard.Drawing.OpenGL/GLEngine.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// using Dashboard.Drawing.OpenGL.Text;
-using Dashboard.OpenGL;
-using OpenTK;
-using OpenTK.Graphics;
-
-namespace Dashboard.Drawing.OpenGL
-{
- public class GLEngine
- {
- private readonly Dictionary _executors = new Dictionary();
-
- public bool IsInitialized { get; private set; } = false;
- public ContextResourcePoolManager ResourcePoolManager { get; private set; } = new ContextResourcePoolManager();
-
- public void Initialize(IBindingsContext? bindingsContext = null)
- {
- if (IsInitialized)
- return;
- IsInitialized = true;
-
- if (bindingsContext != null)
- GLLoader.LoadBindings(bindingsContext);
-
- // Typesetter.Backend = BlurgEngine.Global;
- }
-
- public ContextExecutor GetExecutor(IGLContext glContext)
- {
- if (!_executors.TryGetValue(glContext, out ContextExecutor? executor))
- {
- executor = new ContextExecutor(this, glContext);
- executor.Initialize();
-
- _executors.Add(glContext, executor);
- }
-
- return executor;
- }
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/GradientUniformBuffer.cs b/Dashboard.Drawing.OpenGL/GradientUniformBuffer.cs
deleted file mode 100644
index 71cb866..0000000
--- a/Dashboard.Drawing.OpenGL/GradientUniformBuffer.cs
+++ /dev/null
@@ -1,90 +0,0 @@
-using System.Runtime.InteropServices;
-using Dashboard.OpenGL;
-using OpenTK.Mathematics;
-
-namespace Dashboard.Drawing.OpenGL
-{
- public class GradientUniformBuffer : IInitializer, IGLDisposable, IResourceManager
- {
- private bool _isDisposed;
- private int _top = 0;
- private readonly MappableBuffer _buffer = new MappableBuffer();
- private readonly Dictionary _entries = new Dictionary();
-
- public bool IsInitialized { get; private set; } = false;
-
- public void Initialize()
- {
- if (IsInitialized)
- return;
-
- IsInitialized = true;
-
- _buffer.Initialize();
- }
-
- public Entry InternGradient(Gradient gradient)
- {
- if (_entries.TryGetValue(gradient, out Entry entry))
- return entry;
-
- int count = gradient.Count;
- int offset = _top;
- _top += count;
-
- _buffer.EnsureCapacity(_top);
- _buffer.Map();
- Span span = _buffer.AsSpan()[offset.._top];
-
- for (int i = 0; i < count; i++)
- {
- GradientStop stop = gradient[i];
- span[i] = new GradientUniformStruct()
- {
- Position = stop.Position,
- Color = new Vector4(
- stop.Color.R / 255f,
- stop.Color.G / 255f,
- stop.Color.B / 255f,
- stop.Color.A / 255f),
- };
- }
-
- entry = new Entry(offset, count);
- _entries.Add(gradient, entry);
-
- return entry;
- }
-
- public void Clear()
- {
- _entries.Clear();
- _top = 0;
- }
-
- public record struct Entry(int Offset, int Count);
-
- public void Dispose() => Dispose(true);
-
- public void Dispose(bool safeExit)
- {
- if (_isDisposed)
- return;
- _isDisposed = true;
-
- _buffer.Dispose(safeExit);
- }
-
- string IResourceManager.Name { get; } = nameof(GradientUniformBuffer);
- }
-
- [StructLayout(LayoutKind.Explicit, Size = 8 * sizeof(float))]
- public struct GradientUniformStruct
- {
- [FieldOffset(0 * sizeof(float))]
- public float Position;
-
- [FieldOffset(4 * sizeof(float))]
- public Vector4 Color;
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/IArc.cs b/Dashboard.Drawing.OpenGL/IArc.cs
deleted file mode 100644
index 1bfc99c..0000000
--- a/Dashboard.Drawing.OpenGL/IArc.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-namespace Dashboard.Drawing.OpenGL
-{
- ///
- /// Atomic reference counter.
- ///
- public interface IArc : IDisposable
- {
- ///
- /// The number of references to this.
- ///
- int References { get; }
-
- ///
- /// Increment the number of references.
- ///
- void IncrementReference();
-
- ///
- /// Decrement the number of references.
- ///
- /// True if this was the last reference.
- bool DecrementReference();
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/IInitializer.cs b/Dashboard.Drawing.OpenGL/IInitializer.cs
deleted file mode 100644
index c6d5702..0000000
--- a/Dashboard.Drawing.OpenGL/IInitializer.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Dashboard.Drawing.OpenGL
-{
- public interface IInitializer
- {
- bool IsInitialized { get; }
-
- void Initialize();
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/IResourceManager.cs b/Dashboard.Drawing.OpenGL/IResourceManager.cs
deleted file mode 100644
index fe73b58..0000000
--- a/Dashboard.Drawing.OpenGL/IResourceManager.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Dashboard.Drawing.OpenGL
-{
- public interface IResourceManager
- {
- public string Name { get; }
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/MappableBuffer.cs b/Dashboard.Drawing.OpenGL/MappableBuffer.cs
deleted file mode 100644
index 2df1595..0000000
--- a/Dashboard.Drawing.OpenGL/MappableBuffer.cs
+++ /dev/null
@@ -1,168 +0,0 @@
-using System.Numerics;
-using System.Runtime.CompilerServices;
-using Dashboard.OpenGL;
-using OpenTK.Graphics.OpenGL;
-
-namespace Dashboard.Drawing.OpenGL
-{
- public class MappableBuffer : IInitializer, IGLDisposable where T : struct
- {
- public int Handle { get; private set; } = 0;
- public int Capacity { get; set; } = BASE_CAPACITY;
- public IntPtr Pointer { get; private set; } = IntPtr.Zero;
-
- public bool IsInitialized => Handle != 0;
-
- private bool _isDisposed = false;
- private const int BASE_CAPACITY = 4 << 10; // 4 KiB
- private const int MAX_INCREMENT = 4 << 20; // 4 MiB
-
- ~MappableBuffer()
- {
- Dispose(true, false);
- }
-
- public void Initialize()
- {
- if (IsInitialized)
- return;
-
- Handle = GL.GenBuffer();
- GL.BindBuffer(BufferTarget.ArrayBuffer, Handle);
- GL.BufferData(BufferTarget.ArrayBuffer, Capacity, IntPtr.Zero, BufferUsage.DynamicDraw);
- }
-
- public void EnsureCapacity(int count)
- {
- if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count));
-
- if (Capacity > count)
- return;
-
- SetSize(count, false);
- }
-
- public void SetSize(int count, bool clear = false)
- {
- AssertInitialized();
- Unmap();
-
- int sz = Unsafe.SizeOf();
- int oldsize = Capacity * sz;
- int request = count * sz;
- int newsize;
-
- if (request < BASE_CAPACITY)
- request = BASE_CAPACITY;
-
- if (request > MAX_INCREMENT)
- {
- newsize = ((request + MAX_INCREMENT - 1) / MAX_INCREMENT) * MAX_INCREMENT;
- }
- else
- {
- newsize = checked((int)BitOperations.RoundUpToPowerOf2((ulong)request));
- }
-
- int dest = GL.GenBuffer();
-
- if (clear)
- {
- GL.BindBuffer(BufferTarget.ArrayBuffer, dest);
- GL.BufferData(BufferTarget.ArrayBuffer, newsize, IntPtr.Zero, BufferUsage.DynamicDraw);
- }
- else
- {
- GL.BindBuffer(BufferTarget.CopyWriteBuffer, dest);
- GL.BindBuffer(BufferTarget.CopyReadBuffer, Handle);
-
- GL.BufferData(BufferTarget.CopyWriteBuffer, newsize, IntPtr.Zero, BufferUsage.DynamicDraw);
- GL.CopyBufferSubData(CopyBufferSubDataTarget.CopyReadBuffer, CopyBufferSubDataTarget.CopyWriteBuffer, 0, 0, Math.Min(newsize, oldsize));
- }
-
- GL.DeleteBuffer(Handle);
- Handle = dest;
- Capacity = newsize / Unsafe.SizeOf();
- }
-
- public unsafe void Map()
- {
- if (Pointer != IntPtr.Zero)
- return;
-
- AssertInitialized();
-
- GL.BindBuffer(BufferTarget.ArrayBuffer, Handle);
- Pointer = (IntPtr)GL.MapBuffer(BufferTarget.ArrayBuffer, BufferAccess.ReadWrite);
- }
-
- public void Unmap()
- {
- if (Pointer == IntPtr.Zero)
- return;
-
- AssertInitialized();
-
- GL.BindBuffer(BufferTarget.ArrayBuffer, Handle);
- GL.UnmapBuffer(BufferTarget.ArrayBuffer);
- Pointer = IntPtr.Zero;
- }
-
- public unsafe Span AsSpan()
- {
- if (Pointer == IntPtr.Zero)
- throw new InvalidOperationException("The buffer is not currently mapped.");
-
- AssertInitialized();
-
- return new Span(Pointer.ToPointer(), Capacity);
- }
-
- private void AssertInitialized()
- {
- if (Handle == 0)
- throw new InvalidOperationException("The buffer is not initialized.");
- }
-
- private void Dispose(bool safeExit, bool disposing)
- {
- if (_isDisposed)
- return;
- _isDisposed = true;
-
- if (disposing)
- GC.SuppressFinalize(this);
-
- if (safeExit)
- ContextCollector.Global.DeleteBufffer(Handle);
- }
-
- public void Dispose() => Dispose(true, true);
- public void Dispose(bool safeExit) => Dispose(safeExit, true);
- }
-
- public class MappableBumpAllocator : MappableBuffer where T : struct
- {
- private int _top = 0;
- private int _previousTop = 0;
-
- public ref T Take(out int index)
- {
- index = _top;
- EnsureCapacity(++_top);
- Map();
-
- return ref AsSpan()[index];
- }
-
- public ref T Take() => ref Take(out _);
-
- public void Clear()
- {
- SetSize(0, true);
- _previousTop = _top;
- _top = 0;
- }
- }
-}
diff --git a/Dashboard.Drawing.OpenGL/TransformStack.cs b/Dashboard.Drawing.OpenGL/TransformStack.cs
deleted file mode 100644
index 000fe44..0000000
--- a/Dashboard.Drawing.OpenGL/TransformStack.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using OpenTK.Mathematics;
-
-namespace Dashboard.Drawing.OpenGL
-{
- ///
- /// The current stack of transformations.
- ///
- public class TransformStack
- {
- private Matrix4 _top = Matrix4.Identity;
- private readonly Stack _stack = new Stack();
-
- ///
- /// The top-most transform matrix.
- ///
- public ref readonly Matrix4 Top => ref _top;
-
- ///
- /// The number of matrices in the stack.
- ///
- public int Count => _stack.Count;
-
- ///
- /// Push a transform.
- ///
- /// The transform to push.
- public void Push(in Matrix4 transform)
- {
- _stack.Push(_top);
- _top = transform * _top;
- }
-
- ///
- /// Pop a transform.
- ///
- public void Pop()
- {
- if (!_stack.TryPop(out _top))
- _top = Matrix4.Identity;
- }
-
- ///
- /// Clear the stack of transformations.
- ///
- public void Clear()
- {
- _stack.Clear();
- _top = Matrix4.Identity;
- }
- }
-}
diff --git a/Dashboard.Drawing/Brush.cs b/Dashboard.Drawing/Brush.cs
deleted file mode 100644
index 6d5de2f..0000000
--- a/Dashboard.Drawing/Brush.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using System;
-using System.Drawing;
-
-namespace Dashboard.Drawing
-{
- public class BrushExtension : DrawExtension
- {
- private BrushExtension() : base("DB_Brush") { }
-
- public static readonly BrushExtension Instance = new BrushExtension();
- }
-
- public interface IBrush : IDrawResource
- {
- }
-
- public readonly struct SolidBrush(Color color) : IBrush
- {
- public IDrawExtension Kind { get; } = SolidBrushExtension.Instance;
- public Color Color { get; } = color;
-
- public override int GetHashCode()
- {
- return HashCode.Combine(Kind, Color);
- }
- }
-
- public readonly struct GradientBrush(Gradient gradient) : IBrush
- {
- public IDrawExtension Kind { get; } = GradientBrushExtension.Instance;
- public Gradient Gradient { get; } = gradient;
-
- public override int GetHashCode()
- {
- return HashCode.Combine(Kind, Gradient);
- }
- }
-
- public class SolidBrushExtension : DrawExtension
- {
- private SolidBrushExtension() : base("DB_Brush_solid", new[] { BrushExtension.Instance }) { }
-
- public static readonly SolidBrushExtension Instance = new SolidBrushExtension();
- }
-
- public class GradientBrushExtension : DrawExtension
- {
- private GradientBrushExtension() : base("DB_Brush_gradient", new[] { BrushExtension.Instance }) { }
-
- public static readonly GradientBrushExtension Instance = new GradientBrushExtension();
- }
-}
diff --git a/Dashboard.Drawing/Dashboard.Drawing.csproj b/Dashboard.Drawing/Dashboard.Drawing.csproj
deleted file mode 100644
index 20f3f39..0000000
--- a/Dashboard.Drawing/Dashboard.Drawing.csproj
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- net10.0
- disable
- enable
-
-
-
-
-
-
-
diff --git a/Dashboard.Drawing/DbBaseCommands.cs b/Dashboard.Drawing/DbBaseCommands.cs
deleted file mode 100644
index 937640a..0000000
--- a/Dashboard.Drawing/DbBaseCommands.cs
+++ /dev/null
@@ -1,292 +0,0 @@
-using System;
-using System.Collections;
-using System.Diagnostics.CodeAnalysis;
-using System.Numerics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace Dashboard.Drawing
-{
- public class DbBaseCommands : DrawExtension
- {
- public DrawCommand DrawPoint { get; }
- public DrawCommand DrawLine { get; }
- public RectCommand DrawRectF { get; }
- public RectCommand DrawRectS { get; }
- public RectCommand DrawRectFS { get; }
-
- private DbBaseCommands() : base("DB_base",
- new[]
- {
- BrushExtension.Instance,
- })
- {
- AddCommand(DrawPoint = new DrawCommand("Point", this, PointCommandArgs.CommandSize));
- AddCommand(DrawLine = new DrawCommand("Line", this, LineCommandArgs.CommandSize));
- AddCommand(DrawRectF = new RectCommand(this, RectCommand.Mode.Fill));
- AddCommand(DrawRectS = new RectCommand(this, RectCommand.Mode.Strike));
- AddCommand(DrawRectFS = new RectCommand(this, RectCommand.Mode.FillStrike));
- }
-
- public static readonly DbBaseCommands Instance = new DbBaseCommands();
- }
-
- public struct PointCommandArgs : IParameterSerializer
- {
- public Vector2 Position { get; private set; }
- public float Depth { get; private set; }
- public float Size { get; private set; }
- public IBrush? Brush { get; private set; }
-
- public PointCommandArgs(Vector2 position, float depth, float size, IBrush brush)
- {
- Position = position;
- Depth = depth;
- Brush = brush;
- Size = size;
- }
-
- public int Serialize(DrawQueue queue, Span bytes)
- {
- if (bytes.Length < CommandSize)
- return CommandSize;
-
- Span value = stackalloc Value[]
- {
- new Value(Position, Depth, Size, queue.RequireResource(Brush!))
- };
-
- MemoryMarshal.AsBytes(value).CopyTo(bytes);
- return CommandSize;
- }
-
- [MemberNotNull(nameof(Brush))]
- public void Deserialize(DrawQueue queue, ReadOnlySpan bytes)
- {
- if (bytes.Length < CommandSize)
- throw new Exception("Not enough bytes");
-
- Value value = MemoryMarshal.AsRef(bytes);
-
- Position = value.Position;
- Depth = value.Depth;
- Size = value.Size;
- Brush = (IBrush)queue.Resources[value.BrushIndex];
- }
-
- private record struct Value(Vector2 Position, float Depth, float Size, int BrushIndex);
-
- public static readonly int CommandSize = Unsafe.SizeOf();
- }
-
- public struct LineCommandArgs : IParameterSerializer
- {
- public Vector2 Start { get; private set; }
- public Vector2 End { get; private set; }
- public float Depth { get; private set; }
- public float Size { get; private set; }
- public IBrush? Brush { get; private set; }
-
- public LineCommandArgs(Vector2 start, Vector2 end, float depth, float size, IBrush brush)
- {
- Start = start;
- End = end;
- Depth = depth;
- Size = size;
- Brush = brush;
- }
-
- public int Serialize(DrawQueue queue, Span bytes)
- {
- if (bytes.Length < CommandSize)
- return CommandSize;
-
- Span value = stackalloc Value[]
- {
- new Value(Start, End, Depth, Size, queue.RequireResource(Brush!))
- };
-
- MemoryMarshal.AsBytes(value).CopyTo(bytes);
- return CommandSize;
- }
-
- public void Deserialize(DrawQueue queue, ReadOnlySpan bytes)
- {
- if (bytes.Length < CommandSize)
- throw new Exception("Not enough bytes");
-
- Value value = MemoryMarshal.AsRef(bytes);
-
- Start = value.Start;
- End = value.End;
- Depth = value.Depth;
- Size = value.Size;
- Brush = (IBrush)queue.Resources[value.BrushIndex];
- }
-
- private record struct Value(Vector2 Start, Vector2 End, float Depth, float Size, int BrushIndex);
-
- public static readonly int CommandSize = Unsafe.SizeOf();
- }
-
-
-
- public class RectCommand : IDrawCommand
- {
- private readonly Mode _mode;
- public string Name { get; }
- public IDrawExtension Extension { get; }
- public int Length { get; }
-
- public RectCommand(IDrawExtension extension, Mode mode)
- {
- Extension = extension;
- _mode = mode;
-
- switch (mode)
- {
- case Mode.Fill:
- Name = "RectF";
- Length = Unsafe.SizeOf();
- break;
- case Mode.Strike:
- Name = "RectS";
- Length = Unsafe.SizeOf();
- break;
- default:
- Name = "RectFS";
- Length = Unsafe.SizeOf();
- break;
- }
- }
-
- object? IDrawCommand.GetParams(DrawQueue queue, ReadOnlySpan param)
- {
- return GetParams(queue, param);
- }
-
- public RectCommandArgs GetParams(DrawQueue queue, ReadOnlySpan param)
- {
- if (param.Length < Length)
- throw new Exception("Not enough bytes");
-
- RectCommandArgs args;
-
- switch (_mode)
- {
- case Mode.Fill:
- ref readonly RectF f = ref MemoryMarshal.AsRef(param);
- args = new RectCommandArgs(f.Start, f.End, f.Depth, (IBrush)queue.Resources[f.FillBrushIndex]);
- break;
- case Mode.Strike:
- ref readonly RectS s = ref MemoryMarshal.AsRef(param);
- args = new RectCommandArgs(s.Start, s.End, s.Depth, (IBrush)queue.Resources[s.StrikeBrushIndex], s.StrikeSize, s.BorderKind);
- break;
- default:
- ref readonly RectFS fs = ref MemoryMarshal.AsRef(param);
- args = new RectCommandArgs(fs.Start, fs.End, fs.Depth, (IBrush)queue.Resources[fs.FillBrushIndex],
- (IBrush)queue.Resources[fs.StrikeBrushIndex], fs.StrikeSize, fs.BorderKind);
- break;
- }
-
- return args;
- }
-
- public int WriteParams(DrawQueue queue, object? obj, Span param)
- {
- return WriteParams(queue, (RectCommandArgs)obj, param);
- }
-
- public int WriteParams(DrawQueue queue, RectCommandArgs obj, Span param)
- {
- if (param.Length < Length)
- return Length;
-
- switch (_mode)
- {
- case Mode.Fill:
- ref RectF f = ref MemoryMarshal.AsRef(param);
- f.Start = obj.Start;
- f.End = obj.End;
- f.Depth = obj.Depth;
- f.FillBrushIndex = queue.RequireResource(obj.FillBrush!);
- break;
- case Mode.Strike:
- ref RectS s = ref MemoryMarshal.AsRef(param);
- s.Start = obj.Start;
- s.End = obj.End;
- s.Depth = obj.Depth;
- s.StrikeBrushIndex = queue.RequireResource(obj.StrikeBrush!);
- s.StrikeSize = obj.StrikeSize;
- s.BorderKind = obj.BorderKind;
- break;
- default:
- ref RectFS fs = ref MemoryMarshal.AsRef(param);
- fs.Start = obj.Start;
- fs.End = obj.End;
- fs.Depth = obj.Depth;
- fs.FillBrushIndex = queue.RequireResource(obj.FillBrush!);
- fs.StrikeBrushIndex = queue.RequireResource(obj.StrikeBrush!);
- fs.StrikeSize = obj.StrikeSize;
- fs.BorderKind = obj.BorderKind;
- break;
- }
-
- return Length;
- }
-
- [Flags]
- public enum Mode
- {
- Fill = 1,
- Strike = 2,
- FillStrike = Fill | Strike,
- }
-
- private record struct RectF(Vector2 Start, Vector2 End, float Depth, int FillBrushIndex);
- private record struct RectS(Vector2 Start, Vector2 End, float Depth, int StrikeBrushIndex, float StrikeSize, BorderKind BorderKind);
- private record struct RectFS(Vector2 Start, Vector2 End, float Depth, int FillBrushIndex, int StrikeBrushIndex, float StrikeSize, BorderKind BorderKind);
- }
-
- public struct RectCommandArgs
- {
- public Vector2 Start { get; private set; }
- public Vector2 End { get; private set; }
- public float Depth { get; private set; }
- public float StrikeSize { get; private set; } = 0f;
- public BorderKind BorderKind { get; private set; } = BorderKind.Center;
- public IBrush? FillBrush { get; private set; } = null;
- public IBrush? StrikeBrush { get; private set; } = null;
- public bool IsStruck => StrikeSize != 0;
-
- public RectCommandArgs(Vector2 start, Vector2 end, float depth, IBrush fillBrush)
- {
- Start = start;
- End = end;
- Depth = depth;
- FillBrush = fillBrush;
- }
-
- public RectCommandArgs(Vector2 start, Vector2 end, float depth, IBrush strikeBrush, float strikeSize, BorderKind borderKind)
- {
- Start = start;
- End = end;
- Depth = depth;
- StrikeBrush = strikeBrush;
- StrikeSize = strikeSize;
- BorderKind = borderKind;
- }
-
- public RectCommandArgs(Vector2 start, Vector2 end, float depth, IBrush fillBrush, IBrush strikeBrush, float strikeSize,
- BorderKind borderKind)
- {
- Start = start;
- End = end;
- Depth = depth;
- FillBrush = fillBrush;
- StrikeBrush = strikeBrush;
- StrikeSize = strikeSize;
- BorderKind = borderKind;
- }
- }
-}
diff --git a/Dashboard.Drawing/DrawBuffer.cs b/Dashboard.Drawing/DrawBuffer.cs
deleted file mode 100644
index 269733b..0000000
--- a/Dashboard.Drawing/DrawBuffer.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Numerics;
-
-namespace Dashboard.Drawing
-{
- public enum DrawPrimitive
- {
- Point,
- Line,
- LineStrip,
- Triangle,
- TriangleFan,
- TriangleStrip
- }
-
- public record struct DrawVertex(Vector3 Position, Vector3 TextureCoordinate, Vector4 Color);
-
- public record DrawInfo(DrawPrimitive Primitive, int Count)
- {
-
- }
-
- public class DrawBuffer
- {
-
- }
-}
diff --git a/Dashboard.Drawing/DrawCommand.cs b/Dashboard.Drawing/DrawCommand.cs
deleted file mode 100644
index 2aba61c..0000000
--- a/Dashboard.Drawing/DrawCommand.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-using System;
-
-namespace Dashboard.Drawing
-{
- public interface IDrawCommand
- {
- ///
- /// Name of the command.
- ///
- string Name { get; }
-
- ///
- /// The draw extension that defines this command.
- ///
- IDrawExtension Extension { get; }
-
- ///
- /// The length of the command data segment, in bytes.
- ///
- ///
- /// Must be 0 for simple commands. For commands that are variadic, the
- /// value must be less than 0. Any other positive value, otherwise.
- ///
- int Length { get; }
-
- ///
- /// Get the parameters object for this command.
- ///
- /// The parameter array.
- /// The parameters object.
- object? GetParams(DrawQueue queue, ReadOnlySpan param);
-
- int WriteParams(DrawQueue queue, object? obj, Span param);
- }
-
- public interface IDrawCommand : IDrawCommand
- {
- ///
- /// Get the parameters object for this command.
- ///
- /// The parameter array.
- /// The parameters object.
- new T? GetParams(DrawQueue queue, ReadOnlySpan param);
-
- new int WriteParams(DrawQueue queue, T? obj, Span param);
- }
-
- public sealed class DrawCommand : IDrawCommand
- {
- public string Name { get; }
- public IDrawExtension Extension { get; }
- public int Length { get; } = 0;
-
- public DrawCommand(string name, IDrawExtension extension)
- {
- Name = name;
- Extension = extension;
- }
-
- public object? GetParams(DrawQueue queue, ReadOnlySpan param)
- {
- return null;
- }
-
- public int WriteParams(DrawQueue queue, object? obj, Span param)
- {
- return 0;
- }
- }
-
- public sealed class DrawCommand : IDrawCommand
- where T : IParameterSerializer, new()
- {
- public string Name { get; }
- public IDrawExtension Extension { get; }
- public int Length { get; }
-
- public DrawCommand(string name, IDrawExtension extension, int length)
- {
- Name = name;
- Extension = extension;
- Length = length;
- }
-
- public T? GetParams(DrawQueue queue, ReadOnlySpan param)
- {
- T t = new T();
- t.Deserialize(queue, param);
- return t;
- }
-
- public int WriteParams(DrawQueue queue, T? obj, Span param)
- {
- return obj!.Serialize(queue, param);
- }
-
- int IDrawCommand.WriteParams(DrawQueue queue, object? obj, Span param)
- {
- return WriteParams(queue, (T?)obj, param);
- }
-
- object? IDrawCommand.GetParams(DrawQueue queue, ReadOnlySpan param)
- {
- return GetParams(queue, param);
- }
- }
-}
diff --git a/Dashboard.Drawing/DrawExtension.cs b/Dashboard.Drawing/DrawExtension.cs
deleted file mode 100644
index 6a6a77a..0000000
--- a/Dashboard.Drawing/DrawExtension.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Drawing;
-using System.Linq;
-using System.Numerics;
-using System.Runtime.InteropServices;
-
-namespace Dashboard.Drawing
-{
- ///
- /// Interface for all drawing extensions.
- ///
- public interface IDrawExtension
- {
- ///
- /// Name of this extension.
- ///
- public string Name { get; }
-
- public IReadOnlyList Requires { get; }
-
- ///
- /// The list of commands this extension defines, if any.
- ///
- public IReadOnlyList Commands { get; }
- }
-
- ///
- /// A simple draw extension.
- ///
- public class DrawExtension : IDrawExtension
- {
- private readonly List _drawCommands = new List();
-
- public string Name { get; }
-
- public IReadOnlyList Commands { get; }
-
- public IReadOnlyList Requires { get; }
-
- public DrawExtension(string name, IEnumerable? requires = null)
- {
- Name = name;
- Commands = _drawCommands.AsReadOnly();
- Requires = (requires ?? Enumerable.Empty()).ToImmutableList();
- }
-
- protected void AddCommand(IDrawCommand command)
- {
- _drawCommands.Add(command);
- }
- }
-
- public static class DrawExtensionClass
- {
- ///
- /// Get the draw controller for the given queue.
- ///
- /// The extension instance.
- /// The draw queue.
- /// The draw controller for this queue.
- public static IDrawController GetController(this IDrawExtension extension, DrawQueue queue)
- {
- return queue.GetController(extension);
- }
-
- public static void Point(this DrawQueue queue, Vector2 position, float depth, float size, IBrush brush)
- {
- Vector2 radius = new Vector2(0.5f * size);
- Box2d bounds = new Box2d(position - radius, position + radius);
-
- IDrawController controller = queue.GetController(DbBaseCommands.Instance);
- controller.EnsureBounds(bounds, depth);
- controller.Write(DbBaseCommands.Instance.DrawPoint, new PointCommandArgs(position, depth, size, brush));
- }
-
- public static void Line(this DrawQueue queue, Vector2 start, Vector2 end, float depth, float size, IBrush brush)
- {
- Vector2 radius = new Vector2(size / 2f);
- Vector2 min = Vector2.Min(start, end) - radius;
- Vector2 max = Vector2.Max(start, end) + radius;
- Box2d bounds = new Box2d(min, max);
-
- IDrawController controller = queue.GetController(DbBaseCommands.Instance);
- controller.EnsureBounds(bounds, depth);
- controller.Write(DbBaseCommands.Instance.DrawLine, new LineCommandArgs(start, end, depth, size, brush));
- }
-
- public static void Rect(this DrawQueue queue, Vector2 start, Vector2 end, float depth, IBrush fillBrush)
- {
- IDrawController controller = queue.GetController(DbBaseCommands.Instance);
- Vector2 min = Vector2.Min(start, end);
- Vector2 max = Vector2.Max(start, end);
- controller.EnsureBounds(new Box2d(min, max), depth);
- controller.Write(DbBaseCommands.Instance.DrawRectF, new RectCommandArgs(start, end, depth, fillBrush));
- }
-
- public static void Rect(this DrawQueue queue, Vector2 start, Vector2 end, float depth, IBrush strikeBrush, float strikeSize,
- BorderKind kind = BorderKind.Center)
- {
- IDrawController controller = queue.GetController(DbBaseCommands.Instance);
- Vector2 min = Vector2.Min(start, end);
- Vector2 max = Vector2.Max(start, end);
- controller.EnsureBounds(new Box2d(min, max), depth);
- controller.Write(DbBaseCommands.Instance.DrawRectS, new RectCommandArgs(start, end, depth, strikeBrush, strikeSize, kind));
- }
-
- public static void Rect(this DrawQueue queue, Vector2 start, Vector2 end, float depth, IBrush fillBrush, IBrush strikeBrush,
- float strikeSize, BorderKind kind = BorderKind.Center)
- {
- IDrawController controller = queue.GetController(DbBaseCommands.Instance);
- Vector2 min = Vector2.Min(start, end);
- Vector2 max = Vector2.Max(start, end);
- controller.EnsureBounds(new Box2d(min, max), depth);
- controller.Write(DbBaseCommands.Instance.DrawRectFS, new RectCommandArgs(start, end, depth, fillBrush, strikeBrush, strikeSize, kind));
- }
-
- public static void Text(this DrawQueue queue, Vector3 position, IBrush brush, string text, IFont font,
- Anchor anchor = Anchor.Left)
- {
- IDrawController controller = queue.GetController(DbBaseCommands.Instance);
- SizeF size = Typesetter.MeasureString(font, text);
- controller.EnsureBounds(new Box2d(position.X, position.Y, position.X + size.Width, position.Y + size.Height), position.Z);
- controller.Write(TextExtension.Instance.TextCommand, new TextCommandArgs(font, brush, anchor, position, text));
- }
-
- public static void Text(this DrawQueue queue, Vector3 position, IBrush textBrush, IBrush borderBrush,
- float borderRadius, string text, IFont font, Anchor anchor = Anchor.Left, BorderKind borderKind = BorderKind.Outset)
- {
- IDrawController controller = queue.GetController(DbBaseCommands.Instance);
- SizeF size = Typesetter.MeasureString(font, text);
- controller.EnsureBounds(new Box2d(position.X, position.Y, position.X + size.Width, position.Y + size.Height), position.Z);
- controller.Write(TextExtension.Instance.TextCommand, new TextCommandArgs(font, textBrush, anchor, position, text)
- {
- BorderBrush = borderBrush,
- BorderRadius = borderRadius,
- BorderKind = borderKind,
- });
- }
- }
-}
diff --git a/Dashboard.Drawing/DrawQueue.cs b/Dashboard.Drawing/DrawQueue.cs
deleted file mode 100644
index 140a7e8..0000000
--- a/Dashboard.Drawing/DrawQueue.cs
+++ /dev/null
@@ -1,368 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-
-namespace Dashboard.Drawing
-{
- public class DrawQueue : IEnumerable, IDisposable
- {
- private readonly HashList _extensions = new HashList();
- private readonly HashList _commands = new HashList();
- private readonly HashList _resources = new HashList();
- private readonly DrawController _controller;
- private readonly MemoryStream _commandStream = new MemoryStream();
-
- ///
- /// The absolute boundary of all graphics objects.
- ///
- public Box3d Bounds { get; set; }
-
- ///
- /// The extensions required to draw the image.
- ///
- public IReadOnlyList Extensions => _extensions;
-
- ///
- /// The resources used by this draw queue.
- ///
- public IReadOnlyList Resources => _resources;
-
- ///
- /// The list of commands used by the extension.
- ///
- public IReadOnlyList Command => _commands;
-
- public DrawQueue()
- {
- _controller = new DrawController(this);
- }
-
- ///
- /// Clear the queue.
- ///
- public void Clear()
- {
- _resources.Clear();
- _commands.Clear();
- _extensions.Clear();
- _commandStream.SetLength(0);
- }
-
- public int RequireExtension(IDrawExtension extension)
- {
- foreach (IDrawExtension super in extension.Requires)
- RequireExtension(super);
-
- return _extensions.Intern(extension);
- }
-
- public int RequireResource(IDrawResource resource)
- {
- RequireExtension(resource.Kind);
- return _resources.Intern(resource);
- }
-
- internal IDrawController GetController(IDrawExtension extension)
- {
- _extensions.Intern(extension);
- return _controller;
- }
-
- private void Write(IDrawCommand command)
- {
- if (command.Length > 0)
- throw new InvalidOperationException("This command has a finite length argument.");
-
- int cmdIndex = _commands.Intern(command);
-
- Span cmd = stackalloc byte[6];
- int sz;
-
- if (command.Length == 0)
- {
- // Write a fixed command.
- sz = ToVlq(cmdIndex, cmd);
- }
- else
- {
- // Write a variadic with zero length.
- sz = ToVlq(cmdIndex, cmd);
- cmd[sz++] = 0;
- }
-
- _commandStream.Write(cmd[..sz]);
- }
-
- private void Write(IDrawCommand command, ReadOnlySpan param)
- {
- if (command.Length < 0)
- {
- Span cmd = stackalloc byte[10];
- int cmdIndex = _commands.Intern(command);
- int sz = ToVlq(cmdIndex, cmd);
- sz += ToVlq(param.Length, cmd[sz..]);
- _commandStream.Write(cmd[..sz]);
- _commandStream.Write(param);
- }
- else
- {
- if (command.Length != param.Length)
- throw new ArgumentOutOfRangeException(nameof(param.Length), "Length of the parameter does not match the command.");
-
- Span cmd = stackalloc byte[5];
- int cmdIndex = _commands.Intern(command);
- int sz = ToVlq(cmdIndex, cmd);
-
- _commandStream.Write(cmd[..sz]);
- _commandStream.Write(param);
- }
- }
-
- public Enumerator GetEnumerator() => new Enumerator(this);
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
- private static int ToVlq(int value, Span bytes)
- {
- if (value < 0)
- throw new ArgumentOutOfRangeException(nameof(value), "Must be a positive integer.");
- else if (bytes.Length < 5)
- throw new ArgumentOutOfRangeException(nameof(bytes), "Must at least be five bytes long.");
-
- if (value == 0)
- {
- bytes[0] = 0;
- return 1;
- }
-
- int i;
- for (i = 0; i < 5 && value != 0; i++, value >>= 7)
- {
- if (i > 0)
- bytes[i - 1] |= 1 << 7;
-
- bytes[i] = (byte)(value & 0x7F);
- }
-
- return i;
- }
-
- private static int FromVlq(ReadOnlySpan bytes, out int value)
- {
- value = 0;
-
- int i;
- for (i = 0; i < bytes.Length; i++)
- {
- byte b = bytes[i];
-
- value |= (b & 0x7F) << (7*i);
-
- if ((b & (1 << 7)) == 0)
- {
- i++;
- break;
- }
- }
-
- return i;
- }
-
- public void Dispose()
- {
- throw new NotImplementedException();
- }
-
- private class DrawController(DrawQueue Queue) : IDrawController
- {
- public void EnsureBounds(Box2d bounds, float depth)
- {
- Queue.Bounds = Box3d.Union(Queue.Bounds, bounds, depth);
- }
-
- public void Write(IDrawCommand command)
- {
- Queue.Write(command);
- }
-
- public void Write(IDrawCommand command, ReadOnlySpan bytes)
- {
- Queue.Write(command, bytes);
- }
-
- public void Write(IDrawCommand command, T param) where T : IParameterSerializer
- {
- int length = param.Serialize(Queue, Span.Empty);
- Span bytes = stackalloc byte[length];
-
- param.Serialize(Queue, bytes);
- Write(command, bytes);
- }
-
- public void Write(T2 command, T1 param) where T2 : IDrawCommand
- {
- int length = command.WriteParams(Queue, param, Span.Empty);
- Span bytes = stackalloc byte[length];
-
- command.WriteParams(Queue, param, bytes);
- Write(command, bytes);
- }
- }
-
- public class Enumerator : ICommandFrame, IEnumerator
- {
- private readonly DrawQueue _queue;
- private readonly byte[] _stream;
- private int _length;
- private int _index = -1;
- private int _paramsIndex = -1;
- private int _paramLength = 0;
- private IDrawCommand? _current = null;
-
- public ICommandFrame Current => this;
-
- object? IEnumerator.Current => Current;
-
- public IDrawCommand Command => _current ?? throw new InvalidOperationException();
-
- public bool HasParameters { get; private set; }
-
- public Enumerator(DrawQueue queue)
- {
- _queue = queue;
- _stream = queue._commandStream.GetBuffer();
- _length = (int)queue._commandStream.Length;
- }
-
- public bool MoveNext()
- {
- if (_index == -1)
- _index = 0;
-
- if (_index >= _length)
- return false;
-
-
- _index += FromVlq(_stream[_index .. (_index + 5)], out int command);
- _current = _queue.Command[command];
-
- HasParameters = _current.Length != 0;
-
- if (!HasParameters)
- {
- _paramsIndex = -1;
- return true;
- }
-
- int length;
- if (_current.Length < 0)
- {
- _index += FromVlq(_stream[_index .. (_index + 5)], out length);
- }
- else
- {
- length = _current.Length;
- }
-
- _paramsIndex = _index;
- _paramLength = length;
- _index += length;
-
- return true;
- }
-
- public void Reset()
- {
- _index = -1;
- _current = null;
- }
-
- public object? GetParameter()
- {
- return _current?.GetParams(_queue, _stream.AsSpan(_paramsIndex, _paramLength));
- }
-
- public T GetParameter()
- {
- if (_current is IDrawCommand command)
- {
- return command.GetParams(_queue, _stream.AsSpan(_paramsIndex, _paramLength))!;
- }
- else
- {
- throw new InvalidOperationException();
- }
- }
-
- public bool TryGetParameter([NotNullWhen(true)] out T? parameter)
- {
- if (_current is IDrawCommand command)
- {
- parameter = command.GetParams(_queue, _stream.AsSpan(_paramsIndex, _paramLength))!;
- return true;
- }
- else
- {
- parameter = default;
- return false;
- }
- }
-
- public void Dispose()
- {
- }
- }
- }
-
- public interface ICommandFrame
- {
- public IDrawCommand Command { get; }
-
- public bool HasParameters { get; }
-
- public object? GetParameter();
-
- public T GetParameter();
-
- public bool TryGetParameter([NotNullWhen(true)] out T? parameter);
- }
-
-
- public interface IDrawController
- {
- ///
- /// Ensures that the canvas is at least a certain size.
- ///
- /// The bounding box.
- void EnsureBounds(Box2d bounds, float depth);
-
- ///
- /// Write into the command stream.
- ///
- /// The command to write.
- void Write(IDrawCommand command);
-
- ///
- /// Write into the command stream.
- ///
- /// The command to write.
- /// Any data associated with the command.
- void Write(IDrawCommand command, ReadOnlySpan param);
-
- ///
- /// Write into the command stream.
- ///
- /// The command to write.
- /// Any data associated with the command.
- void Write(IDrawCommand command, T param) where T : IParameterSerializer;
-
- ///
- /// Write into the command stream.
- ///
- /// The command to write.
- /// Any data associated with the command.
- void Write(T2 command, T1 param) where T2 : IDrawCommand;
- }
-}
diff --git a/Dashboard.Drawing/IDrawQueuePaintable.cs b/Dashboard.Drawing/IDrawQueuePaintable.cs
deleted file mode 100644
index a719b7d..0000000
--- a/Dashboard.Drawing/IDrawQueuePaintable.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Dashboard.Windowing;
-
-namespace Dashboard.Drawing
-{
- public interface IDrawQueuePaintable : IPaintable
- {
- DrawQueue DrawQueue { get; }
- }
-}
diff --git a/Dashboard.Drawing/IDrawResource.cs b/Dashboard.Drawing/IDrawResource.cs
deleted file mode 100644
index 2a57ced..0000000
--- a/Dashboard.Drawing/IDrawResource.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Dashboard.Drawing
-{
- ///
- /// Interface for draw resources.
- ///
- public interface IDrawResource
- {
- ///
- /// The extension for this kind of resource.
- ///
- IDrawExtension Kind { get; }
- }
-}
diff --git a/Dashboard.Drawing/IParameterSerializer.cs b/Dashboard.Drawing/IParameterSerializer.cs
deleted file mode 100644
index 5ae0bf6..0000000
--- a/Dashboard.Drawing/IParameterSerializer.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Dashboard.Drawing
-{
- public interface IParameterSerializer
- {
- int Serialize(DrawQueue queue, Span bytes);
- void Deserialize(DrawQueue queue, ReadOnlySpan bytes);
- }
-}
diff --git a/Dashboard.Drawing/TextExtension.cs b/Dashboard.Drawing/TextExtension.cs
deleted file mode 100644
index 1c5d831..0000000
--- a/Dashboard.Drawing/TextExtension.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-using System;
-using System.Numerics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace Dashboard.Drawing
-{
- public class TextExtension : DrawExtension
- {
- public TextCommand TextCommand { get; }
-
- private TextExtension() : base("DB_Text", new [] { BrushExtension.Instance })
- {
- TextCommand = new TextCommand(this);
- }
-
- public static readonly TextExtension Instance = new TextExtension();
- }
-
- public class TextCommand : IDrawCommand
- {
- public string Name { get; } = "Text";
- public IDrawExtension Extension { get; }
- public int Length { get; } = -1;
-
- public TextCommand(TextExtension ext)
- {
- Extension = ext;
- }
-
- public int WriteParams(DrawQueue queue, TextCommandArgs obj, Span param)
- {
- int size = Unsafe.SizeOf() + obj.Text.Length * sizeof(char) + sizeof(char);
-
- if (param.Length < size)
- return size;
-
- ref Header header = ref MemoryMarshal.Cast(param[0..Unsafe.SizeOf()])[0];
- Span text = MemoryMarshal.Cast(param[Unsafe.SizeOf()..]);
-
- header = new Header()
- {
- // Font = queue.RequireResource(obj.Font),
- TextBrush = queue.RequireResource(obj.TextBrush),
- BorderBrush = (obj.BorderBrush != null) ? queue.RequireResource(obj.BorderBrush) : -1,
- BorderRadius = (obj.BorderBrush != null) ? obj.BorderRadius : 0f,
- Anchor = obj.Anchor,
- Position = obj.Position,
- BorderKind = obj.BorderKind,
- };
- obj.Text.CopyTo(text);
-
- return size;
- }
-
- public TextCommandArgs GetParams(DrawQueue queue, ReadOnlySpan param)
- {
- Header header = MemoryMarshal.Cast(param[0..Unsafe.SizeOf()])[0];
- ReadOnlySpan text = MemoryMarshal.Cast(param[Unsafe.SizeOf()..]);
-
- if (header.BorderBrush != -1 && header.BorderRadius != 0)
- {
- return new TextCommandArgs(
- (IFont)queue.Resources[header.Font],
- (IBrush)queue.Resources[header.TextBrush],
- header.Anchor,
- header.Position,
- text.ToString())
- {
- BorderBrush = (IBrush)queue.Resources[header.BorderBrush],
- BorderRadius = header.BorderRadius,
- BorderKind = header.BorderKind,
- };
- }
- else
- {
- return new TextCommandArgs(
- (IFont)queue.Resources[header.Font],
- (IBrush)queue.Resources[header.TextBrush],
- header.Anchor,
- header.Position,
- text.ToString());
- }
- }
-
- int IDrawCommand.WriteParams(DrawQueue queue, object? obj, Span param)
- {
- return WriteParams(queue, (TextCommandArgs)obj!, param);
- }
-
- object? IDrawCommand.GetParams(DrawQueue queue, ReadOnlySpan param)
- {
- return GetParams(queue, param);
- }
-
- private struct Header
- {
- private int _flags;
- public int Font;
- public int TextBrush;
- public int BorderBrush;
- public Vector3 Position;
- public float BorderRadius;
-
- public Anchor Anchor
- {
- get => (Anchor)(_flags & 0xF);
- set => _flags = (_flags & ~0xF) | (int)value;
- }
-
- public BorderKind BorderKind
- {
- get => (_flags & INSET) switch
- {
- OUTSET => BorderKind.Outset,
- INSET => BorderKind.Inset,
- _ => BorderKind.Center,
- };
- set => _flags = value switch
- {
- BorderKind.Outset => (_flags & ~INSET) | OUTSET,
- BorderKind.Inset => (_flags & ~INSET) | INSET,
- _ => (_flags & ~INSET) | CENTER,
- };
- }
-
- private const int INSET = 0x30;
- private const int CENTER = 0x00;
- private const int OUTSET = 0x10;
- }
- }
-
- public record struct TextCommandArgs(IFont Font, IBrush TextBrush, Anchor Anchor, Vector3 Position, string Text)
- {
- public IBrush? BorderBrush { get; init; } = null;
- public float BorderRadius { get; init; } = 0;
-
- public BorderKind BorderKind { get; init; } = BorderKind.Center;
- }
-}
diff --git a/Dashboard.Drawing/Typesetter.cs b/Dashboard.Drawing/Typesetter.cs
deleted file mode 100644
index 343813d..0000000
--- a/Dashboard.Drawing/Typesetter.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Drawing;
-using System.IO;
-using System.Reflection.PortableExecutable;
-
-namespace Dashboard.Drawing
-{
- ///
- /// Interface for registered typesetters.
- ///
- public interface ITypeSetter
- {
- ///
- /// Name of the typesetter.
- ///
- string Name { get; }
-
- SizeF MeasureString(IFont font, string value);
-
- IFont LoadFont(Stream stream);
- IFont LoadFont(string path);
- // IFont LoadFont(NamedFont font);
- }
-
- ///
- /// Class for typesetting related functions.
- ///
- public static class Typesetter
- {
- ///
- /// The typesetting backend for this instance.
- ///
- public static ITypeSetter Backend { get; set; } = new UndefinedTypeSetter();
-
- public static string Name => Backend.Name;
-
- public static SizeF MeasureString(IFont font, string value)
- {
- return Backend.MeasureString(font, value);
- }
-
- public static IFont LoadFont(Stream stream)
- {
- return Backend.LoadFont(stream);
- }
-
- public static IFont LoadFont(string path)
- {
- return Backend.LoadFont(path);
- }
-
- public static IFont LoadFont(FileInfo file)
- {
- return Backend.LoadFont(file.FullName);
- }
-
- // public static IFont LoadFont(NamedFont font)
- // {
- // return Backend.LoadFont(font);
- // }
-
- public static IFont LoadFont(string family, float size, FontWeight weight = FontWeight.Normal,
- FontSlant slant = FontSlant.Normal, FontStretch stretch = FontStretch.Normal)
- {
- // return LoadFont(new NamedFont(family, size, weight, slant, stretch));
- throw new Exception();
- }
-
- private class UndefinedTypeSetter : ITypeSetter
- {
- public string Name { get; } = "Undefined";
-
- [DoesNotReturn]
- private void Except()
- {
- throw new InvalidOperationException("No typesetting backend is loaded.");
- }
-
- public SizeF MeasureString(IFont font, string value)
- {
- Except();
- return default;
- }
-
- public IFont LoadFont(Stream stream)
- {
- Except();
- return default;
- }
-
- public IFont LoadFont(string path)
- {
- Except();
- return default;
- }
-
- // public IFont LoadFont(NamedFont font)
- // {
- // Except();
- // return default;
- // }
- }
- }
-}
diff --git a/Dashboard.ImmediateUI/Dashboard.ImmediateUI.csproj b/Dashboard.ImmediateUI/Dashboard.ImmediateUI.csproj
deleted file mode 100644
index af00df2..0000000
--- a/Dashboard.ImmediateUI/Dashboard.ImmediateUI.csproj
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- net10.0
- disable
- enable
-
-
-
diff --git a/Dashboard.ImmediateUI/DimUI.cs b/Dashboard.ImmediateUI/DimUI.cs
deleted file mode 100644
index 4f7da23..0000000
--- a/Dashboard.ImmediateUI/DimUI.cs
+++ /dev/null
@@ -1,234 +0,0 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Drawing;
-using System.Numerics;
-using System.Text;
-using Dashboard.Drawing;
-
-namespace Dashboard.ImmediateUI
-{
- public class DimUIConfig
- {
- public Vector2 Margin = new Vector2(8, 4);
- public Vector2 Padding = new Vector2(4);
- public required IFont Font { get; init; }
-
- public IBrush TextBrush = new SolidBrush(Color.Black);
- public IBrush DisabledText = new SolidBrush(Color.Gray);
-
- public float ButtonBorderSize = 2f;
- public IBrush ButtonBorderBrush = new SolidBrush(Color.SteelBlue);
- public IBrush ButtonFillBrush = new SolidBrush(Color.SlateGray);
- public IBrush? ButtonShadowBrush = new SolidBrush(Color.FromArgb(32, Color.LightSteelBlue));
- public float ButtonShadowOffset = 2f;
-
- public float InputBorderSize = 2f;
- public IBrush InputPlaceholderTextBrush = new SolidBrush(Color.SteelBlue);
- public IBrush InputBorderBrush = new SolidBrush(Color.SlateGray);
- public IBrush InputFillBrush = new SolidBrush(Color.LightGray);
- public IBrush? InputShadowBrush = new SolidBrush(Color.FromArgb(32, Color.LightSteelBlue));
- public float InputShadowOffset = -2f;
-
- public float MenuBorderSize = 2f;
- public IBrush MenuBorderBrush = new SolidBrush(Color.SteelBlue);
- public IBrush MenuFillBrush = new SolidBrush(Color.SlateGray);
- public IBrush? MenuShadowBrush = new SolidBrush(Color.FromArgb(32, Color.LightSteelBlue));
- public float MenuShadowOffset = 2f;
- }
-
- public class DimUI
- {
- private readonly DimUIConfig _config;
- private Vector2 _pen;
- private Box2d _bounds;
- private bool _firstLine = false;
- private bool _sameLine = false;
- private float _z = -1;
- private float _lineHeight;
- private DrawQueue _queue;
-
- public DimUI(DimUIConfig config)
- {
- _config = config;
- }
-
- [MemberNotNull(nameof(_queue))]
- public void Begin(Box2d bounds, DrawQueue queue)
- {
- _bounds = bounds;
- _pen = _bounds.Min;
- _queue = queue;
- _firstLine = true;
- _lineHeight = 0;
- _z = -1;
- }
-
- public void SameLine()
- {
- _sameLine = true;
- }
-
- private void Line()
- {
- if (!_firstLine && !_sameLine)
- {
- _pen = new Vector2(_bounds.Left, _pen.Y + _lineHeight);
- }
- else
- {
- _firstLine = false;
- _sameLine = false;
- }
-
- _pen.X += _config.Margin.X;
- _lineHeight = 0;
- }
-
- private float Z()
- {
- return _z += 0.001f;
- }
-
- public void Text(string text)
- {
- Line();
-
- SizeF sz = Typesetter.MeasureString(_config.Font, text);
- float z = Z();
- float h = _config.Margin.Y * 2 + sz.Height;
- _queue.Text(new Vector3(_pen + new Vector2(0, _config.Margin.X), z), _config.TextBrush, text, _config.Font);
-
- _lineHeight = Math.Max(_lineHeight, h);
- _pen.X += sz.Width;
- }
-
- public void DrawBox(
- Vector2 position,
- Vector2 size,
- IBrush fill,
- IBrush border, float borderWidth,
- IBrush? shadow, float offset)
- {
- float z = Z();
-
- if (shadow != null)
- {
- if (offset >= 0)
- {
- _queue.Rect(position + new Vector2(offset), position + size + new Vector2(offset + borderWidth), z, shadow);
- }
- else
- {
- // Inset shadows are draw a bit weirdly.
- _queue.Rect(position, position + new Vector2(offset, size.Y), z, shadow);
- _queue.Rect(position + new Vector2(offset, 0), position + new Vector2(size.X - offset, offset), z, shadow);
- }
- }
-
- _queue.Rect(position, position + size, z, fill, border, borderWidth, BorderKind.Outset);
- }
-
- public bool Button(string label)
- {
- Line();
-
- SizeF sz = Typesetter.MeasureString(_config.Font, label);
-
- float h = _config.Margin.Y * 2 + _config.Padding.Y * 2 + sz.Height;
- DrawBox(
- _pen + new Vector2(0, _config.Margin.Y),
- new Vector2(sz.Width + 2 * _config.Padding.X, sz.Height + 2 * _config.Padding.Y),
- _config.ButtonFillBrush,
- _config.ButtonBorderBrush,
- _config.ButtonBorderSize,
- _config.ButtonShadowBrush,
- _config.ButtonShadowOffset);
-
- float z = Z();
-
- _queue.Text(new Vector3(_pen + new Vector2(_config.Padding.X, _config.Margin.Y + _config.Padding.Y), z),
- _config.TextBrush, label, _config.Font);
- _lineHeight = Math.Max(_lineHeight, h);
-
- _pen.X += sz.Width + 2 * _config.Padding.X;
- return false;
- }
-
- public bool Input(string placeholder, StringBuilder value)
- {
- Line();
-
- IBrush textBrush;
- string str;
- if (value.Length == 0)
- {
- textBrush = _config.DisabledText;
- str = placeholder;
- }
- else
- {
- textBrush = _config.TextBrush;
- str = value.ToString();
- }
-
- SizeF sz = Typesetter.MeasureString(_config.Font, str);
-
- float h = _config.Margin.Y * 2 + _config.Padding.Y * 2 + sz.Height;
- DrawBox(
- _pen + new Vector2(0, _config.Margin.Y),
- new Vector2(sz.Width + 2 * _config.Padding.X, sz.Height + 2 * _config.Padding.Y),
- _config.InputFillBrush,
- _config.InputBorderBrush,
- _config.InputBorderSize,
- _config.InputShadowBrush,
- _config.InputShadowOffset);
-
- float z = Z();
-
- _queue.Text(new Vector3(_pen + new Vector2(_config.Padding.X, _config.Margin.Y + _config.Padding.Y), z),
- textBrush, str, _config.Font);
- _lineHeight = Math.Max(_lineHeight, h);
-
- _pen.X += sz.Width + 2 * _config.Padding.X;
- return false;
- }
-
- public void BeginMenu()
- {
-
- }
-
- public bool MenuItem(string name)
- {
- return false;
- }
-
- public void EndMenu()
- {
-
- }
-
- public int Id(ReadOnlySpan str)
- {
- // Uses the FVN-1A algorithm in 32-bit mode.
- const int PRIME = 0x01000193;
- const int BASIS = unchecked((int)0x811c9dc5);
-
- int hash = BASIS;
- for (int i = 0; i < str.Length; i++)
- {
- hash ^= str[i] & 0xFF;
- hash *= PRIME;
- hash ^= str[i] >> 8;
- hash *= PRIME;
- }
-
- return hash;
- }
-
- public void Finish()
- {
- // TODO:
- }
- }
-}