# How to Handle DPI Scaling in Dear ImGui Applications: A Complete Implementation Guide

> Master DPI scaling in Dear ImGui. Learn the three-layer architecture application developers must implement for seamless scaling, from OS awareness to font and style adjustments.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: how-to-guide
- Published: 2026-07-30

---

**Dear ImGui handles DPI scaling through a three-layer architecture that requires OS-level DPI awareness, ImGuiIO configuration flags such as `io.ConfigDpiScaleFonts`, and runtime scaling factors including `style.FontScaleDpi` that the application must wire together before the first frame.**

Dear ImGui (ocornut/imgui) provides robust support for high-DPI monitors through a deliberate design that separates platform responsibilities from UI scaling logic. To handle DPI scaling in Dear ImGui applications effectively, you must coordinate three distinct layers: operating system declarations, backend configuration flags, and internal style variables that control font rasterization and widget geometry.

## The Three-Layer DPI Architecture

DPI scaling in Dear ImGui is intentionally split into three independent concerns that your application must connect:

1.  **OS-Level DPI Awareness**: Prevents the operating system from automatically bitmap-scaling your window, which would produce blurry output. On Windows, this is implemented in `ImGui_ImplWin32_EnableDpiAwareness()` inside `backends/imgui_impl_win32.cpp#L24-L30`. On SDL2, you use the `SDL_WINDOW_ALLOW_HIGHDPI` flag, while GLFW relies on `GLFW_SCALE_TO_MONITOR`.

2.  **ImGuiIO Configuration Flags**: Boolean switches that tell Dear ImGui to automatically update scaling variables when the monitor DPI changes. According to `docs/FAQ.md#L792`, setting `io.ConfigDpiScaleFonts` to `true` enables automatic overwriting of `style.FontScaleDpi`, while `io.ConfigDpiScaleViewports` additionally scales platform windows in the docking branch.

3.  **Internal Scaling Factors**: Runtime values multiplied into geometry calculations. These include `g.Style._MainScale` (accessed via `GetScale()` in `imgui_internal.h#L3348`), `style.FontScaleDpi` (declared in `imgui.h#L2314`), and `io.MouseCursorScale` (defined in `imgui.h#L2375`). These are initialized in `imgui.cpp#L1511` and applied to window sizes at `imgui.cpp#L9217`.

This separation exists because OS awareness is required to get a 1:1 framebuffer, while ImGui’s internal flags provide the library freedom to decide *when* and *how* to apply scaling without breaking user customizations.

## Step 1: Enable OS-Level DPI Awareness

You must declare DPI awareness **before** creating your window. Failure to do so results in the OS scaling the framebuffer automatically, making Dear ImGui’s own scaling redundant and producing blurry fonts.

-   **Windows**: Call `ImGui_ImplWin32_EnableDpiAwareness()` prior to `CreateWindow()`. This helper uses `SetProcessDpiAwarenessContext()` when available, falling back to `SetProcessDPIAware()` on older systems.

-   **SDL2**: Pass the `SDL_WINDOW_ALLOW_HIGHDPI` flag to `SDL_CreateWindow()`, as demonstrated in `examples/example_sdl2_opengl3/main.cpp#L84`.

-   **GLFW**: Set `glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE)` before window creation, or rely on the default high-DPI handling shown in `examples/example_glfw_opengl3/main.cpp#L92`.

-   **macOS**: The native backend already supports HiDPI; no extra call is required.

## Step 2: Configure Automatic DPI Scaling

Once the window is DPI-aware, enable Dear ImGui’s automatic scaling in the docking branch by setting two flags in your initialization code:

```cpp
ImGuiIO& io = ImGui::GetIO();
io.ConfigDpiScaleFonts     = true;  // Auto-updates style.FontScaleDpi
io.ConfigDpiScaleViewports = true;  // Also scales platform windows

```

When `io.ConfigDpiScaleFonts` is enabled, Dear ImGui automatically overwrites `style.FontScaleDpi` whenever the monitor DPI changes, as noted in the initialization code at `imgui.cpp#L1511`. If you prefer manual control, leave these as `false` and assign `style.FontScaleDpi` yourself, as shown in `examples/example_win32_opengl3/main.cpp#L77`.

## Step 3: Understand Internal Scaling Factors

Dear ImGui applies three distinct scales during rendering:

-   **Global UI Scale (`g.Style._MainScale`)**: Retrieved via `GetScale()` in `imgui_internal.h#L3348`, this factor affects widget thickness, window padding, and layout spacing.

-   **Font DPI Scale (`style.FontScaleDpi`)**: Declared in `imgui.h#L2314`, this multiplier is applied to text geometry during glyph rasterization. It allows fonts to scale independently of the global UI scale.

-   **Mouse Cursor Scale (`io.MouseCursorScale`)**: Defined in `imgui.h#L2375`, this scales software-rendered mouse cursors to match the DPI.

You can set an initial manual base scale before the auto-scale system kicks in:

```cpp
ImGuiStyle& style = ImGui::GetStyle();
style.FontScaleDpi = 1.5f;  // Start at 150% font size

```

## Handling Per-Monitor DPI Changes

