Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows 7, 8 and 10 needs apps to be DPI-aware #252

Closed
BenMcLean opened this issue Nov 21, 2016 · 4 comments
Closed

Windows 7, 8 and 10 needs apps to be DPI-aware #252

BenMcLean opened this issue Nov 21, 2016 · 4 comments

Comments

@BenMcLean
Copy link

BenMcLean commented Nov 21, 2016

I first wrote this issue up for libGDX here libgdx/libgdx#3813 only to find out that it's probably a LWJGL issue. My post is below -- everything I say about libGDX is, I believe, really coming from LWJGL.

On Windows 10, there is a feature called UI Scaling described in this article: https://www.thurrott.com/windows/windows-10/4597/windows-10-feature-focus-display-scaling

This is a good feature for people with vision problems to make the text and GUI elements bigger in most Windows programs.

However, when this feature is enabled, two very bad things happen for libGDX:

  1. In full screen mode, we only see the upper left portion of the viewport zoomed in according to the degree of the UI scaling.

  2. Nearest Neighbor pixel rendering screws up and shows blurry pixels instead of sharp edges. (this becomes easier to see with Windows Magnifier, but it's happening and it's nasty)

I have confirmed this by running my program with UI scaling turned off (it works perfect) then turning UI scaling on. (these bad effects happen)

This feature first started on Windows XP but programmers only started having to worry about it when Windows 7 started trying to scale up apps that didn't tell the newer Windows API that they were DPI-aware. I believe that is what the problem is for libGDX. As InfoWorld says, "For apps that aren't high-DPI aware, Microsoft has a quick and dirty fix called DPI virtualization. Windows deliberately reports the wrong DPI resolution to such apps, so their elements render as if they were on a lower-resolution display. The results are then zoomed to fit the current display." http://www.infoworld.com/article/2952506/microsoft-windows/high-resolution-displays-reveal-windows-10-blind-spot.html

What needs to be done to fix this is to make Windows builds of libGDX apps DPI-aware, as discussed in this article from Microsoft https://msdn.microsoft.com/en-us/library/windows/desktop/dn469266(v=vs.85).aspx and explained in this tutorial. https://msdn.microsoft.com/en-us/library/windows/desktop/dd464659(v=vs.85).aspx

Here is a really good blog post about the issue: http://www.hanselman.com/blog/LivingAHighDPIDesktopLifestyleCanBePainful.aspx

If you'd like to see my code, here is the commit I tested this effect on: BenMcLean/badroguelike@31afc8f

As a temporary workaround, libGDX game developers can turn off UI scaling before running the libGDX apps, then turn it back on afterwards to write code, and players can check the "Disable display scaling on high DPI settings" check box under "Compatibility" in the Properties for the app. But that is a real pain to deal with and DPI-awareness is a necessity for Windows apps now.

The wiki indicates that LWJGL only has a high DPI mode implemented for OSX. http://wiki.lwjgl.org/wiki/Using_High_DPI_Mode.html

I also posted this on the LWJGL issue tracker and I'm not sure where it's supposed to go. LWJGL/lwjgl#141

@Spasi
Copy link
Member

Spasi commented Nov 21, 2016

Hey @BenMcLean, thank you for the detailed issue.

The wiki link above is obsolete, it only applies to LWJGL 2. LWJGL 3 uses GLFW, which supports HiDPI on both Windows and macOS. In more detail:

  • On Windows, GLFW calls SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE). If that function is not available, it calls SetProcessDPIAware.
  • GLFW provides both window size and framebuffer size callbacks. The framebuffer size callback must be used to call glViewport whenever the window is resized. This will update the framebuffer to cover the entire window. libGDX should do this already.
  • There are indeed pending GLFW issues related to HiDPI support on Windows. These are scheduled to be fixed in the next GLFW release (3.3). I'm afraid there's nothing we can do on our side but wait. LWJGL nightly builds always include the latest GLFW changes, I'll update this issue once the fixes are implemented.

@code-disaster
Copy link
Contributor

@BenMcLean how does it behave if you run your game with "java -jar game.jar" directly? A packr issue and a customer bug report for our game on Steam made me look into this topic recently. The former states that the scaling problem doesn't appear when running the JAR manually.

My first attempt to call SetProcessDpiAwareness() didn't seem to work at all. It's possible that I screwed up though. What did resolve it was to embed a manifest in the packr executable.

According to our tests, this fix resolved the scaling issues with our game which is running on LWJGL 2. Sadly, I'm still waiting on user feedback to confirm.

@BenMcLean
Copy link
Author

BenMcLean commented Nov 21, 2016

@Spasi I suspect those "pending GLFW issues related to HiDPI support on Windows" are probably all this same issue, but I'm not sure why they weren't coming up in my searches last night. Maybe I misspelled something. Oh well.

@code-disaster I'll see if I can test that when I get a chance.

@Spasi
Copy link
Member

Spasi commented Nov 19, 2017

The GLFW issues mentioned have been fixed.

The next LWJGL build (and the 3.1.4 release) will also include glfw/glfw#1115. The Vorbis demo has been updated to handle DPI transitions correctly. Using Java 9 is recommended for perfect behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants