From 41b7bebba5462402b909b02e4b46ca86389afb00 Mon Sep 17 00:00:00 2001 From: "H. Utku Maden" Date: Thu, 29 Jun 2023 10:42:02 +0300 Subject: [PATCH] Rename geometry types with Q prefix instead of Quik. --- Quik.FreeType/FreeTypeFont.cs | 26 +- Quik.OpenTK/GL30Driver.cs | 41 + Quik.OpenTK/OpenGLTexture.cs | 6 +- Quik.OpenTK/OpenGLTextureManager.cs | 2 +- Quik/CommandMachine/CommandEngine.cs | 16 +- Quik/CommandMachine/CommandQueue.cs | 48 +- Quik/CommandMachine/Frame.cs | 32 +- Quik/Controls/Button.cs | 60 +- Quik/Controls/Container.cs | 3 +- Quik/Controls/Control.cs | 17 +- Quik/Controls/Label.cs | 39 +- Quik/Controls/RootControl.cs | 10 +- Quik/IQuikTexture.cs | 4 +- Quik/IQuikTextureManager.cs | 4 +- Quik/Mouse.cs | 24 +- Quik/QuikApplication.cs | 10 + Quik/QuikCommand.cs | 645 -------- Quik/QuikContext.cs | 51 - Quik/QuikDraw.cs | 43 - Quik/QuikGeometry.cs | 150 +- Quik/QuikStyle.cs | 14 +- Quik/Typography/QuikGlyph.cs | 20 +- Quik/Typography/TextLayout.cs | 24 +- Quik/VertexGenerator/DrawQueue.cs | 14 +- Quik/VertexGenerator/QuikVertex.cs | 12 +- Quik/VertexGenerator/QuikVertexGenerator.cs | 1574 ------------------- Quik/VertexGenerator/VertexCommandEngine.cs | 274 ++-- QuikTestApplication/Program.cs | 226 +-- QuikTestApplication/TestFont.cs | 16 +- 29 files changed, 485 insertions(+), 2920 deletions(-) create mode 100644 Quik/QuikApplication.cs delete mode 100644 Quik/QuikCommand.cs delete mode 100644 Quik/QuikContext.cs delete mode 100644 Quik/QuikDraw.cs delete mode 100644 Quik/VertexGenerator/QuikVertexGenerator.cs diff --git a/Quik.FreeType/FreeTypeFont.cs b/Quik.FreeType/FreeTypeFont.cs index 1c2ad34..6d2112d 100644 --- a/Quik.FreeType/FreeTypeFont.cs +++ b/Quik.FreeType/FreeTypeFont.cs @@ -64,15 +64,15 @@ namespace Quik.FreeType entry.Atlas = new Atlas(_owner.Context.TextureManager, _library); _textures.Add(entry.Atlas); } - entry.Atlas.AttachGlyph(_face.Glyph, out QuikRectangle uvs); + entry.Atlas.AttachGlyph(_face.Glyph, out QRectangle uvs); entry.Metrics = new QuikGlyph( character, uvs, - new QuikVec2(_face.Glyph.Metrics.Width / 64f, _face.Glyph.Metrics.Height / 64f), - new QuikVec2(_face.Glyph.Metrics.HorizontalBearingX / 64f, _face.Glyph.Metrics.HorizontalBearingY / 64f), - new QuikVec2(_face.Glyph.Metrics.VerticalBearingX / 64f , _face.Glyph.Metrics.VerticalBearingY / 64f), - new QuikVec2(_face.Glyph.Metrics.HorizontalAdvance / 64f, _face.Glyph.Metrics.VerticalAdvance / 64f)); + new QVec2(_face.Glyph.Metrics.Width / 64f, _face.Glyph.Metrics.Height / 64f), + new QVec2(_face.Glyph.Metrics.HorizontalBearingX / 64f, _face.Glyph.Metrics.HorizontalBearingY / 64f), + new QVec2(_face.Glyph.Metrics.VerticalBearingX / 64f , _face.Glyph.Metrics.VerticalBearingY / 64f), + new QVec2(_face.Glyph.Metrics.HorizontalAdvance / 64f, _face.Glyph.Metrics.VerticalAdvance / 64f)); _entries[character] = entry; @@ -104,7 +104,7 @@ namespace Quik.FreeType { public QuikTexture Texture; - private QuikVec2 _pointer = new QuikVec2(); + private QVec2 _pointer = new QVec2(); private float _verticalAdvance = 0; private FTLibrary _ft; private FTBitmap _bitmap; @@ -112,7 +112,7 @@ namespace Quik.FreeType public Atlas(IQuikTextureManager textureManager, FTLibrary ft) { Texture = textureManager.CreateTexture( - new QuikVec2(4096, 4096), + new QVec2(4096, 4096), false, QuikImageFormat.RgbaU8); @@ -126,14 +126,14 @@ namespace Quik.FreeType return true; } - public void AttachGlyph(in FTGlyphSlot slot, out QuikRectangle UVs) + public void AttachGlyph(in FTGlyphSlot slot, out QRectangle UVs) { FT.BitmapConvert(_ft, slot.Bitmap, ref _bitmap, 1); - QuikRectangle position = - new QuikRectangle( - _pointer + new QuikVec2(_bitmap.Width + 1, _bitmap.Rows + 1), - _pointer + new QuikVec2(1, 1)); + QRectangle position = + new QRectangle( + _pointer + new QVec2(_bitmap.Width + 1, _bitmap.Rows + 1), + _pointer + new QVec2(1, 1)); Texture.SubImage( _bitmap.Buffer, @@ -145,7 +145,7 @@ namespace Quik.FreeType _pointer.X += _bitmap.Width + 2; _verticalAdvance = Math.Max(_verticalAdvance, slot.Bitmap.Rows + 2); - UVs = new QuikRectangle( + UVs = new QRectangle( position.Right / 4096, position.Bottom / 4096, position.Left / 4096, diff --git a/Quik.OpenTK/GL30Driver.cs b/Quik.OpenTK/GL30Driver.cs index 7a01caa..bee3f57 100644 --- a/Quik.OpenTK/GL30Driver.cs +++ b/Quik.OpenTK/GL30Driver.cs @@ -2,6 +2,8 @@ using System; using System.IO; using System.Reflection; using Quik.OpenGL; +using Quik.VertexGenerator; +using Matrix4 = OpenTK.Mathematics.Matrix4; using static Quik.OpenGL.GLEnum; namespace Quik.OpenTK @@ -86,9 +88,16 @@ namespace Quik.OpenTK { location = GL.GetAttribLocation(_sp, name); } + + _vbo = GL.GenBuffer(); + _ebo = GL.GenBuffer(); + _vao = GL.GenVertexArray(); } private readonly int _sp; + private readonly int _vao; + private readonly int _vbo; + private readonly int _ebo; private const string _nameM4View = "m4View"; private readonly int _locM4View; @@ -122,6 +131,38 @@ namespace Quik.OpenTK SdfAuxEnable = 1 << 3, } + public void Draw(DrawQueue queue) + { + GL.UseProgram(_sp); + GL.BindVertexArray(_vao); + + GL.BindBuffer(GL_ARRAY_BUFFER, _vbo); + GL.BufferData(GL_ARRAY_BUFFER, queue.VertexCount * QuikVertex.Stride, queue.VertexArray, GL_STREAM_DRAW); + GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); + GL.BufferData(GL_ELEMENT_ARRAY_BUFFER, queue.ElementCount * sizeof(int), queue.ElementArray, GL_STREAM_DRAW); + + GL.VertexAttribPointer(_locV2Position, 2, GL_FLOAT, false, QuikVertex.Stride, QuikVertex.PositionOffset); + GL.VertexAttribPointer(_locV2Texture, 2, GL_FLOAT, false, QuikVertex.Stride, QuikVertex.TextureCoordinatesOffset); + GL.VertexAttribPointer(_locV4Color, 4, GL_UNSIGNED_BYTE, false, QuikVertex.Stride, QuikVertex.ColorOffset); + GL.EnableVertexAttribArray(_locV2Position); + GL.EnableVertexAttribArray(_locV2Texture); + GL.EnableVertexAttribArray(_locV4Color); + + GL.Enable(GL_BLEND); + GL.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + Matrix4 m = Matrix4.Identity; + GL.UniformMatrix4(_locM4Model, false, ref m.Row0.X); + + foreach (DrawCall call in queue) + { + GL.BindTexture(GL_TEXTURE_2D, ((OpenGLTexture)call.Texture)?.TextureId ?? 0); + m = Matrix4.CreateOrthographicOffCenter(0, call.Bounds.Right, 0, call.Bounds.Top, 1.0f, -1.0f); + GL.UniformMatrix4(_locM4View, false, ref m.Row0.X); + GL.DrawElements(GL_TRIANGLES, call.Count, GL_UNSIGNED_INT, call.Start); + } + } + private bool _isDisposed = false; private void Dispose(bool disposing) { diff --git a/Quik.OpenTK/OpenGLTexture.cs b/Quik.OpenTK/OpenGLTexture.cs index dfa17b0..2fc8481 100644 --- a/Quik.OpenTK/OpenGLTexture.cs +++ b/Quik.OpenTK/OpenGLTexture.cs @@ -13,7 +13,7 @@ namespace Quik.OpenTK private int _height; private bool _mipmaps; - internal OpenGLTexture(OpenGLTextureManager manager, QuikImageFormat format, QuikVec2 size, bool mipmaps) + internal OpenGLTexture(OpenGLTextureManager manager, QuikImageFormat format, QVec2 size, bool mipmaps) { Manager = manager; _mipmaps = mipmaps; @@ -61,7 +61,7 @@ namespace Quik.OpenTK public override bool Mipmaps => _mipmaps; /// - public override void Image(IntPtr data, QuikImageFormat format, QuikVec2 size, int level, int alignment = 4) + public override void Image(IntPtr data, QuikImageFormat format, QVec2 size, int level, int alignment = 4) { GL.BindTexture(GL_TEXTURE_2D, TextureId); GL.PixelStore(GL_UNPACK_ALIGNMENT, alignment); @@ -69,7 +69,7 @@ namespace Quik.OpenTK } /// - public override void SubImage(IntPtr data, QuikImageFormat format, QuikRectangle location, int level, int alignment = 4) + public override void SubImage(IntPtr data, QuikImageFormat format, QRectangle location, int level, int alignment = 4) { GL.BindTexture(GL_TEXTURE_2D, TextureId); GL.PixelStore(GL_UNPACK_ALIGNMENT, alignment); diff --git a/Quik.OpenTK/OpenGLTextureManager.cs b/Quik.OpenTK/OpenGLTextureManager.cs index 3ff73cc..79f6052 100644 --- a/Quik.OpenTK/OpenGLTextureManager.cs +++ b/Quik.OpenTK/OpenGLTextureManager.cs @@ -9,7 +9,7 @@ namespace Quik.OpenTK private List _reclaimList = new List(); - public QuikTexture CreateTexture(QuikVec2 size, bool mipmaps, QuikImageFormat format) + public QuikTexture CreateTexture(QVec2 size, bool mipmaps, QuikImageFormat format) { return new OpenGLTexture(this, format, size, mipmaps); } diff --git a/Quik/CommandMachine/CommandEngine.cs b/Quik/CommandMachine/CommandEngine.cs index 246bb8e..4514b23 100644 --- a/Quik/CommandMachine/CommandEngine.cs +++ b/Quik/CommandMachine/CommandEngine.cs @@ -9,14 +9,14 @@ namespace Quik.CommandMachine private readonly Stack _zStack = new Stack(); public int ZIndex => _zIndex; - private QuikRectangle _viewport; - private readonly Stack _viewportStack = new Stack(); + private QRectangle _viewport; + private readonly Stack _viewportStack = new Stack(); private readonly Stack _matrixStack = new Stack(); private Command _customCommandBase = Command.CustomCommandBase; private readonly List _customCommands = new List(); - public QuikRectangle Viewport => _viewport; + public QRectangle Viewport => _viewport; // TODO: Make a real matrix class. public float[] ActiveTransforms { get; } @@ -35,7 +35,7 @@ namespace Quik.CommandMachine return id; } - public void ProcessCommands(QuikRectangle bounds, CommandQueue queue) + public void ProcessCommands(QRectangle bounds, CommandQueue queue) { if (!queue.Peek().IsCommand) throw new ArgumentException("The first element in the queue must be a command frame."); @@ -72,13 +72,13 @@ namespace Quik.CommandMachine _viewportStack.Push(_viewport); break; case Command.IntersectViewport: - _viewport = QuikRectangle.Intersect((QuikRectangle)queue.Dequeue(), _viewport); + _viewport = QRectangle.Intersect((QRectangle)queue.Dequeue(), _viewport); break; case Command.StoreViewport: - _viewport = (QuikRectangle)queue.Dequeue(); + _viewport = (QRectangle)queue.Dequeue(); break; case Command.PopViewport: - _viewport = _viewportStack.TryPop(out QuikRectangle viewport) ? viewport : bounds; + _viewport = _viewportStack.TryPop(out QRectangle viewport) ? viewport : bounds; break; case Command.PushZ: _zStack.Push(_zIndex); @@ -111,7 +111,7 @@ namespace Quik.CommandMachine _zIndex = 0; _zStack.Clear(); - _viewport = new QuikRectangle(float.MaxValue, float.MaxValue, float.MinValue, float.MinValue); + _viewport = new QRectangle(float.MaxValue, float.MaxValue, float.MinValue, float.MinValue); _viewportStack.Clear(); _matrixStack.Clear(); diff --git a/Quik/CommandMachine/CommandQueue.cs b/Quik/CommandMachine/CommandQueue.cs index fbd1cc9..6caa034 100644 --- a/Quik/CommandMachine/CommandQueue.cs +++ b/Quik/CommandMachine/CommandQueue.cs @@ -33,13 +33,13 @@ namespace Quik.CommandMachine Enqueue(Command.PushViewport); } - public void IntersectViewport(in QuikRectangle viewport) + public void IntersectViewport(in QRectangle viewport) { Enqueue(Command.IntersectViewport); Enqueue(viewport); } - public void StoreViewport(in QuikRectangle viewport) + public void StoreViewport(in QRectangle viewport) { Enqueue(Command.StoreViewport); Enqueue(viewport); @@ -93,21 +93,21 @@ namespace Quik.CommandMachine Enqueue(Command.PopZ); } - public void Line(in QuikLine line) + public void Line(in QLine line) { Enqueue(Command.Line); Enqueue(line); } - public void Line(params QuikLine[] lines) + public void Line(params QLine[] lines) { Enqueue(Command.Line); Enqueue((Frame)lines.Length); - foreach (QuikLine line in lines) + foreach (QLine line in lines) Enqueue(line); } - public void Bezier(in QuikBezier bezier) + public void Bezier(in QBezier bezier) { Frame a, b; Frame.Create(bezier, out a, out b); @@ -117,14 +117,14 @@ namespace Quik.CommandMachine Enqueue(b); } - public void Bezier(params QuikBezier[] beziers) + public void Bezier(params QBezier[] beziers) { Frame a, b; Enqueue(Command.Bezier); Enqueue((Frame)beziers.Length); - foreach (QuikBezier bezier in beziers) + foreach (QBezier bezier in beziers) { Frame.Create(bezier, out a, out b); Enqueue(a); @@ -132,21 +132,21 @@ namespace Quik.CommandMachine } } - public void Rectangle(in QuikRectangle rectangle) + public void Rectangle(in QRectangle rectangle) { Enqueue(Command.Rectangle); Enqueue(rectangle); } - public void Rectangle(QuikRectangle[] rectangles) + public void Rectangle(QRectangle[] rectangles) { Enqueue(Command.Rectangle); Enqueue((Frame)rectangles.Length); - foreach (QuikRectangle rectangle in rectangles) + foreach (QRectangle rectangle in rectangles) Enqueue(rectangle); } - public void Ellipse(in QuikEllipse ellipse) + public void Ellipse(in QEllipse ellipse) { Frame a, b; Frame.Create(ellipse, out a, out b); @@ -156,12 +156,12 @@ namespace Quik.CommandMachine Enqueue(b); } - public void Ellipse(params QuikEllipse[] ellipses) + public void Ellipse(params QEllipse[] ellipses) { Frame a, b; Enqueue(Command.Ellipse); Enqueue((Frame)ellipses.Length); - foreach (QuikEllipse ellipse in ellipses) + foreach (QEllipse ellipse in ellipses) { Frame.Create(ellipse, out a, out b); Enqueue(a); @@ -169,7 +169,7 @@ namespace Quik.CommandMachine } } - public void Triangle(in QuikTriangle triangle) + public void Triangle(in QTriangle triangle) { Enqueue(Command.Triangle); Enqueue(triangle.A); @@ -177,11 +177,11 @@ namespace Quik.CommandMachine Enqueue(triangle.C); } - public void Triangle(params QuikTriangle[] triangles) + public void Triangle(params QTriangle[] triangles) { Enqueue(Command.Triangle); Enqueue((Frame)triangles.Length); - foreach (QuikTriangle triangle in triangles) + foreach (QTriangle triangle in triangles) { Enqueue(triangle.A); Enqueue(triangle.B); @@ -189,17 +189,17 @@ namespace Quik.CommandMachine } } - public void Polygon(params QuikVec2[] polygon) + public void Polygon(params QVec2[] polygon) { Enqueue(Command.Polygon); Enqueue((Frame)polygon.Length); - foreach (QuikVec2 vertex in polygon) + foreach (QVec2 vertex in polygon) { Enqueue(vertex); } } - public void Image(QuikTexture texture, in QuikRectangle rectangle) + public void Image(QuikTexture texture, in QRectangle rectangle) { Enqueue(Command.Image); Enqueue((Frame)(int)ImageCommandFlags.Single); @@ -207,7 +207,7 @@ namespace Quik.CommandMachine Enqueue(rectangle); } - public void Image(QuikTexture texture, in QuikRectangle rectangle, in QuikRectangle uv) + public void Image(QuikTexture texture, in QRectangle rectangle, in QRectangle uv) { Enqueue(Command.Image); Enqueue((Frame)(int)(ImageCommandFlags.Single | ImageCommandFlags.UVs)); @@ -216,7 +216,7 @@ namespace Quik.CommandMachine Enqueue(uv); } - public void Image(QuikTexture texture, QuikRectangle[] rectangles, bool interleavedUV = false) + public void Image(QuikTexture texture, QRectangle[] rectangles, bool interleavedUV = false) { ImageCommandFlags flags = interleavedUV ? ImageCommandFlags.UVs : ImageCommandFlags.None; @@ -224,13 +224,13 @@ namespace Quik.CommandMachine Enqueue(new Frame((int)flags, rectangles.Length / 2)); Enqueue(new Frame(texture)); - foreach (QuikRectangle rectangle in rectangles) + foreach (QRectangle rectangle in rectangles) { Enqueue(rectangle); } } - public void Image(QuikTexture texture, QuikRectangle[] rectangles, QuikRectangle[] uvs) + public void Image(QuikTexture texture, QRectangle[] rectangles, QRectangle[] uvs) { int count = Math.Min(rectangles.Length, uvs.Length); Enqueue(Command.Image); diff --git a/Quik/CommandMachine/Frame.cs b/Quik/CommandMachine/Frame.cs index 83567cc..c0ec7e1 100644 --- a/Quik/CommandMachine/Frame.cs +++ b/Quik/CommandMachine/Frame.cs @@ -229,34 +229,34 @@ namespace Quik.CommandMachine public static explicit operator int(in Frame frame) => frame._i1; public static explicit operator float(in Frame frame) => frame._f1; public static explicit operator Command(in Frame frame) => (Command)frame._i1; - public static explicit operator QuikVec2(in Frame frame) => - frame.IsFloat ? new QuikVec2(frame._f1, frame._f2) : new QuikVec2(frame._i1, frame._i2); - public static explicit operator QuikColor(in Frame frame) => - new QuikColor((byte)frame._i1, (byte)frame._i2, (byte)frame._i3, (byte)frame._i4); - public static explicit operator QuikRectangle(in Frame frame) => + public static explicit operator QVec2(in Frame frame) => + frame.IsFloat ? new QVec2(frame._f1, frame._f2) : new QVec2(frame._i1, frame._i2); + public static explicit operator QColor(in Frame frame) => + new QColor((byte)frame._i1, (byte)frame._i2, (byte)frame._i3, (byte)frame._i4); + public static explicit operator QRectangle(in Frame frame) => frame.IsFloat ? - new QuikRectangle(frame._f1, frame._f2, frame._f3, frame._f4) : - new QuikRectangle(frame._i1, frame._i2, frame._i3, frame._i4); - public static explicit operator QuikLine(in Frame frame) => + new QRectangle(frame._f1, frame._f2, frame._f3, frame._f4) : + new QRectangle(frame._i1, frame._i2, frame._i3, frame._i4); + public static explicit operator QLine(in Frame frame) => frame.IsFloat ? - new QuikLine(frame._f1, frame._f2, frame._f3, frame._f4) : - new QuikLine(frame._i1, frame._i2, frame._i3, frame._i4); + new QLine(frame._f1, frame._f2, frame._f3, frame._f4) : + new QLine(frame._i1, frame._i2, frame._i3, frame._i4); 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.Max.X, rect.Max.Y, rect.Min.X, rect.Min.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 implicit operator Frame(in QVec2 vector) => new Frame(vector.X, vector.Y); + public static implicit operator Frame(in QColor color) => new Frame(color.R, color.G, color.B, color.A); + public static implicit operator Frame(in QRectangle rect) => new Frame(rect.Max.X, rect.Max.Y, rect.Min.X, rect.Min.Y); + public static implicit operator Frame(in QLine 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) + public static void Create(in QBezier 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) + public static void Create(in QEllipse 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); diff --git a/Quik/Controls/Button.cs b/Quik/Controls/Button.cs index bb1b6bd..ba9ca92 100644 --- a/Quik/Controls/Button.cs +++ b/Quik/Controls/Button.cs @@ -1,3 +1,4 @@ +using Quik.CommandMachine; using Quik.Typography; namespace Quik.Controls @@ -60,46 +61,47 @@ namespace Quik.Controls } } - protected override void OnPaint(QuikDraw draw) + protected override void OnPaint(CommandQueue draw) { - QuikRectangle bounds = AbsoluteBounds; + QRectangle bounds = AbsoluteBounds; switch (_class) { default: case ButtonClass.Normal: - draw.Commands.Enqueue(new QuikCommandRectangle(bounds) { - StrokeStyle = NormalStroke, - FillStyle = NormalFill - }); - break; - case ButtonClass.Hover: - draw.Commands.Enqueue(new QuikCommandRectangle(bounds) { - StrokeStyle = HoverStroke, - FillStyle = HoverFill - }); - break; - case ButtonClass.Active: - draw.Commands.Enqueue(new QuikCommandRectangle(bounds) { - StrokeStyle = ActiveStroke, - FillStyle = ActiveFill - }); + draw.Rectangle(bounds); + // draw.Commands.Enqueue(new QuikCommandRectangle(bounds) { + // StrokeStyle = NormalStroke, + // FillStyle = NormalFill + // }); break; + // case ButtonClass.Hover: + // draw.Commands.Enqueue(new QuikCommandRectangle(bounds) { + // StrokeStyle = HoverStroke, + // FillStyle = HoverFill + // }); + // break; + // case ButtonClass.Active: + // draw.Commands.Enqueue(new QuikCommandRectangle(bounds) { + // StrokeStyle = ActiveStroke, + // FillStyle = ActiveFill + // }); + // break; } // Position the text so that it is centered. - float ascender = Root.Context.DefaultFont.Ascender; - float descender = -Root.Context.DefaultFont.Descender; - QuikVec2 position = - bounds.Min + - new QuikVec2( - Padding, - ( - (bounds.Size.Y - ascender - descender) / - 2) - + descender); + // float ascender = Root.Context.DefaultFont.Ascender; + // float descender = -Root.Context.DefaultFont.Descender; + // QuikVec2 position = + // bounds.Min + + // new QuikVec2( + // Padding, + // ( + // (bounds.Size.Y - ascender - descender) / + // 2) + // + descender); - draw.PutText(Text, position); + // draw.PutText(Text, position); } } } \ No newline at end of file diff --git a/Quik/Controls/Container.cs b/Quik/Controls/Container.cs index e86ae3b..9927a42 100644 --- a/Quik/Controls/Container.cs +++ b/Quik/Controls/Container.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using Quik.CommandMachine; namespace Quik.Controls { @@ -86,7 +87,7 @@ namespace Quik.Controls } } - internal override void NotifyPaint(QuikDraw draw) + internal override void NotifyPaint(CommandQueue draw) { base.NotifyPaint(draw); diff --git a/Quik/Controls/Control.cs b/Quik/Controls/Control.cs index 7f3aef0..9314294 100644 --- a/Quik/Controls/Control.cs +++ b/Quik/Controls/Control.cs @@ -1,4 +1,5 @@ using System; +using Quik.CommandMachine; namespace Quik.Controls { @@ -10,18 +11,18 @@ namespace Quik.Controls protected RootControl Root { get; set; } = null; - public QuikRectangle Bounds { get; set; } + public QRectangle Bounds { get; set; } public bool Focused { get => Root.FocusedControl == this; } - public QuikRectangle AbsoluteBounds + public QRectangle AbsoluteBounds { get => Parent is null ? Bounds - : new QuikRectangle(Parent.Bounds.Min + Bounds.Max, Parent.Bounds.Min + Bounds.Min); + : new QRectangle(Parent.Bounds.Min + Bounds.Max, Parent.Bounds.Min + Bounds.Min); set => Bounds = Parent is null ? value - : new QuikRectangle(value.Min - Parent.Bounds.Min, value.Max - Parent.Bounds.Min); + : new QRectangle(value.Min - Parent.Bounds.Min, value.Max - Parent.Bounds.Min); } private MouseButton DownButtons; @@ -29,7 +30,7 @@ namespace Quik.Controls // Hierarchy events. public event EventHandler Update; - public event EventHandler Paint; + public event EventHandler Paint; public event EventHandler RootChanging; public event EventHandler ParentChanging; public event EventHandler FocusLost; @@ -46,7 +47,7 @@ namespace Quik.Controls public event EventHandler MouseLeave; protected virtual void OnUpdate() => Update?.Invoke(this, EventArgs.Empty); - protected virtual void OnPaint(QuikDraw draw) => Paint?.Invoke(this, draw); + protected virtual void OnPaint(CommandQueue draw) => Paint?.Invoke(this, draw); protected virtual void OnParentChanging(ParentChangedEventArgs args) => ParentChanging?.Invoke(this, args); protected virtual void OnRootChanging(RootChangedEventArgs args) => RootChanging?.Invoke(this, args); protected virtual void OnFocusLost(FocusChangedEventArgs args) => FocusLost?.Invoke(this, args); @@ -70,7 +71,7 @@ namespace Quik.Controls OnUpdate(); } - internal virtual void NotifyPaint(QuikDraw draw) + internal virtual void NotifyPaint(CommandQueue draw) { OnPaint(draw); } @@ -101,7 +102,7 @@ namespace Quik.Controls internal virtual void NotifyMouseMove(MouseMoveEventArgs args) { - QuikRectangle bounds = AbsoluteBounds; + QRectangle bounds = AbsoluteBounds; if (bounds.Contains(args.AbsolutePosition)) { diff --git a/Quik/Controls/Label.cs b/Quik/Controls/Label.cs index 5e73f3b..c1827d6 100644 --- a/Quik/Controls/Label.cs +++ b/Quik/Controls/Label.cs @@ -1,3 +1,4 @@ +using Quik.CommandMachine; using Quik.Typography; namespace Quik.Controls @@ -11,26 +12,26 @@ namespace Quik.Controls public QuikFont Font { get; set; } - protected override void OnPaint(QuikDraw draw) - { - if (MultiLine) - { - QuikRectangle absolute = AbsoluteBounds; - QuikVec2 paddingVector = new QuikVec2(Padding, Padding); - QuikRectangle rectangle; - rectangle.Min = absolute.Min + paddingVector; - rectangle.Max = absolute.Min - paddingVector; + // protected override void OnPaint(CommandQueue draw) + // { + // if (MultiLine) + // { + // QuikRectangle absolute = AbsoluteBounds; + // QuikVec2 paddingVector = new QuikVec2(Padding, Padding); + // QuikRectangle rectangle; + // rectangle.Min = absolute.Min + paddingVector; + // rectangle.Max = absolute.Min - paddingVector; - // FIXME: For now use a puttext command. - draw.PutText(Text, rectangle.Min + new QuikVec2(0, rectangle.Size.Y / 3f)); + // // FIXME: For now use a puttext command. + // draw.PutText(Text, rectangle.Min + new QuikVec2(0, rectangle.Size.Y / 3f)); - // draw.FlowText(Text, rectangle); - } - else - { - QuikVec2 position = AbsoluteBounds.Min + new QuikVec2(Padding, Padding + AbsoluteBounds.Size.Y / 3f); - draw.PutText(Text, position); - } - } + // // draw.FlowText(Text, rectangle); + // } + // else + // { + // QuikVec2 position = AbsoluteBounds.Min + new QuikVec2(Padding, Padding + AbsoluteBounds.Size.Y / 3f); + // draw.PutText(Text, position); + // } + // } } } \ No newline at end of file diff --git a/Quik/Controls/RootControl.cs b/Quik/Controls/RootControl.cs index dae06d7..ee4b3d3 100644 --- a/Quik/Controls/RootControl.cs +++ b/Quik/Controls/RootControl.cs @@ -1,14 +1,16 @@ +using Quik.CommandMachine; + namespace Quik.Controls { public sealed class RootControl : Container { - public QuikContext Context { get; } + // public QuikContext Context { get; } public Control FocusedControl { get; private set; } - public RootControl(QuikContext context) + public RootControl(object context) { - Context = context; + // Context = context; } public void Focus(Control which) @@ -24,7 +26,7 @@ namespace Quik.Controls base.NotifyUpdate(); } - public new void NotifyPaint(QuikDraw draw) + public new void NotifyPaint(CommandQueue draw) { base.NotifyPaint(draw); } diff --git a/Quik/IQuikTexture.cs b/Quik/IQuikTexture.cs index 83f68b4..2f3bf93 100644 --- a/Quik/IQuikTexture.cs +++ b/Quik/IQuikTexture.cs @@ -40,7 +40,7 @@ namespace Quik /// Size of the texture data. /// Mip level. /// Pixel alignment. Expected to be 1, 2, 4, or 8. - public abstract void Image(IntPtr data, QuikImageFormat format, QuikVec2 size, int level, int alignment = 4); + public abstract void Image(IntPtr data, QuikImageFormat format, QVec2 size, int level, int alignment = 4); /// /// Upload texture data. @@ -50,7 +50,7 @@ namespace Quik /// Location of the data in the texture. /// Mip level. /// Pixel alignment. Expected to be 1, 2, 4, or 8. - public abstract void SubImage(IntPtr data, QuikImageFormat format, QuikRectangle location, int level, int alignment = 4); + public abstract void SubImage(IntPtr data, QuikImageFormat format, QRectangle location, int level, int alignment = 4); /// /// Generate the mip maps for the texture. diff --git a/Quik/IQuikTextureManager.cs b/Quik/IQuikTextureManager.cs index 64ff7ef..289d3b8 100644 --- a/Quik/IQuikTextureManager.cs +++ b/Quik/IQuikTextureManager.cs @@ -8,7 +8,7 @@ namespace Quik /// /// The context that owns the texture manager. /// - QuikContext Context { get; set; } + // QuikContext Context { get; set; } /// /// Create a texture. @@ -21,7 +21,7 @@ namespace Quik /// All parameters are hints. If there is a situation where the texture does not /// have mip levels, or format cannot be specified, ignore these parameters. /// - QuikTexture CreateTexture(QuikVec2 size, bool mipmaps, QuikImageFormat format); + QuikTexture CreateTexture(QVec2 size, bool mipmaps, QuikImageFormat format); /// /// A function called on context clear. (useful for discarding old textures) diff --git a/Quik/Mouse.cs b/Quik/Mouse.cs index 146a063..c631e7e 100644 --- a/Quik/Mouse.cs +++ b/Quik/Mouse.cs @@ -16,10 +16,10 @@ namespace Quik public struct MouseState { - public readonly QuikVec2 AbsolutePosition; + public readonly QVec2 AbsolutePosition; public readonly MouseButton ButtonsDown; - public MouseState(QuikVec2 position, MouseButton down) + public MouseState(QVec2 position, MouseButton down) { AbsolutePosition = position; ButtonsDown = down; @@ -28,21 +28,21 @@ namespace Quik public class MouseButtonEventArgs : EventArgs { - public QuikVec2 AbsolutePosition { get; } + public QVec2 AbsolutePosition { get; } public MouseButton Buttons { get; } - public MouseButtonEventArgs(QuikVec2 position, MouseButton buttons) + public MouseButtonEventArgs(QVec2 position, MouseButton buttons) { AbsolutePosition = position; Buttons = buttons; } - public QuikVec2 RelativePosition(QuikVec2 origin) + public QVec2 RelativePosition(QVec2 origin) { return AbsolutePosition - origin; } - public QuikVec2 RelativePosition(Controls.Control control) + public QVec2 RelativePosition(Controls.Control control) { return AbsolutePosition - control.AbsoluteBounds.Min; } @@ -50,23 +50,23 @@ namespace Quik public class MouseMoveEventArgs : EventArgs { - public QuikVec2 AbsolutePosition { get; } - public QuikVec2 LastPosition { get; } - public QuikVec2 Motion { get; } + public QVec2 AbsolutePosition { get; } + public QVec2 LastPosition { get; } + public QVec2 Motion { get; } - public MouseMoveEventArgs(QuikVec2 position, QuikVec2 lastPosition) + public MouseMoveEventArgs(QVec2 position, QVec2 lastPosition) { AbsolutePosition = position; LastPosition = lastPosition; Motion = position - lastPosition; } - public QuikVec2 RelativePosition(QuikVec2 origin) + public QVec2 RelativePosition(QVec2 origin) { return AbsolutePosition - origin; } - public QuikVec2 RelativePosition(Controls.Control control) + public QVec2 RelativePosition(Controls.Control control) { return AbsolutePosition - control.AbsoluteBounds.Min; } diff --git a/Quik/QuikApplication.cs b/Quik/QuikApplication.cs new file mode 100644 index 0000000..e630b8f --- /dev/null +++ b/Quik/QuikApplication.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; + +namespace Quik +{ + public class QuikApplication + { + + } +} \ No newline at end of file diff --git a/Quik/QuikCommand.cs b/Quik/QuikCommand.cs deleted file mode 100644 index 2187dd4..0000000 --- a/Quik/QuikCommand.cs +++ /dev/null @@ -1,645 +0,0 @@ -namespace Quik -{ - /// - /// Enumeration of QUIK commands. - /// - public enum QuikCommandType - { - /// - /// Nothing. - /// - /// - None, - - /// - /// Set a mask region. - /// - Mask, - - /// - /// Draw a line. - /// - /// - Line, - - /// - /// Draw multiple lines. - /// - Lines, - - /// - /// Draw a Bezier curve. - /// - Bezier, - - /// - /// Draw a rectangle. - /// - Rectangle, - - /// - /// Draw multiple rectangles. - /// - Rectangles, - - /// - /// Draw an ellipse. - /// - Ellipse, - - /// - /// Draw multiple ellipses. - /// - Ellipses, - - /// - /// Draw a triangle. - /// - Triangle, - - /// - /// Draw multiple triangles. - /// - Triangles, - - /// - /// Draw a polygon. - /// - Polygon, - - /// - /// Put a character. - /// - PutChar, - - /// - /// Put text. - /// - PutText, - - /// - /// Flow text in box. - /// - FlowText, - - EmitTypeset, - - /// - /// Clear the image mask. - /// - StencilMaskClear, - - /// - /// Create an image mask with the following commands. - /// - StencilMaskBegin, - - /// - /// End the image mask commands. - /// - StencilMaskEnd, - - /// - /// Draw an image. - /// - Image, - - /// - /// Begin defining custom commands after this value. - /// - /// - CustomCommandRange = 1024, - } - - /// - /// A single QUIK command. - /// - public abstract class QuikCommand - { - /// - /// The type ID for the QUIK command. - /// - public abstract QuikCommandType Type { get; } - } - - /// - /// Does nothing. - /// - public sealed class QuikCommandNone : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.None; - } - - public sealed class QuikCommandMask : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Mask; - - public QuikRectangle Bounds { get; } - - public QuikCommandMask(QuikRectangle bounds) - { - Bounds = bounds; - } - } - - /// - /// Draws a line. - /// - public sealed class QuikCommandLine : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Line; - - /// - /// The line to draw. - /// - public QuikLine Line { get; } - - /// - /// Stroke style of the line. - /// - public QuikStrokeStyle Style { get; set; } - - /// - /// Create a draw line command. - /// - /// The line to draw. - public QuikCommandLine(QuikLine line) - { - Line = line; - } - } - - /// - /// Draw multiple lines. - /// - public sealed class QuikCommandLines : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Lines; - - /// - /// The array of lines to draw. - /// - public QuikLine[] Lines { get; } - - /// - /// Stroke style of the lines. - /// - public QuikStrokeStyle Style { get; set; } - - /// - /// Create a draw lines command. - /// - /// The lines to draw. - public QuikCommandLines(QuikLine[] lines) - { - Lines = lines; - } - } - - /// - /// Draw a Bezier curve. - /// - public sealed class QuikCommandBezier : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Bezier; - - /// - /// The Bezier curve segments to draw. - /// - public QuikBezier[] Segments; - - /// - /// Stroke style of the curve. - /// - public QuikStrokeStyle Style { get; set; } - - /// - /// Create a draw Bezier curve command. - /// - /// The Bezier curve segments to draw. - public QuikCommandBezier(QuikBezier[] segments) - { - Segments = segments; - } - } - - /// - /// Draw a rectangle. - /// - public sealed class QuikCommandRectangle : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Rectangle; - - /// - /// The rectangle to draw. - /// - public QuikRectangle Rectangle { get; } - - /// - /// Stroke style of the border. - /// - public QuikStrokeStyle StrokeStyle { get; set; } - - /// - /// Fill style of the contents. - /// - public QuikFillStyle FillStyle { get; set; } - - /// - /// Radius for round corners. - /// - public float CornerRadius { get; set; } - - /// - /// Create a draw rectangle command. - /// - /// The rectangle to draw. - public QuikCommandRectangle(QuikRectangle rectangle) - { - Rectangle = rectangle; - } - } - - /// - /// Draw rectangles. - /// - public sealed class QuikCommandRectangles : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Rectangles; - - /// - /// The rectangles to draw. - /// - public QuikRectangle[] Rectangles { get; } - - /// - /// Stroke style of the border. - /// - public QuikStrokeStyle StrokeStyle { get; set; } - - /// - /// Fill style of the contents. - /// - public QuikFillStyle FillStyle { get; set; } - - /// - /// Radius for round corners. - /// - public float CornerRadius { get; set; } - - /// - /// Create a draw rectangles commands. - /// - /// The rectangles to draw. - public QuikCommandRectangles(QuikRectangle[] rectangles) - { - Rectangles = rectangles; - } - } - - /// - /// Draw an ellipse. - /// - public sealed class QuikCommandEllipse : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Ellipse; - - /// - /// The ellipse to draw. - /// - public QuikEllipse Ellipse { get; } - - /// - /// Stroke style of the border. - /// - public QuikStrokeStyle StrokeStyle { get; set; } - - /// - /// Fill style of the contents. - /// - public QuikFillStyle FillStyle { get; set; } - - /// - /// Create a draw ellipse command. - /// - /// The ellipse to draw. - public QuikCommandEllipse(QuikEllipse ellipse) - { - Ellipse = ellipse; - } - } - - /// - /// Draw ellipses. - /// - public sealed class QuikCommandEllipses : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Ellipses; - - /// - /// The ellipses to draw. - /// - public QuikEllipse[] Ellipses { get; } - - /// - /// Stroke style of the border. - /// - public QuikStrokeStyle StrokeStyle { get; set; } - - /// - /// Fill style of the contents. - /// - public QuikFillStyle FillStyle { get; set; } - - /// - /// Create a draw ellipses command. - /// - /// The ellipses to draw. - public QuikCommandEllipses(QuikEllipse[] ellipses) - { - Ellipses = ellipses; - } - } - - /// - /// Create a draw triangle command. - /// - public sealed class QuikCommandTriangle : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Triangle; - - /// - /// The triangle to draw. - /// - public QuikTriangle Triangle { get; } - - /// - /// Stroke style of the border. - /// - public QuikStrokeStyle StrokeStyle { get; set; } - - /// - /// Fill style of the contents. - /// - public QuikFillStyle FillStyle { get; set; } - - /// - /// Create a draw triangle command. - /// - /// The triangles to draw. - public QuikCommandTriangle(QuikTriangle triangle) - { - Triangle = triangle; - } - } - - /// - /// Draw triangles. - /// - public sealed class QuikCommandTriangles : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Triangles; - - /// - /// The triangles to draw. - /// - public QuikTriangle[] Triangles { get; } - - /// - /// Stroke style of the border. - /// - public QuikStrokeStyle StrokeStyle { get; set; } - - /// - /// Fill style of the contents. - /// - public QuikFillStyle FillStyle { get; set; } - - /// - /// Create a draw triangles command. - /// - /// The triangles to draw. - public QuikCommandTriangles(QuikTriangle[] triangles) - { - Triangles = triangles; - } - } - - /// - /// Draw a polygon. - /// - /// Behavior is defined by rendering backend for concave polygons. - public sealed class QuikCommandPolygon : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Polygon; - - /// - /// The vertices that make up the polygon. - /// - public QuikVec2[] Polygon { get; } - - /// - /// Stroke style of the border. - /// - public QuikStrokeStyle StrokeStyle { get; set; } - - /// - /// Fill style of the contents. - /// - public QuikFillStyle FillStyle { get; set; } - - /// - /// Create a draw polygon command. - /// - /// The polygon to draw. - public QuikCommandPolygon(QuikVec2[] polygon) - { - Polygon = polygon; - } - } - - /// - /// Put a character. - /// - public sealed class QuikCommandPutChar : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.PutChar; - - /// - /// The character to put. - /// - /// This field is integer to accomodate for surrogate pairs. - public int Character { get; } - - /// - /// The baseline start position of the character. - /// - public QuikVec2 Position { get; } - - /// - /// Create a put character command. - /// - /// The character to put. - /// The baseline start position of the character. - public QuikCommandPutChar(int character, QuikVec2 position) - { - Character = character; - Position = position; - } - - /// - /// Create a put character command. - /// - /// The character to put. - /// The baseline start position of the character. - public QuikCommandPutChar(char character, QuikVec2 position) : this((int) character, position) - { - } - } - - /// - /// Put some text. - /// - public sealed class QuikCommandPutText : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.PutText; - - /// - /// The text to put. - /// - public string Text { get; } - - /// - /// The baseline start position of the text. - /// - public QuikVec2 Position { get; } - - /// - /// Create a put text command. - /// - /// The text to put. - /// The baseline start position of the text. - public QuikCommandPutText(string text, QuikVec2 position) - { - Text = text; - Position = position; - } - } - - /// - /// Flow text into a box. - /// - public sealed class QuikCommandFlowText : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.FlowText; - - /// - /// The text to flow. - /// - public string Text { get; } - - /// - /// The flowing box boundaries. - /// - public QuikRectangle Bounds { get; } - - /// - /// Create a flow text command. - /// - /// The text to flow. - /// The flowing box boundaries. - public QuikCommandFlowText(string text, QuikRectangle bounds) - { - Text = text; - Bounds = bounds; - } - } - - /// - /// Emit previously typeset text. - /// - public sealed class QuikCommandEmitText : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.EmitTypeset; - - /// - /// The typeset group to emit. - /// - public Typography.TypesetGroup Group { get; } - - public QuikVec2 Offset { get; } - - /// - /// Create an emit typeset text command. - /// - /// The typeset group to emit. - public QuikCommandEmitText(Typography.TypesetGroup group) - { - Group = group; - Offset = new QuikVec2(0, 0); - } - - /// - /// Create an emit typeset text command. - /// - /// The typeset group to emit. - /// The offset to emit at. - public QuikCommandEmitText(Typography.TypesetGroup group, QuikVec2 offset) - { - Group = group; - Offset = offset; - } - } - - /// - /// Clear the stencil buffer. - /// - public sealed class QuikCommandStencilClear : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.StencilMaskClear; - } - - /// - /// Begin rendering to the stencil buffer. - /// - public sealed class QuikCommandStencilBegin : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.StencilMaskBegin; - } - - /// - /// End rendering to the stencil buffer. - /// - public sealed class QuikCommandStencilEnd : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.StencilMaskEnd; - } - - /// - /// Draw an image. - /// - public sealed class QuikCommandImage : QuikCommand - { - /// - public override QuikCommandType Type => QuikCommandType.Image; - } -} \ No newline at end of file diff --git a/Quik/QuikContext.cs b/Quik/QuikContext.cs deleted file mode 100644 index d6eb4a4..0000000 --- a/Quik/QuikContext.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Quik.Typography; - -namespace Quik -{ - /// - /// An object which QUIK commands may be issued to. - /// - public class QuikContext - { - /// - /// Draw queue. - /// - public QuikDraw Draw { get; } = new QuikDraw(); - - /// - /// The object responsible for managing textures. - /// - public IQuikTextureManager TextureManager { get; } - - /// - /// The object responsible for managing fonts. - /// - public IQuikFontManager FontManager { get; } - - public QuikStrokeStyle DefaultStroke { get; set; } = new QuikStrokeStyle(new QuikColor(0xaaaaaaff), 4); - - public QuikFillStyle DefaultFill { get; set; } = new QuikFillStyle() - { - Color = new QuikColor(0xeeeeeeff) - }; - - public QuikFont DefaultFont { get; set; } - - public QuikContext(IQuikTextureManager textureManager, IQuikFontManager fontManager) - { - TextureManager = textureManager; - FontManager = fontManager; - TextureManager.Context = FontManager.Context = this; - } - - /// - /// Clear the context. - /// - public void Clear() - { - Draw.Clear(); - TextureManager.Clear(); - FontManager.Clear(); - } - } -} \ No newline at end of file diff --git a/Quik/QuikDraw.cs b/Quik/QuikDraw.cs deleted file mode 100644 index 6dcd463..0000000 --- a/Quik/QuikDraw.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Collections.Generic; -using System.IO.Compression; -using System.Linq; - -namespace Quik -{ - /// - /// QUIK draw command provider. - /// - public class QuikDraw - { - /// - /// The draw command queue. - /// - public Queue Commands { get; } = new Queue(); - - public void Clear() => Commands.Clear(); - - public void Mask(QuikRectangle bounds) => Commands.Enqueue(new QuikCommandMask(bounds)); - public void Line(QuikLine line) => Commands.Enqueue(new QuikCommandLine(line)); - public void Line(params QuikLine[] lines) => Commands.Enqueue(new QuikCommandLines(lines)); - public void Line(IEnumerable lines) => Commands.Enqueue(new QuikCommandLines(lines.ToArray())); - public void Bezier(params QuikBezier[] curve) => Commands.Enqueue(new QuikCommandBezier(curve)); - public void Bezier(IEnumerable curve) => Commands.Enqueue(new QuikCommandBezier(curve.ToArray())); - public void Rectangle(QuikRectangle rectangle) => Commands.Enqueue(new QuikCommandRectangle(rectangle)); - public void Rectangle(params QuikRectangle[] rectangles) => - Commands.Enqueue(new QuikCommandRectangles(rectangles)); - public void Rectangle(IEnumerable rectangles) => - Commands.Enqueue(new QuikCommandRectangles(rectangles.ToArray())); - public void Triangle(QuikTriangle triangle) => Commands.Enqueue(new QuikCommandTriangle(triangle)); - public void Triangle(params QuikTriangle[] triangles) => Commands.Enqueue(new QuikCommandTriangles(triangles)); - public void Triangle(IEnumerable triangles) => - Commands.Enqueue(new QuikCommandTriangles(triangles.ToArray())); - public void Polygon(params QuikVec2[] polygon) => Commands.Enqueue(new QuikCommandPolygon(polygon)); - public void Polygon(IEnumerable polygon) => Commands.Enqueue(new QuikCommandPolygon(polygon.ToArray())); - public void StencilClear() => Commands.Enqueue(new QuikCommandStencilClear()); - public void StencilBegin() => Commands.Enqueue(new QuikCommandStencilBegin()); - public void StencilEnd() => Commands.Enqueue(new QuikCommandStencilEnd()); - public void PutChar(char chr, QuikVec2 position) => Commands.Enqueue(new QuikCommandPutChar(chr, position)); - public void PutText(string text, QuikVec2 position) => Commands.Enqueue(new QuikCommandPutText(text, position)); - public void FlowText(string text, QuikRectangle bounds) => Commands.Enqueue(new QuikCommandFlowText(text, bounds)); - } -} \ No newline at end of file diff --git a/Quik/QuikGeometry.cs b/Quik/QuikGeometry.cs index 28b051d..06be595 100644 --- a/Quik/QuikGeometry.cs +++ b/Quik/QuikGeometry.cs @@ -8,69 +8,69 @@ namespace Quik /// A 2 dimensional Vector. /// [DebuggerDisplay("({X}, {Y})")] - public struct QuikVec2 + public struct QVec2 { public float X; public float Y; public float Magnitude => MathF.Sqrt(X * X + Y * Y); - public QuikVec2(float x, float y) + public QVec2(float x, float y) { X = x; Y = y; } - public QuikVec2 Normalize() => this * (1.0f / Magnitude); + public QVec2 Normalize() => this * (1.0f / Magnitude); public float Atan2() => MathF.Atan2(Y, X); - public static QuikVec2 operator +(QuikVec2 a, QuikVec2 b) + public static QVec2 operator +(QVec2 a, QVec2 b) { - return new QuikVec2() + return new QVec2() { X = a.X + b.X, Y = a.Y + b.Y }; } - public static QuikVec2 operator -(QuikVec2 a) + public static QVec2 operator -(QVec2 a) { - return new QuikVec2() + return new QVec2() { X = -a.X, Y = -a.Y }; } - public static QuikVec2 operator -(QuikVec2 a, QuikVec2 b) + public static QVec2 operator -(QVec2 a, QVec2 b) { - return new QuikVec2() + return new QVec2() { X = a.X - b.X, Y = a.Y - b.Y }; } - public static QuikVec2 operator *(float a, QuikVec2 b) + public static QVec2 operator *(float a, QVec2 b) { - return new QuikVec2() + return new QVec2() { X = a * b.X, Y = a * b.Y }; } - public static QuikVec2 operator *(QuikVec2 a, float b) => b * a; + public static QVec2 operator *(QVec2 a, float b) => b * a; - public static bool operator ==(QuikVec2 a, QuikVec2 b) => a.X == b.X && a.Y == b.Y; + public static bool operator ==(QVec2 a, QVec2 b) => a.X == b.X && a.Y == b.Y; - public static bool operator !=(QuikVec2 a, QuikVec2 b) => a.X != b.X || a.Y != b.Y; + public static bool operator !=(QVec2 a, QVec2 b) => a.X != b.X || a.Y != b.Y; public override bool Equals(object obj) { - if (obj is QuikVec2) + if (obj is QVec2) { - return (QuikVec2) obj == this; + return (QVec2) obj == this; } else { @@ -83,7 +83,7 @@ namespace Quik return 63671 * X.GetHashCode() ^ 81083 * Y.GetHashCode(); } - public static float Dot(QuikVec2 a, QuikVec2 b) + public static float Dot(QVec2 a, QVec2 b) { return a.X * b.X + a.Y * b.Y; } @@ -93,7 +93,7 @@ namespace Quik /// A RGBA color value. /// [DebuggerDisplay("({R}, {G}, {B}, {A})")] - public struct QuikColor + public struct QColor { /// /// Red channel. @@ -112,7 +112,7 @@ namespace Quik /// public byte A; - public QuikColor(byte r, byte g, byte b, byte a) + public QColor(byte r, byte g, byte b, byte a) { R = r; G = g; @@ -120,52 +120,52 @@ namespace Quik A = a; } - public QuikColor(byte r, byte g, byte b) : this(r, g, b, 1) { } + public QColor(byte r, byte g, byte b) : this(r, g, b, 1) { } - public QuikColor(uint hexCode) + public QColor(uint hexCode) { R = (byte)((hexCode >> 24) & 0xFF); G = (byte)((hexCode >> 16) & 0xFF); B = (byte)((hexCode >> 8 ) & 0xFF); A = (byte)((hexCode >> 0 ) & 0xFF); } - public QuikColor(int hexCode) : this((uint)hexCode) { } + public QColor(int hexCode) : this((uint)hexCode) { } - public static readonly QuikColor Black = new QuikColor(0, 0, 0, 255); - public static readonly QuikColor Red = new QuikColor(255, 0, 0, 255); - public static readonly QuikColor Green = new QuikColor(0, 255, 0, 255); - public static readonly QuikColor Blue = new QuikColor(0, 0, 255, 255); - public static readonly QuikColor Yellow = new QuikColor(255, 255, 0, 255); - public static readonly QuikColor Cyan = new QuikColor(0, 255, 255, 255); - public static readonly QuikColor Magenta = new QuikColor(255, 0, 255, 255); - public static readonly QuikColor White = new QuikColor(255, 255, 255, 255); + public static readonly QColor Black = new QColor(0, 0, 0, 255); + public static readonly QColor Red = new QColor(255, 0, 0, 255); + public static readonly QColor Green = new QColor(0, 255, 0, 255); + public static readonly QColor Blue = new QColor(0, 0, 255, 255); + public static readonly QColor Yellow = new QColor(255, 255, 0, 255); + public static readonly QColor Cyan = new QColor(0, 255, 255, 255); + public static readonly QColor Magenta = new QColor(255, 0, 255, 255); + public static readonly QColor White = new QColor(255, 255, 255, 255); } /// /// A bezier curve segment. /// [DebuggerDisplay("{Start} -- {ControlA} -- {ControlB} -- {End}")] - public struct QuikBezier + public struct QBezier { /// /// Segment start point. /// - public QuikVec2 Start; + public QVec2 Start; /// /// Start point control point. /// - public QuikVec2 ControlA; + public QVec2 ControlA; /// /// End point control point. /// - public QuikVec2 ControlB; + public QVec2 ControlB; /// /// Segment end point. /// - public QuikVec2 End; + public QVec2 End; /// /// An approximation of the arc length of the bezier curve, for calculating rasterization resolution. @@ -174,7 +174,7 @@ namespace Quik 0.5f * (End - Start).Magnitude + 0.5f * ((ControlA - Start).Magnitude + (ControlB - ControlA).Magnitude + (End - ControlB).Magnitude); - public QuikBezier(QuikVec2 start, QuikVec2 controlA, QuikVec2 controlB, QuikVec2 end) + public QBezier(QVec2 start, QVec2 controlA, QVec2 controlB, QVec2 end) { Start = start; ControlA = controlA; @@ -182,7 +182,7 @@ namespace Quik End = end; } - public QuikBezier( + public QBezier( float startX, float startY, float controlAx, @@ -192,10 +192,10 @@ namespace Quik float endX, float endY) : this( - new QuikVec2(startX, startY), - new QuikVec2(controlAx, controlAy), - new QuikVec2(controlBx, controlBy), - new QuikVec2(endX, endY)) + new QVec2(startX, startY), + new QVec2(controlAx, controlAy), + new QVec2(controlBx, controlBy), + new QVec2(endX, endY)) { } @@ -204,7 +204,7 @@ namespace Quik /// /// Control parameter (between 0 and 1) /// The point on the curve. - public QuikVec2 GetBezierPoint(float t) + public QVec2 GetBezierPoint(float t) { float T = 1 - t; return @@ -219,7 +219,7 @@ namespace Quik /// /// Control parameter (between 0 and 1) /// The tangent curve. - public QuikVec2 GetBezierTangent(float t) + public QVec2 GetBezierTangent(float t) { float T = 1 - t; return @@ -230,10 +230,10 @@ namespace Quik ).Normalize(); } - internal QuikVec2 GetBezierNormal(float t) + internal QVec2 GetBezierNormal(float t) { - QuikVec2 tangent = GetBezierTangent(t); - return new QuikVec2(-tangent.Y, tangent.X); + QVec2 tangent = GetBezierTangent(t); + return new QVec2(-tangent.Y, tangent.X); } } @@ -241,25 +241,25 @@ namespace Quik /// A line segment. /// [DebuggerDisplay("{Start} -- {End}")] - public struct QuikLine + public struct QLine { /// /// Start point. /// - public QuikVec2 Start; + public QVec2 Start; /// /// End point. /// - public QuikVec2 End; + public QVec2 End; - public QuikLine(QuikVec2 start, QuikVec2 end) + public QLine(QVec2 start, QVec2 end) { Start = start; End = end; } - public QuikLine(float startX, float startY, float endX, float endY) + public QLine(float startX, float startY, float endX, float endY) { Start.X = startX; Start.Y = startY; @@ -267,12 +267,12 @@ namespace Quik End.Y = endY; } - public QuikVec2 Normal() + public QVec2 Normal() { - QuikVec2 tangent = Tangent(); - return new QuikVec2(-tangent.Y, tangent.X); + QVec2 tangent = Tangent(); + return new QVec2(-tangent.Y, tangent.X); } - public QuikVec2 Tangent() + public QVec2 Tangent() { return (End - Start).Normalize(); } @@ -282,17 +282,17 @@ namespace Quik /// A rectangle. /// [DebuggerDisplay("({Right}, {Top}, {Left}, {Bottom})")] - public struct QuikRectangle + public struct QRectangle { /// /// Rectangle maximum point. /// - public QuikVec2 Max; + public QVec2 Max; /// /// Rectangle minimum point. /// - public QuikVec2 Min; + public QVec2 Min; public float Left { @@ -318,39 +318,39 @@ namespace Quik set => Min.Y = value; } - public QuikVec2 Size + public QVec2 Size { get => Max - Min; set => Max = Min + value; } - public QuikRectangle(QuikVec2 max, QuikVec2 min) + public QRectangle(QVec2 max, QVec2 min) { Max = max; Min = min; } - public QuikRectangle(float r, float t, float l, float b) + public QRectangle(float r, float t, float l, float b) { - Max = new QuikVec2() {X = r, Y = t}; - Min = new QuikVec2() {X = l, Y = b}; + Max = new QVec2() {X = r, Y = t}; + Min = new QVec2() {X = l, Y = b}; } - public bool Contains(QuikVec2 point) + public bool Contains(QVec2 point) { return point.X > Left && point.X < Right && point.Y > Bottom && point.Y < Top; } - internal void Translate(in QuikVec2 offset) + internal void Translate(in QVec2 offset) { Min += offset; Max += offset; } - public static QuikRectangle Intersect(in QuikRectangle a, in QuikRectangle b) => - new QuikRectangle( + public static QRectangle Intersect(in QRectangle a, in QRectangle b) => + new QRectangle( Math.Min(a.Right, b.Right), Math.Min(a.Top, b.Top), Math.Max(a.Left, b.Left), @@ -363,43 +363,43 @@ namespace Quik /// /// It is undefined to have an ellipse with non-orthogonal axes. [DebuggerDisplay("{Center} ellipse {AxisA}; {AxisB}")] - public struct QuikEllipse + public struct QEllipse { /// /// Ellipse center point. /// - public QuikVec2 Center; + public QVec2 Center; /// /// First ellipse axis. /// - public QuikVec2 AxisA; + public QVec2 AxisA; /// /// Second ellipse axis. /// - public QuikVec2 AxisB; + public QVec2 AxisB; } /// /// A triangle. /// [DebuggerDisplay("{A} -- {B} -- {C}")] - public struct QuikTriangle + public struct QTriangle { /// /// First vertex. /// - public QuikVec2 A; + public QVec2 A; /// /// Second vertex. /// - public QuikVec2 B; + public QVec2 B; /// /// Third vertex. /// - public QuikVec2 C; + public QVec2 C; } } \ No newline at end of file diff --git a/Quik/QuikStyle.cs b/Quik/QuikStyle.cs index db3cfe5..72d7085 100644 --- a/Quik/QuikStyle.cs +++ b/Quik/QuikStyle.cs @@ -54,9 +54,9 @@ namespace Quik { public abstract object this[string key] { get; set; } - public QuikColor? Color + public QColor? Color { - get => (QuikColor?)this["color"]; + get => (QColor?)this["color"]; set => this["color"] = value; } @@ -120,9 +120,9 @@ namespace Quik set => this["stroke-width"] = value; } - public QuikColor? StrokeColor + public QColor? StrokeColor { - get => (QuikColor?)this["stroke-color"]; + get => (QColor?)this["stroke-color"]; set => this["stroke-color"] = value; } @@ -236,7 +236,7 @@ namespace Quik /// /// Stroke color. /// - public QuikColor Color { get; set; } + public QColor Color { get; set; } /// /// Stroke width. @@ -252,7 +252,7 @@ namespace Quik { } - public QuikStrokeStyle(QuikColor color, float width /*, QuikStipplePattern pattern*/) + public QuikStrokeStyle(QColor color, float width /*, QuikStipplePattern pattern*/) { Color = color; Width = width; @@ -269,6 +269,6 @@ namespace Quik /// public class QuikFillStyle { - public QuikColor Color { get; set; } + public QColor Color { get; set; } } } \ No newline at end of file diff --git a/Quik/Typography/QuikGlyph.cs b/Quik/Typography/QuikGlyph.cs index 437d22c..e4d3d14 100644 --- a/Quik/Typography/QuikGlyph.cs +++ b/Quik/Typography/QuikGlyph.cs @@ -13,35 +13,35 @@ namespace Quik.Typography /// /// Location of the glyph on the atlas. /// - public QuikRectangle Location { get; } + public QRectangle Location { get; } /// /// Size of the glyph in units. /// - public QuikVec2 Size { get; } + public QVec2 Size { get; } /// /// Bearing vector for horizontal layout. /// - public QuikVec2 HorizontalBearing { get; } + public QVec2 HorizontalBearing { get; } /// /// Bearing vector for vertical layout. /// - public QuikVec2 VerticalBearing { get; } + public QVec2 VerticalBearing { get; } /// /// Advance vector for vertical and horizontal layouts. /// - public QuikVec2 Advance { get; } + public QVec2 Advance { get; } public QuikGlyph( int character, - QuikRectangle location, - QuikVec2 size, - QuikVec2 horizontalBearing, - QuikVec2 verticalBearing, - QuikVec2 advance) + QRectangle location, + QVec2 size, + QVec2 horizontalBearing, + QVec2 verticalBearing, + QVec2 advance) { Character = character; Location = location; diff --git a/Quik/Typography/TextLayout.cs b/Quik/Typography/TextLayout.cs index 392399e..7fa228e 100644 --- a/Quik/Typography/TextLayout.cs +++ b/Quik/Typography/TextLayout.cs @@ -181,7 +181,7 @@ namespace Quik.Typography int index = 0; bool firstLine = true; - QuikVec2 pen = new QuikVec2(0, -PreSpace); + QVec2 pen = new QVec2(0, -PreSpace); while (index < Blocks.Count) { @@ -225,7 +225,7 @@ namespace Quik.Typography pen.Y -= PostSpace; - group.BoundingBox = new QuikRectangle(width, 0, 0, pen.Y); + group.BoundingBox = new QRectangle(width, 0, 0, pen.Y); group.Translate(-pen); } @@ -263,9 +263,9 @@ namespace Quik.Typography TypesetGroup group, Queue line, float interblockWs, - ref QuikVec2 pen) + ref QVec2 pen) { - QuikVec2 penpal = pen; + QVec2 penpal = pen; while (line.TryDequeue(out HorizontalTextBlock block)) { @@ -285,7 +285,7 @@ namespace Quik.Typography new TypesetCharacter( chr, texture, - new QuikRectangle( + new QRectangle( penpal.X + metrics.Advance.X, penpal.Y + metrics.HorizontalBearing.Y, penpal.X + metrics.HorizontalBearing.X, @@ -306,7 +306,7 @@ namespace Quik.Typography new TypesetCharacter( chr, texture, - new QuikRectangle( + new QRectangle( penpal.X + metrics.Advance.X, penpal.Y + metrics.HorizontalBearing.Y, penpal.X + metrics.HorizontalBearing.X, @@ -353,14 +353,14 @@ namespace Quik.Typography { public int Character; public QuikTexture Texture; - public QuikRectangle Position; - public QuikRectangle UV; + public QRectangle Position; + public QRectangle UV; public TypesetCharacter( int chr, QuikTexture texture, - in QuikRectangle position, - in QuikRectangle uv) + in QRectangle position, + in QRectangle uv) { Character = chr; Texture = texture; @@ -374,7 +374,7 @@ namespace Quik.Typography private int _count = 0; private TypesetCharacter[] _array = Array.Empty(); - public QuikRectangle BoundingBox; + public QRectangle BoundingBox; public int Count => _count; @@ -395,7 +395,7 @@ namespace Quik.Typography _count = 0; } - public void Translate(QuikVec2 offset) + public void Translate(QVec2 offset) { BoundingBox.Translate(offset); diff --git a/Quik/VertexGenerator/DrawQueue.cs b/Quik/VertexGenerator/DrawQueue.cs index c498aed..680f7a6 100644 --- a/Quik/VertexGenerator/DrawQueue.cs +++ b/Quik/VertexGenerator/DrawQueue.cs @@ -12,7 +12,7 @@ namespace Quik.VertexGenerator private readonly List _drawCalls = new List(); private int _start; private int _baseOffset; - private QuikRectangle _bounds; + private QRectangle _bounds; private QuikTexture _texture; public int ZDepth { get; private set; } @@ -32,7 +32,7 @@ namespace Quik.VertexGenerator } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void StartDrawCall(in QuikRectangle bounds, QuikTexture texture, int baseOffset) + public void StartDrawCall(in QRectangle bounds, QuikTexture texture, int baseOffset) { _start = ElementCount; _texture = texture; @@ -41,13 +41,13 @@ namespace Quik.VertexGenerator } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void StartDrawCall(in QuikRectangle bounds) => StartDrawCall(bounds, null, _vertices.Count); + public void StartDrawCall(in QRectangle bounds) => StartDrawCall(bounds, null, _vertices.Count); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void StartDrawCall(in QuikRectangle bounds, int baseOffset) => StartDrawCall(bounds, null, baseOffset); + public void StartDrawCall(in QRectangle bounds, int baseOffset) => StartDrawCall(bounds, null, baseOffset); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void StartDrawCall(in QuikRectangle bounds, QuikTexture texture) => StartDrawCall(bounds, texture, _vertices.Count); + public void StartDrawCall(in QRectangle bounds, QuikTexture texture) => StartDrawCall(bounds, texture, _vertices.Count); [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddVertex(in QuikVertex vertex) @@ -98,10 +98,10 @@ namespace Quik.VertexGenerator { public int Start { get; } public int Count { get; } - public QuikRectangle Bounds { get; } + public QRectangle Bounds { get; } public QuikTexture Texture { get; } - public DrawCall(int start, int count, in QuikRectangle bounds, QuikTexture texture) + public DrawCall(int start, int count, in QRectangle bounds, QuikTexture texture) { Start = start; Count = count; diff --git a/Quik/VertexGenerator/QuikVertex.cs b/Quik/VertexGenerator/QuikVertex.cs index e34db6d..7247e15 100644 --- a/Quik/VertexGenerator/QuikVertex.cs +++ b/Quik/VertexGenerator/QuikVertex.cs @@ -11,17 +11,17 @@ namespace Quik.VertexGenerator /// /// Position value. /// - public QuikVec2 Position; + public QVec2 Position; /// /// Texture Coordinates. /// - public QuikVec2 TextureCoordinates; + public QVec2 TextureCoordinates; /// /// Per vertex color value. /// - public QuikColor Color; + public QColor Color; /// /// Per vertex depth index value. @@ -29,9 +29,9 @@ namespace Quik.VertexGenerator public int ZIndex; public static int PositionOffset => 0; - public static unsafe int TextureCoordinatesOffset => sizeof(QuikVec2); - public static unsafe int ColorOffset => 2 * sizeof(QuikVec2); - public static unsafe int ZIndexOffset => ColorOffset + sizeof(QuikColor); + public static unsafe int TextureCoordinatesOffset => sizeof(QVec2); + public static unsafe int ColorOffset => 2 * sizeof(QVec2); + public static unsafe int ZIndexOffset => ColorOffset + sizeof(QColor); public static unsafe int Stride => sizeof(QuikVertex); } } \ No newline at end of file diff --git a/Quik/VertexGenerator/QuikVertexGenerator.cs b/Quik/VertexGenerator/QuikVertexGenerator.cs deleted file mode 100644 index d04268a..0000000 --- a/Quik/VertexGenerator/QuikVertexGenerator.cs +++ /dev/null @@ -1,1574 +0,0 @@ -using System; -using System.Collections.Generic; -using Quik.Typography; - -namespace Quik.VertexGenerator -{ - /// - /// Generates vertices from draw commands for GPU APIs like OpenGL. - /// - public class QuikVertexGenerator - { - // There is a very specific reason I am not using lists like a regular - // person would use. It has to do with the fact that there is no way - // to access the internal pointer of a System.Collections.Generic.List<> - // in older versions of .NET. Avoiding a copy of an entire vertex buffer - // would be very much appreciated by many devs. So please don't be - // "smart" around this code. - // - mixed. - - /// - /// Controls the buffer granularity. - /// - private const int BufferGranularity = 4096; - - /// - /// List of vertices. - /// - private QuikVertex[] _vertexBuffer = new QuikVertex[BufferGranularity]; - - /// - /// Pointer into the vertex buffer. - /// - private int _vertexBufferPointer = 0; - - private float _vertexUsage = 0; - - /// - /// List of element indices. - /// - private short[] _elementBuffer = new short[BufferGranularity]; - - /// - /// Pointer into the element buffer. - /// - private int _elementBufferPointer = 0; - - private float _elementUsage; - private long _bufferUsageCounter; - - /// - /// Moving average of the vertex count. - /// - public float VertexUsage => _vertexUsage; - - /// - /// Moving average of the element count. - /// - public float ElementUsage => _elementUsage; - - /// - /// Get a reference to the vertex buffer. - /// - public QuikVertex[] VertexBuffer => _vertexBuffer; - - /// - /// Number of vertices in the vertex buffer. - /// - public int VertexCount => _vertexBufferPointer; - - /// - /// Get a reference to the element buffer. - /// - public short[] ElementBuffer => _elementBuffer; - - /// - /// Number of elements in the element buffer. - /// - public int ElementCount => _elementBufferPointer; - - public List DrawCalls { get; } = new List(); - - public float CurveGranularity { get; set; } = 1f; - - public QuikContext Context { get; } - - public QuikVertexGenerator(QuikContext context) - { - Context = context; - } - - /// - /// Expands the vertex buffer by the buffer granularity constant. - /// - private void ExpandVertexBuffer() - { - Array.Resize(ref _vertexBuffer, _vertexBuffer.Length + BufferGranularity); - } - - /// - /// Expands the element buffer by the buffer granularity constant. - /// - private void ExpandElementBuffer() - { - Array.Resize(ref _elementBuffer, _elementBuffer.Length + BufferGranularity); - } - - /// - /// Add vertices to the list. - /// - /// The list of vertices to add. - private void AddVertex(params QuikVertex[] vertices) - { - int requiredCapacity = _vertexBufferPointer + vertices.Length; - while (requiredCapacity > _vertexBuffer.Length) - { - ExpandVertexBuffer(); - } - - Array.Copy(vertices, 0, _vertexBuffer, _vertexBufferPointer, vertices.Length); - _vertexBufferPointer += vertices.Length; - } - - /// - /// Add element indices to the list. - /// - /// The list of indices to add. - private void AddElement(params short[] indices) - { - int requiredCapacity = _elementBufferPointer + indices.Length; - while (requiredCapacity > _elementBuffer.Length) - { - ExpandElementBuffer(); - } - - Array.Copy(indices, 0, _elementBuffer, _elementBufferPointer, indices.Length); - _elementBufferPointer += indices.Length; - } - - private void MovingAverage(ref float average, long sampleCounter, int newSample) - { - // Thanks to stackoverflow for a neat formula. - // https://stackoverflow.com/questions/12636613/how-to-calculate-moving-average-without-keeping-the-count-and-data-total - - const float order = 4; - - average = average + (newSample - average) / Math.Min(sampleCounter + 1, order); - } - - private bool _renderStencilMask = false; - - private QuikRectangle _bounds = new QuikRectangle( - float.PositiveInfinity, float.PositiveInfinity, - float.NegativeInfinity, float.NegativeInfinity); - - /// - /// Clear the drawing buffers. - /// - public void Clear() - { - int newVertexSize; - int newElementSize; - - _bufferUsageCounter++; - MovingAverage(ref _vertexUsage, _bufferUsageCounter, _vertexBufferPointer); - MovingAverage(ref _elementUsage, _bufferUsageCounter, _elementBufferPointer); - - newVertexSize = (int)(Math.Ceiling(_vertexUsage / BufferGranularity) * BufferGranularity); - newElementSize = (int)(Math.Ceiling(_elementUsage / BufferGranularity) * BufferGranularity); - - Array.Resize(ref _vertexBuffer, newVertexSize); - Array.Resize(ref _elementBuffer, newElementSize); - - _vertexBufferPointer = 0; - _elementBufferPointer = 0; - - DrawCalls.Clear(); - } - - public QuikDrawCall CallTemplate; - - public event VertexGeneratorCommandHandler HandleCommand; - - protected virtual bool OnHandleCommand(QuikVertexGenerator generator, QuikCommand command) - { - bool anyCalls = false; - HandleCommand?.Invoke(generator, command, ref anyCalls); - return anyCalls; - } - - public void ConsumeCommand(QuikCommand command) - { - CallTemplate.Target = _renderStencilMask ? QuikRenderTarget.Stencil : QuikRenderTarget.Color; - - switch (command.Type) - { - case QuikCommandType.Mask: - CallTemplate.Bounds = ((QuikCommandMask)command).Bounds; - break; - case QuikCommandType.StencilMaskClear: - CallTemplate.ClearStencil = true; - break; - case QuikCommandType.StencilMaskBegin: - _renderStencilMask = true; - CallTemplate.Target = QuikRenderTarget.Stencil; - break; - case QuikCommandType.StencilMaskEnd: - _renderStencilMask = false; - CallTemplate.Target = QuikRenderTarget.Color; - break; - - case QuikCommandType.Line: - RenderLine(command as QuikCommandLine); - goto exit_with_call; - case QuikCommandType.Lines: - RenderLine(command as QuikCommandLines); - goto exit_with_call; - case QuikCommandType.Bezier: - RenderBezier(command as QuikCommandBezier); - goto exit_with_call; - - case QuikCommandType.Rectangle: - RenderRectangles(command as QuikCommandRectangle); - goto exit_with_call; - case QuikCommandType.Rectangles: - RenderRectangles(command as QuikCommandRectangles); - goto exit_with_call; - - case QuikCommandType.PutChar: - RenderCharacter(command as QuikCommandPutChar); - goto exit_with_call; - - case QuikCommandType.PutText: - RenderTextPut(command as QuikCommandPutText); - goto exit_with_call; - - case QuikCommandType.EmitTypeset: - RenderTextTypeset(command as QuikCommandEmitText); - goto exit_with_call; - - default: - { - if (OnHandleCommand(this, command)) - goto exit_with_call; - break; - } - } - return; - exit_with_call: - CallTemplate.ClearStencil = false; - } - - #region Lines & Beziers - - /// - /// Generates a basic line segment. - /// - /// The vertex base to modify when generating vertices. - /// The line segment. - /// The width of the line. - /// Start index of the generated line. - /// The line normal. - private void GenerateLineSegment( - QuikVertex baseVertex, - QuikLine line, - float width, - out short lineStartIndex, - out QuikVec2 normal) - { - QuikVec2 tangent = (line.End - line.Start).Normalize(); - normal = new QuikVec2() {X = -tangent.Y, Y = tangent.X}; - lineStartIndex = (short)_vertexBufferPointer; - - QuikVertex startA = baseVertex, startB = baseVertex; - QuikVertex endA = baseVertex, endB = baseVertex; - - startA.Position = line.Start + width / 2 * normal; - startB.Position = line.Start - width / 2 * normal; - endA.Position = line.End + width / 2 * normal; - endB.Position = line.End - width / 2 * normal; - - // Add the major line vertices. - AddVertex(startA, startB, endA, endB); - - // Add the line indices. - AddElement( - (short) (lineStartIndex + 1), - (short) (lineStartIndex + 2), - (short) (lineStartIndex + 0), - (short) (lineStartIndex + 1), - (short) (lineStartIndex + 3), - (short) (lineStartIndex + 2) - ); - } - - /// - /// Gets the rounding resolution for a line segment. - /// - /// The width of the line. - /// The angle of the cap or joint arc. - /// The rounding resolution. - private int GetRoundingResolution(float radius, float arc) - { - return (int) Math.Ceiling(arc * radius * CurveGranularity); - } - - /// - /// Generate a round start cap on a line. - /// - /// The base vertex to modify for generation. - /// The start point. - /// The line normal. - /// The width of line to generate. - /// End cap resolution. - /// The positive vertex index of the line start. - /// The negative vertex index of the line start. - public void GenerateStartCap( - QuikVertex baseVertex, - QuikVec2 start, - QuikVec2 normal, - float width, - int resolution, - short lineStartPositiveIndex, - short lineStartNegativeIndex - ) - { - QuikVertex circlePoint = baseVertex; - short lastIndex = lineStartPositiveIndex; - for (int i = 0; i < resolution; i++) - { - float angle = (float) (i + 1) / (resolution + 1) * MathF.PI; - float cosT = MathF.Cos(angle); - float sinT = MathF.Sin(angle); - - QuikVec2 displacement = new QuikVec2() - { - X = normal.X * cosT - normal.Y * sinT, - Y = normal.X * sinT + normal.Y * cosT - } * (width / 2); - - circlePoint.Position = start + displacement; - - short segmentIndex = (short)_vertexBufferPointer; - - AddVertex(circlePoint); - AddElement( - lineStartNegativeIndex, - lastIndex, - segmentIndex); - - lastIndex = segmentIndex; - } - } - - /// - /// Generate a round line end cap. - /// - /// Base vertex to modify for generation. - /// The line end. - /// The line normal. - /// The line width. - /// Cap generation resolution. - /// Vertex index of the positive line end. - /// Vertex index of the negative line end. - public void GenerateEndCap( - QuikVertex baseVertex, - QuikVec2 end, - QuikVec2 normal, - float width, - int resolution, - short lineEndPositiveIndex, - short lineEndNegativeIndex - ) - { - QuikVertex circlePoint = baseVertex; - short lastIndex = lineEndPositiveIndex; - for (int i = 0; i < resolution; i++) - { - float angle = -(float) (i + 1) / (resolution + 1) * MathF.PI; - float cosT = MathF.Cos(angle); - float sinT = MathF.Sin(angle); - - QuikVec2 displacement = new QuikVec2() - { - X = normal.X * cosT - normal.Y * sinT, - Y = normal.X * sinT + normal.Y * cosT - } * (width / 2); - - circlePoint.Position = end + displacement; - - AddVertex(circlePoint); - AddElement( - lineEndNegativeIndex, - lastIndex, - (short) (_vertexBufferPointer - 1)); - - lastIndex = (short) (_vertexBufferPointer - 1); - } - } - - /// - /// Generate a joint on the line negative edge. - /// - /// Base vertex to modify for generation. - /// The focus of the joint. - /// With of the lines. - /// Index of the negative end vertex. - /// Index of the negative start vertex. - /// Joint resolution. - /// Arc length of the joint. - /// Normal of the previous line. - private void GenerateNegativeJoint( - QuikVertex baseVertex, - QuikVec2 focus, - float width, - short prevNegativeLineIndex, - short nextNegativeLineIndex, - int resolution, - float arc, - QuikVec2 prevNormal) - { - QuikVertex focusVertex = baseVertex; - short focusIndex = (short) _vertexBufferPointer; - short lastIndex = prevNegativeLineIndex; - - focusVertex.Position = focus; - AddVertex(focusVertex); - - for (int i = 0; i < resolution; i++) - { - float angle = (float) (i + 1) / (resolution + 1) * arc; - float cosT = MathF.Cos(angle); - float sinT = MathF.Sin(angle); - - QuikVec2 displacement = new QuikVec2() - { - X = -prevNormal.X * cosT + prevNormal.Y * sinT, - Y = -prevNormal.X * sinT - prevNormal.Y * cosT - } * (width / 2); - - QuikVertex segmentVertex = focusVertex; - segmentVertex.Position += displacement; - - short segmentIndex = (short) _vertexBufferPointer; - AddVertex(segmentVertex); - - AddElement(lastIndex, segmentIndex, focusIndex); - - lastIndex = segmentIndex; - } - - // Add final triangle. - AddElement(lastIndex, nextNegativeLineIndex, focusIndex); - } - - /// - /// Generate a joint on the line negative edge. - /// - /// Base vertex to modify for generation. - /// The focus of the joint. - /// With of the lines. - /// Index of the positive end vertex. - /// Index of the positive start vertex. - /// Joint resolution. - /// Arc length of the joint. - /// Normal of the next line. - private void GeneratePositiveJoint( - QuikVertex baseVertex, - QuikVec2 focus, - float width, - short prevPositiveLineIndex, - short nextPositiveLineIndex, - int resolution, - float arc, - QuikVec2 nextNormal) - { - QuikVertex focusVertex = baseVertex; - short focusIndex = (short) _vertexBufferPointer; - short lastIndex = nextPositiveLineIndex; - - focusVertex.Position = focus; - AddVertex(focusVertex); - - for (int i = 0; i < resolution; i++) - { - float angle = (float) (i + 1) / (resolution + 1) * arc; - float cosT = MathF.Cos(angle); - float sinT = MathF.Sin(angle); - - QuikVec2 displacement = new QuikVec2() - { - X = nextNormal.X * cosT - nextNormal.Y * sinT, - Y = nextNormal.X * sinT + nextNormal.Y * cosT - } * (width / 2); - - QuikVertex segmentVertex = focusVertex; - segmentVertex.Position += displacement; - - short segmentIndex = (short) _vertexBufferPointer; - AddVertex(segmentVertex); - - AddElement(lastIndex, segmentIndex, focusIndex); - - lastIndex = segmentIndex; - } - - // Add final triangle. - AddElement(lastIndex, prevPositiveLineIndex, focusIndex); - } - - /// - /// Generate a joint. - /// - /// Base vertex to modify. - /// Focus of the joint. - /// Tangent of the previous line segment. - /// Tangent of the next line segment. - /// Width of the lines. - /// Vertex index of the positive end. - /// Vertex index of the negative end. - /// Vertex index of the positive start. - /// Vertex index of the negative start. - public void GenerateJoint( - QuikVertex baseVertex, - QuikVec2 focus, - QuikVec2 prevTangent, - QuikVec2 nextTangent, - float width, - short prevPositiveEndIndex, - short prevNegativeEndIndex, - short nextPositiveStartIndex, - short nextNegativeStartIndex - ) - { - QuikVec2 prevNormal, nextNormal; - QuikVec2 averageTangent; - - prevNormal = new QuikVec2() { X = -prevTangent.Y, Y = prevTangent.X }; - nextNormal = new QuikVec2() { X = -nextTangent.Y, Y = nextTangent.X }; - - averageTangent = 0.5f * (prevTangent + nextTangent); - - // Figure out which side needs the joint. - QuikVec2 positiveEdge = ((focus + nextNormal) - (focus + prevNormal)).Normalize(); - QuikVec2 negativeEdge = ((focus - nextNormal) - (focus - prevNormal)).Normalize(); - - float positiveDot, negativeDot; - positiveDot = QuikVec2.Dot(averageTangent, positiveEdge); - negativeDot = QuikVec2.Dot(averageTangent, negativeEdge); - - float arc = MathF.Acos(QuikVec2.Dot(prevNormal, nextNormal)); - int resolution = GetRoundingResolution(width, arc); - - if (positiveDot < negativeDot) - { - // Negative edge rounding. - GenerateNegativeJoint(baseVertex, focus, width, prevNegativeEndIndex, nextNegativeStartIndex, resolution, arc, prevNormal); - } - else if (negativeDot < positiveDot) - { - // Positive edge rounding. - GeneratePositiveJoint(baseVertex, focus, width, prevPositiveEndIndex, nextPositiveStartIndex, resolution, arc, nextNormal); - } - else - { - // There is a cusp. Generate an end cap. - GenerateEndCap(baseVertex, focus, prevNormal.Normalize(), width, GetRoundingResolution(width, MathF.PI), prevPositiveEndIndex, prevNegativeEndIndex); - } - } - - /// - /// Renders a line. - /// - /// The draw call to generate. - /// The line to draw. - private void RenderLine(QuikCommandLine line) - { - // Skip over stipple patterns for now. - QuikStrokeStyle style = line.Style ?? Context.DefaultStroke; - QuikVertex baseVertex = new QuikVertex() { Color = style.Color }; - - GenerateLineSegment(baseVertex, line.Line, style.Width, out short startOffset, out QuikVec2 normal); - - // Now calculate the end caps. - int endCapResolution = GetRoundingResolution(style.Width, MathF.PI); - - // Construct start cap. - GenerateStartCap(baseVertex, line.Line.Start, normal, style.Width, endCapResolution, startOffset, (short) - (startOffset + 1)); - - // Construct end cap. - GenerateEndCap(baseVertex, line.Line.End, normal, style.Width, endCapResolution, (short) (startOffset + 2),(short) - (startOffset + 3)); - - QuikDrawCall call = CallTemplate; - call.Offset = (short) (startOffset * 2); - call.Count = (short) (_elementBufferPointer - startOffset); - DrawCalls.Add(call); - } - - /// - /// Render lines. - /// - /// The draw call to generate. - /// The lines command. - private void RenderLine(QuikCommandLines lines) - { - // Skip over stipple patterns for now. - QuikStrokeStyle style = lines.Style ?? Context.DefaultStroke; - QuikVertex baseVertex = new QuikVertex() { Color = style.Color }; - bool isStart; - bool isEnd; - short startOffset = (short)_elementBufferPointer; - short lastStartIndex = 0; - short lineStartIndex; - QuikVec2 normal; - int resolution = GetRoundingResolution(style.Width, MathF.PI); - - for (int i = 0; i < lines.Lines.Length; i++) - { - QuikLine line = lines.Lines[i]; - - isStart = i == 0 || line.Start != lines.Lines[i - 1].End; - isEnd = i == lines.Lines.Length - 1 || line.End != lines.Lines[i + 1].Start; - - GenerateLineSegment(baseVertex, line, style.Width, out lineStartIndex, out normal); - - if (isStart) - { - GenerateStartCap(baseVertex, line.Start, normal, style.Width, resolution, lineStartIndex, - (short)(lineStartIndex + 1)); - } - else - { - QuikLine prev = lines.Lines[i - 1]; - QuikVec2 prevTangent = (prev.End - prev.Start).Normalize(); - QuikVec2 nextTangent = (line.End - line.Start).Normalize(); - - GenerateJoint( - baseVertex, - line.Start, - prevTangent, - nextTangent, - style.Width, - (short) (lastStartIndex + 2), - (short) (lastStartIndex + 3), - lineStartIndex, - (short)(lineStartIndex + 1)); - } - - if (isEnd) - { - GenerateEndCap(baseVertex, line.End, normal, style.Width, resolution, (short)(lineStartIndex + 2), (short)(lineStartIndex + 3)); - } - - lastStartIndex = lineStartIndex; - } - - QuikDrawCall call = CallTemplate; - call.Offset = (short) (startOffset * 2); - call.Count = (short) (_elementBufferPointer - startOffset); - DrawCalls.Add(call); - } - - private void RenderBezier(QuikCommandBezier bezier) - { - QuikStrokeStyle style = bezier.Style ?? Context.DefaultStroke; - QuikVertex baseVertex = new QuikVertex() { Color = style.Color }; - bool isStart; - bool isEnd; - short startOffset = (short)_elementBufferPointer; - int capResolution = GetRoundingResolution(style.Width, MathF.PI); - - short lastEndPositive = 0; - short lastEndNegative = 0; - - for (int i = 0; i < bezier.Segments.Length; i++) - { - QuikBezier segment = bezier.Segments[i]; - - isStart = i == 0 || segment.Start != bezier.Segments[i - 1].End; - isEnd = i == bezier.Segments.Length - 1 || segment.End != bezier.Segments[i + 1].Start; - - GenerateBezierSegment( - baseVertex, - segment, - style.Width, - out short startPositive, - out short startNegative, - out short endPositive, - out short endNegative, - out QuikVec2 startNormal, - out QuikVec2 endNormal); - - if (isStart) - { - GenerateStartCap(baseVertex, segment.Start, startNormal, style.Width, capResolution, - startPositive, startNegative); - } - else - { - GenerateJoint( - baseVertex, - segment.Start, - bezier.Segments[i-1].GetBezierTangent(1), - segment.GetBezierTangent(0), - style.Width, - lastEndPositive, - lastEndNegative, - startPositive, - startNegative - ); - } - - if (isEnd) - { - GenerateEndCap( - baseVertex, - segment.End, - endNormal, - style.Width, - capResolution, - endPositive, - endNegative - ); - } - - lastEndPositive = endPositive; - lastEndNegative = endNegative; - } - - QuikDrawCall call = CallTemplate; - call.Offset = (short) (startOffset * 2); - call.Count = (short) (_elementBufferPointer - startOffset); - DrawCalls.Add(call); - } - - private void GenerateBezierSegment( - QuikVertex baseVertex, - QuikBezier bezier, - float width, - out short startPositiveIndex, - out short startNegativeIndex, - out short endPositiveIndex, - out short endNegativeIndex, - out QuikVec2 startNormal, - out QuikVec2 endNormal) - { - QuikVec2 startTangent = bezier.GetBezierTangent(0); - QuikVec2 endTangent = bezier.GetBezierTangent(1); - - startNormal = new QuikVec2(-startTangent.Y, startTangent.X).Normalize(); - endNormal = new QuikVec2(-endTangent.Y, endTangent.X).Normalize(); - - int resolution = GetRoundingResolution(width, bezier.RasterizationArc); - - startPositiveIndex = (short)_vertexBufferPointer; - startNegativeIndex = (short) (startPositiveIndex + 1); - - QuikVertex startPositive = baseVertex; - QuikVertex startNegative = baseVertex; - startPositive.Position = bezier.Start + 0.5f * width * startNormal; - startNegative.Position = bezier.Start - 0.5f * width * startNormal; - - AddVertex(startPositive, startNegative); - - for (int i = 0; i < resolution; i++) - { - float t = (float) (i + 1) / resolution; - - QuikVec2 at = bezier.GetBezierTangent(t).Normalize(); - - QuikVec2 a = bezier.GetBezierPoint(t); - QuikVec2 an = 0.5f * width * new QuikVec2(-at.Y, at.X); - short index = (short) _vertexBufferPointer; - - QuikVertex apv = baseVertex, anv = baseVertex; - apv.Position = a + an; - anv.Position = a - an; - - AddVertex(apv, anv); - AddElement( - (short)(index - 2), - (short)(index - 1), - (short)(index + 0), - (short)(index - 1), - (short)(index + 1), - (short)(index + 0)); - } - - endNegativeIndex = (short) (_vertexBufferPointer - 1); - endPositiveIndex = (short) (_vertexBufferPointer - 2); - } - - #endregion - - #region Rectangles - - private void RenderRectangles(QuikCommandRectangle rectangle) - { - QuikStrokeStyle stroke = rectangle.StrokeStyle ?? Context.DefaultStroke; - QuikFillStyle fill = rectangle.FillStyle ?? Context.DefaultFill; - - short start = (short) _elementBufferPointer; - - GenerateRectangle(rectangle.Rectangle, stroke, fill, rectangle.CornerRadius); - - QuikDrawCall call = CallTemplate; - call.Offset = (short) (start * 2); - call.Count = (short) (_elementBufferPointer - start); - DrawCalls.Add(call); - } - - private void GenerateRectangle(QuikRectangle rectangle, QuikStrokeStyle stroke, QuikFillStyle fill, float cornerRadius) - { - float semiStroke = 0.5f * stroke.Width; - - if (cornerRadius == 0) - { - // If there is no stroke radius, draw a simpler rectangle. - if (stroke.Width == 0) - { - // If there is no border, just 4 points is enough. - - GenerateRectangleSimple(rectangle, fill); - } - else - { - // If there is a border, take it into account. - - QuikRectangle innerRectangle = rectangle; - innerRectangle.Left += semiStroke; - innerRectangle.Top -= semiStroke; - innerRectangle.Right -= semiStroke; - innerRectangle.Bottom += semiStroke; - - GenerateRectangleSimple(innerRectangle, fill); - GenerateRectangleBorderSimple(rectangle, stroke); - } - } - else - { - float innerRadius = cornerRadius - semiStroke; - - if (innerRadius <= 0) - { - QuikRectangle innerRectangle = new QuikRectangle( - rectangle.Right - semiStroke, - rectangle.Top - semiStroke, - rectangle.Left + semiStroke, - rectangle.Bottom + semiStroke - ); - - GenerateRectangleSimple(innerRectangle, fill); - GenerateRectangleBorderNarrow(rectangle, stroke, cornerRadius); - } - else - { - // Generate the inner rectangle. - QuikRectangle innerRectangle = new QuikRectangle( - rectangle.Right - semiStroke * 0.95f, - rectangle.Top - semiStroke * 0.95f, - rectangle.Left + semiStroke * 0.95f, - rectangle.Bottom + semiStroke * 0.95f - ); - GenerateRectangleRound(innerRectangle, fill, innerRadius); - - if (stroke.Width > 0) - { - GenerateRectangleBorderWide(rectangle, stroke, cornerRadius); - } - } - } - } - - private void GenerateRectangleBorderNarrow( - QuikRectangle rectangle, - QuikStrokeStyle stroke, - float cornerRadius) - { - float semiStroke = 0.5f * stroke.Width; - float inset = cornerRadius - semiStroke; - short start = (short) _vertexBufferPointer; - - QuikVertex baseVertex = new QuikVertex() {Color = stroke.Color}; - QuikVertex a = baseVertex, b = baseVertex, c = baseVertex, d = baseVertex, - e = baseVertex, f = baseVertex, g = baseVertex, h = baseVertex, - i = baseVertex, j = baseVertex, k = baseVertex, l = baseVertex, - q1 = baseVertex, q2 = baseVertex, q3 = baseVertex, q4 = baseVertex; - - a.Position = new QuikVec2(rectangle.Left + semiStroke, rectangle.Bottom + semiStroke); - b.Position = new QuikVec2(rectangle.Right - semiStroke, rectangle.Bottom + semiStroke); - c.Position = new QuikVec2(rectangle.Right - semiStroke, rectangle.Top - semiStroke); - d.Position = new QuikVec2(rectangle.Left + semiStroke, rectangle.Top - semiStroke); - - q1.Position = new QuikVec2(rectangle.Left + inset, rectangle.Bottom + inset); - q2.Position = new QuikVec2(rectangle.Right - inset, rectangle.Bottom + inset); - q3.Position = new QuikVec2(rectangle.Right - inset, rectangle.Top - inset); - q4.Position = new QuikVec2(rectangle.Left + inset, rectangle.Top - inset); - - e.Position = new QuikVec2(q1.Position.X, rectangle.Bottom - semiStroke); - f.Position = new QuikVec2(q2.Position.X, rectangle.Bottom - semiStroke); - g.Position = new QuikVec2(rectangle.Right + semiStroke, q2.Position.Y); - h.Position = new QuikVec2(rectangle.Right + semiStroke, q3.Position.Y); - i.Position = new QuikVec2(q3.Position.X, rectangle.Top + semiStroke); - j.Position = new QuikVec2(q4.Position.X, rectangle.Top + semiStroke); - k.Position = new QuikVec2(rectangle.Left - semiStroke, q4.Position.Y); - l.Position = new QuikVec2(rectangle.Left - semiStroke, q1.Position.Y); - - AddVertex(a, b, c, d, e, f, g, h, i, j, k, l, q1, q2, q3, q4); - AddElement( - (short) (start + 4), (short) (start + 5), (short) (start + 13), - (short) (start + 4), (short) (start + 13), (short) (start + 12), - (short) (start + 12), (short) (start + 13), (short) (start + 1), - (short) (start + 12), (short) (start + 1), (short) (start + 0), - - (short) (start + 13), (short) (start + 6), (short) (start + 7), - (short) (start + 13), (short) (start + 7), (short) (start + 14), - (short) (start + 13), (short) (start + 14), (short) (start + 2), - (short) (start + 13), (short) (start + 2), (short) (start + 1), - - (short) (start + 3), (short) (start + 2), (short) (start + 14), - (short) (start + 3), (short) (start + 14), (short) (start + 15), - (short) (start + 15), (short) (start + 14), (short) (start + 8), - (short) (start + 15), (short) (start + 8), (short) (start + 9), - - (short) (start + 0), (short) (start + 3), (short) (start + 15), - (short) (start + 0), (short) (start + 15), (short) (start + 12), - (short) (start + 12), (short) (start + 15), (short) (start + 10), - (short) (start + 12), (short) (start + 10), (short) (start + 11) - ); - - int resolution = GetRoundingResolution(cornerRadius, 0.5f * MathF.PI); - short last, next; - - last = (short) (start + 7); - for (int idx = 0; idx < resolution; idx++) - { - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - QuikVertex vertex = baseVertex; - vertex.Position = q3.Position + cornerRadius * new QuikVec2(MathF.Cos(angle), MathF.Sin(angle)); - - next = (short) _vertexBufferPointer; - AddVertex(vertex); - AddElement((short)(start + 14), last, next); - last = next; - } - AddElement((short)(start + 14), last, (short)(start + 8)); - - last = (short) (start + 9); - for (int idx = 0; idx < resolution; idx++) - { - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - QuikVertex vertex = baseVertex; - vertex.Position = q4.Position + cornerRadius * new QuikVec2(-MathF.Sin(angle), MathF.Cos(angle)); - - next = (short) _vertexBufferPointer; - AddVertex(vertex); - AddElement((short)(start + 15), last, next); - last = next; - } - AddElement((short)(start + 15), last, (short)(start + 10)); - - last = (short) (start + 11); - for (int idx = 0; idx < resolution; idx++) - { - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - QuikVertex vertex = baseVertex; - vertex.Position = q1.Position + cornerRadius * new QuikVec2(-MathF.Cos(angle), -MathF.Sin(angle)); - - next = (short) _vertexBufferPointer; - AddVertex(vertex); - AddElement((short)(start + 12), last, next); - last = next; - } - AddElement((short)(start + 12), last, (short)(start + 4)); - - last = (short) (start + 5); - for (int idx = 0; idx < resolution; idx++) - { - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - QuikVertex vertex = baseVertex; - vertex.Position = q2.Position + cornerRadius * new QuikVec2(MathF.Sin(angle), -MathF.Cos(angle)); - - next = (short) _vertexBufferPointer; - AddVertex(vertex); - AddElement((short)(start + 13), last, next); - last = next; - } - AddElement((short)(start + 13), last, (short)(start + 6)); - } - - private void GenerateRectangleBorderWide(QuikRectangle rectangle, QuikStrokeStyle stroke, float cornerRadius) - { - float semiStroke = 0.5f * stroke.Width; - float outerRadius = cornerRadius + semiStroke; - float innerRadius = cornerRadius - semiStroke; - short start = (short) _vertexBufferPointer; - - // The corner foci. - QuikVec2 q1 = new QuikVec2(rectangle.Min.X + cornerRadius, rectangle.Min.Y + cornerRadius); - QuikVec2 q2 = new QuikVec2(rectangle.Max.X - cornerRadius, rectangle.Min.Y + cornerRadius); - QuikVec2 q3 = new QuikVec2(rectangle.Max.X - cornerRadius, rectangle.Max.Y - cornerRadius); - QuikVec2 q4 = new QuikVec2(rectangle.Min.X + cornerRadius, rectangle.Max.Y - cornerRadius); - - QuikVertex baseVertex = new QuikVertex() {Color = stroke.Color}; - QuikVertex a = baseVertex, b = baseVertex, c = baseVertex, d = baseVertex, - e = baseVertex, f = baseVertex, g = baseVertex, h = baseVertex, - i = baseVertex, j = baseVertex, k = baseVertex, l = baseVertex, - m = baseVertex, n = baseVertex, o = baseVertex, p = baseVertex; - - a.Position = new QuikVec2(q1.X, q1.Y - innerRadius); - b.Position = new QuikVec2(q2.X, q2.Y - innerRadius); - c.Position = new QuikVec2(q2.X + innerRadius, q2.Y); - d.Position = new QuikVec2(q3.X + innerRadius, q3.Y); - e.Position = new QuikVec2(q3.X, q3.Y + innerRadius); - f.Position = new QuikVec2(q4.X, q4.Y + innerRadius); - g.Position = new QuikVec2(q4.X - innerRadius, q4.Y); - h.Position = new QuikVec2(q1.X - innerRadius, q1.Y); - - i.Position = new QuikVec2(q1.X, rectangle.Bottom - semiStroke); - j.Position = new QuikVec2(q2.X, rectangle.Bottom - semiStroke); - k.Position = new QuikVec2(rectangle.Right + semiStroke, q2.Y); - l.Position = new QuikVec2(rectangle.Right + semiStroke, q3.Y); - m.Position = new QuikVec2(q3.X, rectangle.Top + semiStroke); - n.Position = new QuikVec2(q4.X, rectangle.Top + semiStroke); - o.Position = new QuikVec2(rectangle.Left - semiStroke, q4.Y); - p.Position = new QuikVec2(rectangle.Left - semiStroke, q1.Y); - - AddVertex(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p); - AddElement( - (short)(start + 8), (short)(start + 1), (short)(start + 0), - (short)(start + 8), (short)(start + 9), (short)(start + 1), - (short)(start + 2), (short)(start + 11), (short)(start + 3), - (short)(start + 2), (short)(start + 10), (short)(start + 11), - (short)(start + 5), (short)(start + 12), (short)(start + 13), - (short)(start + 5), (short)(start + 4), (short)(start + 12), - (short)(start + 15), (short)(start + 6), (short)(start + 14), - (short)(start + 15), (short)(start + 7), (short)(start + 6) - ); - - int resolution = GetRoundingResolution(outerRadius, 0.5f * MathF.PI); - short last0, last1; - short next0, next1; - - last0 = (short) (start + 3); - last1 = (short) (start + 11); - for (int idx = 0; idx < resolution; idx++) - { - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - QuikVec2 normal = new QuikVec2(MathF.Cos(angle), MathF.Sin(angle)); - QuikVertex v0 = baseVertex, v1 = baseVertex; - - v0.Position = q3 + innerRadius * normal; - v1.Position = q3 + outerRadius * normal; - - next0 = (short) (_vertexBufferPointer + 0); - next1 = (short) (_vertexBufferPointer + 1); - - AddVertex(v0, v1); - AddElement( - last0, next1, next0, - last0, last1, next1); - - last0 = next0; - last1 = next1; - } - - AddElement( - last0, (short)(start + 12), (short)(start + 4), - last0, last1, (short)(start + 12) - ); - - last0 = (short) (start + 5); - last1 = (short) (start + 13); - for (int idx = 0; idx < resolution; idx++) - { - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - QuikVec2 normal = new QuikVec2(-MathF.Sin(angle), MathF.Cos(angle)); - QuikVertex v0 = baseVertex, v1 = baseVertex; - - v0.Position = q4 + innerRadius * normal; - v1.Position = q4 + outerRadius * normal; - - next0 = (short) (_vertexBufferPointer + 0); - next1 = (short) (_vertexBufferPointer + 1); - - AddVertex(v0, v1); - AddElement( - last0, next1, next0, - last0, last1, next1); - - last0 = next0; - last1 = next1; - } - - AddElement( - last0, (short)(start + 14), (short)(start + 6), - last0, last1, (short)(start + 14) - ); - - last0 = (short) (start + 7); - last1 = (short) (start + 15); - for (int idx = 0; idx < resolution; idx++) - { - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - QuikVec2 normal = new QuikVec2(-MathF.Cos(angle), -MathF.Sin(angle)); - QuikVertex v0 = baseVertex, v1 = baseVertex; - - v0.Position = q1 + innerRadius * normal; - v1.Position = q1 + outerRadius * normal; - - next0 = (short) (_vertexBufferPointer + 0); - next1 = (short) (_vertexBufferPointer + 1); - - AddVertex(v0, v1); - AddElement( - last0, next1, next0, - last0, last1, next1); - - last0 = next0; - last1 = next1; - } - - AddElement( - last0, (short)(start + 8), (short)(start + 0), - last0, last1, (short)(start + 8) - ); - - last0 = (short) (start + 1); - last1 = (short) (start + 9); - for (int idx = 0; idx < resolution; idx++) - { - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - QuikVec2 normal = new QuikVec2(MathF.Sin(angle), -MathF.Cos(angle)); - QuikVertex v0 = baseVertex, v1 = baseVertex; - - v0.Position = q2 + innerRadius * normal; - v1.Position = q2 + outerRadius * normal; - - next0 = (short) (_vertexBufferPointer + 0); - next1 = (short) (_vertexBufferPointer + 1); - - AddVertex(v0, v1); - AddElement( - last0, next1, next0, - last0, last1, next1); - - last0 = next0; - last1 = next1; - } - - AddElement( - last0, (short)(start + 10), (short)(start + 2), - last0, last1, (short)(start + 10) - ); - } - - private void GenerateRectangleRound( - QuikRectangle rectangle, - QuikFillStyle fill, - float radius) - { - short baseElement = (short) _vertexBufferPointer; - QuikVertex baseVertex = new QuikVertex() {Color = fill.Color}; - QuikVertex a = baseVertex, - b = baseVertex, - c = baseVertex, - d = baseVertex, - e = baseVertex, - f = baseVertex, - g = baseVertex, - h = baseVertex, - i = baseVertex, - j = baseVertex, - k = baseVertex, - l = baseVertex; - - // Generate base 5 patches. - - a.Position = new QuikVec2( - rectangle.Left + radius, - rectangle.Bottom + radius); - b.Position = new QuikVec2( - rectangle.Right - radius, - rectangle.Bottom + radius); - c.Position = new QuikVec2( - rectangle.Right - radius, - rectangle.Top - radius); - d.Position = new QuikVec2( - rectangle.Left + radius, - rectangle.Top - radius); - e.Position = new QuikVec2( - rectangle.Left + radius, - rectangle.Bottom); - f.Position = new QuikVec2( - rectangle.Right - radius, - rectangle.Bottom); - g.Position = new QuikVec2( - rectangle.Right, - rectangle.Bottom + radius); - h.Position = new QuikVec2( - rectangle.Right, - rectangle.Top - radius); - i.Position = new QuikVec2( - rectangle.Right - radius, - rectangle.Top); - j.Position = new QuikVec2( - rectangle.Left + radius, - rectangle.Top); - k.Position = new QuikVec2( - rectangle.Left, - rectangle.Top - radius); - l.Position = new QuikVec2( - rectangle.Left, - rectangle.Bottom + radius); - - AddVertex(a, b, c, d, e, f, g, h, i, j, k, l); - AddElement( - (short) (baseElement + 0), (short) (baseElement + 1), (short) (baseElement + 2), - (short) (baseElement + 0), (short) (baseElement + 2), (short) (baseElement + 3), - (short) (baseElement + 4), (short) (baseElement + 5), (short) (baseElement + 1), - (short) (baseElement + 4), (short) (baseElement + 1), (short) (baseElement + 0), - (short) (baseElement + 1), (short) (baseElement + 6), (short) (baseElement + 7), - (short) (baseElement + 1), (short) (baseElement + 7), (short) (baseElement + 2), - (short) (baseElement + 3), (short) (baseElement + 2), (short) (baseElement + 8), - (short) (baseElement + 3), (short) (baseElement + 8), (short) (baseElement + 9), - (short) (baseElement + 11), (short) (baseElement + 0), (short) (baseElement + 3), - (short) (baseElement + 11), (short) (baseElement + 3), (short) (baseElement + 10)); - - // Now generate corner patches. - - int resolution = GetRoundingResolution(radius, 0.5f * MathF.PI); - short focus, last, current; - - focus = (short) (baseElement + 2); - last = (short) (baseElement + 7); - for (int idx = 0; idx < resolution; idx++) - { - QuikVertex vertex = baseVertex; - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - vertex.Position = c.Position + radius * new QuikVec2(MathF.Cos(angle), MathF.Sin(angle)); - current = (short) _vertexBufferPointer; - - AddVertex(vertex); - AddElement(focus, last, current); - - last = current; - } - - AddElement(focus, last, (short) (baseElement + 8)); - - - focus = (short) (baseElement + 3); - last = (short) (baseElement + 9); - for (int idx = 0; idx < resolution; idx++) - { - QuikVertex vertex = baseVertex; - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - vertex.Position = d.Position + radius * new QuikVec2(-MathF.Sin(angle), MathF.Cos(angle)); - current = (short) _vertexBufferPointer; - - AddVertex(vertex); - AddElement(focus, last, current); - - last = current; - } - - AddElement(focus, last, (short) (baseElement + 10)); - - focus = (short) (baseElement + 0); - last = (short) (baseElement + 11); - for (int idx = 0; idx < resolution; idx++) - { - QuikVertex vertex = baseVertex; - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - vertex.Position = a.Position + radius * new QuikVec2(-MathF.Cos(angle), -MathF.Sin(angle)); - current = (short) _vertexBufferPointer; - - AddVertex(vertex); - AddElement(focus, last, current); - - last = current; - } - - AddElement(focus, last, (short) (baseElement + 4)); - - focus = (short) (baseElement + 1); - last = (short) (baseElement + 5); - for (int idx = 0; idx < resolution; idx++) - { - QuikVertex vertex = baseVertex; - float angle = 0.5f * MathF.PI * (idx + 1) / (resolution + 1); - vertex.Position = b.Position + radius * new QuikVec2(MathF.Sin(angle), -MathF.Cos(angle)); - current = (short) _vertexBufferPointer; - - AddVertex(vertex); - AddElement(focus, last, current); - - last = current; - } - - AddElement(focus, last, (short) (baseElement + 6)); - } - - private void GenerateRectangleBorderSimple(QuikRectangle rectangle, QuikStrokeStyle stroke) - { - QuikVertex baseStrokeVertex = new QuikVertex() {Color = stroke.Color}; - float semiStroke = 0.5f * stroke.Width; - - // AB - GenerateLineSegment( - baseStrokeVertex, - new QuikLine( - rectangle.Min.X + semiStroke, - rectangle.Min.Y, - rectangle.Max.X - semiStroke, - rectangle.Min.Y - ), - stroke.Width, - out _, - out _); - - // BC - GenerateLineSegment( - baseStrokeVertex, - new QuikLine( - rectangle.Max.X, - rectangle.Min.Y - semiStroke, - rectangle.Max.X, - rectangle.Max.Y + semiStroke - ), - stroke.Width, - out _, - out _); - - // CD - GenerateLineSegment( - baseStrokeVertex, - new QuikLine( - rectangle.Max.X - semiStroke, - rectangle.Max.Y, - rectangle.Min.X + semiStroke, - rectangle.Max.Y - ), - stroke.Width, - out _, - out _); - - // DA - GenerateLineSegment( - baseStrokeVertex, - new QuikLine( - rectangle.Min.X, - rectangle.Max.Y + semiStroke, - rectangle.Min.X, - rectangle.Min.Y - semiStroke - ), - stroke.Width, - out _, - out _); - } - - private void GenerateRectangleSimple( - QuikRectangle rectangle, - QuikFillStyle fill) - { - QuikVertex a, b, c, d; - a = b = c = d = new QuikVertex() {Color = fill.Color}; - a.Position = rectangle.Min; - b.Position = new QuikVec2(rectangle.Right, rectangle.Bottom); - c.Position = rectangle.Max; - d.Position = new QuikVec2(rectangle.Left, rectangle.Top); - - short idxA = (short) _vertexBufferPointer; - short idxB = (short) (idxA + 1); - short idxC = (short) (idxA + 2); - short idxD = (short) (idxA + 3); - - AddVertex(a, b, c, d); - AddElement( - idxA, - idxB, - idxC, - idxA, - idxC, - idxD - ); - } - - private void RenderRectangles(QuikCommandRectangles rectangles) - { - QuikStrokeStyle stroke = rectangles.StrokeStyle ?? Context.DefaultStroke; - QuikFillStyle fill = rectangles.FillStyle ?? Context.DefaultFill; - - short start = (short) _elementBufferPointer; - - for (int i = 0; i < rectangles.Rectangles.Length; i++) - { - GenerateRectangle(rectangles.Rectangles[i], stroke, fill, rectangles.CornerRadius); - } - - QuikDrawCall call = CallTemplate; - call.Offset = (short) (start * 2); - call.Count = (short) (_elementBufferPointer - start); - DrawCalls.Add(call); - } - - #endregion - - #region Text - - private void RenderCharacter(QuikCommandPutChar chr) - { - Context.DefaultFont.GetCharacter(chr.Character, out QuikTexture texture, out QuikGlyph metrics); - - QuikVertex a, b, c, d; - a = b = c = d = new QuikVertex() {Color = new QuikColor(0xffffffff)}; - - a.Position = chr.Position + new QuikVec2(0, metrics.HorizontalBearing.Y - metrics.Size.Y); - a.TextureCoordinates = metrics.Location.Min; - - b.Position = a.Position + new QuikVec2(metrics.Size.X, 0); - c.Position = a.Position + metrics.Size; - d.Position = a.Position + new QuikVec2(0, metrics.Size.Y); - - b.TextureCoordinates = new QuikVec2(metrics.Location.Right, metrics.Location.Bottom); - c.TextureCoordinates = metrics.Location.Max; - d.TextureCoordinates = new QuikVec2(metrics.Location.Left, metrics.Location.Top); - - short startVertex = (short)_vertexBufferPointer; - short startElement = (short) _elementBufferPointer; - AddVertex(a, b, c, d); - AddElement(startVertex, (short)(startVertex + 1), (short)(startVertex + 2), startVertex, (short)(startVertex + 2), (short)(startVertex + 3)); - - QuikDrawCall call = CallTemplate; - call.Texture = texture; - call.Offset = (short) (startElement * 2); - call.Count = 6; - DrawCalls.Add(call); - } - - private void RenderTextPut(QuikCommandPutText text) - { - short startElement = (short)_elementBufferPointer; - QuikFont font = Context.DefaultFont; - QuikVertex vertex = new QuikVertex() {Color = new QuikColor(0x000000ff)}; - QuikVec2 pointer = text.Position; - QuikTexture texture = null; - - for (int i = 0; i < text.Text.Length; i++) - { - int chr = text.Text[i]; - QuikGlyph metrics; - - QuikTexture ntex; - font.GetCharacter(chr, out ntex, out metrics); - - if (ntex != texture && texture != null) - { - QuikDrawCall call = CallTemplate; - call.Texture = texture; - call.Offset = (short) (startElement * 2); - call.Count = (short)(_elementBufferPointer - startElement); - DrawCalls.Add(call); - - startElement = (short) _elementBufferPointer; - } - - texture = ntex; - QuikVertex a, b, c, d; - a = b = c = d = vertex; - - a.Position = pointer + new QuikVec2(0, metrics.HorizontalBearing.Y - metrics.Size.Y); - a.TextureCoordinates = metrics.Location.Min; - - b.Position = a.Position + new QuikVec2(metrics.Size.X, 0); - c.Position = a.Position + metrics.Size; - d.Position = a.Position + new QuikVec2(0, metrics.Size.Y); - - b.TextureCoordinates = new QuikVec2(metrics.Location.Right, metrics.Location.Bottom); - c.TextureCoordinates = metrics.Location.Max; - d.TextureCoordinates = new QuikVec2(metrics.Location.Left, metrics.Location.Top); - - pointer.X += metrics.Advance.X; - - short startVertex = (short)_vertexBufferPointer; - AddVertex(a, b, c, d); - AddElement(startVertex, (short)(startVertex + 1), (short)(startVertex + 2), startVertex, (short)(startVertex + 2), (short)(startVertex + 3)); - } - - { - QuikDrawCall call = CallTemplate; - call.Texture = texture; - call.Offset = (short) (startElement * 2); - call.Count = (short)(_elementBufferPointer - startElement); - DrawCalls.Add(call); - } - } - - private void RenderTextTypeset(QuikCommandEmitText text) - { - short startElement = (short)_elementBufferPointer; - TypesetGroup group = text.Group; - QuikVertex vertex = new QuikVertex() { Color = new QuikColor(0x000000ff) }; - QuikTexture texture = null; - - group.SortBy(TypesetGroup.SortByTexture); - foreach (TypesetCharacter chr in group) - { - if (texture == null) - { - texture = chr.Texture; - } - else if (texture != chr.Texture) - { - EmitCall(); - - startElement = (short)_elementBufferPointer; - texture = chr.Texture; - - CallTemplate.ClearStencil = false; - } - - QuikVertex a, b, c, d; - a = b = c = d = vertex; - - a.Position = new QuikVec2(chr.Position.Left, chr.Position.Bottom) + text.Offset; - b.Position = new QuikVec2(chr.Position.Right, chr.Position.Bottom) + text.Offset; - c.Position = new QuikVec2(chr.Position.Right, chr.Position.Top) + text.Offset; - d.Position = new QuikVec2(chr.Position.Left, chr.Position.Top) + text.Offset; - - a.TextureCoordinates = new QuikVec2(chr.UV.Left, chr.UV.Bottom); - b.TextureCoordinates = new QuikVec2(chr.UV.Right, chr.UV.Bottom); - c.TextureCoordinates = new QuikVec2(chr.UV.Right, chr.UV.Top); - d.TextureCoordinates = new QuikVec2(chr.UV.Left, chr.UV.Top); - - short startVertex = (short)_vertexBufferPointer; - AddVertex(a, b, c, d); - AddElement(startVertex, (short)(startVertex + 1), (short)(startVertex + 2), startVertex, (short)(startVertex + 2), (short)(startVertex + 3)); - } - - EmitCall(); - - void EmitCall() - { - QuikDrawCall call = CallTemplate; - - call.Texture = texture; - call.Offset = (short)(startElement * 2); - call.Count = (short)(_elementBufferPointer - startElement); - DrawCalls.Add(call); - } - } - #endregion - } - - public delegate void VertexGeneratorCommandHandler(QuikVertexGenerator generator, QuikCommand command, ref bool anyCalls); - - public enum QuikRenderTarget - { - Color, - Stencil - } - - public struct QuikDrawCall - { - public QuikRenderTarget Target; - public short Offset; - public short Count; - public QuikRectangle Bounds; - public bool ClearStencil; - public QuikTexture Texture; - } -} \ No newline at end of file diff --git a/Quik/VertexGenerator/VertexCommandEngine.cs b/Quik/VertexGenerator/VertexCommandEngine.cs index 0ffcc44..acbac08 100644 --- a/Quik/VertexGenerator/VertexCommandEngine.cs +++ b/Quik/VertexGenerator/VertexCommandEngine.cs @@ -16,12 +16,12 @@ namespace Quik.VertexGenerator protected QuikVertex StrokeVertex => new QuikVertex() { ZIndex = Style.ZIndex ?? this.ZIndex, - Color = Style.StrokeColor ?? QuikColor.Black, + Color = Style.StrokeColor ?? QColor.Black, }; protected QuikVertex FillVertex => new QuikVertex() { ZIndex = Style.ZIndex ?? this.ZIndex, - Color = Style.Color ?? QuikColor.White, + Color = Style.Color ?? QColor.White, }; public override void Reset() @@ -54,7 +54,7 @@ namespace Quik.VertexGenerator return (int) Math.Ceiling(arc * radius * CurveGranularity); } - private readonly List LineList = new List(); + private readonly List LineList = new List(); private void LineProc(CommandQueue queue) { Frame frame = queue.Dequeue(); @@ -67,12 +67,12 @@ namespace Quik.VertexGenerator for (int i = 0; i < count; i++) { frame = queue.Dequeue(); - LineList.Add((QuikLine)frame); + LineList.Add((QLine)frame); } } else { - LineList.Add((QuikLine)frame); + LineList.Add((QLine)frame); } float width = Style.StrokeWidth ?? 1; @@ -81,7 +81,7 @@ namespace Quik.VertexGenerator LineInfo prevBase, nextBase = default; for (int i = 0; i < LineList.Count; i++) { - QuikLine line = LineList[i]; + QLine line = LineList[i]; // A line segment needs a start cap if it is the first segment in // the list, or the last end point is not the current start point. bool isStart = (i == 0 || line.Start != LineList[i - 1].End); @@ -112,11 +112,11 @@ namespace Quik.VertexGenerator DrawQueue.EndDrawCall(); } - private LineInfo GenerateLineSegment(in QuikLine line) + private LineInfo GenerateLineSegment(in QLine line) { QuikVertex vertex = StrokeVertex; QuikVertex a, b, c, d; - QuikVec2 normal = line.Normal(); + QVec2 normal = line.Normal(); float width = Style.StrokeWidth ?? 1; a = b = c = d = vertex; @@ -136,20 +136,20 @@ namespace Quik.VertexGenerator } private void GenerateJoint( - in QuikVec2 center, - in QuikVec2 prevNormal, - in QuikVec2 nextNormal, + in QVec2 center, + in QVec2 prevNormal, + in QVec2 nextNormal, in LineInfo prevInfo, in LineInfo nextInfo) { // Figure out which side needs the joint. - QuikVec2 meanNormal = 0.5f * (prevNormal + nextNormal); - QuikVec2 meanTangent = new QuikVec2(meanNormal.Y, -meanNormal.X); - QuikVec2 positiveEdge = ((center + nextNormal) - (center + prevNormal)).Normalize(); - QuikVec2 negativeEdge = ((center - nextNormal) - (center - prevNormal)).Normalize(); + QVec2 meanNormal = 0.5f * (prevNormal + nextNormal); + QVec2 meanTangent = new QVec2(meanNormal.Y, -meanNormal.X); + QVec2 positiveEdge = ((center + nextNormal) - (center + prevNormal)).Normalize(); + QVec2 negativeEdge = ((center - nextNormal) - (center - prevNormal)).Normalize(); float positive, negative; - positive = QuikVec2.Dot(meanTangent, positiveEdge); - negative = QuikVec2.Dot(meanNormal, negativeEdge); + positive = QVec2.Dot(meanTangent, positiveEdge); + negative = QVec2.Dot(meanNormal, negativeEdge); if (positive == negative) { @@ -161,7 +161,7 @@ namespace Quik.VertexGenerator QuikVertex vertex = StrokeVertex; float radius = Style.StrokeWidth/2 ?? 0.5f; - float arc = MathF.Acos(QuikVec2.Dot(prevNormal, nextNormal)); + float arc = MathF.Acos(QVec2.Dot(prevNormal, nextNormal)); int resolution = GetRoundingResolution(radius, arc); bool isNegative = positive < negative; @@ -187,10 +187,10 @@ namespace Quik.VertexGenerator float cos = MathF.Cos(angle); float sin = MathF.Sin(angle); - QuikVec2 displacement; + QVec2 displacement; if (isNegative) { - displacement = new QuikVec2() + displacement = new QVec2() { X = -prevNormal.X * cos + prevNormal.Y * sin, Y = -prevNormal.X * sin - prevNormal.Y * cos @@ -198,7 +198,7 @@ namespace Quik.VertexGenerator } else { - displacement = new QuikVec2() + displacement = new QVec2() { X = nextNormal.X * cos - nextNormal.Y * sin, Y = nextNormal.X * sin + nextNormal.Y * cos @@ -222,8 +222,8 @@ namespace Quik.VertexGenerator } private void GenerateCap( - in QuikVec2 center, - in QuikVec2 normal, + in QVec2 center, + in QVec2 normal, in LineInfo info, bool endCap) { @@ -250,10 +250,10 @@ namespace Quik.VertexGenerator float cos = MathF.Cos(angle); float sin = MathF.Sin(angle); - QuikVec2 displacement; + QVec2 displacement; if (endCap) { - displacement = new QuikVec2() + displacement = new QVec2() { X = normal.X * cos + normal.Y * sin, Y = -normal.X * sin + normal.Y * cos @@ -261,7 +261,7 @@ namespace Quik.VertexGenerator } else { - displacement = new QuikVec2() + displacement = new QVec2() { X = normal.X * cos - normal.Y * sin, Y = normal.X * sin + normal.Y * cos @@ -279,7 +279,7 @@ namespace Quik.VertexGenerator } } - private readonly List BezierList = new List(); + private readonly List BezierList = new List(); private void BezierProc(CommandQueue queue) { Frame a = queue.Dequeue(); @@ -296,11 +296,11 @@ namespace Quik.VertexGenerator b = queue.Dequeue(); BezierList.Add( - new QuikBezier( - new QuikVec2(a.GetF(0), a.GetF(1)), - new QuikVec2(b.GetF(0), b.GetF(1)), - new QuikVec2(b.GetF(2), b.GetF(3)), - new QuikVec2(a.GetF(2), a.GetF(3)) + new QBezier( + new QVec2(a.GetF(0), a.GetF(1)), + new QVec2(b.GetF(0), b.GetF(1)), + new QVec2(b.GetF(2), b.GetF(3)), + new QVec2(a.GetF(2), a.GetF(3)) ) ); } @@ -310,11 +310,11 @@ namespace Quik.VertexGenerator b = queue.Dequeue(); BezierList.Add( - new QuikBezier( - new QuikVec2(a.GetF(0), a.GetF(1)), - new QuikVec2(b.GetF(0), b.GetF(1)), - new QuikVec2(b.GetF(2), b.GetF(3)), - new QuikVec2(a.GetF(2), a.GetF(3)) + new QBezier( + new QVec2(a.GetF(0), a.GetF(1)), + new QVec2(b.GetF(0), b.GetF(1)), + new QVec2(b.GetF(2), b.GetF(3)), + new QVec2(a.GetF(2), a.GetF(3)) ) ); } @@ -325,7 +325,7 @@ namespace Quik.VertexGenerator LineInfo prevBase, nextBase = default; for (int i = 0; i < LineList.Count; i++) { - QuikBezier bezier = BezierList[i]; + QBezier bezier = BezierList[i]; // A line segment needs a start cap if it is the first segment in // the list, or the last end point is not the current start point. bool isStart = (i == 0 || bezier.Start != BezierList[i - 1].End); @@ -356,12 +356,12 @@ namespace Quik.VertexGenerator DrawQueue.EndDrawCall(); } - private LineInfo GenerateBezierSegment(in QuikBezier bezier) + private LineInfo GenerateBezierSegment(in QBezier bezier) { - QuikVec2 startTangent = bezier.GetBezierTangent(0); - QuikVec2 endTangent = bezier.GetBezierTangent(1); - QuikVec2 startNormal = new QuikVec2(-startTangent.Y, startTangent.X).Normalize(); - QuikVec2 endNormal = new QuikVec2(-endTangent.Y, endTangent.X).Normalize(); + QVec2 startTangent = bezier.GetBezierTangent(0); + QVec2 endTangent = bezier.GetBezierTangent(1); + QVec2 startNormal = new QVec2(-startTangent.Y, startTangent.X).Normalize(); + QVec2 endNormal = new QVec2(-endTangent.Y, endTangent.X).Normalize(); float width = Style.StrokeWidth ?? 1; float radius = 0.5f * width; @@ -380,9 +380,9 @@ namespace Quik.VertexGenerator for (int i = 0; i < resolution; i++, index += 2) { float t = (i + 1.0f) / resolution; - QuikVec2 at = bezier.GetBezierTangent(t).Normalize(); - QuikVec2 a = bezier.GetBezierPoint(t); - QuikVec2 an = radius * new QuikVec2(-at.Y, at.X); + QVec2 at = bezier.GetBezierTangent(t).Normalize(); + QVec2 a = bezier.GetBezierPoint(t); + QVec2 an = radius * new QVec2(-at.Y, at.X); v.Position = a + an; DrawQueue.AddVertex(v); @@ -396,7 +396,7 @@ namespace Quik.VertexGenerator return new LineInfo(vbase, 0, 1, index - 2, index - 1); } - private readonly List RectangleList = new List(); + private readonly List RectangleList = new List(); private void RectangleProc(CommandQueue queue) { Frame frame = queue.Dequeue(); @@ -407,12 +407,12 @@ namespace Quik.VertexGenerator for (int i = 0; i < count; i++) { frame = queue.Dequeue(); - RectangleList.Add((QuikRectangle)frame); + RectangleList.Add((QRectangle)frame); } } else { - RectangleList.Add((QuikRectangle)frame); + RectangleList.Add((QRectangle)frame); } float stroke = Style.StrokeWidth ?? 1.0f; @@ -420,8 +420,8 @@ namespace Quik.VertexGenerator DrawQueue.StartDrawCall(Viewport); for (int i = 0; i < RectangleList.Count; i++) { - QuikRectangle outer = RectangleList[i]; - QuikRectangle inner = new QuikRectangle( + QRectangle outer = RectangleList[i]; + QRectangle inner = new QRectangle( outer.Right - stroke, outer.Top - stroke, outer.Left + stroke, outer.Bottom + stroke); @@ -445,7 +445,7 @@ namespace Quik.VertexGenerator DrawQueue.EndDrawCall(); } - private void GenerateRectangleBase(in QuikRectangle rectangle, float radius) + private void GenerateRectangleBase(in QRectangle rectangle, float radius) { /* +--j-------i--+ @@ -466,16 +466,16 @@ namespace Quik.VertexGenerator // Draw center rectangle. - QuikVec2 aPos, bPos, cPos, dPos; + QVec2 aPos, bPos, cPos, dPos; QuikVertex v = FillVertex; - aPos = v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Bottom + radius); + aPos = v.Position = new QVec2(rectangle.Left + radius, rectangle.Bottom + radius); DrawQueue.AddVertex(v); - bPos = v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Bottom + radius); + bPos = v.Position = new QVec2(rectangle.Right - radius, rectangle.Bottom + radius); DrawQueue.AddVertex(v); - cPos = v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Top - radius); + cPos = v.Position = new QVec2(rectangle.Right - radius, rectangle.Top - radius); DrawQueue.AddVertex(v); - dPos = v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Top - radius); + dPos = v.Position = new QVec2(rectangle.Left + radius, rectangle.Top - radius); DrawQueue.AddVertex(v); DrawQueue.AddElement(0); DrawQueue.AddElement(1); DrawQueue.AddElement(2); @@ -486,9 +486,9 @@ namespace Quik.VertexGenerator // Draw south rectangle. - v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Bottom); + v.Position = new QVec2(rectangle.Left + radius, rectangle.Bottom); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Bottom); + v.Position = new QVec2(rectangle.Right - radius, rectangle.Bottom); DrawQueue.AddVertex(v); DrawQueue.AddElement(4); DrawQueue.AddElement(5); DrawQueue.AddElement(1); @@ -496,9 +496,9 @@ namespace Quik.VertexGenerator // Draw east rectangle. - v.Position = new QuikVec2(rectangle.Right, rectangle.Bottom + radius); + v.Position = new QVec2(rectangle.Right, rectangle.Bottom + radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right, rectangle.Top - radius); + v.Position = new QVec2(rectangle.Right, rectangle.Top - radius); DrawQueue.AddVertex(v); DrawQueue.AddElement(1); DrawQueue.AddElement(6); DrawQueue.AddElement(7); @@ -506,9 +506,9 @@ namespace Quik.VertexGenerator // Draw north rectangle. - v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Top); + v.Position = new QVec2(rectangle.Right - radius, rectangle.Top); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Top); + v.Position = new QVec2(rectangle.Left + radius, rectangle.Top); DrawQueue.AddVertex(v); DrawQueue.AddElement(3); DrawQueue.AddElement(2); DrawQueue.AddElement(8); @@ -516,9 +516,9 @@ namespace Quik.VertexGenerator // Draw west rectangle. - v.Position = new QuikVec2(rectangle.Left, rectangle.Top - radius); + v.Position = new QVec2(rectangle.Left, rectangle.Top - radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left, rectangle.Bottom + radius); + v.Position = new QVec2(rectangle.Left, rectangle.Bottom + radius); DrawQueue.AddVertex(v); DrawQueue.AddElement(11); DrawQueue.AddElement(0); DrawQueue.AddElement(3); @@ -535,7 +535,7 @@ namespace Quik.VertexGenerator float xoff = MathF.Cos(theta) * radius; float yoff = MathF.Sin(theta) * radius; - v.Position = cPos + new QuikVec2(xoff, yoff); + v.Position = cPos + new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(2); DrawQueue.AddElement(previous); DrawQueue.AddElement((previous = current++)); } @@ -550,7 +550,7 @@ namespace Quik.VertexGenerator float xoff = -MathF.Sin(theta) * radius; float yoff = MathF.Cos(theta) * radius; - v.Position = dPos + new QuikVec2(xoff, yoff); + v.Position = dPos + new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(3); DrawQueue.AddElement(previous); DrawQueue.AddElement((previous = current++)); } @@ -565,7 +565,7 @@ namespace Quik.VertexGenerator float xoff = -MathF.Cos(theta) * radius; float yoff = -MathF.Sin(theta) * radius; - v.Position = aPos + new QuikVec2(xoff, yoff); + v.Position = aPos + new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(0); DrawQueue.AddElement(previous); DrawQueue.AddElement((previous = current++)); } @@ -580,14 +580,14 @@ namespace Quik.VertexGenerator float xoff = -MathF.Sin(theta) * radius; float yoff = MathF.Cos(theta) * radius; - v.Position = bPos + new QuikVec2(xoff, yoff); + v.Position = bPos + new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(1); DrawQueue.AddElement(previous); DrawQueue.AddElement((previous = current++)); } DrawQueue.AddElement(1); DrawQueue.AddElement(previous); DrawQueue.AddElement(6); } - private void GenerateRectangleStripStraight(in QuikRectangle rectangle) + private void GenerateRectangleStripStraight(in QRectangle rectangle) { /* h---------g @@ -609,22 +609,22 @@ namespace Quik.VertexGenerator DrawQueue.RestoreOffset(); - v.Position = new QuikVec2(rectangle.Left + stroke, rectangle.Bottom + stroke); + v.Position = new QVec2(rectangle.Left + stroke, rectangle.Bottom + stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - stroke, rectangle.Bottom + stroke); + v.Position = new QVec2(rectangle.Right - stroke, rectangle.Bottom + stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - stroke, rectangle.Top - stroke); + v.Position = new QVec2(rectangle.Right - stroke, rectangle.Top - stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left + stroke, rectangle.Top - stroke); + v.Position = new QVec2(rectangle.Left + stroke, rectangle.Top - stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left, rectangle.Bottom); + v.Position = new QVec2(rectangle.Left, rectangle.Bottom); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right, rectangle.Bottom); + v.Position = new QVec2(rectangle.Right, rectangle.Bottom); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right, rectangle.Top); + v.Position = new QVec2(rectangle.Right, rectangle.Top); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left, rectangle.Top); + v.Position = new QVec2(rectangle.Left, rectangle.Top); DrawQueue.AddVertex(v); DrawQueue.AddElement(4); DrawQueue.AddElement(5); DrawQueue.AddElement(1); // SSW @@ -637,7 +637,7 @@ namespace Quik.VertexGenerator DrawQueue.AddElement(4); DrawQueue.AddElement(3); DrawQueue.AddElement(7); // SWW } - private void GenerateRectangleStripNarrow(in QuikRectangle rectangle, float radius) + private void GenerateRectangleStripNarrow(in QRectangle rectangle, float radius) { /* v-j---i-u @@ -662,73 +662,73 @@ namespace Quik.VertexGenerator 20: 0 1 2 3 */ QuikVertex v = StrokeVertex; - QuikVec2 nPos, qPos, tPos, wPos; + QVec2 nPos, qPos, tPos, wPos; float stroke = Style.StrokeWidth ?? 1.0f; DrawQueue.RestoreOffset(); // a-b-c-d - v.Position = new QuikVec2(rectangle.Left + stroke, rectangle.Bottom + stroke); + v.Position = new QVec2(rectangle.Left + stroke, rectangle.Bottom + stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - stroke, rectangle.Bottom + stroke); + v.Position = new QVec2(rectangle.Right - stroke, rectangle.Bottom + stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - stroke, rectangle.Top - stroke); + v.Position = new QVec2(rectangle.Right - stroke, rectangle.Top - stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left + stroke, rectangle.Top - stroke); + v.Position = new QVec2(rectangle.Left + stroke, rectangle.Top - stroke); DrawQueue.AddVertex(v); // ef-gh-ij-kl - v.Position = new QuikVec2(rectangle.Left + stroke, rectangle.Bottom); + v.Position = new QVec2(rectangle.Left + stroke, rectangle.Bottom); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left + stroke, rectangle.Bottom); + v.Position = new QVec2(rectangle.Left + stroke, rectangle.Bottom); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right, rectangle.Bottom + stroke); + v.Position = new QVec2(rectangle.Right, rectangle.Bottom + stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right, rectangle.Top - stroke); + v.Position = new QVec2(rectangle.Right, rectangle.Top - stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - stroke, rectangle.Top); + v.Position = new QVec2(rectangle.Right - stroke, rectangle.Top); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - stroke, rectangle.Top); + v.Position = new QVec2(rectangle.Right - stroke, rectangle.Top); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left, rectangle.Top - stroke); + v.Position = new QVec2(rectangle.Left, rectangle.Top - stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left, rectangle.Bottom + stroke); + v.Position = new QVec2(rectangle.Left, rectangle.Bottom + stroke); DrawQueue.AddVertex(v); // mno - v.Position = new QuikVec2(rectangle.Left, rectangle.Bottom + radius); + v.Position = new QVec2(rectangle.Left, rectangle.Bottom + radius); DrawQueue.AddVertex(v); - nPos = v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Bottom + radius); + nPos = v.Position = new QVec2(rectangle.Left + radius, rectangle.Bottom + radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Bottom); + v.Position = new QVec2(rectangle.Left + radius, rectangle.Bottom); DrawQueue.AddVertex(v); // pqr - v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Bottom); + v.Position = new QVec2(rectangle.Right - radius, rectangle.Bottom); DrawQueue.AddVertex(v); - qPos = v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Bottom + radius); + qPos = v.Position = new QVec2(rectangle.Right - radius, rectangle.Bottom + radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right, rectangle.Bottom + radius); + v.Position = new QVec2(rectangle.Right, rectangle.Bottom + radius); DrawQueue.AddVertex(v); // stu - v.Position = new QuikVec2(rectangle.Right, rectangle.Top - radius); + v.Position = new QVec2(rectangle.Right, rectangle.Top - radius); DrawQueue.AddVertex(v); - tPos = v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Top - radius); + tPos = v.Position = new QVec2(rectangle.Right - radius, rectangle.Top - radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Top); + v.Position = new QVec2(rectangle.Right - radius, rectangle.Top); DrawQueue.AddVertex(v); // vwx - v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Top); + v.Position = new QVec2(rectangle.Left + radius, rectangle.Top); DrawQueue.AddVertex(v); - wPos = v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Top - radius); + wPos = v.Position = new QVec2(rectangle.Left + radius, rectangle.Top - radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left, rectangle.Top - radius); + v.Position = new QVec2(rectangle.Left, rectangle.Top - radius); DrawQueue.AddVertex(v); // E @@ -779,7 +779,7 @@ namespace Quik.VertexGenerator float xoff = MathF.Cos(theta) * radius; float yoff = MathF.Sin(theta) * radius; - v.Position = tPos + new QuikVec2(xoff, yoff); + v.Position = tPos + new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(19); DrawQueue.AddElement(previous); DrawQueue.AddElement((previous = current++)); } @@ -794,7 +794,7 @@ namespace Quik.VertexGenerator float xoff = -MathF.Sin(theta) * radius; float yoff = MathF.Cos(theta) * radius; - v.Position = wPos + new QuikVec2(xoff, yoff); + v.Position = wPos + new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(22); DrawQueue.AddElement(previous); DrawQueue.AddElement((previous = current++)); } @@ -809,7 +809,7 @@ namespace Quik.VertexGenerator float xoff = -MathF.Cos(theta) * radius; float yoff = -MathF.Sin(theta) * radius; - v.Position = nPos + new QuikVec2(xoff, yoff); + v.Position = nPos + new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(23); DrawQueue.AddElement(previous); DrawQueue.AddElement((previous = current++)); } @@ -824,14 +824,14 @@ namespace Quik.VertexGenerator float xoff = -MathF.Sin(theta) * radius; float yoff = MathF.Cos(theta) * radius; - v.Position = qPos + new QuikVec2(xoff, yoff); + v.Position = qPos + new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(16); DrawQueue.AddElement(previous); DrawQueue.AddElement((previous = current++)); } DrawQueue.AddElement(16); DrawQueue.AddElement(previous); DrawQueue.AddElement(17); } - private void GenerateRectangleStripWide(in QuikRectangle rectangle, float radius) + private void GenerateRectangleStripWide(in QRectangle rectangle, float radius) { /* l---k @@ -855,40 +855,40 @@ namespace Quik.VertexGenerator float innerRadius = radius - stroke; DrawQueue.RestoreOffset(); - v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Bottom); + v.Position = new QVec2(rectangle.Left + radius, rectangle.Bottom); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Bottom); + v.Position = new QVec2(rectangle.Right - radius, rectangle.Bottom); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Bottom + stroke); + v.Position = new QVec2(rectangle.Right - radius, rectangle.Bottom + stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Bottom + stroke); + v.Position = new QVec2(rectangle.Left + radius, rectangle.Bottom + stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - stroke, rectangle.Bottom + radius); + v.Position = new QVec2(rectangle.Right - stroke, rectangle.Bottom + radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right, rectangle.Top - radius); + v.Position = new QVec2(rectangle.Right, rectangle.Top - radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right, rectangle.Top - radius); + v.Position = new QVec2(rectangle.Right, rectangle.Top - radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - stroke, rectangle.Bottom + radius); + v.Position = new QVec2(rectangle.Right - stroke, rectangle.Bottom + radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Top - stroke); + v.Position = new QVec2(rectangle.Left + radius, rectangle.Top - stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Top - stroke); + v.Position = new QVec2(rectangle.Right - radius, rectangle.Top - stroke); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Right - radius, rectangle.Top); + v.Position = new QVec2(rectangle.Right - radius, rectangle.Top); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left + radius, rectangle.Top); + v.Position = new QVec2(rectangle.Left + radius, rectangle.Top); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left, rectangle.Bottom + radius); + v.Position = new QVec2(rectangle.Left, rectangle.Bottom + radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left + stroke, rectangle.Top - radius); + v.Position = new QVec2(rectangle.Left + stroke, rectangle.Top - radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left + stroke, rectangle.Top - radius); + v.Position = new QVec2(rectangle.Left + stroke, rectangle.Top - radius); DrawQueue.AddVertex(v); - v.Position = new QuikVec2(rectangle.Left, rectangle.Bottom + radius); + v.Position = new QVec2(rectangle.Left, rectangle.Bottom + radius); DrawQueue.AddVertex(v); // S @@ -908,7 +908,7 @@ namespace Quik.VertexGenerator int resolution = GetRoundingResolution(radius, 0.5f * MathF.PI); int current = 16; - QuikVec2 center = new QuikVec2(rectangle.Right - radius, rectangle.Top - radius); + QVec2 center = new QVec2(rectangle.Right - radius, rectangle.Top - radius); int s1 = 7, s2 = 6; for (int i = 0; i < resolution - 1; i++) { @@ -916,9 +916,9 @@ namespace Quik.VertexGenerator float xoff = MathF.Cos(theta); float yoff = MathF.Sin(theta); - v.Position = center + radius * new QuikVec2(xoff, yoff); + v.Position = center + radius * new QVec2(xoff, yoff); DrawQueue.AddVertex(v); - v.Position = center + innerRadius * new QuikVec2(xoff, yoff); + v.Position = center + innerRadius * new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(s1); DrawQueue.AddElement(s2); DrawQueue.AddElement(current + 0); @@ -931,7 +931,7 @@ namespace Quik.VertexGenerator DrawQueue.AddElement(s1); DrawQueue.AddElement(s2); DrawQueue.AddElement(9); // Draw NW arc - center = new QuikVec2(rectangle.Left + radius, rectangle.Top - radius); + center = new QVec2(rectangle.Left + radius, rectangle.Top - radius); s1 = 8; s2 = 11; for (int i = 0; i < resolution - 1; i++) { @@ -939,9 +939,9 @@ namespace Quik.VertexGenerator float xoff = -MathF.Sin(theta); float yoff = MathF.Cos(theta); - v.Position = center + radius * new QuikVec2(xoff, yoff); + v.Position = center + radius * new QVec2(xoff, yoff); DrawQueue.AddVertex(v); - v.Position = center + innerRadius * new QuikVec2(xoff, yoff); + v.Position = center + innerRadius * new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(s1); DrawQueue.AddElement(s2); DrawQueue.AddElement(current + 0); @@ -954,7 +954,7 @@ namespace Quik.VertexGenerator DrawQueue.AddElement(s1); DrawQueue.AddElement(s2); DrawQueue.AddElement(14); // Draw SW arc - center = new QuikVec2(rectangle.Left + radius, rectangle.Bottom + radius); + center = new QVec2(rectangle.Left + radius, rectangle.Bottom + radius); s1 = 13; s2 = 12; for (int i = 0; i < resolution - 1; i++) { @@ -962,9 +962,9 @@ namespace Quik.VertexGenerator float xoff = -MathF.Cos(theta); float yoff = -MathF.Sin(theta); - v.Position = center + radius * new QuikVec2(xoff, yoff); + v.Position = center + radius * new QVec2(xoff, yoff); DrawQueue.AddVertex(v); - v.Position = center + innerRadius * new QuikVec2(xoff, yoff); + v.Position = center + innerRadius * new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(s1); DrawQueue.AddElement(s2); DrawQueue.AddElement(current + 0); @@ -977,7 +977,7 @@ namespace Quik.VertexGenerator DrawQueue.AddElement(s1); DrawQueue.AddElement(s2); DrawQueue.AddElement(3); // Draw SW arc - center = new QuikVec2(rectangle.Right - radius, rectangle.Bottom + radius); + center = new QVec2(rectangle.Right - radius, rectangle.Bottom + radius); s1 = 2; s2 = 1; for (int i = 0; i < resolution - 1; i++) { @@ -985,9 +985,9 @@ namespace Quik.VertexGenerator float xoff = MathF.Sin(theta); float yoff = -MathF.Cos(theta); - v.Position = center + radius * new QuikVec2(xoff, yoff); + v.Position = center + radius * new QVec2(xoff, yoff); DrawQueue.AddVertex(v); - v.Position = center + innerRadius * new QuikVec2(xoff, yoff); + v.Position = center + innerRadius * new QVec2(xoff, yoff); DrawQueue.AddVertex(v); DrawQueue.AddElement(s1); DrawQueue.AddElement(s2); DrawQueue.AddElement(current + 0); diff --git a/QuikTestApplication/Program.cs b/QuikTestApplication/Program.cs index d6f86de..c8b23c4 100644 --- a/QuikTestApplication/Program.cs +++ b/QuikTestApplication/Program.cs @@ -15,6 +15,7 @@ using Quik.Controls; using Quik.OpenGL; using GL = Quik.OpenGL.GL; using static Quik.OpenGL.GLEnum; +using Quik.CommandMachine; namespace QuikTestApplication { @@ -62,17 +63,21 @@ void main() GL.LoadBindings(new GLFWBindingsContext().GetProcAddress); FreeTypeFontManager fontManager = new FreeTypeFontManager(); - QuikContext context = new QuikContext(new OpenGLTextureManager(), fontManager); - QuikVertexGenerator gen = new QuikVertexGenerator(context); + QuikContext context = new QuikContext(new OpenGLTextureManager(), fontManager); + + VertexGeneratorEngine engine = new VertexGeneratorEngine(); + CommandQueue cmdQueue = new CommandQueue(); + GL30Driver gldriver; + RootControl root = new RootControl(context); Button button = new Button() { - Bounds = new QuikRectangle(120, 60, 20, 20), + Bounds = new QRectangle(120, 60, 20, 20), Text = "button", Padding = 8, - NormalStroke = new QuikStrokeStyle(new QuikColor(0xccccccff), 4f), - HoverStroke = new QuikStrokeStyle(new QuikColor(0x1010ccff), 4f), - ActiveStroke = new QuikStrokeStyle(new QuikColor(0x999999ff), 4f), + NormalStroke = new QuikStrokeStyle(new QColor(0xccccccff), 4f), + HoverStroke = new QuikStrokeStyle(new QColor(0x1010ccff), 4f), + ActiveStroke = new QuikStrokeStyle(new QColor(0x999999ff), 4f), }; button.Clicked += (sender, args) => { if (!args.Buttons.HasFlag(Quik.MouseButton.Primary)) @@ -98,109 +103,7 @@ void main() GL.Enable(GL_MULTISAMPLE); - int sp; - { - int vs, fs; - - sp = GL.CreateProgram(); - - vs = GL.CreateShader(GL_VERTEX_SHADER); - fs = GL.CreateShader(GL_FRAGMENT_SHADER); - - GL.ShaderSource(vs, vertex); - GL.CompileShader(vs); - GL.ShaderSource(fs, fragment); - GL.CompileShader(fs); - - GL.AttachShader(sp, vs); - GL.AttachShader(sp, fs); - GL.LinkProgram(sp); - - GL.UseProgram(sp); - } - - new GL30Driver(); - - int vbo, ebo, vao; - vbo = GL.GenBuffer(); - ebo = GL.GenBuffer(); - - vao = GL.GenVertexArray(); - GL.BindVertexArray(vao); - - GL.BindBuffer(GL_ARRAY_BUFFER, vbo); - GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); - - int loc; - GL.VertexAttribPointer( - loc = GL.GetAttribLocation(sp, "position"), - 2, - GL_FLOAT, - false, - QuikVertex.Stride, - QuikVertex.PositionOffset); - GL.EnableVertexAttribArray(loc); - GL.VertexAttribPointer( - loc = GL.GetAttribLocation(sp, "texcoord"), - 2, - GL_FLOAT, - false, - QuikVertex.Stride, - QuikVertex.TextureCoordinatesOffset); - GL.EnableVertexAttribArray(loc); - GL.VertexAttribPointer( - loc = GL.GetAttribLocation(sp, "color"), - 4, - GL_UNSIGNED_BYTE, - true, - QuikVertex.Stride, - QuikVertex.ColorOffset); - GL.EnableVertexAttribArray(loc); - - loc = GL.GetUniformLocation(sp, "matrix"); - - int offsetLoc = GL.GetUniformLocation(sp, "texture0offset"); - - QuikStrokeStyle strokeBorder = new QuikStrokeStyle() - { - Color = new QuikColor(0xaaaaaaff), - Width = 8 - }; - - QuikStrokeStyle strokeNoBorder = new QuikStrokeStyle() - { - Color = new QuikColor(0xaaaaaaff), - Width = 0 - }; - - QuikFillStyle fill = new QuikFillStyle() - { - Color = new QuikColor(0xeeeeeeff) - }; - - QuikFillStyle magenta = new QuikFillStyle - { - Color = new QuikColor(0xff00ffff) - }; - - int whiteTexture = GL.GenTexture(); - uint[] whitePixel = {0xFFFFFFFF}; - GL.BindTexture(GL_TEXTURE_2D, whiteTexture); - GL.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, whitePixel); - GL.TexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - GL.TexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - context.DefaultFont = context.FontManager.GetFont(new QuikFontStyle("Arial", 16, QuikFontType.Normal)); - - const string testString = - "The quick brown fox jumps over the lazy dog. " + - "Sphinx of black quartz judge my vow. " + - "Have some japanese for fun: これが読めるかな?"; - - var para = new HorizontalParagraph(); - para.ConsumeText(context.DefaultFont, testString); - var typeset = new TypesetGroup(); - para.Typeset(typeset, 200); + gldriver = new GL30Driver(); window.Context.SwapInterval = 0; Stopwatch stopwatch = Stopwatch.StartNew(); @@ -215,7 +118,7 @@ void main() if (window.IsFocused) { var mouseState = window.MouseState; - QuikVec2 postion = new QuikVec2(mouseState.Position.X, window.ClientSize.Y - mouseState.Position.Y) * (dpi/72f); + QVec2 postion = new QVec2(mouseState.Position.X, window.ClientSize.Y - mouseState.Position.Y) * (dpi/72f); Quik.MouseButton buttons = (mouseState.IsButtonDown(OpenTK.Windowing.GraphicsLibraryFramework.MouseButton.Button1) ? Quik.MouseButton.Primary : 0) | (mouseState.IsButtonDown(OpenTK.Windowing.GraphicsLibraryFramework.MouseButton.Button2) ? Quik.MouseButton.Secondary : 0) | @@ -224,107 +127,24 @@ void main() root.NotifyMouse(new Quik.MouseState(postion, buttons)); } - root.Bounds = new QuikRectangle( + root.Bounds = new QRectangle( window.ClientSize.X, window.ClientSize.Y, 0, 0); root.NotifyUpdate(); - GL.Viewport(0, 0, window.Size.X, window.Size.Y); + cmdQueue.Clear(); + root.NotifyPaint(cmdQueue); + + engine.Reset(); + engine.ProcessCommands(root.Bounds, cmdQueue); + + DrawQueue drawQueue = engine.DrawQueue; - GL.ClearColor(1,1,1,1); GL.Clear(GL_COLOR_BUFFER_BIT); - GL.Enable(GL_BLEND); - GL.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - Matrix4 matrix = Matrix4.CreateOrthographicOffCenter( - 0, - (float)window.Size.X*dpi/72f, - 0, - (float)window.Size.Y*dpi/72f, - 1, - -1); - GL.UniformMatrix4(loc, false, ref matrix.Row0.X); + gldriver.Draw(drawQueue); - context.Draw.Commands.Enqueue( - new QuikCommandRectangle(new QuikRectangle(120, 60, 20, 20)) - { - CornerRadius = 0, - FillStyle = fill, - StrokeStyle = strokeNoBorder - }); - - context.Draw.Commands.Enqueue( - new QuikCommandRectangle(new QuikRectangle(240, 60, 140, 20)) - { - CornerRadius = 4, - FillStyle = fill, - StrokeStyle = strokeNoBorder - }); - - context.Draw.Commands.Enqueue( - new QuikCommandRectangle(new QuikRectangle(360, 60, 260, 20)) - { - CornerRadius = 15, - FillStyle = fill, - StrokeStyle = strokeNoBorder - }); - - context.Draw.Commands.Enqueue( - new QuikCommandRectangle(new QuikRectangle(120, 120, 20, 80)) - { - CornerRadius = 0, - FillStyle = fill, - StrokeStyle = strokeBorder - }); - - context.Draw.Commands.Enqueue( - new QuikCommandRectangle(new QuikRectangle(240, 120, 140, 80)) - { - CornerRadius = 4, - FillStyle = fill, - StrokeStyle = strokeBorder - }); - - context.Draw.Commands.Enqueue( - new QuikCommandRectangle(new QuikRectangle(360, 120, 260, 80)) - { - CornerRadius = 15, - FillStyle = fill, - StrokeStyle = strokeBorder - }); - - // context.Draw.PutText("これが読めるかな?", new QuikVec2(25,30)); - root.NotifyPaint(context.Draw); - - context.Draw.Commands.Enqueue(new QuikCommandEmitText(typeset, new QuikVec2(200, 200))); - - QuikCommand command; - while (context.Draw.Commands.TryDequeue(out command)) - { - gen.ConsumeCommand(command); - } - - GL.BufferData(GL_ARRAY_BUFFER, gen.VertexCount * QuikVertex.Stride, gen.VertexBuffer, GL_STREAM_DRAW); - GL.BufferData(GL_ELEMENT_ARRAY_BUFFER, gen.ElementCount * 2, gen.ElementBuffer, GL_STREAM_DRAW); - - GL.Enable(GL_BLEND); - GL.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - foreach (QuikDrawCall call in gen.DrawCalls) - { - GL.BindTexture( - GL_TEXTURE_2D, - call.Texture == null ? whiteTexture : (call.Texture as OpenGLTexture).TextureId); - if (call.Texture != null) - GL.Uniform2(offsetLoc, 0.5f / call.Texture.Width, 0.5f / call.Texture.Height); - GL.DrawElements(GL_TRIANGLES, call.Count, GL_UNSIGNED_SHORT, call.Offset); - } - GL.Disable(GL_BLEND); - - int callCount = gen.DrawCalls.Count; - gen.Clear(); - System.Threading.Thread.Sleep(1); window.Context.SwapBuffers(); frames++; @@ -334,7 +154,7 @@ void main() Console.WriteLine("Frames: {0}", frames*(ms - lastMs)/1000); frames = 0; lastMs = ms; - Console.WriteLine("Vertex Usage: {0} ; Element Usage: {1} Calls: {2}", gen.VertexUsage, gen.ElementUsage, callCount); + Console.WriteLine("Vertex Usage: {0} ; Element Usage: {1} Calls: {2}", drawQueue.VertexCount, drawQueue.ElementCount, drawQueue.DrawCallCount); } } } diff --git a/QuikTestApplication/TestFont.cs b/QuikTestApplication/TestFont.cs index 46196a6..f9ff127 100644 --- a/QuikTestApplication/TestFont.cs +++ b/QuikTestApplication/TestFont.cs @@ -18,7 +18,7 @@ namespace QuikTestApplication private static Dictionary _glyphs = new Dictionary(); public static byte[] TextureData { get; private set; } = Array.Empty(); - public static QuikVec2 TextureSize { get; private set; } + public static QVec2 TextureSize { get; private set; } public QuikTexture Texture { get; } @@ -55,7 +55,7 @@ namespace QuikTestApplication _style = new QuikFontStyle(family, fontSize, style); - QuikVec2 atlasSize = default; + QVec2 atlasSize = default; atlasSize.X = float.Parse(document.DocumentElement.Attributes["width"].Value); atlasSize.Y = float.Parse(document.DocumentElement.Attributes["height"].Value); @@ -63,18 +63,18 @@ namespace QuikTestApplication foreach (XmlElement element in document.SelectNodes("/font/character")) { - QuikRectangle UVs; - QuikVec2 origin; + QRectangle UVs; + QVec2 origin; float advance; int chr = element.Attributes["text"].Value[0]; - QuikVec2 pos; - QuikVec2 size; + QVec2 pos; + QVec2 size; pos.X = float.Parse(element.Attributes["x"].Value); pos.Y = float.Parse(element.Attributes["y"].Value); size.X = float.Parse(element.Attributes["width"].Value); size.Y = float.Parse(element.Attributes["height"].Value); - UVs = new QuikRectangle( + UVs = new QRectangle( (pos.X + size.X)/atlasSize.X, pos.Y/atlasSize.Y, pos.X/atlasSize.X, @@ -85,7 +85,7 @@ namespace QuikTestApplication advance = float.Parse(element.Attributes["advance"].Value); - QuikGlyph glyph = new QuikGlyph(chr, UVs, size, origin, default, new QuikVec2(advance, 0)); + QuikGlyph glyph = new QuikGlyph(chr, UVs, size, origin, default, new QVec2(advance, 0)); _glyphs.Add(chr, glyph); _characters.Add(chr); }