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.
Related
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.
With a single monitor my program works in both windowed and full screen mode (using any resolution chosen from EnumAdapterModes), but when I plug in my second monitor (running the same code) I can create a full screen device at any resolution from EnumAdapterModes, but only at the native resolution (1600 x 900) does it display the scene, otherwise the screen is just black among other problems listed below.
What I've discovered so far:
This problem does not occur in windowed or multihead mode
I can still render to a texture (I had to switch modes to display it though)
All function calls return success codes (including TestCooperativeLevel)
If I try to draw to the back buffer using Clear or the DrawPrimitive functions or call Present (which still leaves a black screen), than calls to GetRenderTargetData fail and attempting to lock a volume texture will return different slice pitches at sub levels
Commercial games that use Direct3D9 (Portal) don't have any problem switching between resolutions with my second monitor plugged in so there must be a solution
The problem seems to be related to the back buffer created by the Direct3D9 run time but the only solution I can come up with is to force multihead mode on devices with multiple monitors, any ideas?
Question that seems to have the same problem but lacks a solution: How do I render a fullscreen frame with a different resolution than my display?
Finally figured it out, seems to be a driver bug in Windows Vista and later and using Direct3D9Ex fixed the problem.
I didn't want to use Direct3D9Ex because it was only introduced on Windows Vista and I wanted to support Windows XP as a minimum, but MSDN has some sample code on how to support both so it's all good.
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.
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.
I would like to know the OpenGL Rendering settings for having a program render OpenGL over top of any window on screen that has a specific color code (screen-level buffer?)
I.E. VLC Media Player and Media Player Classic both have rendering modes which allow you to full-screen then minimize player, but maintain watching media via allowing a specific color to act as a transparent mask. For example, you could set the background color of a terminal application to be 0x000010 for VLC 0x000001 for MPC and you could then type over the media using text (as it is in it's original color). When you try to do a "printscreen" all you get is the mask color, However, this is an acceptable side-effect.
Is it possible to do this as well with any OpenGL application with the right settings and hardware? If so, what are the settings or at least the terminology of this effect to further research it?
What you are trying to implement is called "overlay". You can try this angelcode tutorial. If I remember correctly, there was also a tutorial in DirectX SDK.
If you need to use OpenGL, you will need to perform offscreen rendering (using FBO or P-buffer), read the results using glReadPixels() and display using overlay.