-
-
Notifications
You must be signed in to change notification settings - Fork 10.3k
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
DPI handling and multiple screens #1676
Comments
Maybe SDF fonts? Rendering is simple/fast, they scale to any DPI, and you get prety things like outlines or shadows, and subpixel rendering for free. |
One also need to distinguish between Retina displays (on macOS), which are also hi-dpi screens, and regular hi-dpi external screens. On a Retina display on macOS there is a pixel ratio of 2.0 between the size of the FrameBuffer, and the size of the application window. This means that to get shap fonts, at least with the current settings, you need to load the font at 2x the size, and then set And then there is the hi-dpi scaling factor ( At least that's how I implemented it when I dabbled into this for libigl. I ended up checking the Note that screens with different DPI is possible on macOS natively, but is only possible on Linux with Wayland. X only support a global DPI setting. On the backend side, for GLFW, I get the pixel ratio as This approach I described is a bit annoying because I make all my menu size be proportional to the hidpi_scaling factor. At the time I couldn't figure out a better way to apply a global zoom to ImGui that also affects padding, etc. Maybe that's something to think about. And +1 for SDF fonts, outlines and arbitrary zoom would be pretty cool things to have. Hope this helps. |
Is there a reliable way to simulate it for testing purposes? I don’t have HiDPI/Retina display and using some software emulators didn’t work for me. |
OK, found a way to simulate it on macOS here: https://gist.github.com/simX/3191869 |
If you are interested in DPI handling, imgui_impl_win32.cpp in the Viewport branch include a few extra helpers:
The particularity of those helpers if they they compile without the latest 10-ish Windows SDK and they don't require the EXE to link with Windows 10-era DLL. They manually load functions from Windows DLL and redefine flags/enums locally, which appears to be standard way to achieve both. Most big software would do the dynamic loading fulfill the "can run on older Windows" requirement, but few projects needs to care about "can build with older SDK". |
Any news on this? |
I wanted to leave a note here on an approach I just took to handle high DPI at any resolution for a game engine. I'm so impressed by how easy it was to override data in ImGui! I don't need high DPI resolution, just a reasonable upscale. I'm doing post-processing effects on the frame anyway, so my approach is to: 1) render scene 2) render ImGui widgets to texture via FBO. My FBO size is fixed, and much smaller than high DPI resolution. The only change I needed to make was after calling
I was just really excited that it was so easy to do what I wanted and wanted to share. I scale my window size based on the desktop resolution (for windowed mode I hack 96% of the desktop height to account for OS titlebar/chrome) and render the FBO to screen. My ImGui widgets (and fonts) are now normalized independently of the resolution, and look the same on my Win8 desktop and Win10 laptop. The FBO render is relatively cheap, so I also get a significant performance boost by rendering to texture. |
… instead of calling Platform_GetWindowDpiScale() before the platform window creation. Might even tentatively see if things work out without Platform_GetWindowDpiScale. (#1676)
Here's how I'm implementing HiDPI support for the ImGui integration in Magnum with latest ImGui (1.66b). Hopefully this info will be useful to somebody :) In order to seamlessly account for how HiDPI is done on Linux, Android, macOS/iOS and Windows, I'm exposing these three parameters (all of them two-dimensional float vectors):
On Windows, Linux and Android, Then, on the ImGui side:
The following web demo is HiDPI-enabled and it should show everything crisp and in the same physical size on both normal and Retina screens: https://magnum.graphics/showcase/imgui/ |
@mosra How do you handle when windows are dragged between two monitors with different DPI? The traditional method is to keep rendering at the highest of the needed DPI then downsample on the other monitor only switching to the lower DPI render once the window fully exists on the lower-DPI monitor. This is a case often missed by most things though and it can make sizing of things a bit odd otherwise. ^.^; |
@OvermindDL1 I'm able to respond to DPI change events and adjust the three above parameters based on that. All with the assumption that DPI change event ( |
…ue from io.DisplayFramebufferScale). This is to allow render functions being written without pulling any data from ImGuiIO, allowing incoming multi-viewport feature to behave on Retina display and with multiple displays. If you are not using a custom binding, please update your render function code ahead of time, and use draw_data->FramebufferScale instead of io.DisplayFramebufferScale. (#2306, #1676) Examples: Metal, OpenGL2, OpenGL3: Fixed offsetting of clipping rectangle with ImDrawData::DisplayPos != (0,0) when the display frame-buffer scale scale is not (1,1). While this doesn't make a difference when using master branch, this is effectively fixing support for multi-viewport with Mac Retina Displays on those examples. (#2306) Also using ImDrawData::FramebufferScale instead of io.DisplayFramebufferScale. Examples: Clarified the use the ImDrawData::DisplayPos to offset clipping rectangles.
I'm currently implementing Imgui on my glfw/vulkan engine. I used the imgui_impl_vulkan.cpp and imgui_impl_vulkan.h to ease the integration unfortunately I got a DPI problem (imgui used only 1/4 of the screen and the mouse acted like it was fullscreen).
it fixed most of my scissor related problems
Which fixed the rest |
Thank you @newincpp . I assume you are running on Mac OSX with a Retina screen? (Afaik DisplayFramebufferScale is only > 1 on OSX). I have now applied to the Vulkan back-end similar changes made recently to Metal/GL2/GL3 renderer to handle this via the |
Hey, I am currently trying to implement a rust backend for ImGui. Properly handling DpiScale seems to be a huge challenge for me and I could not find a better place to ask this. Sorry if this is the wrong place. The problem I have is that there seems to currently be no way to handle multiple monitors with different DPI. On windows, cursor and window positions/sizes are all in physical coordinates, which I can pass to ImGui without a problem, however, incorporating the necessary UI "zoom" factor is something I don't know how to do. Setting the framebuffer scale is not appropriate since it is a global setting instead of per viewport. Setting viewport.DpiScale seems to have no effect for me (hope I am not doing anything wrong on this part). In the FAQ, I can see that there currently are workarounds for handling the font dpi properly, but there seems to be no discussion on how to properly scale the UI as a whole, which would be necessary on high-dpi monitors to not make everything too small to read. |
I've been toying with DPI handling recently. Part of this is motivated by the work on Multiple Viewport #1542 which are making this topic trickier than it already was before. Some (early and experimental) commits are being pushed to the Viewport branch.
This is mostly a thread to link commits too, write down some notes and eventually attract feedback, suggestion or solutions.
The work involve
Single viewport DPI handling can be handled by the application at the moment (by using a larger font and scaling e.g. the style appropriately), however we ought to clarify and simplify the work that needs to be done, and support it in the examples. The position/size of windows relative to their viewport also ideally ought to be scaled.
Multi viewport DPI handling involve changing those depending on where we are located: moving an imgui window from screen 1 to screen 2 can affect sizing. Effectively calling Begin() can put you in a different DPI context. It's trickier to solve because e.g. our font system currently don't allow for arbitrary quality scaling so we may have to come up with scheme to make that more transparent eventually. Likewise for style (and scaling style sizes is a lossy operation).
Platform-side: At the moment I am focusing on Windows. I imagine (hope) MacOS will be easier but I don't have reliable access to a Mac right now. I don't know about Linux. The platform dependent part of the work is not very complex. Under Windows, consideration of backward compatibility with older versions of Windows and Windows SDK makes the code more messy, but nothing really hard.
The text was updated successfully, but these errors were encountered: