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

Screen resolution change cannot be handled correctly on windows 11 platform #6556

Closed
cliche9 opened this issue Jun 28, 2023 · 11 comments
Closed

Comments

@cliche9
Copy link

cliche9 commented Jun 28, 2023

Thanks for creating such an amazing GUI framework, it's really great!

Here is my issue:

Version/Branch of Dear ImGui:

Version: 1.89.6
Branch: docking

Back-end/Renderer/Compiler/OS/Dependencies

Back-ends: GLFW
Renderer: OpenGL
Compiler: MSVC 2022
Operating System: Windows 11
Dependencies: imgui-node-editor and GLFW&OpenGL related(glm, glad, etc.)

My Issue/Question:

  1. When I set the screen resolution scale to 100%, the program works fine.
    1

  2. When the program is running, I scale the screen resolution to 125%, the program goes black.
    2

  3. When my screen resolution is set to 125%, the program goes wired. The mouse cannot operate correctly, as if a single mouse position occupies multiple pixels, making it impossible to perform proper positioning and selection operations.
    3

It seems like the screen's dpi change cannot be handled correctly. I don't know how to address this problem.

@ocornut ocornut added the dpi label Jun 28, 2023
@ocornut
Copy link
Owner

ocornut commented Jun 28, 2023

  1. When the program is running, I scale the screen resolution to 125%, the program goes black.

This doesn't seem to happen in our example. Can you test the example_glfw_opengl3 example to compare?

  1. When my screen resolution is set to 125%, the program goes wired. The mouse cannot operate correctly,

I can think of many variants of this, which is generally confusing for users/developers, but only on other backends and platforms. But GLFW in particular enable DPI awareness and there are no known problem on GLFW+OpenGL+Windows. Likewise can you check example_glfw_opengl3 ?

Use Tools->Metrics and Tools->DebugLog inputs to try to inspect things.

(PS: You can drag or paste images/gifs into messages without needing to host them elsewhere.)

@cliche9
Copy link
Author

cliche9 commented Jun 28, 2023

  1. When the program is running, I scale the screen resolution to 125%, the program goes black.

This doesn't seem to happen in our example. Can you test the example_glfw_opengl3 example to compare?

  1. When my screen resolution is set to 125%, the program goes wired. The mouse cannot operate correctly,

I can think of many variants of this, which is generally confusing for users/developers, but only on other backends and platforms. But GLFW in particular enable DPI awareness and there are no known problem on GLFW+OpenGL+Windows. Likewise can you check example_glfw_opengl3 ?

Use Tools->Metrics and Tools->DebugLog inputs to try to inspect things.

(PS: You can drag or paste images/gifs into messages without needing to host them elsewhere.)

example_glfw_opengl3 works fine on any conditions, I just checked my code, it has a very similar main loop like example_glfw_opengl3, maybe I should check imgui-node-editor. Anyway, thanks for your answer

@cliche9
Copy link
Author

cliche9 commented Jun 29, 2023

I've checked my code. Finally I found that when I recreateFontAtlas when the program is running, the program went black. Is it illegal to rebuild Dear ImGui Font Style?
Here is my recreateFontAtlas code:

void Application::recreateFontAtlas() {
    printf("Recreate font triggered\n");
    ImGuiIO& io = ImGui::GetIO();

    IM_DELETE(io.Fonts);

    io.Fonts = IM_NEW(ImFontAtlas);

    ImFontConfig config;
    config.OversampleH = 4;
    config.OversampleV = 4;
    config.PixelSnapH = false;

    defaultFont = io.Fonts->AddFontFromFileTTF("../assets/font/Play-Regular.ttf", 18.0f, &config);
    headerFont  = io.Fonts->AddFontFromFileTTF("../assets/font/Cuprum-Bold.ttf",  20.0f, &config);

    io.Fonts->Build();
}

@ocornut
Copy link
Owner

ocornut commented Jun 29, 2023

Wow wow you should not delete and reaffect io.Fonts. You can call its clear function, load new functions and then call the backend function to destroy/recreate fonts.

@cliche9
Copy link
Author

cliche9 commented Jun 29, 2023

Wow wow you should not delete and reaffect io.Fonts. You can call its clear function, load new functions and then call the backend function to destroy/recreate fonts.

Would you please explain more about how to reload io.Fonts or is there a FAQ mentioned this question?

@ocornut
Copy link
Owner

