Apos.Shapes

Shape rendering library for MonoGame and KNI.

DiscordNuGetNuGet

Description

This library draws crisp anti-aliased shapes on the GPU using SDFs. It also draws text with the FontStashSharp API and textures with the SpriteBatch API. Shapes, text, and textures can be interleaved in any order. Everything renders together in a single batch that never needs to break.

Special thanks to Inigo Quilez for doing a lot of the work on the math functions.

Shapes drawn with Apos.Shapes

Features

  • 10 shapes: Circle, Ellipse, Line, Path, Rectangle, Hexagon, Equilateral Triangle, Triangle, Arc, Ring
  • Fill, Border, and Draw variants for every shape
  • Paths draw a polyline as one continuous shape: translucent strokes blend once even where segments meet, with round, miter, or bevel joins and round, butt, or square caps, mixable within one path. Points come from an array or one at a time with BeginPath/PathTo/EndPath. closed: true, or ClosePath(), joins the last point back to the first, which is also how a curve or an ellipse gets dashed: flatten it to a closed path
  • Rounded corners (per-corner radii on rectangles), rotation, and adjustable anti-aliasing
  • Dashed outlines and strokes: borders dash along the perimeter, lines, arcs, rings, and paths cut into dashes (flat or round-capped, down to dotted lines), with the pattern fitted to the shape so it closes seamlessly
  • Gradients: linear, radial, conical, spiral, and more, with repeat styles and Oklab / Oklch / RGB color interpolation
  • Blue noise dithering so slow gradients don’t band on 8-bit displays
  • Text (FontStashSharp API)
  • Textures (SpriteBatch API)
  • Clipping to a rectangle
  • One batch for everything. Mixing shapes, text, and textures never breaks the batch
  • Precompiled shader embedded in the assembly using ShadowDusk. No need for Wine to build on Linux or OSX.
  • Works with MonoGame 3.8.2+ and KNI

Documentation

You can also try the library directly in your browser here.

Getting started

Install with:

dotnet add package Apos.Shapes

Set the HiDef profile in your game’s constructor. (With KNI, use FL10_0 instead.) Create a ShapeBatch, then draw between Begin and End:

using Apos.Shapes;

public class Game1 : Game {
    GraphicsDeviceManager _graphics;
    ShapeBatch _sb;

    public Game1() {
        _graphics = new GraphicsDeviceManager(this);
        _graphics.GraphicsProfile = GraphicsProfile.HiDef;
    }

    protected override void LoadContent() {
        _sb = new ShapeBatch(GraphicsDevice);
    }

    protected override void Draw(GameTime gameTime) {
        GraphicsDevice.Clear(new Color(17, 24, 39));

        _sb.Begin();
        _sb.FillCircle(new Vector2(120, 120), 75, new Color(96, 165, 250));
        _sb.DrawRectangle(new Vector2(240, 70), new Vector2(150, 100), new Color(220, 38, 38), Color.White, 4f, 20f);
        _sb.BorderLine(new Vector2(120, 240), new Vector2(390, 240), 15, Color.White, 2f);
        _sb.End();

        base.Draw(gameTime);
    }
}

Read the Getting started guide for the full walkthrough.

Other projects you might like

Edit this page on GitHub