Apos.Shapes - Shape rendering in MonoGame.

I created a new library for drawing shapes.

https://github.com/Apostolique/Apos.Shapes
https://www.nuget.org/packages/Apos.Shapes/

Currently supports drawing filled circles and rectangles with a border. It works similarly to the SpriteBatch. I tested it on the DesktopGL and WindowsDX platforms. I’m using SDFs which means the shapes should look good at any size.

using Apos.Shapes;

// ...

_graphics.GraphicsProfile = GraphicsProfile.HiDef;

// ...

ShapeBatch _sb = new ShapeBatch(GraphicsDevice, Content);

// ...

_sb.Begin();
_sb.DrawCircle(new Vector2(100f, 0f), 100f, Color.Red, Color.White, 4f);
_sb.DrawCircle(new Vector2(100, 100), 50, Color.Red, Color.White, 4f);
_sb.DrawCircle(new Vector2(170, 150), 75, Color.Blue * 0.5f, Color.White, 2f);
_sb.DrawRectangle(new Vector2(400, 120), new Vector2(100, 200), Color.Green, Color.White, 10f);
_sb.End();

I’ll be adding more shapes over time including stuff like rounded rectangles.

5 Likes

Very nice thats going to be super handy. Especially when mocking up game ideas without having to load in sprites etc

You should add a draw rectangle overload that rotates the rectangle, altho your input parameter would probably have to be a center location as a well as width and height

I’m thinking of adding an overload that takes in a matrix32. That would allow you to do any world transformation including skewing.

btw, for now you can already pass a view matrix to the begin call. Not exactly the same though since it would transform the whole batch.

1 Like

True. But also keeping it similar to spritebatch rotation would be nice to where you just pass a float radian in for rotation. But you would need to pass a center vector, width, height and rotation

That could work, it would be backed by the matrix32 behind the scene.

Version 0.1.2 is out!

Fixed

  • Shapes weren’t drawn at the correct position

Optimized

  • The ShapeBatch should be slightly faster

Version 0.1.3 is out!

Added

  • Line segments. The end caps are rounded.

Fixed

  • Anti-aliasing between main color and border color

Come on, what’s with the outdated begin/end approach.

What would you suggest instead?

No begin/end whatsoever.

Can you show an example of what your API would look like?

This, if we are going extreme barebones.

But ideally, FlushBatch will be called automatically (which it is, in high-level monofoxe API)

@Martenfur what is your api recomendation? I skimmed your .cs file but I can’t really tell… you mean like how you have the _vbatch object setup?

The most basic api should go like this:

draw()
draw()
flush() // basically, equivalent to end()

However, ideally, flush() should happen behind the scenes. But this requires a bit tighter integrarion.

How do you pass the view matrix? Or other variables I can pass in the begin call?

Version 0.1.4 is out!

I separated the fill and border draw.

There are now 3 drawing methods types: Draw, Fill, Border.

Filled shape drawing:

  • FillCircle
  • FillRectangle
  • FillLine

Border only drawing. A border encases a shape without going outside it’s boundaries.

  • BorderCircle
  • BorderRectangle
  • BorderLine

Draw both together in a single call:

  • DrawCircle
  • DrawRectangle
  • DrawLine
1 Like

I successfully incorporated this into my current project by pulling in the nuget package and adding the AposShapesEffect.fx to my Content file.

I was able to draw a red Circle border on top of everything in my main Draw().

However, I see nothing when I try to draw the same Circle to a different RenderTarget inside a SpriteBatch.Begin() … End().
My game draws the main elements to a separate render target which allows zooming in/out etc.
My guess is the circle is always being drawn on the normal render target and thus gets hidden when I finally draw my ‘scene’.

I may dive in to see if this is easy to implement.

UPDATE
I separated the Apos calls out into a separate pass in my game and it works quite nicely now.
Here I am using 3 BorderCircles (red/yellow/red) to highlight units:

This is the same but using the Primitives2D functions:

So it’s a really nice improvement in quality!

Awesome! Looks better because mine has anti-aliasing. It’s a game changer.

Yeah, can’t mix SpriteBatch and ShapeBatch at the same time, have to end one to begin the other. In the future, I’d like to create a “MetaBatch” library that would handle that behind the scene.

Just released a new version that automatically resizes the batch so it only needs to get flushed once per .End() call.

Made the ShapeBatch become much faster based on my tests when drawing a lot of shapes.