MonoGame.Forms - Create your Editor Environment!

Thank you for your informative reply, sqrMin1… :slight_smile:

So then, if I am ever able to complete my military simulation, I could then use this library to create, for example, a scenario editor. Is this a better understanding of your software?

Yes, you could do that, but it realy depends on your needs.

For example: it’s also possible to create a scenario editor without the need of a rendering window, as long as such an editor only needs to process and handle plain data.

But if you need a graphical / rendered representation of such data (which includes realtime updates), then MonoGame.Forms is there to help you with that.

MonoGame.Forms 1.6.5.3 - MSAA Accessibility

  • The maximum MultiSampleCount (MSAA Antialising) of the users GraphicsDevice is now cached in PresentationParameters.MultiSampleCount, so this information becomes easy to access in custom controls, which is useful when working with custom RenderTargets.
  • It’s now possible to get the clamped MultiSampleCount in custom controls by calling GetClampedMultisampleCount(int).
  • This function always returns the desired MultiSampleCount clamped to the nearest power of two in a descending order (e.g.: input = 7; output = 4).

NuGet: NuGet Gallery | MonoGame.Forms 1.6.7.1


Easy to work with MultiSampling in MonoGame.Forms:

MonoGame.Forms 1.6.6.0 - MSAA Accessibility (Refreshed)

  • GetClampedMultisampleCount is now internal.
  • Added public void SetMultiSampleCount(int) which calls the new internal event Action<int> UpdateMultiSampleCount, so the wanted MultiSampleCount will be available in all editor service classes.
  • Added internal AntialisingRenderTarget and internal void RefreshAntiAlisingRenderTarget, which automatically updates itself based on ClientSize and WantedMultiSampleCount.
  • GraphicsDeviceService is now internal.
  • as well as the corresponding field in GraphicsDeviceControl.
  • Added the internal int MaxMultiSampleCount and cache the value there instead of in the presentation parameters, to make this value save from manipulation, because it is used by the GetClampedMultisampleCount in GraphicsDeviceControl as a fallback.

Use Antialising (MSAA) in your custom controls like this:

protected override void Initialize()
{
   base.Initialize();

   SetMultiSampleCount(8); //Usual numbers are 0, 2, 4, 8
}

protected override void Draw()
{
   base.Draw();

   Editor.BeginAntialising();

   Editor.spriteBatch.Begin();

   //Your drawings

   Editor.spriteBatch.End();

   Editor.EndAntialising();
}

As you can see, everything between BeginAntialising() and EndAntialising() will be affected by MSAA.

NuGet: NuGet Gallery | MonoGame.Forms 1.6.7.1

MonoGame.Forms 1.6.6.2 - Antialising Fixes

  • Added missing nuget references to SharpDX.dll, SharpDX.DXGI.dll and SharpDX.Direct3D11.dll.
  • Added public int GetFrameRate to get the current frame rate of a custom control.
  • Changed internal event Action UpdateMultiSampleCount to public so the user can react to multi sample changes in custom controls.
  • The AntialisingRenderTarget now correctly gets disposed on refreshing.
  • Fixed a NullReferenceException when the SwapChainRenderTarget is null.
  • Rethought the disabling of the AntialisingRenderTarget after a ControlResize event. It automatically reactivates itself after 500 milliseconds after a ControlResize event occours.
  • This prevents OutOfMemoryExceptions on recreating the AntialisingRenderTarget as well as NullReferenceExceptions if the current internal Rendertarget is lost, when switching from the AntialisingRenderTarget to the SwapChainRenderTarget.

Dev Note for the next Build (1.6.7.0):
Planning to implement a RenderTarget Manager where users can add their custom RenderTargets to, so they becoming automatically updated internally (based on the ClientSize for example).

NuGet: NuGet Gallery | MonoGame.Forms 1.6.7.1

2 Likes

