Istrebitel's picture

How to dispose off the game window without destroying OpenGL context?

Greetings.

I need to use OpenGL in an application that will call it from time to time. So, when need be, I need to show the OpenGL window (GameWindow class), let it stay there until it's no longer needed, then hide it until I need it again. Since each time the window is shown, it handles a linear process, I'd like to create new window each time, not re-use the old one. However, it seems that if I call Close() or Exit() on the window, whole OpenTK is terminated - trying to create another GameWindow gives an exception:

Object reference not set to an instance of an object
at OpenTK.Graphics.GraphicsContext.<.cctor>b__0()
at OpenTK.Graphics.GraphicsContext.get_CurrentContext()
at OpenTK.Graphics.GraphicsContext.LoadAll()
...

So, how can I do it, or is it not possible to just close the window (disposing everything associated with it, freeing memory and so on) and open another one?

PS:
Also, as a side small question, is the way to go fullscreen with OpenTK really to make a gamewindow which is maximized? I mean, usually, with DX programs, fullscreen means dedicated output, when only your application is output on the screen - different from "windowed fullscreen" where your application is just borderless and shown on top of other windows. Since I can alt-tab out of my "full screen" opengl program and see it in the background, I assume this is not "true" full screen but "windowed fullscreen".

Is there a way to go "true" full screen with OpenTK?


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

Destroying and recreating a window should work fine, this looks like a bug. Could you please compile a debug version of OpenTK.dll from https://github.com/opentk/opentk and run your application with that? This will log diagnostic messages to the output window in Visual Studio (ctrl+alt+o) that will help us understand what is going on.

To the best of my knowledge, the correct way to enter "true" fullscreen on windows is to create a borderless, maximized window with the "always on top" attribute. This is exactly what OpenTK does and, at least on WinXP and Vista, this bypasses the compositor (e.g. print screen returns a black window). If you have any references for a better approach, I'd be happy to implement that.

(You can also try the SDL backend to see if it behaves differently. Simply copy SDL.dll from opentk/Dependencies/ to your application directory and launch it again.)

Edit: I just tested the following code on opentk/master and it runs without a hitch:

            using (Toolkit.Init())
            {
                for (int i = 0; i < 20; i++)
                {
                    using (var gw = new GameWindow())
                    {
                        gw.UpdateFrame += (sender, e) =>
                        {
                            if (OpenTK.Input.Keyboard.GetState().IsKeyDown(OpenTK.Input.Key.Escape))
                                gw.Exit();
                        };
                        gw.Run(); 
                    }
                }
            }
Istrebitel's picture

When VS complained that "using (Toolkit.Init())" line is incorrect (not IDisposable), I found out that I clicked the wrong button on the download screen. I thought I should get "Download OpenTK" version but apparently, I should have gotten "Nightly" version. It is just, I'm used to "Nightly" being "bugged as hell", so I didn't even consider getting it instead.

Btw, in "Download OpenTK" (I assume, "stable" version) even the OpenTK.Input.Keyboard does not work (not implemented).

Still, sorry for making you go through trouble of testing it. Indeed, on nightly, it works perfectly!

the Fiddler's picture

This is one of the cases where the nightly version is more stable than the "stable" version, mainly because it contains three years worth of improvements.

There will be a new release very soon.

Istrebitel's picture

Oh, yes, forgot to add, about the fullscreen:

The way DirectX fullscreen works is that program gets exclusive input and output - for example, if you start a game on multi-monitor machine, one monitor will display the game and other monitors will go blank. There is no way any other window can appear over the game, there is no way to get mouse or keyboard focus away from the game, windows open on other monitors are not shown, etc.

The way OpenTK fullscreen works, other monitors continue to display stuff. This may have good and bad sides to it, but it's significantly different.

Is there any reason why OpenTK does not support the former fullscreen?

the Fiddler's picture

OpenTK uses standard GDI and WGL calls, whereas DX applications uses DXGI::SetFullscreenState. This explains the difference in behavior.

It is not clear whether you can layer an OpenGL application on top of DXGI, but it is worth investigating now that GDI has been deprecated. I have filed an issue at https://github.com/opentk/opentk/issues/2

Note that all OpenGL toolkits I am aware of (SDL, GLFW, GLUT) use GDI+WGL in a similar manner as OpenTK.