For a video game, consider your... ern... non-widget-GUI. If you use your game window to handle rendering and to handle widgets, you are mixing concerns. Therefore, either you make the widgets a subsystem (which probably means you have to roll your own), or you render your game inside of a widget.
OpenTK.GLControl is a WinForms control that allows you to render using OpenGL (via OpenTK). Since it is a WinForms control, it is a widget you can add to a regular WinForms form and use it to render.
That will allow you to add other regular WinForm controls (such as button, text boxes, etc...) ontop of it.
I have been able to get the verion 1.1.1589.5942 to work on WinForms. To have it work properly, you need to:
Application.Idle to place your render codde.
- Make sure you call
- If you want to have multiple
GLControl, you will have to call
GL calls only apply to the current control.
Futhermore, Mono supports WinForm on Linux and other platforms. In theory this can work without additional changes to the code.
Tested no Windows on .NET 4.6, working correctly. Not tested on Linux.
Roll your own
Do you remember SmallTalk? Yeah, me neither. But I'm aware the MVC was introduced in SmallTalk by Trygve Reenskaug.
The real MVC, not that thing the PHP frameworks claim to be.
It is a simple idea... You have an object-oriented model of reality, and to access it you create a tool that presents a view and handles the interaction with the user:
It is better to understand with this diagram from Wikipedia:
But using MVC isn't enough...
Plot twist! MVC is dead. well, sort of.
MVC was dethroned by the concept of GUI components (A.K.A Controls, A.K.A Widgets) a long time ago.
Using widgets it is common to implement a "fat"※ view class, because it does not have to deal with the actual display instead its concern is to handle the widgets (which will worry about rendering the interface).
※: I say "fat" because it has the controller logic. It no longer has to worry about rendering, so this is not really mixing concerns.
To implement GUI widgets you need a hierarchical structure that as the window as root and contains the different GUI widgets.
Each widget is a class, it has an internal view model (state) and behavior, and it is responsible of rendering its appearance. Therefore, the widget class is an encapsulation of fragments of view, controller and view model. It should be noted that the view model in the widget is a surrogate for a fragment of the actual model of the application... if you do not want your "fat" view to handle synchronizing the model (reading and writing attributes to the widget), you would have to implement some kind of binding. And then you have MVVC.
The object in charge of that hierarchy is the "composer", it should compartmentalize the window to give each widget the space where it will render. It should take care of Z order, it could handle widget sizes and preferably it should abstract the coordinates in such way that the widget code does not need to worry about its own position on the parent widget when rendering.
Speaking of handling the coordinates, one of the important features of the GUI widget system is scrolling. The composer should allow you to scroll all the contents of the window by some offset, and the widgets should not have to have special code to handle that. You should also think about positioning and resizing. For instance, Layouts are a useful model, also Dock and Anchors. And you may also want to borrow the ideas of
absolute position from HTML + CSS.
Finally, for a modern widget system, you also need to implement an "event dispatcher", capable of bubbling events.
While the above is enough to make a good GUI widget system, I want to note that some modern systems has opted to support CSS (or a subset of it) to manage the attributes of the widgets. So, if you want to create a general solution, consider to support selectors, to facilitate the creation of tools that apply CSS (or similar) to the system.
Of course, you still would need to implement buttons, sliders, input boxes, etc...