# How to Handle DPI Scaling and High-DPI Displays in Dear ImGui

> Master DPI scaling and high-DPI displays in Dear ImGui with platform settings, IO flags, and viewport scaling for crisp UIs. Learn how to automatically adjust fonts and geometry.

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

---

**TLDR:** Dear ImGui handles high-DPI displays through a combination of platform-specific DPI awareness settings, IO configuration flags, and per-viewport scaling factors that automatically adjust fonts and UI geometry.

Managing DPI scaling is essential when building desktop applications that must look crisp on Retina displays and 4K monitors. The ocornut/imgui repository provides built-in mechanisms to handle high-DPI displays through framebuffer scaling and viewport-based DPI detection. This guide explains how to configure your application using the actual source implementation found in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h), [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), and the various platform backends.

## Core DPI Scaling Mechanisms

Dear ImGui's approach to high-DPI support centers on three key data structures that communicate display density from the platform layer to the rendering pipeline.

### DisplayFramebufferScale and FramebufferScale

The global DPI scale factor is stored in **`ImGuiIO::DisplayFramebufferScale`** ([`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h#L2420), which represents the ratio between pixels and screen coordinates for the main display. When the multi-viewport feature is enabled, each `ImGuiViewport` maintains its own `FramebufferScale` derived from the platform window's DPI. According to the source in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h#L3486), the **`Viewport::Scale`** field carries this per-monitor scaling factor, ensuring that UI geometry remains crisp when windows move between displays of different densities.

### Runtime DPI Tracking

During `NewFrame()`, the backend updates **`CurrentDpiScale`** ([`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp#L4688) based on the active monitor. This value propagates to `ImDrawData::FramebufferScale`, which the renderer uses to calculate final pixel positions. All built-in widgets automatically respect this scale when computing sizes, so standard ImGui controls render sharply without manual intervention.

## Platform-Specific DPI Awareness Setup

Before ImGui can apply scaling, the underlying platform window must report accurate DPI information. Each backend requires specific initialization to enable high-DPI support.

### Windows (Win32)

For Win32 applications, call **`ImGui_ImplWin32_EnableDpiAwareness()`** before creating your window. This helper function, defined in [`imgui_impl_win32.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_win32.cpp#L24-L30), invokes `SetProcessDpiAwarenessContext()` to declare the process as per-monitor DPI aware. Alternatively, you can call Windows API functions directly:

```cpp
ImGui_ImplWin32_EnableDpiAwareness();   // Recommended helper

// Or manually:
::SetProcessDPIAware();  // System DPI aware (legacy)
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);  // Modern

```

### SDL2

When creating your window with SDL2, pass the **`SDL_WINDOW_ALLOW_HIGHDPI`** flag and ensure Windows DPI awareness is set:

```cpp
SDL_Window* window = SDL_CreateWindow(
    "Demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
    1280, 720,
    SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);

::SetProcessDPIAware();  // Windows-specific

```

### GLFW

GLFW applications should enable monitor scaling and query content scale:

```cpp
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);

// Later, when needed:
float x_scale, y_scale;
glfwGetMonitorContentScale(monitor, &x_scale, &y_scale);

```

## Configuring Automatic DPI Scaling

The docking branch provides automatic scaling through configuration flags that eliminate manual font resizing.

### Enabling Auto-Scale Features

Set these fields in `ImGuiIO` before calling `NewFrame()` (found in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h#L2296-L2298):

```cpp
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;    // Required for per-monitor DPI
io.ConfigDpiScaleFonts = true;                        // Rebuild font atlas automatically
io.ConfigDpiScaleViewports = true;                    // Scale entire UI automatically

```

When **`ConfigDpiScaleFonts`** is enabled, ImGui rebuilds the font atlas using **`FontScaleDpi`** ([`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h#L2296) to match the current display density. The **`ConfigDpiScaleViewports`** flag ensures that `CellPadding`, `FrameRounding`, and other style fields in `ImGuiStyle` ([`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp#L9194) adjust automatically when monitors change.

## Manual DPI Handling and Custom Rendering

For custom drawing or integrating non-ImGui resources that require pixel-perfect alignment, access the current viewport's scale factor directly:

```cpp
ImGuiViewport* vp = ImGui::GetWindowViewport();
float dpiScale = vp->Scale;  // e.g., 2.0f on Retina displays

// Apply to custom draw commands
ImDrawList* dl = ImGui::GetWindowDrawList();
dl->AddCircle(ImVec2(100, 100) * dpiScale, 10.0f * dpiScale, 
              ImGui::GetColorU32(ImGuiCol_Text));

```

You can also read the global scale from `io.DisplayFramebufferScale.x` when `ViewportsEnable` is not active, though per-viewport scaling is preferred for multi-monitor setups.

## Summary

- **Platform setup is required first**: Call `ImGui_ImplWin32_EnableDpiAwareness()` for Win32 or use `SDL_WINDOW_ALLOW_HIGHDPI` for SDL2 before initializing ImGui.
- **Enable viewport support**: Set `ImGuiConfigFlags_ViewportsEnable` to allow per-monitor DPI detection when windows move between displays.
- **Use automatic scaling flags**: Enable `ConfigDpiScaleFonts` and `ConfigDpiScaleViewports` (docking branch only) to automatically rebuild fonts and scale UI geometry.
- **Access scale factors via Viewport**: Read `ImGuiViewport::Scale` for custom drawing or external resource management that must match ImGui's pixel density.
- **Core implementation**: Library state resides in `ImGuiIO::DisplayFramebufferScale` and per-viewport `FramebufferScale` as defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h).

## Frequently Asked Questions

### Does Dear ImGui automatically detect DPI changes when moving windows between monitors?

Yes, provided you enable `ImGuiConfigFlags_ViewportsEnable` in the IO configuration. When this flag is set, each `ImGuiViewport` tracks its own `Scale` factor derived from the platform window's current monitor. The backend updates this value during `NewFrame()`, allowing the UI to adapt without manual intervention when dragging windows between displays of different densities.

### Why do my fonts look blurry on high-DPI displays?

Blurry fonts occur when the font atlas is rendered at the base pixel size and then stretched by the display's scale factor. Enable `io.ConfigDpiScaleFonts = true` (docking branch) to automatically rebuild the font atlas with `FontScaleDpi` applied. This ensures glyphs render at the correct physical pixel size for the current display density, eliminating upscaling artifacts.

### Do I need the docking branch to use DPI scaling?

Basic DPI scaling works in the master branch using `DisplayFramebufferScale` and manual font reloading. However, automatic per-monitor scaling via `ConfigDpiScaleFonts` and `ConfigDpiScaleViewports` requires the docking branch. For multi-monitor setups with different DPI values, the docking branch's viewport system is strongly recommended.

### How do I scale custom OpenGL or DirectX rendering to match ImGui's DPI?

Retrieve the current scale from the active viewport and multiply your custom geometry by this factor. Access `ImGui::GetWindowViewport()->Scale` to get the float value (typically 1.0 for standard displays, 2.0 for Retina). Apply this multiplier to vertex positions, line thickness, and point sizes in your custom draw calls to maintain visual consistency with ImGui's scaled output.