New in development queue system.
This commit is contained in:
parent
3d672022e1
commit
98b1c1a277
59
Quik/CommandQueue/Command.cs
Normal file
59
Quik/CommandQueue/Command.cs
Normal file
@ -0,0 +1,59 @@
|
||||
namespace Quik.CommandQueue
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumeration of built-in Quik commands.
|
||||
/// </summary>
|
||||
public enum Command
|
||||
{
|
||||
#region Control Commands
|
||||
/// <summary>
|
||||
/// Invoke a function directly.
|
||||
/// </summary>
|
||||
Invoke,
|
||||
|
||||
/// <summary>
|
||||
/// Begin conditional rendering segment.
|
||||
/// </summary>
|
||||
ConditionalBegin,
|
||||
|
||||
/// <summary>
|
||||
/// End conditional rendering segment.
|
||||
/// </summary>
|
||||
ConditionalEnd,
|
||||
|
||||
PushViewport,
|
||||
StoreViewport,
|
||||
PopViewport,
|
||||
|
||||
IncrementZ,
|
||||
AddZ,
|
||||
StoreZ,
|
||||
DecrementZ,
|
||||
|
||||
PushMatrix,
|
||||
StoreIdentityMatrix,
|
||||
StoreMatrix,
|
||||
PopMatrix,
|
||||
|
||||
PushStyle,
|
||||
StoreStyle,
|
||||
PopStyle,
|
||||
#endregion
|
||||
|
||||
#region Draw Commands
|
||||
Line,
|
||||
Bezier,
|
||||
Rectangle,
|
||||
Ellipse,
|
||||
Triangle,
|
||||
Polygon,
|
||||
Image,
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Start index for custom commands.
|
||||
/// </summary>
|
||||
CustomCommandBase = 1024,
|
||||
}
|
||||
}
|
8
Quik/CommandQueue/CommandHandler.cs
Normal file
8
Quik/CommandQueue/CommandHandler.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Quik.CommandQueue
|
||||
{
|
||||
/// <summary>
|
||||
/// A delegate for a QUIK command.
|
||||
/// </summary>
|
||||
/// <param name="stack">The current stack.</param>
|
||||
public delegate void QuikCommandHandler(object state);
|
||||
}
|
232
Quik/CommandQueue/CommandQueue.cs
Normal file
232
Quik/CommandQueue/CommandQueue.cs
Normal file
@ -0,0 +1,232 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Quik.CommandQueue
|
||||
{
|
||||
public class CommandQueue : Queue<Frame>
|
||||
{
|
||||
public void Invoke(QuikCommandHandler handler)
|
||||
{
|
||||
Enqueue(Command.Invoke);
|
||||
Enqueue(new Frame(handler));
|
||||
}
|
||||
|
||||
public void ConditionalBegin(bool value)
|
||||
{
|
||||
Enqueue(Command.ConditionalBegin);
|
||||
Enqueue((Frame)(value ? 1 : 0));
|
||||
}
|
||||
|
||||
public void ConditionalBegin(Func<bool> condition)
|
||||
{
|
||||
Enqueue(Command.ConditionalBegin);
|
||||
Enqueue(new Frame(condition));
|
||||
}
|
||||
|
||||
public void ConditionalEnd()
|
||||
{
|
||||
Enqueue(Command.ConditionalEnd);
|
||||
}
|
||||
|
||||
public void PushViewport(in QuikRectangle viewport)
|
||||
{
|
||||
Enqueue(Command.PushViewport);
|
||||
Enqueue(viewport);
|
||||
}
|
||||
|
||||
public void StoreViewport(in QuikRectangle viewport)
|
||||
{
|
||||
Enqueue(Command.StoreViewport);
|
||||
Enqueue(viewport);
|
||||
}
|
||||
|
||||
public void PopViewport()
|
||||
{
|
||||
Enqueue(Command.PopViewport);
|
||||
}
|
||||
|
||||
public void IncrementZ()
|
||||
{
|
||||
Enqueue(Command.IncrementZ);
|
||||
}
|
||||
|
||||
public void AddZ(int value)
|
||||
{
|
||||
if (value == 1)
|
||||
{
|
||||
IncrementZ();
|
||||
}
|
||||
else if (value == -1)
|
||||
{
|
||||
DecrementZ();
|
||||
}
|
||||
else
|
||||
{
|
||||
Enqueue(Command.AddZ);
|
||||
Enqueue((Frame)value);
|
||||
}
|
||||
}
|
||||
|
||||
public void StoreZ(int value)
|
||||
{
|
||||
Enqueue(Command.StoreZ);
|
||||
Enqueue((Frame)value);
|
||||
}
|
||||
|
||||
public void DecrementZ()
|
||||
{
|
||||
Enqueue(Command.DecrementZ);
|
||||
}
|
||||
|
||||
public void Line(in QuikLine line)
|
||||
{
|
||||
Enqueue(Command.Line);
|
||||
Enqueue(line);
|
||||
}
|
||||
|
||||
public void Line(params QuikLine[] lines)
|
||||
{
|
||||
Enqueue(Command.Line);
|
||||
Enqueue((Frame)lines.Length);
|
||||
foreach (QuikLine line in lines)
|
||||
Enqueue(line);
|
||||
}
|
||||
|
||||
public void Bezier(in QuikBezier bezier)
|
||||
{
|
||||
Frame a, b;
|
||||
Frame.Create(bezier, out a, out b);
|
||||
|
||||
Enqueue(Command.Bezier);
|
||||
Enqueue(a);
|
||||
Enqueue(b);
|
||||
}
|
||||
|
||||
public void Bezier(params QuikBezier[] beziers)
|
||||
{
|
||||
Frame a, b;
|
||||
|
||||
Enqueue(Command.Bezier);
|
||||
Enqueue((Frame)beziers.Length);
|
||||
|
||||
foreach (QuikBezier bezier in beziers)
|
||||
{
|
||||
Frame.Create(bezier, out a, out b);
|
||||
Enqueue(a);
|
||||
Enqueue(b);
|
||||
}
|
||||
}
|
||||
|
||||
public void Rectangle(in QuikRectangle rectangle)
|
||||
{
|
||||
Enqueue(Command.Rectangle);
|
||||
Enqueue(rectangle);
|
||||
}
|
||||
|
||||
public void Rectangle(QuikRectangle[] rectangles)
|
||||
{
|
||||
Enqueue(Command.Rectangle);
|
||||
Enqueue((Frame)rectangles.Length);
|
||||
foreach (QuikRectangle rectangle in rectangles)
|
||||
Enqueue(rectangle);
|
||||
}
|
||||
|
||||
public void Ellipse(in QuikEllipse ellipse)
|
||||
{
|
||||
Frame a, b;
|
||||
Frame.Create(ellipse, out a, out b);
|
||||
|
||||
Enqueue(Command.Ellipse);
|
||||
Enqueue(a);
|
||||
Enqueue(b);
|
||||
}
|
||||
|
||||
public void Ellipse(params QuikEllipse[] ellipses)
|
||||
{
|
||||
Frame a, b;
|
||||
Enqueue(Command.Ellipse);
|
||||
Enqueue((Frame)ellipses.Length);
|
||||
foreach (QuikEllipse ellipse in ellipses)
|
||||
{
|
||||
Frame.Create(ellipse, out a, out b);
|
||||
Enqueue(a);
|
||||
Enqueue(b);
|
||||
}
|
||||
}
|
||||
|
||||
public void Triangle(in QuikTriangle triangle)
|
||||
{
|
||||
Enqueue(Command.Triangle);
|
||||
Enqueue(triangle.A);
|
||||
Enqueue(triangle.B);
|
||||
Enqueue(triangle.C);
|
||||
}
|
||||
|
||||
public void Triangle(params QuikTriangle[] triangles)
|
||||
{
|
||||
Enqueue(Command.Triangle);
|
||||
Enqueue((Frame)triangles.Length);
|
||||
foreach (QuikTriangle triangle in triangles)
|
||||
{
|
||||
Enqueue(triangle.A);
|
||||
Enqueue(triangle.B);
|
||||
Enqueue(triangle.C);
|
||||
}
|
||||
}
|
||||
|
||||
public void Polygon(params QuikVec2[] polygon)
|
||||
{
|
||||
Enqueue(Command.Polygon);
|
||||
Enqueue((Frame)polygon.Length);
|
||||
foreach (QuikVec2 vertex in polygon)
|
||||
{
|
||||
Enqueue(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Image(IQuikTexture texture, in QuikRectangle rectangle)
|
||||
{
|
||||
Enqueue(Command.Image);
|
||||
Enqueue((Frame)(int)ImageCommandFlags.Single);
|
||||
Enqueue(new Frame(texture));
|
||||
Enqueue(rectangle);
|
||||
}
|
||||
|
||||
public void Image(IQuikTexture texture, in QuikRectangle rectangle, in QuikRectangle uv)
|
||||
{
|
||||
Enqueue(Command.Image);
|
||||
Enqueue((Frame)(int)(ImageCommandFlags.Single | ImageCommandFlags.UVs));
|
||||
Enqueue(new Frame(texture));
|
||||
Enqueue(rectangle);
|
||||
Enqueue(uv);
|
||||
}
|
||||
|
||||
public void Image(IQuikTexture texture, QuikRectangle[] rectangles, bool interleavedUV = false)
|
||||
{
|
||||
ImageCommandFlags flags = interleavedUV ? ImageCommandFlags.UVs : ImageCommandFlags.None;
|
||||
|
||||
Enqueue(Command.Image);
|
||||
Enqueue(new Frame((int)flags, rectangles.Length / 2));
|
||||
Enqueue(new Frame(texture));
|
||||
|
||||
foreach (QuikRectangle rectangle in rectangles)
|
||||
{
|
||||
Enqueue(rectangle);
|
||||
}
|
||||
}
|
||||
|
||||
public void Image(IQuikTexture texture, QuikRectangle[] rectangles, QuikRectangle[] uvs)
|
||||
{
|
||||
int count = Math.Min(rectangles.Length, uvs.Length);
|
||||
Enqueue(Command.Image);
|
||||
Enqueue(new Frame((int)ImageCommandFlags.UVs, count));
|
||||
Enqueue(new Frame(texture));
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Enqueue(rectangles[i]);
|
||||
Enqueue(uvs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
212
Quik/CommandQueue/Frame.cs
Normal file
212
Quik/CommandQueue/Frame.cs
Normal file
@ -0,0 +1,212 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Quik.CommandQueue
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
public struct Frame
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
private FrameType _type;
|
||||
|
||||
[FieldOffset(sizeof(FrameType) + 0*sizeof(int))]
|
||||
private int _i1;
|
||||
[FieldOffset(sizeof(FrameType) + 1*sizeof(int))]
|
||||
private int _i2;
|
||||
[FieldOffset(sizeof(FrameType) + 2*sizeof(int))]
|
||||
private int _i3;
|
||||
[FieldOffset(sizeof(FrameType) + 3*sizeof(int))]
|
||||
private int _i4;
|
||||
|
||||
[FieldOffset(sizeof(FrameType) + 0*sizeof(float))]
|
||||
private float _f1;
|
||||
[FieldOffset(sizeof(FrameType) + 1*sizeof(float))]
|
||||
private float _f2;
|
||||
[FieldOffset(sizeof(FrameType) + 2*sizeof(float))]
|
||||
private float _f3;
|
||||
[FieldOffset(sizeof(FrameType) + 3*sizeof(float))]
|
||||
private float _f4;
|
||||
|
||||
[FieldOffset(sizeof(FrameType))]
|
||||
private object _object;
|
||||
|
||||
public bool IsCommand => _type == FrameType.Command;
|
||||
public bool IsInteger =>
|
||||
_type == FrameType.IVec1 ||
|
||||
_type == FrameType.IVec2 ||
|
||||
_type == FrameType.IVec3 ||
|
||||
_type == FrameType.IVec4;
|
||||
public bool IsFloat =>
|
||||
_type == FrameType.IVec1 ||
|
||||
_type == FrameType.IVec2 ||
|
||||
_type == FrameType.IVec3 ||
|
||||
_type == FrameType.IVec4;
|
||||
|
||||
public int VectorSize
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (_type)
|
||||
{
|
||||
case FrameType.None:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
case FrameType.Vec2: case FrameType.IVec2:
|
||||
return 2;
|
||||
case FrameType.Vec3: case FrameType.IVec3:
|
||||
return 3;
|
||||
case FrameType.Vec4: case FrameType.IVec4:
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Frame None { get; } = new Frame() {
|
||||
_type = FrameType.None
|
||||
};
|
||||
|
||||
public Frame(Command command) : this((int)command)
|
||||
{
|
||||
}
|
||||
|
||||
public Frame(object o)
|
||||
{
|
||||
_type = FrameType.Object;
|
||||
|
||||
_i1 = _i2 = _i3 = _i4 = default;
|
||||
_f1 = _f2 = _f3 = _f4 = default;
|
||||
_object = null;
|
||||
|
||||
_object = o;
|
||||
}
|
||||
|
||||
public Frame(int i1)
|
||||
{
|
||||
_type = FrameType.IVec1;
|
||||
|
||||
_i1 = _i2 = _i3 = _i4 = default;
|
||||
_f1 = _f2 = _f3 = _f4 = default;
|
||||
_object = null;
|
||||
|
||||
_i1 = i1;
|
||||
}
|
||||
|
||||
public Frame(int i1, int i2)
|
||||
{
|
||||
_type = FrameType.IVec2;
|
||||
|
||||
_i1 = _i2 = _i3 = _i4 = default;
|
||||
_f1 = _f2 = _f3 = _f4 = default;
|
||||
_object = null;
|
||||
|
||||
_i1 = i1;
|
||||
_i2 = i2;
|
||||
}
|
||||
|
||||
public Frame(int i1, int i2, int i3)
|
||||
{
|
||||
_type = FrameType.IVec3;
|
||||
|
||||
_i1 = _i2 = _i3 = _i4 = default;
|
||||
_f1 = _f2 = _f3 = _f4 = default;
|
||||
_object = null;
|
||||
|
||||
_i1 = i1;
|
||||
_i2 = i2;
|
||||
_i3 = i3;
|
||||
}
|
||||
|
||||
public Frame(int i1, int i2, int i3, int i4)
|
||||
{
|
||||
_type = FrameType.IVec4;
|
||||
|
||||
_i1 = _i2 = _i3 = _i4 = default;
|
||||
_f1 = _f2 = _f3 = _f4 = default;
|
||||
_object = null;
|
||||
|
||||
_i1 = i1;
|
||||
_i2 = i2;
|
||||
_i3 = i3;
|
||||
_i4 = i4;
|
||||
}
|
||||
|
||||
public Frame(float f1)
|
||||
{
|
||||
_type = FrameType.Vec1;
|
||||
|
||||
_i1 = _i2 = _i3 = _i4 = default;
|
||||
_f1 = _f2 = _f3 = _f4 = default;
|
||||
_object = null;
|
||||
|
||||
_f1 = f1;
|
||||
}
|
||||
|
||||
public Frame(float f1, float f2)
|
||||
{
|
||||
_type = FrameType.Vec2;
|
||||
|
||||
_i1 = _i2 = _i3 = _i4 = default;
|
||||
_f1 = _f2 = _f3 = _f4 = default;
|
||||
_object = null;
|
||||
|
||||
_f1 = f1;
|
||||
_f2 = f2;
|
||||
}
|
||||
|
||||
public Frame(float f1, float f2, float f3)
|
||||
{
|
||||
_type = FrameType.Vec3;
|
||||
|
||||
_i1 = _i2 = _i3 = _i4 = default;
|
||||
_f1 = _f2 = _f3 = _f4 = default;
|
||||
_object = null;
|
||||
|
||||
_f1 = f1;
|
||||
_f2 = f2;
|
||||
_f3 = f3;
|
||||
}
|
||||
|
||||
public Frame(float f1, float f2, float f3, float f4)
|
||||
{
|
||||
_type = FrameType.Vec4;
|
||||
|
||||
_i1 = _i2 = _i3 = _i4 = default;
|
||||
_f1 = _f2 = _f3 = _f4 = default;
|
||||
_object = null;
|
||||
|
||||
_f1 = f1;
|
||||
_f2 = f2;
|
||||
_f3 = f3;
|
||||
_f4 = f4;
|
||||
}
|
||||
|
||||
public T As<T>() where T : class
|
||||
{
|
||||
return (T)_object;
|
||||
}
|
||||
|
||||
public static implicit operator int(in Frame frame) => frame._i1;
|
||||
public static implicit operator float(in Frame frame) => frame._f1;
|
||||
public static implicit operator Command(in Frame frame) => (Command)frame._i1;
|
||||
|
||||
public static explicit operator Frame(int i) => new Frame(i);
|
||||
public static explicit operator Frame(float f) => new Frame(f);
|
||||
public static implicit operator Frame(Command cmd) => new Frame(cmd);
|
||||
public static implicit operator Frame(in QuikVec2 vector) => new Frame(vector.X, vector.Y);
|
||||
public static implicit operator Frame(in QuikColor color) => new Frame(color.R, color.G, color.B, color.A);
|
||||
public static implicit operator Frame(in QuikRectangle rect) => new Frame(rect.Min.X, rect.Min.Y, rect.Max.X, rect.Max.Y);
|
||||
public static implicit operator Frame(in QuikLine line) => new Frame(line.Start.X, line.Start.Y, line.End.X, line.Start.Y);
|
||||
|
||||
public static void Create(in QuikBezier bezier, out Frame a, out Frame b)
|
||||
{
|
||||
a = new Frame(bezier.Start.X, bezier.Start.Y, bezier.End.X, bezier.End.Y);
|
||||
b = new Frame(bezier.ControlA.X, bezier.ControlA.Y, bezier.ControlB.X, bezier.ControlB.Y);
|
||||
}
|
||||
|
||||
public static void Create(in QuikEllipse ellipse, out Frame a, out Frame b)
|
||||
{
|
||||
a = new Frame(ellipse.Center.X, ellipse.Center.Y);
|
||||
b = new Frame(ellipse.AxisA.X, ellipse.AxisA.Y, ellipse.AxisB.X, ellipse.AxisB.Y);
|
||||
}
|
||||
}
|
||||
}
|
17
Quik/CommandQueue/FrameType.cs
Normal file
17
Quik/CommandQueue/FrameType.cs
Normal file
@ -0,0 +1,17 @@
|
||||
namespace Quik.CommandQueue
|
||||
{
|
||||
public enum FrameType
|
||||
{
|
||||
None,
|
||||
Command,
|
||||
IVec1,
|
||||
IVec2,
|
||||
IVec3,
|
||||
IVec4,
|
||||
Vec1,
|
||||
Vec2,
|
||||
Vec3,
|
||||
Vec4,
|
||||
Object,
|
||||
}
|
||||
}
|
10
Quik/CommandQueue/ImageCommandFlags.cs
Normal file
10
Quik/CommandQueue/ImageCommandFlags.cs
Normal file
@ -0,0 +1,10 @@
|
||||
namespace Quik.CommandQueue
|
||||
{
|
||||
public enum ImageCommandFlags
|
||||
{
|
||||
None = 0,
|
||||
|
||||
Single = 1 << 0,
|
||||
UVs = 1 << 1
|
||||
}
|
||||
}
|
@ -29,7 +29,8 @@ namespace Quik
|
||||
/// <param name="format">Color format of the data.</param>
|
||||
/// <param name="size">Size of the texture data.</param>
|
||||
/// <param name="level">Mip level.</param>
|
||||
void Image(IntPtr data, QuikImageFormat format, QuikVec2 size, int level);
|
||||
/// <param name="alignment">Pixel alignment. Expected to be 1, 2, 4, or 8.</param>
|
||||
void Image(IntPtr data, QuikImageFormat format, QuikVec2 size, int level, int alignment = 4);
|
||||
|
||||
/// <summary>
|
||||
/// Upload texture data.
|
||||
@ -38,7 +39,8 @@ namespace Quik
|
||||
/// <param name="format">Color format for the data.</param>
|
||||
/// <param name="location">Location of the data in the texture.</param>
|
||||
/// <param name="level">Mip level.</param>
|
||||
void SubImage(IntPtr data, QuikImageFormat format, QuikRectangle location, int level);
|
||||
/// <param name="alignment">Pixel alignment. Expected to be 1, 2, 4, or 8.</param>
|
||||
void SubImage(IntPtr data, QuikImageFormat format, QuikRectangle location, int level, int alignment = 4);
|
||||
|
||||
/// <summary>
|
||||
/// Generate the mip maps for the texture.
|
||||
|
@ -308,6 +308,19 @@ namespace Quik
|
||||
Max = new QuikVec2() {X = r, Y = t};
|
||||
Min = new QuikVec2() {X = l, Y = b};
|
||||
}
|
||||
|
||||
public bool Contains(QuikVec2 point)
|
||||
{
|
||||
return
|
||||
point.X > Left && point.X < Right &&
|
||||
point.Y > Bottom && point.Y < Top;
|
||||
}
|
||||
|
||||
internal void Translate(in QuikVec2 offset)
|
||||
{
|
||||
Min += offset;
|
||||
Max += offset;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -7,6 +7,8 @@ namespace Quik
|
||||
RgbaU8,
|
||||
RedF,
|
||||
RgbF,
|
||||
RgbaF
|
||||
RgbaF,
|
||||
AlphaU8,
|
||||
AlphaF
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user