Determine DPI?


kgamiel wrote on Sunday, June 02, 2013:

In a cross-platform glfw application, what is the preferred way to determine dpi of current display? Specifically on OSX and Linux.


elmindreda wrote on Monday, June 03, 2013:

Not with 2.7, but you can with 3.0.


Can you elaborate on how? I’ve seen the changes for GLFW 3.0 mentions high DPI and I’ve found glfwSetFramebufferSizeCallback, but I have no idea how to initialize a window in GLFW that uses windows DPI or how to specify the window and framebuffer size myself. The result is that I have a very tiny GLFW window on my laptop monitor and have to squint to see use my GUI :wink:


Window creation sets the size of the window in screen coordinates, once you’ve done this you can then query the framebuffer size with glfwGetFramebufferSize and use the ratio between screen size and framebuffer size to scale your UI.


Well in my case windows scaling is set to 250% (verified with GetDpiForWindow(hwnd)) but my window and framebuffer have the same size, so it looks like glfw ignores the dpi.

I’m on 3.2.1 and using an intel GPU btw. Haven’t tried if using my nvidia GPU changes anything, but I’m assuming it’s handled by windows and GPU/driver independent.


Ignore my answer above, I misunderstood the question - I thought you had framebuffer size vs window size issues.

You can query the DPI through the glfwGetMonitorPhysicalSize function along with the math listed there.


No I would actually love to have that issue, because that would mean progress. :smiley:

I’m not sure how calculating the DPI helps me. I already know the DPI from windows own API (but using glfw of course makes it slightly easier.)

My problem is that my system has a scaling mode of 250%. When I call glfwCreateWindow with width and height 640x480 I would expect a window with size 1600x1200 and a framebuffer size of 640x480. What I get is a window and framebuffer size of 640x480 and no way (that I’ve found) to change. So how do I get GLFW to respect windows scaling mode?


The window size you request is in screen coordinates. So if you want a window size of 1600x1200 screen coordinates you ask for one of that size.

The OS pixel ratio of framebuffer to screen coordinates and DPI are two separate things. In your case you have 1:1 pixels to screen coords (I think this is always the case for Windows OS but I’m not sure).

So you need to alter your application code to handle this. Once you’ve calculated the DPI you then need to scale your window size and UI size to suit. If you want to render to a lower resolution then scale up you’ll need to use a render target and then scale, but scaling the UI would give better quality.