From 3c6c5692b894252cdf3c5e6dae7cc5405b1f07b2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 15 Sep 2025 16:40:10 +0200 Subject: [PATCH] Examples: Win32+Vulkan, GLFW+Metal: Fixed not applying content scale. (#8921, #8756) Somehow it breaks in Win32+OpenGL3 example: when enabled Win32 applies some extra scale. --- docs/CHANGELOG.txt | 3 +- examples/example_glfw_metal/main.mm | 47 ++++++++++++++----------- examples/example_win32_opengl3/main.cpp | 12 +++++-- examples/example_win32_vulkan/main.cpp | 14 ++++++-- 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index db4587e69..766473516 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -107,7 +107,8 @@ Other Changes: while navigating and to not close popup automatically. - CI: Updates Windows CI to use a more recent VulkanSDK. (#8925, #8778) [@yaz0r] - Examples: Android: Android+OpenGL3: update Gradle project (#8888, #8878) [@scribam] -- Examples: GLFW+OpenGL2, GLFW+Vulkan: Fixed not applying content scale. (#8921, #8756) +- Examples: GLFW+OpenGL2, GLFW+Vulkan, GLFW+Metal, Win32+Vulkan: Fixed not applying + content scale consistently with other examples. (#8921, #8756) - Backends: SDL3: use SDL_GetWindowDisplayScale() on Mac to obtain DisplayFrameBufferScale, fixing incorrect values during resolution changes e.g. going fullscreen. (#8703, #4414) [@jclounge] diff --git a/examples/example_glfw_metal/main.mm b/examples/example_glfw_metal/main.mm index 4ec8b5927..cc86d655c 100644 --- a/examples/example_glfw_metal/main.mm +++ b/examples/example_glfw_metal/main.mm @@ -27,17 +27,40 @@ static void glfw_error_callback(int error, const char* description) int main(int, char**) { + glfwSetErrorCallback(glfw_error_callback); + if (!glfwInit()) + return 1; + + // Create window with graphics context + float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + GLFWwindow* window = glfwCreateWindow((int)(1280 * main_scale), (int)(800 * main_scale), "Dear ImGui GLFW+Metal example", nullptr, nullptr); + if (window == nullptr) + return 1; + // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls - // Setup style + // Setup Dear ImGui style ImGui::StyleColorsDark(); //ImGui::StyleColorsLight(); + // Setup scaling + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) + style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose) + + id device = MTLCreateSystemDefaultDevice(); + id commandQueue = [device newCommandQueue]; + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOpenGL(window, true); + ImGui_ImplMetal_Init(device); + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. @@ -54,24 +77,6 @@ int main(int, char**) //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf"); //IM_ASSERT(font != nullptr); - // Setup window - glfwSetErrorCallback(glfw_error_callback); - if (!glfwInit()) - return 1; - - // Create window with graphics context - glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - GLFWwindow* window = glfwCreateWindow(1280, 800, "Dear ImGui GLFW+Metal example", nullptr, nullptr); - if (window == nullptr) - return 1; - - id device = MTLCreateSystemDefaultDevice(); - id commandQueue = [device newCommandQueue]; - - // Setup Platform/Renderer backends - ImGui_ImplGlfw_InitForOpenGL(window, true); - ImGui_ImplMetal_Init(device); - NSWindow *nswin = glfwGetCocoaWindow(window); CAMetalLayer *layer = [CAMetalLayer layer]; layer.device = device; diff --git a/examples/example_win32_opengl3/main.cpp b/examples/example_win32_opengl3/main.cpp index 8748ab777..648d0d969 100644 --- a/examples/example_win32_opengl3/main.cpp +++ b/examples/example_win32_opengl3/main.cpp @@ -36,11 +36,14 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // Main code int main(int, char**) { + // Make process DPI aware and obtain main monitor scale + //ImGui_ImplWin32_EnableDpiAwareness(); // FIXME: This somehow doesn't work in the Win32+OpenGL example. Why? + float main_scale = ImGui_ImplWin32_GetDpiScaleForMonitor(::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY)); + // Create application window - //ImGui_ImplWin32_EnableDpiAwareness(); WNDCLASSEXW wc = { sizeof(wc), CS_OWNDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr }; ::RegisterClassExW(&wc); - HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+OpenGL3 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, nullptr, nullptr, wc.hInstance, nullptr); + HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+OpenGL3 Example", WS_OVERLAPPEDWINDOW, 100, 100, (int)(1280 * main_scale), (int)(800 * main_scale), nullptr, nullptr, wc.hInstance, nullptr); // Initialize OpenGL if (!CreateDeviceWGL(hwnd, &g_MainWindow)) @@ -67,6 +70,11 @@ int main(int, char**) ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); + // Setup scaling + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) + style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose) + // Setup Platform/Renderer backends ImGui_ImplWin32_InitForOpenGL(hwnd); ImGui_ImplOpenGL3_Init(); diff --git a/examples/example_win32_vulkan/main.cpp b/examples/example_win32_vulkan/main.cpp index aa80e8696..b4b3a0860 100644 --- a/examples/example_win32_vulkan/main.cpp +++ b/examples/example_win32_vulkan/main.cpp @@ -342,11 +342,14 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // Main code int main(int, char**) { + // Make process DPI aware and obtain main monitor scale + ImGui_ImplWin32_EnableDpiAwareness(); + float main_scale = ImGui_ImplWin32_GetDpiScaleForMonitor(::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY)); + // Create application window - //ImGui_ImplWin32_EnableDpiAwareness(); WNDCLASSEXW wc = { sizeof(wc), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr }; ::RegisterClassExW(&wc); - HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+Vulkan Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, nullptr, nullptr, wc.hInstance, nullptr); + HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+Vulkan Example", WS_OVERLAPPEDWINDOW, 100, 100, (int)(1280 * main_scale), (int)(800 * main_scale), nullptr, nullptr, wc.hInstance, nullptr); ImVector extensions; extensions.push_back("VK_KHR_surface"); @@ -369,7 +372,7 @@ int main(int, char**) // Show the window // FIXME: Retrieve client size from window itself. ImGui_ImplVulkanH_Window* wd = &g_MainWindowData; - SetupVulkanWindow(wd, surface, 1280, 800); + SetupVulkanWindow(wd, surface, (int)(1280 * main_scale), (int)(800 * main_scale)); ::ShowWindow(hwnd, SW_SHOWDEFAULT); ::UpdateWindow(hwnd); @@ -384,6 +387,11 @@ int main(int, char**) ImGui::StyleColorsDark(); //ImGui::StyleColorsLight(); + // Setup scaling + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) + style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose) + // Setup Platform/Renderer backends ImGui_ImplWin32_Init(hwnd); ImGui_ImplVulkan_InitInfo init_info = {};