Exemplo n.º 1
0
        public DrawingSurface(DrawingBackend backend, int width, int height)
        {
            if (width < 0 || height < 0)
            {
                throw new Exception("Area of DrawingSurface's is neagative");
            }

            _factory = backend.Factory;
            _device  = backend.Device;

            _backend = backend;
            _width   = width;
            _height  = height;

            var textureDesc = new Texture2DDescription
            {
                MipLevels         = 1,
                ArraySize         = 1,
                BindFlags         = BindFlags.RenderTarget,
                CpuAccessFlags    = CpuAccessFlags.None,
                Format            = Format.B8G8R8A8_UNorm,
                OptionFlags       = ResourceOptionFlags.None,
                Width             = _width,
                Height            = _height,
                Usage             = ResourceUsage.Default,
                SampleDescription = new SampleDescription(1, 0)
            };

            _texture = new Texture2D(_device, textureDesc);
        }
Exemplo n.º 2
0
        public DrawingSurface(DrawingBackend backend, int width, int height)
        {
            if (width < 0 || height < 0)
                throw new Exception("Area of DrawingSurface's is neagative");

            _factory = backend.Factory;
            _device = backend.Device;

            _backend = backend;
            _width = width;
            _height = height;

            var textureDesc = new Texture2DDescription
            {
                MipLevels = 1,
                ArraySize = 1,
                BindFlags = BindFlags.RenderTarget,
                CpuAccessFlags = CpuAccessFlags.None,
                Format = Format.B8G8R8A8_UNorm,
                OptionFlags = ResourceOptionFlags.None,
                Width = _width,
                Height = _height,
                Usage = ResourceUsage.Default,
                SampleDescription = new SampleDescription(1, 0)
            };

            _texture = new Texture2D(_device, textureDesc);
        }
Exemplo n.º 3
0
 public void TestCreateBitmapDrawingTarget()
 {
     using (var backend = new DrawingBackend())
     {
         using (var target = backend.CreateBitmapDrawingSurface(10, 10))
         {
         }
     }
 }
Exemplo n.º 4
0
 public void TestCreateBitmapDrawingTarget()
 {
     using (var backend = new DrawingBackend())
     {
         using (var target = backend.CreateBitmapDrawingSurface(10, 10))
         {
         }
     }
 }
Exemplo n.º 5
0
        public void TestDrawingAndQueryBitmap()
        {
            using (var backend = new DrawingBackend())
            {
                using (var target = backend.CreateBitmapDrawingSurface(10, 10))
                {
                    using (var drawingTarget = target.BeginDraw())
                    {
                        drawingTarget.Line(0, 0, 10, 10);
                    }

                    var rawBitmap = target.ExtractRawBitmap();
                }
            }
        }
Exemplo n.º 6
0
        public void TestDrawingAndQueryBitmap()
        {
            using (var backend = new DrawingBackend())
            {
                using (var target = backend.CreateBitmapDrawingSurface(10, 10))
                {
                    using (var drawingTarget = target.BeginDraw())
                    {
                        drawingTarget.Line(0, 0, 10, 10);
                    }

                    var rawBitmap = target.ExtractRawBitmap();
                }
            }
        }
Exemplo n.º 7
0
        internal unsafe void Launch()
        {
            Console.WriteLine("Tessellation...");
            Console.WriteLine("    Left click to add a point.");
            Console.WriteLine("    'c' to close the current polyline and start a new one.");
            Console.WriteLine("    's' stroke the polyline.");
            Console.WriteLine("    't' to tessellate the polygon.");
            Console.WriteLine("    'r' reset the polygon.");

            using var windowServer     = new WindowServer();
            using var renderingContext = new RenderingContext { Settings = new RenderingSettings { Samples = 8 } };

            using var window               = windowServer.CreateWindow(renderingContext);
            window.Title                   = "Tessellation";
            window.BorderStyle             = WindowBorderStyle.Sizable;
            window.Size                    = (800, 800);
            renderingContext.CurrentWindow = window;

            var viewportSize = window.ViewportSize;
            var windowSize   = window.Size;

            var backend = new DrawingBackend(new EntryPointLoader(renderingContext))
            {
                PixelScaling = viewportSize.height / windowSize.height
            };

            var dataLock = new object();
            var vertices = new List <(double x, double y)>();
            List <List <(double x, double y)> >?polygon = new List <List <(double x, double y)> >();
            var contour = default(List <(double x, double y)>);
            var colors  = new RgbaColor[]
            {
                new RgbaColor(255, 255, 255, 255),
                new RgbaColor(110, 100, 70, 200),
                new RgbaColor(130, 30, 50, 200),
                new RgbaColor(150, 90, 80, 200),
                new RgbaColor(170, 40, 40, 200),
                new RgbaColor(190, 80, 90, 200),
                new RgbaColor(210, 50, 30, 200),
                new RgbaColor(230, 70, 100, 200),
            };

            var buffer            = new PointCoordinates[6];
            var vertexBuffer      = backend.CreateVertexBuffer(VertexType.PointCoordinates, 6);
            var colorBufferHandle = backend.CreateUniformBuffer(UniformType.RgbaColor, colors.Length);

            var transformBufferHandle = backend.CreateUniformBuffer(UniformType.AffineTransform, 1);

            var commandBufferInit = backend.CreateCommandBuffer();

            backend.BeginRecordCommands(commandBufferInit);
            backend.AddClearCommand(commandBufferInit, new RgbaColor(55, 55, 55, 255));
            backend.AddUseShaderCommand(commandBufferInit, ShaderKind.PlainColor);
            backend.AddBindUniformCommand(commandBufferInit, Uniform.Color, colorBufferHandle, 0);
            backend.AddBindUniformCommand(commandBufferInit, Uniform.Transform, transformBufferHandle, 0);
            backend.AddBindVertexBufferCommand(commandBufferInit, vertexBuffer);
            backend.EndRecordCommands(commandBufferInit);

            var bindColorCommandBuffers = new CommandBufferHandle[colors.Length];

            for (int i = 1; i < colors.Length; i++)
            {
                bindColorCommandBuffers[i - 1] = backend.CreateCommandBuffer();
                backend.BeginRecordCommands(bindColorCommandBuffers[i - 1]);
                backend.AddBindUniformCommand(bindColorCommandBuffers[i - 1], Uniform.Color, colorBufferHandle, i);
                backend.EndRecordCommands(bindColorCommandBuffers[i - 1]);
            }

            var commandBufferDrawTriangle = backend.CreateCommandBuffer();

            backend.BeginRecordCommands(commandBufferDrawTriangle);
            backend.AddDrawCommand(commandBufferDrawTriangle, DrawingPrimitive.Triangles, 0, 3);
            backend.EndRecordCommands(commandBufferDrawTriangle);

            var commandBufferDrawTriangles = backend.CreateCommandBuffer();

            backend.BeginRecordCommands(commandBufferDrawTriangles);
            backend.AddDrawCommand(commandBufferDrawTriangles, DrawingPrimitive.Triangles, 0, 6);
            backend.EndRecordCommands(commandBufferDrawTriangles);

            var drawLineStripArgsBufferHandle = backend.CreateVertexRangeBuffer(1);
            var drawLineStripCommandBuffer    = backend.CreateCommandBuffer();

            backend.BeginRecordCommands(drawLineStripCommandBuffer);
            backend.AddDrawIndirectCommand(drawLineStripCommandBuffer, DrawingPrimitive.LineStrip, drawLineStripArgsBufferHandle, 0);
            backend.EndRecordCommands(drawLineStripCommandBuffer);


            var vertexRanges         = new VertexRange[1];
            var commandBufferHandles = new CommandBufferHandle[2];
            var transforms           = new AffineTransform[1];

            transforms[0] = new AffineTransform(m11: 1, m22: 1);

            var drawLock           = new object();
            var interruptRendering = false;
            var requireRendering   = true;

            void draw()
            {
                while (!interruptRendering)
                {
                    if (requireRendering)
                    {
                        requireRendering = false;
                        renderingContext.CurrentWindow = window;
                        backend.PixelScaling           = viewportSize.height / windowSize.height;
                        backend.WindowSize             = windowSize;
                        backend.UpdateUniformBuffer(colorBufferHandle, colors, 0, colors.Length);

                        backend.BeginRenderFrame();
                        backend.UpdateUniformBuffer(transformBufferHandle, transforms, 0, 1);
                        commandBufferHandles[0] = commandBufferInit;
                        backend.SubmitCommands(commandBufferHandles, 0, 1);

                        lock (dataLock)
                        {
                            if (polygon != null)
                            {
                                for (int j = 0; j < polygon.Count; j++)
                                {
                                    var c = polygon[j];
                                    if (c.Count == 1)
                                    {
                                        commandBufferHandles[0] = commandBufferDrawTriangles;

                                        var(x, y) = c[0];
                                        var x0 = x - 2;
                                        var y0 = y - 2;
                                        var x1 = x + 2;
                                        var y1 = y - 2;
                                        var x2 = x + 2;
                                        var y2 = y + 2;
                                        var x3 = x - 2;
                                        var y3 = y + 2;

                                        buffer[0] = new PointCoordinates(x0, y0);
                                        buffer[1] = new PointCoordinates(x1, y1);
                                        buffer[2] = new PointCoordinates(x2, y2);
                                        buffer[3] = new PointCoordinates(x2, y2);
                                        buffer[4] = new PointCoordinates(x3, y3);
                                        buffer[5] = new PointCoordinates(x0, y0);

                                        backend.UpdateVertexBuffer(vertexBuffer, buffer, 0, 6);
                                        backend.SubmitCommands(commandBufferHandles, 0, 1);
                                    }
                                    else
                                    {
                                        commandBufferHandles[0] = drawLineStripCommandBuffer;
                                        vertexRanges[0]         = new VertexRange(0, 6);
                                        backend.UpdateVertexRangeBuffer(drawLineStripArgsBufferHandle, vertexRanges, 0, 1);
                                        var n = 0;
                                        for (int i = 0; i < c.Count; i++)
                                        {
                                            var(x, y) = c[i];
                                            buffer[n] = new PointCoordinates(x, y);

                                            if (++n == 6)
                                            {
                                                backend.UpdateVertexBuffer(vertexBuffer, buffer, 0, 6);
                                                backend.SubmitCommands(commandBufferHandles, 0, 1);
                                                buffer[0] = new PointCoordinates(x, y);
                                                n         = 1;
                                            }
                                        }
                                        if (j < polygon.Count - 1 || contour == null)
                                        {
                                            var(x, y) = c[0];
                                            buffer[n] = new PointCoordinates(x, y);
                                            ++n;
                                        }
                                        if (n > 1)
                                        {
                                            backend.UpdateVertexBuffer(vertexBuffer, buffer, 0, n);
                                            vertexRanges[0] = new VertexRange(0, n);
                                            backend.UpdateVertexRangeBuffer(drawLineStripArgsBufferHandle, vertexRanges, 0, 1);
                                            backend.SubmitCommands(commandBufferHandles, 0, 1);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                commandBufferHandles[1] = commandBufferDrawTriangle;
                                for (int i = 0; i < vertices.Count - 2; i += 3)
                                {
                                    commandBufferHandles[0] = bindColorCommandBuffers[((i / 3) % (colors.Length - 1))];
                                    var(x, y) = vertices[i];
                                    buffer[0] = new PointCoordinates(x, y);
                                    (x, y)    = vertices[i + 1];
                                    buffer[1] = new PointCoordinates(x, y);
                                    (x, y)    = vertices[i + 2];
                                    buffer[2] = new PointCoordinates(x, y);

                                    backend.UpdateVertexBuffer(vertexBuffer, buffer, 0, 3);
                                    backend.SubmitCommands(commandBufferHandles, 0, 2);
                                }
                            }
                        }

                        backend.EndRenderFrame();
                        renderingContext.SwapBuffers(window);
                        renderingContext.CurrentWindow = null;
                    }

                    lock (drawLock)
                    {
                        Monitor.Wait(drawLock, 50);
                    }
                }
            }

            window.TextInput += (sender, e) =>
            {
                switch (e.CodePoint)
                {
                case 'c':
                    lock (dataLock)
                    {
                        if (contour != null && contour.Count > 2)
                        {
                            contour.Add(contour[0]);
                        }
                        contour = null;
                    }
                    requireRendering = true;
                    break;

                case 'r':
                    lock (dataLock)
                    {
                        polygon = new List <List <(double x, double y)> >();
                        contour = null;
                        vertices.Clear();
                    }
                    requireRendering = true;
                    break;

                case 's':
                {
                    var p = new List <List <(double x, double y)> >();
                    var polylineStroker = new PolylineStroker(new StrokeHandler(p))
                    {
                        StrokeWidth    = 20,
                        StrokeLinecap  = StrokeLinecap.Round,
                        StrokeLineJoin = StrokeLineJoin.Round
                    };
                    foreach (var c in polygon)
                    {
                        polylineStroker.Stroke(c);
                    }
                    contour = null;
                    polygon = p;
                }
                    requireRendering = true;
                    break;

                case 't':
                    if (vertices.Count == 0)
                    {
                        lock (dataLock)
                        {
                            var tessellator = new Tessellator2D <int, int>(new TessellateHandler(vertices))
                            {
                                OutputKind  = OutputKind.TrianglesOnly,
                                WindingRule = WindingRule.NonZero
                            };

                            tessellator.BeginPolygon(0);
                            foreach (var c in polygon)
                            {
                                tessellator.BeginContour();
                                foreach (var(x, y) in c)
                                {
                                    tessellator.AddVertex(x, y, 0);
                                }
                                tessellator.EndContour();
                            }
                            tessellator.EndPolygon();
                            vertices.Clear();

                            tessellator.OutputKind = OutputKind.TriangleEnumerator;

                            tessellator.BeginPolygon(0);
                            foreach (var c in polygon)
                            {
                                tessellator.BeginContour();
                                foreach (var(x, y) in c)
                                {
                                    tessellator.AddVertex(x, y, 0);
                                }
                                tessellator.EndContour();
                            }
                            var sw = new System.Diagnostics.Stopwatch();
                            var f  = System.Diagnostics.Stopwatch.Frequency;
                            sw.Start();
                            tessellator.EndPolygon();

                            while (tessellator.Move())
                            {
                                var(x, y, _) = tessellator.Vertex;
                                vertices.Add((x, y));
                            }

                            sw.Stop();
                            Console.WriteLine("Tessellated " + (vertices.Count / 3) + " triangles in " +
                                              (sw.ElapsedTicks * 1e3 / f).ToString("0.000") + "ms");
                            polygon = null;
                        }
                    }
                    requireRendering = true;
                    break;
                }
            };

            window.MouseDown += (sender, e) =>
            {
                lock (dataLock)
                {
                    if (e.ChangedButton == MouseButton.Left && polygon != null)
                    {
                        if (contour == null)
                        {
                            contour = new List <(double x, double y)>();
                            polygon.Add(contour);
                        }
                        else if (window.CursorPosition.x == contour[contour.Count - 1].x &&
                                 window.CursorPosition.y == contour[contour.Count - 1].y)
                        {
                            return;
                        }
                        contour.Add(window.CursorPosition);
                        requireRendering = true;
                    }
                }
            };

            void resize()
            {
                viewportSize     = window.ViewportSize;
                windowSize       = window.Size;
                requireRendering = true;
                lock (drawLock)
                {
                    Monitor.Pulse(drawLock);
                }
            }

            var runLoop = MainRunLoop.Create(windowServer);

            var drawThread = new Thread(draw);

            window.Closed += (sender, e) =>
            {
                interruptRendering = true;
                drawThread.Join();
                runLoop.Interrupt();
                backend.Dispose();
            };
            window.Resize            += (sender, e) => resize();
            window.FramebufferResize += (sender, e) => resize();

            renderingContext.CurrentWindow = null;
            drawThread.Start();
            window.Visible = true;
            runLoop.Run();

            Console.WriteLine("Tessellation done.");
        }
Exemplo n.º 8
0
        internal void Launch()
        {
            Console.WriteLine("Bezier...");
            Console.WriteLine("    'i': Image.");
            Console.WriteLine("    's': SVG tiger.");
            Console.WriteLine("    't': Text.");

            using var windowServer     = new WindowServer();
            using var renderingContext = new RenderingContext { Settings = new RenderingSettings { Samples = 8 } };
            using var window           = windowServer.CreateWindow(renderingContext);

            window.Title                   = "Bézier";
            window.BorderStyle             = WindowBorderStyle.Sizable;
            window.Size                    = (900, 900);
            renderingContext.CurrentWindow = window;

            var viewportSize       = window.ViewportSize;
            var windowSize         = window.Size;
            var backend            = new DrawingBackend(new EntryPointLoader(renderingContext));
            var openTypeCollection = new OpenTypeCollection();
            var nameId             = typeof(VectorGraphicsLauncher).Namespace + ".Resources.ebrima.ttf";

            openTypeCollection.AddFontResource(nameId, () => Assembly.GetExecutingAssembly().GetManifestResourceStream(nameId) !);
            using var sharedContext  = new SharedDrawingContext(backend, openTypeCollection);
            using var drawingContext = new DrawingContext(sharedContext)
                  {
                      ClearColor = new RgbaColor(155, 155, 155, 255)
                  };
            var redrawRequired = true;

            var images = new List <ImageDrawing>();
            var paths  = new List <PathDrawing>();
            var labels = new List <LabelDrawing>();

            window.TextInput += (sender, e) =>
            {
                switch (e.CodePoint)
                {
                case 'i':
                {
                    var image      = new RasterImage();
                    var namePrefix = typeof(DrawTextureLauncher).Namespace + ".Resources.";
                    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "kitten.png"))
                    {
                        image.LoadPng(stream ?? throw new InvalidOperationException());
                    }
                    var imageDrawing = new ImageDrawing()
                    {
                        Image = image
                    };
                    images.Add(imageDrawing);
                    redrawRequired = true;
                }
                break;

                case 's':
                {
                    images.Clear();
                    paths.Clear();
                    labels.Clear();

                    var sw = new System.Diagnostics.Stopwatch();
                    sw.Start();

                    var pathReader = new SvgPathReader();
                    var transform  = new AffineTransform(m11: 1.76, m22: 1.76, m31: 325, m32: 255);

                    var       namePrefix = typeof(VectorGraphicsLauncher).Namespace + ".Resources.";
                    XDocument document;
                    using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "Ghostscript_Tiger.svg"))
                    {
                        document = XDocument.Load(stream);
                    }
                    XNamespace ns    = "http://www.w3.org/2000/svg";
                    var        rootG = document.Element(ns + "svg").Element(ns + "g");
                    foreach (var g in rootG.Elements(ns + "g"))
                    {
                        var path = new PathDrawing
                        {
                            Transform = transform
                        };
                        paths.Add(path);
                        foreach (var a in g.Attributes())
                        {
                            switch (a.Name.LocalName)
                            {
                            case "fill":
                                path.FillColor = ParseSvgColor(a.Value);
                                break;

                            case "stroke":
                                path.StrokeColor = ParseSvgColor(a.Value);
                                break;

                            case "stroke-width":
                                path.StrokeWidth = float.Parse(a.Value);
                                break;
                            }
                        }
                        pathReader.PathData = g.Element(ns + "path").Attribute("d").Value;
                        var x        = 0f;
                        var y        = 0f;
                        var initialX = 0f;
                        var initialY = 0f;
                        (double x, double y)c2 = (0, 0);
                        bool hasPreviousC2 = false;
                        while (pathReader.Read())
                        {
                            switch (pathReader.PathCommand)
                            {
                            case PathCommandType.MoveTo:
                                x = pathReader.X;
                                y = pathReader.Y;
                                path.Move((x, y));
                                initialX      = x;
                                initialY      = y;
                                hasPreviousC2 = false;
                                break;

                            case PathCommandType.MoveToRelative:
                                x += pathReader.X;
                                y += pathReader.Y;
                                path.Move((x, y));
                                initialX      = x;
                                initialY      = y;
                                hasPreviousC2 = false;
                                break;

                            case PathCommandType.LineToRelative:
                                x += pathReader.X;
                                y += pathReader.Y;
                                path.AddLine((x, y));
                                hasPreviousC2 = false;
                                break;

                            case PathCommandType.CurveToRelative:
                            {
                                var c1 = ((double)x + pathReader.X1, (double)y + pathReader.Y1);
                                c2 = (x + pathReader.X2, y + pathReader.Y2);
                                x += pathReader.X;
                                y += pathReader.Y;
                                path.AddCubicBezier(c1, c2, (x, y));
                                hasPreviousC2 = true;
                            }
                            break;

                            case PathCommandType.SmoothCurveToRelative:
                            {
                                (double x, double y)c1;
                                if (hasPreviousC2)
                                {
                                    c1 = (2 * x - c2.x, 2 * y - c2.y);
                                }
                                else
                                {
                                    c1 = (x, y);
                                }
                                c2 = (x + pathReader.X2, y + pathReader.Y2);
                                x += pathReader.X;
                                y += pathReader.Y;
                                path.AddCubicBezier(c1, c2, (x, y));
                                hasPreviousC2 = true;
                            }
                            break;

                            case PathCommandType.VerticalLineToRelative:
                                y += pathReader.Y;
                                path.AddLine((x, y));
                                hasPreviousC2 = false;
                                break;

                            case PathCommandType.Closepath:
                                path.AddLine((initialX, initialY));
                                hasPreviousC2 = false;
                                break;

                            default:
                                Console.WriteLine("Unhandled command: " + pathReader.PathCommand);
                                break;
                            }
                        }
                    }
                    sw.Stop();
                    Console.WriteLine($"SVG file decoded in {sw.ElapsedMilliseconds}ms ({paths.Count} paths).");
                    redrawRequired = true;
                }
                break;

                case 't':
                {
                    images.Clear();
                    paths.Clear();
                    labels.Clear();

                    var label = new LabelDrawing
                    {
                        Transform     = new AffineTransform(m11: 4, m22: 4, m31: 20, m32: 50),
                        FontFamily    = "Ebrima",
                        FontSubfamily = FontSubfamily.Normal,
                        FontPoints    = 8
                    };
                    label.AppendString("The quick brown fox jumps over the lazy dog.");
                    labels.Add(label);

                    for (int i = 0; i < 15; i++)
                    {
                        label = new LabelDrawing
                        {
                            Transform     = new AffineTransform(m11: 1, m22: 1, m31: 20, m32: 100 + i * 30),
                            FontFamily    = "Ebrima",
                            FontSubfamily = FontSubfamily.Normal,
                            FontPoints    = 32 - i * 2
                        };
                        label.AppendString("The quick brown fox jumps over the lazy dog.");
                        labels.Add(label);
                    }
                    redrawRequired = true;
                }
                break;
                }
            };

            void draw()
            {
                var sw = new System.Diagnostics.Stopwatch();

                sw.Start();

                renderingContext.CurrentWindow            = window;
                drawingContext.SharedContext.PixelScaling = viewportSize.height / windowSize.height;

                drawingContext.StartDrawing();

                foreach (var image in images)
                {
                    image.Draw(drawingContext);
                }
                foreach (var path in paths)
                {
                    path.Draw(drawingContext);
                }
                foreach (var label in labels)
                {
                    label.Draw(drawingContext, 0, 0);
                }

                drawingContext.FinishDrawing();
                renderingContext.SwapBuffers(window);

                sw.Stop();
                Console.WriteLine($"Drawn in {sw.ElapsedMilliseconds}ms.");
            }

            void resize()
            {
                viewportSize       = window.ViewportSize;
                windowSize         = window.Size;
                backend.WindowSize = windowSize;
            }

            window.Resize += (sender, e) =>
            {
                resize();
                draw();
            };

            var runLoop = MainRunLoop.Create(windowServer);

            window.Closed += (sender, e) =>
            {
                drawingContext.Dispose();
                backend.Dispose();
                runLoop.Interrupt();
            };

            resize();
            runLoop.RecurringActions.Add((delay) =>
            {
                if (redrawRequired)
                {
                    draw();
                    redrawRequired = false;
                }
            });

            window.Visible = true;
            runLoop.Run();
            Console.WriteLine("Bezier done.");
        }