MonoGame.Forms 1.6.7.1 - Render Target Manager

  • Added a RenderTargetManager to fully manage custom RenderTarget2D’s internally - based on ClientSize and MultiSampleCount.
  • Fixed memory leaks on reinitialization of custom controls.
  • Added public event Action RenderTargetsRefreshed so the user can get notified when the RenderTarget2D’s, hold by the RenderTargetManager, got refreshed.
  • Renamed events to make it more clear what they are meaning:
  • UpdateSwapChainRenderTarget -> SwapChainRenderTargetRefreshed
  • UpdateMultiSampleCount -> MultiSampleCountRefreshed
  • Made SwapChainRenderTargetRefreshed internal.
  • Changed some XML comments so they are better understandable.

Using the RenderTargetManager

protected override void Initialize()
{
    base.Initialize();

    // Adding a new Rendertarget2D with the keyname "MyTarget" to the Manager
        Editor.GetRenderTargetManager.CreateNewRenderTarget2D("MyTarget", false);
}

public override void Draw()
{    
    // Set the new RenderTarget
    Editor.BeginRenderTarget("MyTarget", clearColor: Color.Transparent);

    // Your Drawings ...

        // Automatically revert to the SwapChainRenderTarget
        Editor.EndRenderTarget("MyTarget", drawToSpriteBatch: false, clearGraphics: false); 
}

NuGet: https://www.nuget.org/packages/MonoGame.Forms/

I’ve been working with forms for a bit, and I’ve run into a small snag. I think I know the issue, but I’m not sure how to get around it.

I have my main window, which has the map editor portion of it(using UpdateWindow). I use OnMouseMove to drag objects around and it works fine.

I have a second form I open sometimes using ShowDialog() which has a different UpdateWindow. When I use OnMouseMove and other mouse events on here, it sometimes will work, sometimes won’t, and other times I’ll drag things around and then it will stop working.

I’m assuming the mouse events are conflicting between the two UpdateWindow’s since the first one is still open in the background. Any good way around this?

Hey @thera and thanks for your message.

You could do the following to get around this:

  • If you just want to move entities inside your editor you could replace all Windows Forms events with native events from the MonoGame.Framework (e.g. Mouse.GetState(), Keyboard.GetState()).

  • If you don’t want to replace all Windows Forms events you currently have, you could try to disable your main window control right before you open your second form.

Did you take a look at the MapHost sample from the MonoGame.Forms repo? It will show you how to handle multiple render windows visible at the same time.

If you prefer to work with multiple float style render windows like in your example, then I recommend using the DockPanelSuit together with MonoGame.Forms.

Thanks for the suggestions. Worse case scenario, I can definitely, go the route of using Mouse.GetState().

In regards to your second suggestion, I’m assuming you’re referring to the Enabled property for the control? I’ve tried that to no success. I’ll study the maphost sample a bit further though, thank you!

Edit: I think I figured out what it is, although I’ll have to think a bit on how to fix it. Both of the UpdateWindow controls utilize zooming in and out, so I need transform the mouse coordinates. Whenever it doesn’t work, its returning a different Matrix, which is probably the control from the base form.

 Matrix viewMatrix = Editor.Cam.get_transformation(Editor.graphics);

            return viewMatrix * Matrix.Identity;

I’ll have to mull this over for a bit haha.

Yes, but I saw why it can’t work after your message. Somehow I forgot to implement this. In the moment the custom controls just checking for Visibility and for AutomaticInvalidation. I will write a patch to make It work in the next iteration of MonoGame.Forms.

You could try to turn off the AutomaticInvalidation on your main window. Then no control events are getting raised and also the Update and Draw methods won’t get updated anymore.

This could also resolve the issue with different matrices.

Normally you wouldn’t have such problems, when using multiple controls on one Form. I have not tested the use case of having multiple Forms together with custom render controls. MonoGame.Forms works best when hosting multiple custom render controls on Panels for example.

When working with several custom controls in different windows (e.g. floating windows), then the DockPanelSuit will be a great help. I use it myself for this purpose and during the development of MonoGame.Forms I always made sure that it works flawlessly with this library. So I can really recommend it in this case.

But if you want to create a simpler editor environment I recommend having multiple custom render controls in Panels and Tabs on one Form only.

I tried setting the following:

this.AutoValidate = AutoValidate.Disable;