ocornut commented Jun 29, 2023

Replace your delete/new sequence by calls to the clear function + call the destroy/create function declared in imgui_impl_opengl3.h

This will be streamlined and made simpler with future work.

@cliche9
Copy link
Author

cliche9 commented Jun 29, 2023

Replace your delete/new sequence by calls to the clear function + call the destroy/create function declared in imgui_impl_opengl3.h

This will be streamlined and made simpler with future work.

Thanks! I solved the black screen problem by the replacement.

  1. When my screen resolution is set to 125%, the program goes wired. The mouse cannot operate correctly, as if a single mouse position occupies multiple pixels, making it impossible to perform proper positioning and selection operations.

Additionally, about question 3, I remove all the code about changing io.DisplaySize, io.DisplayFramebufferScale and io.MousePos in my newFrame function, now it works fine!

@ocornut
Copy link
Owner

ocornut commented Jun 29, 2023

Closing this.

Note that your approach will have some issues on Mac by default. We're working on standardizing a few things to make things works for everyone neatly.

@ocornut ocornut closed this as completed Jun 29, 2023
@wangzihe
Copy link

wangzihe commented Aug 24, 2023

@ocornut I am trying to use the above code to reload fonts when there is a change in DPI scale. However, I kept running into the following assert:

Assertion failed: cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas), file imgui_draw.cpp, line 2370

The assertion is really with io_ref.Fonts->Build. I don't know what this assertion is checking. Could you share some light on this? The assertation only happens when I tried to clear old fonts and then reload the font. It works okay when I first loaded the font.

Here is the system configuration:

Dear ImGui 1.89.4 (18940)
--------------------------------

sizeof(size_t): 4, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: _WIN32
define: _MSC_VER=1934
define: _MSVC_LANG=201402
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------

io.BackendPlatformName: imgui_impl_glfw
io.BackendRendererName: imgui_impl_opengl3

Here is the snippet of code I used to load/reload fonts when DPI scale changes.

  • To load/reload font
    int dpi_scale_int = round(dpi_scale);
    ImFont* font = io_ref.Fonts->AddFontFromFileTTF(
        "./src/fonts/NotoSansSC-Light.otf",
        19.0f * dpi_scale, NULL,
        io_ref.Fonts->GetGlyphRangesChineseFull());
    if (font == NULL) {
        LOG(ERROR) << "Failed to load font file";
    }

    // merge in icons from Font Awesome
    ImFontConfig icons_config;
    icons_config.MergeMode = true;
    icons_config.PixelSnapH = true;
    io_ref.Fonts->AddFontFromFileTTF("./src/external/fa-solid-900.ttf",
        15.0f * dpi_scale, &icons_config, icons_ranges);

    io_ref.Fonts->Build();
  • To clear font
    ImGuiIO& io_ref = ImGui::GetIO();
    if (io_ref.Fonts->Fonts.size()) {
        io_ref.Fonts->ClearFonts();
    }
    ImGui_ImplOpenGL3_DestroyFontsTexture();
    ImGui_ImplOpenGL3_CreateFontsTexture();

@pengqiyu
Copy link

aboute question 3, you can modify imgui_impl_win32.cpp -> ImGui_ImplWin32_WndProcHandler function, event WM_NCMOUSEMOVE,
'''
io.AddMouseSourceEvent(mouse_source);
float dpiScale = ImGui_ImplWin32_GetDpiScaleForHwnd(hwnd);
int titleBarHeight = GetSystemMetrics(SM_CYCAPTION);
RECT rect;
GetWindowRect(hwnd, &rect);
io.AddMousePosEvent((float)(mouse_pos.x - rect.left) / dpiScale + rect.left, (float)(mouse_pos.y - rect.top - titleBarHeight) / dpiScale + rect.top + titleBarHeight);
'''

@KarlHedlund
Copy link

Just want to chime in that if you ended up in this thread while trying to solve DPI scaling and you've still got a black window, don't call io.Fonts->Build();

Here's what worked for me, calling it outside of NewFrame:

        io.Fonts->Clear();
        auto font1 = io.Fonts->AddFontFromFileTTF("C:/Windows/Fonts/Arial.ttf", 16);
        ImGui_ImplOpenGL3_DestroyFontsTexture();
        IM_ASSERT(ImGui_ImplOpenGL3_CreateFontsTexture());

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

5 participants