MonoGame.Extended
MonoGame.Extended copied to clipboard
[shapes] Draw circle
Noticed a bug with DrawCircle. In the image below is a circle of radius 32, drawn with red color, half opacity (alpha = .5f) and 32 sides. The issue should be clear to see - rather than drawing the circle with half opacity, some triangles from which the fan is made of are overlapping, resulting in the effect below. On the other hand, functions work fine with alpha = 1. Please note, that some other MonoGame.Extended shapes (ex. rectangle) work fine. I'd be interested in fixing this issue myself, if you approve this is unintended behavior.
Edit: would be nice to have DrawTriangle, FillCircle & FillTriangle.

if you approve this is unintended behavior.
Ah yes, please do.
Oh btw, while we are on the topic I previously got permission to borrow the DebugView.cs code from the VelcroPhysics library (formerly known as Farseer Physics).
I believe their shape algorithm's are better than ours and they use a PrimitiveBatch class that draws the shapes in a cleaner way (it doesn't rely on SpriteBatch).
Actually found that the bug is present in all shapes. Reproduce: Change background color to black Set alpha to 0.5f Draw rectangle Notice how joints overlap
For myself I've solved this by drawing shapes with 3d color vertices, using basic effect, provided with matrices (world, view, projection) to represent 3d world equal to camera 2d view matrix.
My solution, not in very clean state now tho that I'd port over is here: https://github.com/lofcz/SimplexRpgEngine/blob/master/SimplexCore/SgmlDraw.cs
Draw circle for example is able of rendering arcs this way:

drawing shapes with 3d color vertices, using basic effect
Yeah, that's how Velcro's PrimitiveBatch does it I believe. I think that's the right way to go. The only downside I can think of is that you can't draw a shape in the middle of another SpriteBatch call without messing around with the depth.
On the other hand, the PrimitiveBatch could also be modified to render sprites so maybe it's not a big deal either way.
That's a good point and I have to admit that I didn't take this under consideration before. Do you think that the problem can be solved by queuing both sprite and primitive calls into two stacks?
Update: Personally I found no way around this to preserve one batch call for everything. I was really scared about performance drops in case of multiple batches but it turned ram used up only about 5-7% for me.
Circles are made of triangles:

I found no way around this to preserve one batch call for everything.
It's a common misconception that having multiple batches is a performance bottleneck. It's actually perfectly okay and often desirable to have a handful of batches.
The bigger hit to performance is probably going to be texture switching. It's much better to pack all of your sprites into a single texture sheet if you can. Of course, if you can't there's still sensible ways to manage your textures by considering how they are drawn and layered to minimize texture switching.
See how exactly does XNA's SpriteBatch work?
That said, the next challenge is what order to draw things. The simplest approach with a SpriteBatch is called the painter's algorithm which simply means you call Draw in the right order (from back to front).
Of course, that's not the only way to do it. You can also assign each sprite and shape a depth value and enable depth sorting. However, doing it this way you probably will want multiple batches to handle alpha blending and such.
Thanks for a valuable advice. Personally I will try to automatize https://www.codeandweb.com/texturepacker/monogame
As for depth - I have defined a RoomLayer, where each GameRoom is equipped with a list of these. They can be of a various type (actors, tiles, etc.) but more importantly each GameObject belongs to a RoomLayer. This allows for sorting of layers, eg. having one layer above others. As for the in-layer sorting, I was used to:
depth = -Position.Y; so I will just sort each layer by this property and then draw in order.
Not sure whether this will work as flawlessly as I imagine but only way to learn something is to try it!
Update - worked out entire shapes library, currently optimizing via object pooling. https://github.com/lofcz/SimplexRpgEngine/blob/master/SimplexCore/SgmlDraw.cs
It seems the solution is to upgrade the code to support drawing shapes using a custom batcher.