imgui-node-editor icon indicating copy to clipboard operation
imgui-node-editor copied to clipboard

Fonts blurry on HiDPI

Open up-to-you opened this issue 4 years ago • 10 comments

Firstly, thanks for such awesome tool!

I plugged libfreetype and successfully loaded Fira Code font, but fonts are still blurry on 4k, i tried to adjust fringeScale, but it didn't made any sharpness, only overall scale, that can be also achieved with glfw window flags.

I see a lot of commented code related to fringeScale in your recent commits (Blueprints example), but can't spot the place where do i need to start my further investigation.

I know that the issue more likely must be submitted directly to imgui project, but there is custom/modified version of imgui in your project (especially with fringeScale).

Can you suggest the direction for further issue solving ?

Fonts are loaded in a such way:

    ImGuiIO& io = ImGui::GetIO();
    ImFontConfig font_config = ImFontConfig();
    font_config.OversampleH = 7;
    font_config.OversampleV = 5;

    io.Fonts->AddFontFromFileTTF("../FiraCode-Regular.ttf", 16.0f, &font_config);

    unsigned int flags = ImGuiFreeType::ForceAutoHint;
    ImGuiFreeType::BuildFontAtlas(io.Fonts, flags);

    unsigned char* out_pixels;
    int out_width;
    int out_height;
    io.Fonts->GetTexDataAsRGBA32(&out_pixels, &out_width, &out_height);

OS: Ubuntu 19.10, libfreetype 2.10.1

up-to-you avatar Dec 09 '19 21:12 up-to-you

@up-to-you This may be entirely irrelevant, but you might be getting a really low imgui render if you're using something in your OS that increases the size of your windows so that they are not tiny on a 4k monitor.

I am on Windows 10, but I found what is happening with blurry blueprints at zoomed-in-4k in the Example code. The ImGui::GetIO().DisplaySize is controlling the imgui render resolution in this concept. When I change Window's DPI scale using the "Change the size of text, apps, and other items" option in the display settings, this number changes when the window is full screen. Basically, the number drops greatly when I use zoom settings over 100%. So when I have window zoom off at 4k, it renders ImGui at 3840x3840, but when I change the scale to 250%, ImGui renders at 1536 x 1536. So basically when the OS wants a bigger window, the examples reduce the texture size that imgui draws to. This this indeed makes things bigger - but it's blurry. This is a good implementation because faithfully maintaining the relationships between the elements while using ImGui's scaling functions is probably nigh impossible. The current implementation is a bit blurry, but it doesn't break the element relationships when you zoom in and out.

Here's where that is happening.... I used "breakpoints when a variable value changes" and found that DisplaySize was being changed dynamically in this order...

  1. Entry.cpp has a main loop at the bottom that calls frame()...
  2. frame() is a lambda in that same file that calls...
  3. ImGui_ImplWin32_NewFrame() in the imgui_impl_ win32.cpp file...
  4. which has this code:

// Setup display size (every frame to accommodate for window resizing) RECT rect; ::GetClientRect(g_hWnd, &rect); io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));

So that's the hook. If you want really sharp results, I would re-implement this so that io.DisplaySize is kept at an appropriate number for the window size at 4k... (since its the window draw surface) but scale things up using a different method:

  1. Reload the font so that its bigger (A good starting point might be 12point * zoom factor)
  2. Rebuild the font atlas
  3. call style.ScaleAllSizes()
  4. At this point the only thing that is tiny is the special pin icons in Blueprints.cpp. So those will need their own call ( Still working on this).

hope this is useful!

crolando avatar Feb 15 '20 03:02 crolando

For the previous issue, I found that the issue was actually that the windows process was not DPI-Aware. When I changed the visual studio option to enable DPI-Awareness for the blueprint project, this issue went away, and actually the scaling worked fine.

Others can do this by going into the Blueprint's project properties, and going to: Configuration Properties > Manifest Tool > All Options > Dpi Awareness I set my value to "High DPI Aware", which is a slightly older mode that works down to windows 8.1.