For applications that span multiple monitors with different DPIs, query the scale factor each frame or when the window moves. The Win32 backend provides `ImGui_ImplWin32_GetDpiScaleForMonitor()` for this purpose. Internally, Dear ImGui stores the current monitor’s scale in `g.CurrentDpiScale` (see `imgui.cpp#L4700`), which the docking branch uses to update viewport scaling automatically when `io.ConfigDpiScaleViewports` is enabled.

If you are not using the docking branch, manually multiply the OS-reported DPI scale (e.g., from SDL’s `SDL_GetWindowDisplayScale` or GLFW’s `glfwGetWindowContentScale`) into `style.FontScaleDpi` and `io.MouseCursorScale` during your main loop.

## Complete Cross-Platform Implementation

The following snippet demonstrates the full initialization flow for Win32, SDL2, and GLFW backends:

```cpp
// ------------------------------------------------------------
// 1. Create a DPI-aware window (platform-specific)
// ------------------------------------------------------------
#if defined(_WIN32)
    // Win32 – ask Windows to make the process DPI-aware
    ImGui_ImplWin32_EnableDpiAwareness();   // → backends/imgui_impl_win32.cpp
    // Create your Win32 window as usual (hwnd)
#elif defined(__APPLE__) && defined(__MACH__)
    // macOS – the native backend already supports HiDPI; no extra call needed
    // Create NSWindow/GLFW window normally
#else
    // SDL2 example (works for both SDL2 and SDL3)
    SDL_Window* window = SDL_CreateWindow(
        "My ImGui App",
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        1280, 720,
        SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
#endif

// ------------------------------------------------------------
// 2. Initialise ImGui (common to all back-ends)
// ------------------------------------------------------------
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();

// Enable ImGui's own DPI handling (requires docking branch)
// This will automatically rewrite style.FontScaleDpi whenever the monitor DPI changes.
io.ConfigDpiScaleFonts     = true;   // scales fonts
io.ConfigDpiScaleViewports = true;   // also scales platform windows (if you use viewports)

// Optional: set a manual base scale before the auto-scale runs
ImGuiStyle& style = ImGui::GetStyle();
style.FontScaleDpi = 1.2f;           // start at 120% font size

// ------------------------------------------------------------
// 3. Backend-specific init (example for Win32)
// ------------------------------------------------------------
#if defined(_WIN32)
    ImGui_ImplWin32_Init(hwnd);
#elif defined(__APPLE__) && defined(__MACH__)
    ImGui_ImplOSX_Init();
#else
    ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
#endif

// ------------------------------------------------------------
// 4. Main loop – ImGui will now use the DPI-aware scalings automatically
// ------------------------------------------------------------
while (!done)
{
    // Platform event handling...
    ImGui_Impl..._NewFrame();
    ImGui::NewFrame();

    // Your UI code here
    ImGui::Text("DPI-aware window");

    ImGui::Render();
    ImGui_Impl..._RenderDrawData(ImGui::GetDrawData());
}

```

## Summary

-   **OS awareness comes first**: Call `ImGui_ImplWin32_EnableDpiAwareness()` or use `SDL_WINDOW_ALLOW_HIGHDPI` before creating the window to prevent OS-level bitmap scaling.
-   **Enable automatic handling**: Set `io.ConfigDpiScaleFonts` and `io.ConfigDpiScaleViewports` to `true` in the docking branch to let Dear ImGui manage `style.FontScaleDpi` automatically.
-   **Three scales control rendering**: `g.Style._MainScale` for UI geometry, `style.FontScaleDpi` for text, and `io.MouseCursorScale` for cursors.
-   **Manual fallback**: If not using the docking branch, query the monitor DPI via your platform API and assign the scale factor to `style.FontScaleDpi` directly.

## Frequently Asked Questions

### Does DPI scaling require the docking branch of Dear ImGui?

The automatic scaling flags `io.ConfigDpiScaleFonts` and `io.ConfigDpiScaleViewports` are only available in the docking branch. If you are using the master branch, you must manually calculate the DPI scale using `ImGui_ImplWin32_GetDpiScaleForMonitor()` or equivalent platform functions, then assign the value to `style.FontScaleDpi` each frame.

### Why do my fonts appear blurry even after calling EnableDpiAwareness?

Blurriness indicates that the OS is still bitmap-scaling your framebuffer. Verify that you called `ImGui_ImplWin32_EnableDpiAwareness()` **before** creating the window, and ensure your graphics API backend (OpenGL, DirectX, Vulkan) is creating a backbuffer at the full native resolution rather than a scaled resolution.

### How do I calculate the correct scale factor for a specific monitor?

On Windows, use `ImGui_ImplWin32_GetDpiScaleForMonitor()` provided in the Win32 backend. For SDL2, call `SDL_GetWindowDisplayScale(window)`. For GLFW, use `glfwGetWindowContentScale(window, &xscale, &yscale)`. Multiply this value by your base `style.FontScaleDpi` to get the final scale.

### Can I use different scale factors for different viewports when using multi-viewports?

Yes. When `io.ConfigDpiScaleViewports` is enabled in the docking branch, Dear ImGui automatically applies per-viewport scaling based on the monitor each viewport resides on. The internal variable `g.CurrentDpiScale` (see `imgui.cpp#L4700`) tracks this per-viewport value, ensuring that platform windows render at the correct DPI regardless of which monitor they occupy.