This didn’t seem to help. So I tried setting the controls CauseValidation = false and I think it has helped. Unfortuantly it’s a bit ‘random’ when it doesn’t work, so I’ll have to play around with it and see if it acts up, but so far its promising

DockPanelSuit looks very cool, and I’ll definately check it out in more detail. Thanks for your help! :slight_smile:

Sorry, it wasn’t clear enough from my side. I meant this. (Wiki)

It’s a part of the library and you can set this property directly from a custom render control.

Oh, I was getting a bit confused since I couldn’t find it! I’ll test with that, thanks for letting me know.

Nothing support with OpenGL DesktopGL :frowning:

I played around with DesktopGL support in the past and I successfully managed to get a SDL GameWindow embed in a Form, which makes it possible to use / create a MonoGame DesktopGL project in WindowsForms.

But the problem is that it only worked using P/Invoke, which destroys the cross platform compatibility. So I decided to not support DesktopGL for now.

A way better solution would be to have a seperate SwapChainRenderTarget for OpenGL. This would be also the easiest and most obvious way to implement this feature in MonoGame.Forms, because the library uses the exact same technique for WindowsDX (SwapChainRenderTarget in MonoGame).

A SwapChainRenderTarget for OpenGL is btw also suggested on the MonoGame repo:

I really don’t understand because OpenTK can’t but I feel issue looks like it works only OpenGL.net right?

You mean SwapChainRenderTarget works with OpenGL.net?

Thanks for understanding. so sad how do Mac and Linux users wait longer until we have gray hairs?

I’m not sure if I understood you correctly, but OpenTK was wiped out and now SDL2 is in use.

Well, you somehow need to give the OpenGL UserControl the graphics context of the SDL_GameWindow. This could be kinda practical when creating an invisible SDL_GameWindow using the SDL_WINDOW_HIDDEN flag.

But you need to modify the source of OpenGL.Net then, because the UserControl automatically creates a context and make it the current one.

It’s also possible to create a GL context using SDL:

SDL_GLContext SDL_GL_CreateContext(SDL_Window* window)

But as you can see it requires a SDL_Window as parameter. So you would need to create this SDL_Window (invisible) first and then getting the corresponding context with SDL_GL_GetCurrentContext. But I don’t know how to connect this context with the OpenGL.Net UserControl.

I also saw SDL_CreateWindowFrom, were you give the native window handle as a parameter, but didn’t manage to get it working right.

I want to mention that I am not an expert at this, but maybe it’s a better idea to create the SwapChainRenderTarget.GL by using the SDL_Surface !?

Would be nice to know what someone with a better knowledge thinks about this.

Wait I don’t listen about SDL of OpenTK? But how is version of OpenTK? You mean OpenTK-SDL2?

But it is very outdated. It won’t work for my computer ( very new since December 2016 ) over 1 years ago.

Do I need use old version of OpenTK-SDL2?

This comment comment kind of rubbed me the wrong way. It’s a pretty harsh comment considering you admit you don’t know why the backend was switched out.

The reason MG now uses SDL is because the OpenTK had annoying bugs and it was not being maintained, so they did not get fixed. SDL is actively maintained, widely used and battle-tested.

To be blunt, I think your comment is pretty ignorant because whether you PInvoke into SDL or use OpenTK directly, you’re using a platform-specific solution outside of MonoGame. In fact you can use OpenTK directly right now if you wish to do so. Also saying there is an artificial block to the OpenGL context is a weird kind of phrasing because MonoGame exposes a certain cross platform API which by itself means it can not give you access to the GL context.

There is no staff, no one gets paid for working on MonoGame. It’s a community effort and everyone can help out with design/feature suggestions or implementations :slight_smile:

“In 3.4 we had a workaround, right now there are no workarounds, except this workaround.”

As an aside, you can also get the context handle using reflection.

@BlizzCrafter sorry about the wall of text that is mostly a personal convorsation to Jjagg, I can remove it, just need him to see it cause I believe he had a misunderstanding what I was talking about, I know sometimes im not clear - you should read it too in case you misinterpreted what I was saying I didnt mean to sound harsh to the community as if anyone has been being malicious. Just tried to provide some background from my experience so you would have an idea why the GL was such a problem outside of platform specific patches…