MonoGame.Forms - Create your Editor Environment!

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…

God thanks @SpiceyWolf you explains hard that. Reason SDL loves only OpenGL.net - I will check if OpenGL.net works fine with embedded MonoGame on WinForms.

OpenTK is passive OpenGL engine. I see 2 different of OpenTK and OpenGL.net

You’re right and thanks for shouting to my head because idea press to my head. I think you are hero because OpenTK has many bugs and can’t work with MonoGame on WinForms. I don’t know that OpenGL.net can work yet?

Shit, same problem with GraphicsAdapter(). But i feel that SDL i found GraphicsDevice() with parameters from GraphicsDeviceManager it is possible wrong because SDL and OpenTK have conflict or unhandledexception with handle that is why you need upgrade nevest version of OpenTK and don’t use old version!

Yes you say sdl but I have found some timportant dynamic libraries from vcpkg.

sdl has a lot of features like it has 3 extra extensions of SDL2 like image, mixer and ttf.

I think MonoGamer hold SDL2 better than GLFW right. But I understand reason. I will try with SDL2-CS But I am not sure that SDL has support with multiple windows.

I’ll check that… Do not worry!

@Jens_Eckervogt (and anyone else) - I have successfully made a Winforms control that allows for a single dll to be used interchangeably with MG dx or gl versions. Requires only a single API to be used with it and handles like standard Winforms controls (Drop a control, make it unique by modifying an externally set event). The only issue with it is it loses a bit of performance due to how I get the stuff rendered so best used for a very low amount of controls (The more controls needed the slower it all gets per present).

(Note about yesterday): I was handling like contexts which required alot of management and I realized that way way more work than necessary so I literally fixed all my issues at the same time and gained a bit of performance back by simplifying what i was doing.

@BlizzCrafter - Unless you end up redoing your dx handler the way I did (Which would downgrade alot of performance yours gets) ud need to compiler condition against DX and GL separately and have the GL end use my method of handling stuff if you want working GL support. Your version definitely includes some 1-ups over myne so Im not attempting to shadow ur work out or anything yours would obviously be more optimal as is for complex editors -> Especially since you include all the special background loop stuff for simulating the Update(Game Logic).

[UPDATE]
Github: https://github.com/SpiceyWolf/MonoGame.Framework.Winforms
Nuget: Install-Package MonoGame.Framework.Winforms -Version 1.0.0

2 Likes

Hey @SpiceyWolf

I took a small look at your repo and already did some small performance tests.

I noticed that you made use of GraphicsDevice.GetBackBufferData() which was originally implemented to have a quick way of taking a screenshot or snapshot of the current BackBuffer (if I remembering correctly) and should be a bit slow if called continuously.

However for me and some quick first test it doesn’t turned out that badly. I managed to have 9 GL controls (from you) and 9 DX controls (from MonoGame.Forms) and they worked all without lags and below 10% CPU usage (Intel Core i5-7600K). Further it’s possible to adjust the intervall, which raises the performance.

Before you posted your solution of MonoGame GL controls, I played around with the abbility of SDL_Surface returning the pixels of the screen as a pointer and I marshaled it to a byte array. So I had kinda the same approach and i’m thinking it is a way we can and should go (though i’m not an expert at this and still thinking of having a robust SwapChainRenderTarget.GL would be the best thing).

That’s why I plan to catch up on your idea with the BackBufferData and creating a SwapChain (alike) with it. Then it could possibly a simple thing to implement it to the MonoGame.Forms library without much hassle as a consistent integration.

I would then let the community and MonoGame.Forms users do their own integration and performance tests and see how it turnes out on different machines and editor needs.

As I said earlier in this thread: I’m always open for your ideas and suggestions as well as your sample projects showing feature ideas and so on to make the MonoGame.Forms library more awesome. So I will take my time and start experimenting with it further.

I start working on it on monday and will reply back with my experience.

Till then thank you very much for your effort and have a nice day and weekend everyone! :slight_smile:

Im glad you could get some ideas from it… As far as it goes I couldnt see any other way of doing it the SwapChain method though since I believe even SDL directly limits your window generation and either way MonoGame limits you to one graphics device on a GL build (At least it seems to since I couldnt find the generation code in source and in my test projects it crapped out trying to make as econd window) and so the only stable way i could get more than 1 control to load and function properly was simply ripping the graphic contents out manually and plastering them where i wanted xD If it could be implimented to create a GL based SwapChian in MonoGame directly i feel that would eliminate all the problems of just doing it the classic way and gaining back the inevitably lost performance… BUT as for now, this will at least get people working in GL and I dont see any code in my own source that shouldnt function properly in Linux and Mac (Ive used the bitmap handling code in Linux before and never had a problem)

What exactly doesn’t work with the canonical shared contexts for each handle?

Abusing a single GL context for multiple windows instead of shared contexts mangles the driver’s multiple GPU support.