SDL 2.0.4 on Ubuntu 16.04 - Multiple displays fullscreen problem - c++

I have a vertical dual screen setup with each monitor's size of 1920x1080.
My software must run on both screens with a single SDL window (1920x2160) on fullscreeen.
The SDL_WindowFlags mask used in the window creation is the following : (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP).
Since SDL_WINDOW_FULLSCREEN_DESKTOP polls the actual hardware resolution (as far as i know) I am presented with a single screen of 1920x1080 (the first half of the software's GUI) rather than 1920x2160 so the second screen is not drawn.
A workaround is to change the mask to (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS) to run it in windowed borderless mode but that case is not applicable to the software needs (its required and it should not be done like this).
Any recommendations for running the software in real fullscreen, excluding splitting the logic into many SDL windows, are welcomed.

Related

OpenGL and Windows 10 per-monitor aware DPI scaling

What's the correct way to deal with DPI scaling in an OpenGL application when the application is DPI monitor aware. aka:
SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
I'm finding different behaviour on different devices - probably driver related, but some machines need to setup the viewport like this:
glViewport(0, 0, prc->right, prc->bottom)
while others need something like this:
glViewport(0, 0, (int)(prc->right * 96 / dpi), (int)(prc->bottom * 96 / dpi));
(where prc is the client rect and dpi is the current DPI of the window).
I've put together a simple demo program that shows the problem. The problems happen after changing the system scaling, but before signing out/back in.
Problems include:
Rendering at the wrong scale (not sure which driver is wrong)
Vertical shifting by what looks like the difference in the title bar height before changing the scaling vs after changing the scaling. (on macbook pro/bootcamp)
I've tried tearing down and recreating the wgl context on WM_DPICHANGED but to no avail and not sure what else to try.
Update: I've updated the sample program repo to include screen shots of what I'm seeing and I've included the .exe for the test program.
See here: https://bitbucket.org/toptensoftware/minimalopengl/overview
Update 2 - found a GPU that works as expected Radeon RX460. Updated screen shots in repo to show what's expected.
Update 3 - I'm now fairly confident this is caused by issues with the NVidia and Intel drivers and have logged bugs with both. I guess WHQL compliance doesn't cover OpenGL drivers.
Still... it'd be nice to have proper documentation or example program from Microsoft on how OpenGL and the per-monitor DPI support is supposed to work.
Have the same problem on gtx 1050. I've noticed that this problem only appears with SetThreadDpiAwarenessContext function.
from msdn:
SetThreadDpiAwarenessContext function.
Set the DPI awareness for the current thread to the provided value.
It means that if driver creates one or more additional threads to render OpenGL, each thread will have different dpi awareness level.
So there are three solutions:
Use old SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE) function from Windows 8.1 and call EnableNonClientDpiScaling(hWnd) in WM_NCCREATE message;
Use new SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) from Creators Update;
Set dpi awareness level in application manifest (will be applied to whole application).
Both functions set awareness level for whole process.

SDL2 Fullscreen resolution issue (extending render over second screen)

I am using multiple monitors on my PC. One of them is a TV. When I launch my application on my regular monitors, the application gets scaled properly.
However, when I run the application in fullscreen on my TV, the resolution will be too large and the output shows partially on another screen (see the blue colored output in my screenshot).
The TV is connected via HDMI and uses the same resolution as the other screens (1920x1080). It seems to be a software issue, because the output is partially visible on another screen.
I am using the following code to toggle fullscreen mode:
SDL_SetWindowFullscreen( m_Window, SDL_WINDOW_FULLSCREEN );
Any ideas on how to solve this issue?
UPDATE
When I make the TV my main display in Windows, it seems to fit properly on the TV. However, it still shows partially on the other screen (but this time it shows twice) and the mouse positioning is incorrect on the TV. Maybe the resolution is changed differently?
UPDATE 2
Windows 10 allows font sizes to be changed on a monitor. This is why my resolution detection in SDL2 identified a different resolution for my TV. Now I need to find a way to work around this.

Transparent window on top of immersive full-screen mode

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.

Full screen Direct3D9 device only displays at native resolution when second monitor is plugged in

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.

C++ Draw a small dot in the center of a screen

I want to draw a small dot at the center of the screen so that it must remain after running of any application. A dot should stay even after I launch an application in full screen mode. Like a dead pixel.
I have already installed Visual C++ on my computer with Windows 7. I have some experience with C++, but I never worked with graphics under Windows OS.
How can I draw a dot on a screen?
Many graphics cards have overlay features, and it is likely possible to set one up to be foremost on the screen regardless of what other applications are rendering in other layers.
But the method to do that would be specific to the video card model and driver.
Or, you can try to get your code inside the application doing full-screen rendering, find their rendering context, and draw to it at the ideal time. Which still requires a bunch of variants for all the different graphics APIs.
Here is someone who describes Steam's attempt to solve the portability issue (with a zillion implementations) and how to take advantage of that.
I would create a properly positioned 1x1 pixel (or whatever size you need) window with no borders or title bar, all client area and paint it appropriately. It's important that the window is created with the WS_EX_TOPMOST style. As long as your program is running, the window will be visible as long as there are no other windows with that style overlapping it.
I've done this as a prank. It worked really well over a full-screen OpenGL game (Quake III). I installed it on a friend's machine so that it would flash the word LOSER! in big letters in the center of the screen at random times during the game.
This worked perfectly well on an XP system. I imagine it should work on Windows 7.