Пример #1
0
        static void Main(string[] args)
        {
            // Create the window and the graphics device
            VeldridInit(out var window, out var graphicsDevice);

            // Create a texture storage that manages textures.
            // Textures in OpenWheels are represented with integer values.
            // A platform-specific ITextureStorageImplementation handles texture creation,
            // destruction and modification.
            var texStorage = new VeldridTextureStorage(graphicsDevice);

            // Create a renderer that implements the OpenWheels.Rendering.IRenderer interface
            // this guy actually draws everything to the backbuffer
            var renderer = new VeldridRenderer(graphicsDevice, texStorage);

            // OpenWheels always requires a texture to render, so renderer implementations only need a single shader
            // Even for untextured primitives we need to have a texture set. So we create a white 1x1 texture for those.
            ReadOnlySpan <Color> blankSpan = stackalloc Color[] { Color.White };
            var blank = texStorage.CreateTexture(1, 1, TextureFormat.Rgba32);

            texStorage.SetData(blank, blankSpan);

            // Our batcher lets use make calls to render lots of different primitive shapes and text.
            // When we're done the batcher can export draw calls so the renderer can use them do the drawing.
            // We won't use text rendering in this sample so we use the dummy text renderer.
            var batcher = new Batcher(NullBitmapFontRenderer.Instance);

            var first = true;

            // We run the game loop here and do our drawing inside of it.
            VeldridRunLoop(window, graphicsDevice, () =>
            {
                renderer.Clear(Color.CornflowerBlue);

                // Start a new batch
                batcher.Start();

                // set the texture to the blank one we registered
                batcher.SetTexture(blank);

                // Let's draw some primitives. The API is very obvious, you can use IntelliSense to find supported shapes.
                batcher.FillRect(new RectangleF(10, 10, 100, 100), Color.LimeGreen);

                // Note that subsequent line segments are connected at their corners
                Span <Vector2> points = stackalloc Vector2[] { new Vector2(140, 20), new Vector2(320, 20), new Vector2(320, 120), new Vector2(420, 120) };
                batcher.DrawLineStrip(points, Color.Red, 20);

                batcher.FillTriangle(new Vector2(500, 20), new Vector2(600, 70), new Vector2(500, 120), Color.White);

                // The tessellation of the circle and corners for the rounded rectangle can be adjusted with the maxError parameter
                batcher.DrawCircle(new Vector2(700, 70), 50, Color.BlueViolet, 2);

                batcher.FillRoundedRect(new RectangleF(790, 10, 100, 100), 10, Color.SandyBrown);

                var pa    = new Vector2(50, 220);
                var pb    = new Vector2(150, 120);
                var pc    = new Vector2(250, 220);
                var curve = new QuadraticBezier(pa, pb, pc);
                // The segmentation for curves can be adjusted with the segmentsPerLength parameter
                // Using that parameter and an (over)estimate of the length of the curve the number of segments
                // is computed
                batcher.DrawCurve(curve, Color.DarkGoldenrod, 2);

                var o      = new Vector2(0, 100);
                var pd     = new Vector2(200, 420);
                var curve2 = new CubicBezier(pa + o, pb + o, pd, pc + o);
                batcher.DrawCurve(curve2, Color.DarkOrchid, 2);

                // Finish the batch and let the renderer draw everything to the back buffer.
                batcher.Render(renderer);

                if (first)
                {
                    Console.WriteLine("Vertices: " + batcher.VerticesSubmitted);
                    Console.WriteLine("Indices: " + batcher.IndicesSubmitted);
                    Console.WriteLine("Batches: " + batcher.BatchCount);
                    first = false;
                }
            });
Пример #2
0
        static void Main(string[] args)
        {
            // Create the window and the graphics device
            VeldridInit(out var window, out var graphicsDevice);

            // Create a renderer that implements the OpenWheels.Rendering.IRenderer interface
            // this guy actually draws everything to the backbuffer
            var renderer = new VeldridRenderer(graphicsDevice);

            // Our batcher lets use make calls to render lots of different primitive shapes and text.
            // When we're done the batcher sends the draw calls to the renderer which will actually do the drawing.

            // Alternatively to Batcher you can use StringIdBatcher so you can register and set the active texture
            // and font with a string identifier.
            var batcher = new Batcher(renderer);

            var checkerBoardTextureId = batcher.LoadTexture("checkerboard.png");

            // OpenWheels defines a sprite as an image that's part of a texture
            // To create a sprite, we pass a texture and a region of that texture (in pixels) that contains the actual image
            // let's add a sprite that draws 3/4th of the checkerboard
            // So if our original texture looks like this:
            //         |##  |
            //         |##  |
            //         |  ##|
            //         |  ##|
            // We'll create a sprite that looks like this:
            //         |## |
            //         |## |
            //         |  #|

            var cbSize                = renderer.GetTextureSize(checkerBoardTextureId);
            var subSpriteRect         = new Rectangle(0, 0, (cbSize.Width * 3) / 4, (cbSize.Height * 3) / 4);
            var checkerBoardSubSprite = new Sprite(checkerBoardTextureId, subSpriteRect);

            var frame = 0;

            // We run the game loop here and do our drawing inside of it.
            VeldridRunLoop(window, graphicsDevice, () =>
            {
                renderer.Clear(Color.CornflowerBlue);

                // Start a new batch
                batcher.Start();

                // we set the texture using the texture id we got back when registering the texture
                // OpenWheels internally only works with sprites
                // If you set a texture on a batcher it will convert it to a sprite with the region being the
                // entire texture bounds
                batcher.SetTexture(checkerBoardTextureId);

                // The Batcher API is stateful. Anything we render now will use the checkerboard texture.
                // By default the UV coordinates 0, 0, 1, 1 are use, so our texture is stretched
                batcher.FillRect(new RectangleF(50, 20, 100, 100), Color.White);
                batcher.FillRect(new RectangleF(200, 20, 100, 200), Color.White);

                // Let's draw our subsprite
                batcher.Sprite = checkerBoardSubSprite;
                batcher.FillRect(new RectangleF(350, 20, 100, 100), Color.White);

                // We can only draw 1 texture in a single draw call, but since our subsprite actually uses the same
                // texture as our full checkerboard the batcher can still combine the calls into a single batch.

                batcher.SetTexture(checkerBoardTextureId);
                // Most of the primitives support UV coordinates one way or another.
                batcher.FillCircle(new Vector2(550, 70), 50, Color.White, .25f);
                batcher.FillRoundedRect(new RectangleF(650, 20, 100, 100), 15, Color.White);

                var v1 = new Vector2(50, 280);
                var v2 = new Vector2(150, 380);
                batcher.DrawLine(v1, v2, Color.White, 6f);
                // Note that the texture rotates with the line
                // This is different from the circle(segment) primitives where we draw a cutout of the active texture
                // There are a lot of ways to UV-map shapes, but OpenWheels currently picks just one for each shape

                // we can set a matrix to transform UV coordinates
                // let's make our texture loop in length while keeping it's aspect ratio and UV across its width.

                // The sampler should wrap to be able to loop the texture (the default sampler state is LinearClamp)
                // This state sticks across frames, so we could set it before the render loop as well
                batcher.SamplerState = SamplerState.LinearWrap;
                var v3 = new Vector2(200, 280);
                var v4 = new Vector2(300, 380);
                const float lineWidth = 10f;

                // we want our UV aspect ratio to be 1:1, but it's lineWidth:length and we want to use
                // the coordinate system of the width, so we normalize height to get the right aspect ratio
                // (note that height is defined as the forward direction of the line)

                var uvHeight        = Vector2.Distance(v3, v4) / lineWidth;
                batcher.UvTransform = Matrix3x2.CreateScale(1f, uvHeight);
                batcher.DrawLine(v3, v4, Color.White, lineWidth);

                // Reset the uv transform
                batcher.UvTransform = Matrix3x2.Identity;

                // The color value we can pass to these methods is multiplied with our texture color at each pixel.
                batcher.FillRect(new RectangleF(350, 280, 100, 100), Color.Red);

                // Finish the batch and let the renderer draw everything to the back buffer.
                batcher.Finish();

                if (frame < 2)
                {
                    // Note that the first frame renders in two batches because we change the sampler state
                    // halfway through.
                    // Every subsequent frame render in a single batch because the sampler state stays at LinearClamp
                    Console.WriteLine("Frame " + frame);
                    Console.WriteLine("Vertices: " + batcher.VerticesSubmitted);
                    Console.WriteLine("Indices: " + batcher.IndicesSubmitted);
                    Console.WriteLine("Batches: " + batcher.BatchCount);
                    Console.WriteLine();
                    frame++;
                }
            });

            renderer.Dispose();
            graphicsDevice.Dispose();
        }
Пример #3
0
        static void Main(string[] args)
        {
            // Create the window and the graphics device
            VeldridInit(out var window, out var graphicsDevice);

            // Create a texture storage that manages textures.
            // Textures in OpenWheels are represented with integer values.
            // A platform-specific ITextureStorageImplementation handles texture creation,
            // destruction and modification.
            var texStorage = new VeldridTextureStorage(graphicsDevice);

            // Create a renderer that implements the OpenWheels.Rendering.IRenderer interface.
            // This guy actually draws everything to the backbuffer.
            var renderer = new VeldridRenderer(graphicsDevice, texStorage);

            // To render text Batcher needs an IBitmapFontRenderer implementation.
            // Our batcher lets use make calls to render lots of different primitive shapes and text.
            // When we're done the batcher sends the draw calls to the renderer which will actually do the drawing.
            // textures using a string identifier. Internally in OpenWheels textures are identified by an integer.
            var batcher = new Batcher();

            // OpenWheels.Rendering.ImageSharp contains several extension methods to easily load
            // images and fonts into an ITextureStorage implementation.
            // Using this library is the easiest way to handle font and texture loading, but it's a separate lib so you can
            // use another solution if you prefer.

            // The following call creates a font atlas and the corresponding image for the glyphs.
            // By default it includes only the basic Latin characters in the atlas.
            // The created image is registered with the renderer and the font can be
            // set using the Batcher by calling `SetFont(fontId)`.

            // m6x11 font by Daniel Linssen: https://managore.itch.io
            // Note that this is a pixel perfect font and so it will look good even though OpenWheels has pretty bad text rendering.
            var font = texStorage.LoadFont("Resources/m6x11.ttf", 32, (int)'?');

            // Google's Roboto font
            //var font = texStorage.LoadFont("Resources/Roboto-Medium.ttf", 32, (int) '?');

            var first = true;

            // We run the game loop here and do our drawing inside of it.
            VeldridRunLoop(window, graphicsDevice, () =>
            {
                renderer.Clear(Color.CornflowerBlue);

                // Start a new batch
                batcher.Start();

                // Note that drawing text changes the active texture to the font atlas texture.
                // So if you're rendering other stuff, make sure you set a texture before drawing anything else
                batcher.DrawText(font, "Hello, World!", new Vector2(100f, 80f), Color.Black);
                batcher.DrawText(font, "This is rendered from a font atlas!", new Vector2(100f, 130f), .5f, Color.DarkRed);

                // Reset the transformation matrix
                batcher.PositionTransform = Matrix3x2.Identity;

                // Let's also render the font atlas so we can see how this works
                batcher.SetTexture(font.Texture);
                var atlasSize = texStorage.GetTextureSize(font.Texture);
                batcher.FillRect(new RectangleF(100, 170, atlasSize.Width, atlasSize.Height), Color.Black);

                // Finish the frame and let the renderer draw everything to the back buffer.
                batcher.Render(renderer);

                if (first)
                {
                    Console.WriteLine("Vertices: " + batcher.VerticesSubmitted);
                    Console.WriteLine("Indices: " + batcher.IndicesSubmitted);
                    Console.WriteLine("Batches: " + batcher.BatchCount);
                    first = false;
                }
            });

            renderer.Dispose();
            graphicsDevice.Dispose();
        }
Пример #4
0
        static void Main(string[] args)
        {
            // Create the window and the graphics device
            VeldridInit(out var window, out var graphicsDevice);

            // Create a renderer that implements the OpenWheels.Rendering.IRenderer interface
            // this guy actually draws everything to the backbuffer
            var renderer = new VeldridRenderer(graphicsDevice);

            // Our batcher lets use make calls to render lots of different primitive shapes and text.
            // When we're done the batcher sends the draw calls to the renderer which will actually do the drawing.
            // StringIdBatcher is an extension of batcher that supports registering and setting fonts and
            // textures using a string identifier. Internally in OpenWheels textures are identified by an integer.
            var batcher = new StringIdBatcher(renderer);

            const string fontId = "font";

            // This creates a font atlas and the corresponding image for the letters.
            // By default it includes only the basic Latin characters in the atlas.
            // The created image is registered with the renderer and the font can be
            // set using the StringIdBatcher by calling `SetFont(fontId)`.

            // LoadSystemFont and other extension methods to load textures and fonts into a batcher in a single method call
            // are defined in the OpenWheels.Rendering.ImageSharp library.
            // Using this library is the easiest way to handle font and texture loading, but it's a separate lib so you can
            // use another solution if you prefer.

            // Note: System fonts only work on Windows, you can use a font file and call instead `LoadFont` on other platforms.
            batcher.LoadSystemFont("Consolas", 24, '?', fontId);

            // set the font
            batcher.SetFont(fontId);

            var first = true;

            // We run the game loop here and do our drawing inside of it.
            VeldridRunLoop(window, graphicsDevice, () =>
            {
                renderer.Clear(Color.CornflowerBlue);

                // Start a new batch
                batcher.Start();

                // Note that drawing text changes the active texture to the font atlas texture.
                // So if you're rendering other stuff, make sure you set a texture before drawing anything else
                batcher.DrawText("Hello World!", new Vector2(100f), Color.Black);

                // We rotate and translate this one a little bit for style 😎
                batcher.PositionTransform = Matrix3x2.CreateTranslation(52, -154) * Matrix3x2.CreateRotation((float)Math.PI / 2f);
                batcher.DrawText("Hell  World!", Vector2.Zero, Color.Black, va: VerticalAlignment.Bottom);

                // Reset the transformation matrix
                batcher.PositionTransform = Matrix3x2.Identity;

                // Finish the batch and let the renderer draw everything to the back buffer.
                batcher.Finish();

                if (first)
                {
                    Console.WriteLine("Vertices: " + batcher.VerticesSubmitted);
                    Console.WriteLine("Indices: " + batcher.IndicesSubmitted);
                    Console.WriteLine("Batches: " + batcher.BatchCount);
                    first = false;
                }
            });

            renderer.Dispose();
            graphicsDevice.Dispose();
        }