I'm porting a small graphics engine from DirectX 9 to OpenGL. The engine uses SDL (now ported to 2.0) to manage input and window creation.
I want to know how to correctly handle window events for both OpenGL and DirectX. I'm interested in these for Desktop platforms (linux, OSX and windows)
Window resolution change
Full screen to windowed / windowed to fullscreen handling
Alt+tab handling -
I've tried to search through the net but information is quite not focused in one place. I imagine many others faced the same problem before.
Are there any resources to read guidelines on that kind of handling for my engine?
Is it possible to handle resolution change without losing transfered resources to the renderer system in both OpenGL and DirectX?
Window resolution change
OpenGL itself requires no special treatment for this. Unfortunately SDL goes through a full window reinitialization, including the OpenGL context on a window size change, which means, that all OpenGL state objects (that is, textures, vertex buffers, shaders and so on) are lost.
This is however a limitation of SDL.
Personally I thus prefer GLFW for creating a OpenGL window and context. You can still use SDL for other things though (like audio, networking, image loading and such).
Full screen to windowed / windowed to fullscreen handling
The is effectively a window size change as well. See above.
Alt+tab handling -
OpenGL requires no special effort for this. Just minimize the window when Alt+Tab-ing out and stop the game loop. When the window gets restored just continue the game loop.
Related
I am looking for some information about rendering child windows in specific about how OpenGL interop with GDI. The problem that I have is that I have basically is that I have two windows, first, the main windows are created in qt, and inside of qt, a child window is hosted that leverages an OpenGL renderer.
Now what I wanted to do is to host an overlay on top of my OpenGL window, so I use that to overlay the OpenGL window. The problem that I am having is that when I render with OpenGL, the OpenGL generated graphics seem to obscure the graphics area including and effectively undo the graphics composited by qt.
In the image below the blue area is the qt overlay, in that picture I'm using GDI (BeginPaint/EndPaint) so and the windows seem to interact fine. That is, window order seems correct, the client region is correct. The moment I start to render with Opengl the blue area gets replaced with whatever OpenGL renders.
What I did I basically created to create the overlay I created a second frameless, topmost QMainWindow, and once the platform HWND was initialized I reparent it. Basically I change the new windows parent to be the same parent of my OpenGL window.
What I believed this would do is that the every window, gets drawn separately and the desktop composition manager would make the final composition and basically avoiding the infamous airspace problem as documented by Microsoft in their WPF framework.
What I would like to know is what could cause these issues? At this point, I lack understanding why once i render with OpenGL the pixels by qt overlay are obscured, even though windows hierarchy should say make them composited. What could I do to accomplish what I want?
Mixing OpenGL and GDI drawing on a shared drawable (that also includes sibling / childwindows without the CS_OWNDC windowclass style flag) never was supported. That's not something about Qt, but simply how OpenGL and GDI interact.
But the more important issue is: Why the hell aren't you using the OpenGL support built right into Qt in the first place? Ever since Qt-5 – if available – uses OpenGL to draw everything (all the UI elements). Qt-5 makes it trivial to mix Qt stuff and OpenGL drawing.
I am working on an openGL project. The application should handle window resize events and correctly adjust the aspect ratio accordingly. I've seen many solutions for window resize handling, but they all require GLUT. Is there a way that I can implement the window resize handling without using GLUT?
OpenGL does not know anything about windows, it just knows about a default framebuffer - sometimes called an window-system provided framebuffer or whatever. The default framebuffer can be a window, some output surface or even hardware overlay, or some off-screen resource (like pbuffers or some implementation and/or platform-specific stuff). The connection between an actual windows and a GL context is done via platform-specific GL binding APIs like egl (originated for mobile/embedded GLES, but nowadays also applicable for desktop GL), wgl (on Windows), glX on Unix X11 window system, and so on.
But managing the window is a topic completely outside of the realm of OpenGL.
Is there a way that I can implement the window resize handling without using GLUT?
Yes, GLUT is just a (very outdated!) cross-plattform wrapper around those platform-specifc APIs mentioned before. You can always directly implement all that stuff using the native APIs of your platform. Or you can use some other wrapper API or windowing toolkit with OpenGL support (like GLFW, SDL, Qt, gtk, wxWindows, whatever).
I am trying to draw on top of another process while it is in immersive full-screen mode.
I know this is possible using GDI and I have 2 questions:
Is it possible using a top-level transparent window ? (on top of the immersive process)
Is there a higher level API witch I can use instead of GDI?
Thank you :)
In Windows, you have two possibilities for creating a fullscreen window:
A full-screen application with exclusive drawing rights to the display.
A borderless window that extends to the full desktop resolution.
The first option allows you to change display properties like resolution, bit depth and refresh rate, while the second option is bound to use the same options here as a normal (windowed) desktop application.
Overlaying a fullscreen window with a top-level window is only possible if the fullscreen application is implemented with option 2. In that case however, any code that is able to create a transparent top-level window will do (be it pure WinAPI/GDI, or something more sophisticated, like Qt).
With option 1, as the description suggests, the fullscreen application has exclusive drawing rights to the display. Attempting to bring another window in front of it will either minimize the fullscreen application or force it into windowed mode.
There are some hacks how you can still get an overlay in this case, but they are rather invasive. For example, with a fullscreen application based on D3D, you can hook into D3D's Present routine and have D3D draw your overlay before displaying the back buffer. The important point here is that the code for drawing the overlay is executed from within the process of the fullscreen application, as that is the only process that is allowed draw to the screen at that point.
Note that some applications (in particular video games protected by anti-cheat software) do not like it very much if you inject code into the process this way.
Note that the Win API also provides an interface for so called hardware overlays, which allow drawing on top of exclusive fullscreen applications. Unfortunately, this mechanism is not widely supported on consumer hardware and might not work depending on which graphics card you are trying to run it on.
I have a fully working engine that is using SDL and OpenGL. I have a textured box on my OpenGL/SDL screen - however when I try to change the video mode (e.g. toggle fullscreen with F11) the texturing is lost (the box is just plain white), if I toggle back to windowed mode the box is still white (with the textured image lost). Does this mean I cannot change my video mode in the middle of the application (e.g. toggle fullscreen) or does it mean I have to reload my OGL textures every time I do so?
Some extra notes: I am using CodeBlocks with MinGW on windows 7, the libraries I have linked are: SOIL (a library for easily loading textures in OGL - http://www.lonesock.net/soil.html), OpenGL32, Glu32 and SDL.
I have some images to demonstrate my problem (the first one is windowed mode and the second one is when I try to change to fullscreen with a call to SDL_SetVideoMode(...) - SDL_WM_ToggleFullScreen doesn't work.
I have a textured box on my OpenGL/SDL screen - however when I try to change the video mode (e.g. toggle fullscreen with F11) the texturing is lost (the box is just plain white), if I toggle back to windowed mode the box is still white (with the textured image lost). Does this mean I cannot change my video mode in the middle of the application (e.g. toggle fullscreen) or does it mean I have to reload my OGL textures every time I do so?
It strongly depends on how the used framework implements video mode changes.
In general when deleting an OpenGL context all it's associated data is lost, except if there's another OpenGL context with which a "sharing" has been established. That can be used to keep all uploaded data persistent between context recreation. However a mere video mode change usually doesn't require a context recreation, and usually also not a window recreation.
However the framework used by you (SDL) will completely clean up a window and the context when changing the video mode, thus loosing you the loaded resources. Unstable development versions of SDL have better OpenGL support, allowing for video mode changes without context teardown inbetween.
Unfortunately, the problem stems from the way SDL recreates the window. I had this problem before and the solution for me was to set up a special uninitialize and initialize function that only got rid of/created images.
Essentially, when SDL's Resize event is called (http://www.libsdl.org/docs/html/sdlresizeevent.html) you would uninitialize any artistic assets required and then re-initialize them after entering or leaving fullscreen.
I've written an OpenGL application in Linux through GLX. It uses double buffering with glXSwapBuffers and Sync to VBlank set via NVIDIA X Server Settings. I'm using Compiz and have smooth moving of windows and no tearing (Sync to VBlank enabled in Compiz settings).
But when I
Try to move or resize the OpenGL window or
Move other windows through the area occupied by the OpenGL window
the system stutters and freezes for 3-4 seconds. Moving other
windows outside the area occupied by the OpenGL window is smooth as always.
Moreover the problem only arises if the OpenGL application is in the
loop of producing frames of animation therefore swapping the buffers.
If the content is static and the application is not swapping the buffers there are no problems,moving the various windows is smooth.
Could be a synchronization issue between my application and Compiz?
I don't know if it's still in the same shape as a few years ago, but…
Your description matches very well a Compiz SNAFU. Every window resize triggers the recreation of a texture that will receive the window contents. Texture creation is a costly operation and hence should be avoided. Unfortunately the Compiz developers don't seems the brightest ones, because they did not realize there's an obvious solution to this problem: Windows in X11 can be reparented without much cost (every Window manager does this several times), it's called stacking. Compiz is a window manager.
So why doesn't Compiz keep a desktop sized window around into which it reparents those windows that are about to be resized, gets its constant sized window texture from there and after finishing the resize operation reparents the window into its decoration frame?
I don't know why this is the case. Anyway, some things Compiz does are not very smart.
If you want to fix this, well: Compiz is open source and I just described what to do.