Exemplo n.º 9
0
        internal void Launch()
        {
            Console.WriteLine("Text Area...");

            using var windowServer = new WindowServer();
            using var renderingContext = new RenderingContext { Settings = new RenderingSettings { Samples = 8 } };
            using var window = windowServer.CreateWindow(renderingContext);

            window.Title = "Text Area";
            window.BorderStyle = WindowBorderStyle.Sizable;
            window.Size = (900, 900);
            renderingContext.CurrentWindow = window;

            var viewportSize = window.ViewportSize;
            var windowSize = window.Size;
            var backend = new DrawingBackend(new EntryPointLoader(renderingContext))
            {
                PixelScaling = viewportSize.height / windowSize.height
            };

            var openTypeCollection = new OpenTypeCollection();
            var nameId = typeof(VectorGraphicsLauncher).Namespace + ".Resources.Hack-Regular.ttf";
            openTypeCollection.AddFontResource(nameId, () => Assembly.GetExecutingAssembly().GetManifestResourceStream(nameId)!);

            using var sharedContext = new SharedDrawingContext(backend, openTypeCollection);
            using var drawingContext = new DrawingContext(sharedContext)
            {
                ClearColor = new RgbaColor(35, 35, 35, 255)
            };

            var styles = new MonospaceTextStyles(256);
            var fontSubfamily = openTypeCollection.LookupFontSubfamily("Hack", FontSubfamily.Normal);
            styles.GetStyle(fontSubfamily, new RgbaColor(255, 255, 255, 255), new RgbaColor(0, 0, 0, 0));
            var textArea = new TextArea(styles, "Hack", fontSubfamily, 9);
            var path = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly()!.Location)!, "..", "..", "..", "TextAreaLauncher.cs");
            textArea.Load(path);
            const int textLeft = 20;
            const int textTop = 30;

            window.Scroll += (sender, e) =>
            {
                textArea.ScrollVertically(e.DeltaY * 30);
            };

            var hideCaret = true;

            window.KeyDown += (sender, e) =>
            {
                switch (e.Keycode)
                {
                    case Keycode.Up:
                        textArea.MoveUp();
                        hideCaret = false;
                        break;
                    case Keycode.Down:
                        textArea.MoveDown();
                        hideCaret = false;
                        break;
                    case Keycode.Left:
                        textArea.MoveLeft();
                        hideCaret = false;
                        break;
                    case Keycode.Right:
                        textArea.MoveRight();
                        hideCaret = false;
                        break;
                    case Keycode.F11:
                        textArea.FontPoints--;
                        break;
                    case Keycode.F12:
                        textArea.FontPoints++;
                        break;
                    case Keycode.Backspace:
                        textArea.Backspace();
                        hideCaret = false;
                        break;
                    case Keycode.Tab:
                        textArea.Tab();
                        hideCaret = false;
                        break;
                    case Keycode.Enter:
                        textArea.Enter();
                        hideCaret = false;
                        break;
                }
            };

            window.TextInput += (sender, e) =>
            {
                textArea.Insert(e.CodePoint);
                hideCaret = false;
            };

            window.MouseDown += (sender, e) =>
            {
                if (e.ChangedButton == MouseButton.Left)
                {
                    var (x, y) = window.CursorPosition;
                    textArea.LeftMouseDown(x, y);
                    hideCaret = false;
                }
            };

            var interruptThread = false;

            void draw()
            {
                renderingContext.CurrentWindow = window;
                drawingContext.SharedContext.PixelScaling = viewportSize.height / windowSize.height;

                drawingContext.StartDrawing();

                textArea.Render(drawingContext);

                drawingContext.FinishDrawing();

                renderingContext.SwapBuffers(window);
            }

            void resize()
            {
                viewportSize = window.ViewportSize;
                windowSize = window.Size;
                renderingContext.CurrentWindow = window;
                backend.WindowSize = windowSize;
                textArea.SetViewRectangle(textLeft, textTop, (windowSize.width - textLeft - 30), (windowSize.height - textTop - 50));
            }

            window.Resize += (sender, e) =>
            {
                resize();
                draw();
            };

            var runLoop = MainRunLoop.Create(windowServer);
            var text = default(DecoratedText<byte>);
            var version = 0;
            var th = new Thread(() =>
            {
                var regexList = new List<Regex>();
                var styleList = new List<MonospaceTextStyle>();

                regexList.Add(new Regex("\\b(break|case|class|const|else|false|float|for|foreach|" +
                    "if|int|internal|public|namespace|new|unsafe|using|string|switch|true|var|void)\\b"));
                styleList.Add(styles.GetStyle(fontSubfamily, new RgbaColor(81, 153, 213, 255), new RgbaColor(0, 0, 0, 0)));

                regexList.Add(new Regex(@"\b-?\d+(,\d+)*(\.\d+((e|E)\d+)?)?\b"));
                styleList.Add(styles.GetStyle(fontSubfamily, new RgbaColor(0, 0, 0, 255), new RgbaColor(230, 180, 50, 255)));

                regexList.Add(new Regex(@"""(\\.|[^""\\])*"""));
                styleList.Add(styles.GetStyle(fontSubfamily, new RgbaColor(250, 180, 230, 255), new RgbaColor(0, 0, 0, 0)));

                while (!interruptThread)
                {
                    var t = text;
                    text = null;
                    var v = version;
                    if (t != null)
                    {
                        var txt = new StyledMonospaceText(t, styles);
                        var builder = new StringBuilder();
                        for (int i = 0; i < txt.LineCount; i++)
                        {
                            builder.Clear();
                            txt.CopyLineTo(i, builder);
                            var str = builder.ToString();
                            for (int j = 0; j < regexList.Count; j++)
                            {
                                var m = regexList[j].Match(str);
                                var s = styleList[j];
                                while (m.Success)
                                {
                                    txt.StyleRange(s, (i, m.Index), (i, m.Index + m.Length));
                                    m = m.NextMatch();
                                }
                            }
                        }
                        void f(int currentVersion, StyledMonospaceText newText)
                        {
                            runLoop.InvokeLater(0, (lag) =>
                            {
                                if (textArea.Version == currentVersion)
                                {
                                    textArea.SetText(newText);
                                }
                            });
                        }
                        f(v, txt);
                    }
                    Thread.Sleep(500);
                }
            });

            void blink(long lag)
            {
                textArea.HideCaret = hideCaret;
                hideCaret = !hideCaret;
                if (textArea.RequireRestyle)
                {
                    text = textArea.GetText();
                    version = textArea.Version;
                }
                runLoop.InvokeLater(500, blink);
            }

            runLoop.InvokeLater(500, blink);

            window.Closed += (sender, e) =>
            {
                backend.Dispose();
                runLoop.Interrupt();
                interruptThread = true;
            };

            resize();
            runLoop.RecurringActions.Add((time) =>
            {
                if (textArea.RequireRender)
                {
                    draw();
                }
            });
            th.Start();
            window.Visible = true;
            runLoop.Run();

            Console.WriteLine("Text Area done.");
        }
Exemplo n.º 10
0
 public void TestDeviceCreation()
 {
     using (var backend = new DrawingBackend())
     {
     }
 }
Exemplo n.º 11
0
        internal unsafe void Launch()
        {
            Console.WriteLine("Glyph...");
            Console.WriteLine("    type any key to display the corresponding glyph.");
            Console.WriteLine("The top glyph is rasterized before being rendered as an image.");
            Console.WriteLine("The bottom glyph is tessellated and rendered as a set of triangles.");

            using var windowServer     = new WindowServer();
            using var renderingContext = new RenderingContext { Settings = new RenderingSettings { Samples = 8 } };
            using var window           = windowServer.CreateWindow(renderingContext);

            window.BorderStyle             = WindowBorderStyle.Sizable;
            window.Size                    = (500, 700);
            renderingContext.CurrentWindow = window;

            var viewportSize = window.ViewportSize;
            var windowSize   = window.Size;
            var vertices     = new List <(double x, double y)>();

            using var backend = new DrawingBackend(new EntryPointLoader(renderingContext))
                  {
                      PixelScaling = viewportSize.height / windowSize.height
                  };

            var colors = new RgbaColor[]
            {
                new RgbaColor(255, 255, 255, 255),
                new RgbaColor(110, 100, 70, 200),
                new RgbaColor(130, 30, 50, 200),
                new RgbaColor(150, 90, 80, 200),
                new RgbaColor(170, 40, 40, 200),
                new RgbaColor(190, 80, 90, 200),
                new RgbaColor(210, 50, 30, 200),
                new RgbaColor(230, 70, 100, 200),
            };

            var bufferTexture       = new PointAndImageCoordinates[6];
            var vertexBufferTexture = backend.CreateVertexBuffer(VertexType.PointAndImageCoordinates, 6);
            var buffer            = new PointCoordinates[3];
            var vertexBuffer      = backend.CreateVertexBuffer(VertexType.PointCoordinates, 3);
            var colorBufferHandle = backend.CreateUniformBuffer(UniformType.RgbaColor, colors.Length);

            backend.UpdateUniformBuffer(colorBufferHandle, colors, 0, colors.Length);

            const int GlyphSize = 300;

            var transformBufferHandle = backend.CreateUniformBuffer(UniformType.AffineTransform, 1);
            var imageHandle           = backend.CreateImage(GlyphSize, GlyphSize, ImageFormat.GreyscaleAlpha, ImageComponentType.UnsignedByte);

            var commandBufferInit = backend.CreateCommandBuffer();

            backend.BeginRecordCommands(commandBufferInit);
            backend.AddClearCommand(commandBufferInit, new RgbaColor(55, 55, 55, 255));
            backend.EndRecordCommands(commandBufferInit);

            var displayImageCommandBuffer = backend.CreateCommandBuffer();

            backend.BeginRecordCommands(displayImageCommandBuffer);
            backend.AddBindImageCommand(displayImageCommandBuffer, imageHandle);
            backend.AddUseShaderCommand(displayImageCommandBuffer, ShaderKind.GreyscaleImage);
            backend.AddBindUniformCommand(displayImageCommandBuffer, Uniform.Transform, transformBufferHandle, 0);
            backend.AddBindUniformCommand(displayImageCommandBuffer, Uniform.Color, colorBufferHandle, 0);
            backend.AddBindVertexBufferCommand(displayImageCommandBuffer, vertexBufferTexture);
            backend.AddDrawCommand(displayImageCommandBuffer, DrawingPrimitive.Triangles, 0, 6);
            backend.EndRecordCommands(displayImageCommandBuffer);

            var commandBufferInitDrawTriangle = backend.CreateCommandBuffer();

            backend.BeginRecordCommands(commandBufferInitDrawTriangle);
            backend.AddUseShaderCommand(commandBufferInitDrawTriangle, ShaderKind.PlainColor);
            backend.AddBindUniformCommand(commandBufferInitDrawTriangle, Uniform.Transform, transformBufferHandle, 0);
            backend.EndRecordCommands(commandBufferInitDrawTriangle);

            var bindColorCommandBuffers = new CommandBufferHandle[colors.Length];

            for (int i = 1; i < colors.Length; i++)
            {
                bindColorCommandBuffers[i - 1] = backend.CreateCommandBuffer();
                backend.BeginRecordCommands(bindColorCommandBuffers[i - 1]);
                backend.AddBindUniformCommand(bindColorCommandBuffers[i - 1], Uniform.Color, colorBufferHandle, i);
                backend.EndRecordCommands(bindColorCommandBuffers[i - 1]);
            }

            var commandBufferDrawTriangle = backend.CreateCommandBuffer();

            backend.BeginRecordCommands(commandBufferDrawTriangle);
            backend.AddBindVertexBufferCommand(commandBufferDrawTriangle, vertexBuffer);
            backend.AddDrawCommand(commandBufferDrawTriangle, DrawingPrimitive.Triangles, 0, 3);
            backend.EndRecordCommands(commandBufferDrawTriangle);

            var commandBufferHandles = new CommandBufferHandle[2];
            var transforms           = new AffineTransform[1];

            transforms[0] = new AffineTransform(m11: 1, m22: 1);

            var  bitmap         = new byte[GlyphSize * (GlyphSize + 5)];
            bool glyphAvailable = false;

            void draw()
            {
                renderingContext.CurrentWindow = window;

                backend.BeginRenderFrame();
                backend.UpdateUniformBuffer(transformBufferHandle, transforms, 0, 1);
                commandBufferHandles[0] = commandBufferInit;
                backend.SubmitCommands(commandBufferHandles, 0, 1);

                if (glyphAvailable)
                {
                    commandBufferHandles[0] = displayImageCommandBuffer;
                    backend.UpdateImage(imageHandle, bitmap, 0, 0, GlyphSize, GlyphSize);
                    bufferTexture[0] = new PointAndImageCoordinates(0, 0, 0, 0);
                    bufferTexture[1] = new PointAndImageCoordinates(0, 300, 0, 1);
                    bufferTexture[2] = new PointAndImageCoordinates(300, 300, 1, 1);
                    bufferTexture[3] = new PointAndImageCoordinates(0, 0, 0, 0);
                    bufferTexture[4] = new PointAndImageCoordinates(300, 300, 1, 1);
                    bufferTexture[5] = new PointAndImageCoordinates(300, 0, 1, 0);
                    backend.UpdateVertexBuffer(vertexBufferTexture, bufferTexture, 0, 6);
                    backend.SubmitCommands(commandBufferHandles, 0, 1);

                    commandBufferHandles[0] = commandBufferInitDrawTriangle;
                    backend.SubmitCommands(commandBufferHandles, 0, 1);

                    commandBufferHandles[1] = commandBufferDrawTriangle;
                    for (int i = 0; i < vertices.Count - 2; i += 3)
                    {
                        commandBufferHandles[0] = bindColorCommandBuffers[((i / 3) % (colors.Length - 1))];
                        var(x, y) = vertices[i];
                        buffer[0] = new PointCoordinates(x, y);
                        (x, y)    = vertices[i + 1];
                        buffer[1] = new PointCoordinates(x, y);
                        (x, y)    = vertices[i + 2];
                        buffer[2] = new PointCoordinates(x, y);

                        backend.UpdateVertexBuffer(vertexBuffer, buffer, 0, 3);
                        backend.SubmitCommands(commandBufferHandles, 0, 2);
                    }
                }

                backend.EndRenderFrame();

                renderingContext.SwapBuffers(window);
            }

            OpenType openType;
            var      namePrefix = typeof(GlyphLauncher).Namespace + ".Resources.";

            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(namePrefix + "ebrima.ttf"))
            {
                openType = OpenType.Load(stream ?? throw new InvalidOperationException())[0];
Exemplo n.º 12
0
 public void TestDeviceCreation()
 {
     using (var backend = new DrawingBackend())
     {
     }
 }