crolando avatar Feb 15 '20 03:02 crolando

@up-to-you , @crolando

Can you checkout an updated version of develop branch? I was tinkering with HiDPI support there and I think I got it working both on Windows and with GLFW3 at the same time. Out of Windows, macOS, and Linux the last one is least tested. If GLFW3 return expected values I think you will get desired result.

Right now example app regenerate font atlas when DPI change.

As for keeping font sharp when zooming. I had to modify font generator to achieve such result. In imstb_truetype.h it was a matter of disabling calls to stbtt__h_prefilter and stbtt__v_prefilter in stbtt_PackFontRangesRenderIntoRects.

With FreeType2 it was more complicated. I remember adding support for DPI scaling so font will be rasterized with greater precision without affecting metrics. Yet I cannot recall where is that code now. I will propose it as a PR when I find it.

thedmd avatar Dec 05 '20 17:12 thedmd

@thedmd I've been testing this on windows and it works great for me. I have a 4k monitor and did lots of scaling tests in 4k. Then I did 1080p and did more scaling tests. everything looks sharp. I tried to get GLFW3 to be the backend by messing with the cmakelists.txt and vs project settings but gave up - I don't really understand what to edit to get that working.

crolando avatar Dec 05 '20 20:12 crolando

@crolando Are you trying to use GLFW3 on Windows?

thedmd avatar Dec 05 '20 20:12 thedmd

@thedmd yes that's what I was trying for the 2nd test. Is that valid?

crolando avatar Dec 05 '20 20:12 crolando

You can use this script to find glfw3 on windows: Findglfw3.cmake.txt

Remove .txt and put it in misc/cmake-modules/Findglfw3.cmake.

Change path to GLFW3 here:

set(GLFW_ROOT_DIR c:/Users/thedmd/Desktop/ProjectX-Deps/glfw-3.3.2.bin.WIN64)
set(GLFW_VERSION_STRING 3.2.2)

To switch backend you can hack main config and add:

add_definitions(
    -DBACKEND_CONFIG=IMGUI_GLFW
)

You may also select OpenGL as a backend by setting:

add_definitions(
    -DRENDERER_CONFIG=IMGUI_OGL3
)

Ideally these should be options in CMake, but I didn't had time to make them that way.

I'm glad HiDPI is working for you. :)

thedmd avatar Dec 05 '20 20:12 thedmd

@up-to-you , @crolando

Can you checkout an updated version of develop branch? I was tinkering with HiDPI support there and I think I got it working both on Windows and with GLFW3 at the same time. Out of Windows, macOS, and Linux the last one is least tested. If GLFW3 return expected values I think you will get desired result.

Right now example app regenerate font atlas when DPI change.

As for keeping font sharp when zooming. I had to modify font generator to achieve such result. In imstb_truetype.h it was a matter of disabling calls to stbtt__h_prefilter and stbtt__v_prefilter in stbtt_PackFontRangesRenderIntoRects.

With FreeType2 it was more complicated. I remember adding support for DPI scaling so font will be rasterized with greater precision without affecting metrics. Yet I cannot recall where is that code now. I will propose it as a PR when I find it.

Hi, I tried your fix on DX11 . It's working well for the editor part , the nodes texts are not blurry anymore . But the other texts of the UI (so all that is not related to the node editor part) are sharpened , without anti aliasing :-/

SadE54 avatar Nov 18 '21 08:11 SadE54

You can add extra font with higher oversample and use if for node editor only. Changing font before ed::Begin and ed::Resume and restoring after ed::End and ed::Suspend should do the trick.

In out editor I'm using three fonts: one with high DPI (x4), one with small DPI (x2) and one regular. First two are used depending on zoom level in node editor, last is used for all not scaled UI elements. Fonts are changed according to rule above.

Does this help?

thedmd avatar Nov 18 '21 09:11 thedmd

yeah thx for the tip , I will try that.

SadE54 avatar Nov 18 '21 09:11 SadE54