Skip to main content

Overview

Integrating Dear ImGui into an existing application typically involves:
  1. Adding the core Dear ImGui files to your project
  2. Choosing and integrating platform and renderer backends
  3. Initializing Dear ImGui in your application startup
  4. Calling Dear ImGui functions in your main loop
  5. Rendering the Dear ImGui draw data
Most integrations take less than an hour when using existing backends. Custom backends require more time but are straightforward to implement.

Core files

The core Dear ImGui library is self-contained in these files (from the repository root):
imgui.cpp          // Main implementation
imgui.h            // Public API
imgui_draw.cpp     // Rendering
imgui_tables.cpp   // Tables functionality
imgui_widgets.cpp  // Widget implementations
No build process required - just add these files to your existing project and compile them.

Choosing backends

Dear ImGui needs two types of backends:

Platform backends

Handle windowing, input (mouse/keyboard/gamepad), and OS features:
  • imgui_impl_glfw.cpp - GLFW (cross-platform, recommended)
  • imgui_impl_sdl2.cpp / imgui_impl_sdl3.cpp - SDL2/SDL3 (cross-platform)
  • imgui_impl_win32.cpp - Win32 native API (Windows only)
  • imgui_impl_osx.mm - macOS native API
  • imgui_impl_android.cpp - Android native
  • imgui_impl_glut.cpp - GLUT/FreeGLUT (legacy, not recommended)

Renderer backends

Handle texture creation and rendering Dear ImGui draw commands:
  • imgui_impl_opengl3.cpp - OpenGL 3/4, OpenGL ES 2/3, WebGL
  • imgui_impl_opengl2.cpp - OpenGL 2 (legacy fixed pipeline)
  • imgui_impl_dx11.cpp - DirectX 11
  • imgui_impl_dx12.cpp - DirectX 12
  • imgui_impl_dx9.cpp - DirectX 9
  • imgui_impl_vulkan.cpp - Vulkan
  • imgui_impl_metal.mm - Metal (macOS/iOS)
  • imgui_impl_wgpu.cpp - WebGPU
  • imgui_impl_sdlrenderer3.cpp - SDL_Renderer

Integration steps

1

Add files to your project

Copy the core files and your chosen backends:
# Core library
imgui/imgui.cpp
imgui/imgui_draw.cpp
imgui/imgui_tables.cpp
imgui/imgui_widgets.cpp
imgui/imgui_demo.cpp

# Backends (example: GLFW + OpenGL3)
imgui/backends/imgui_impl_glfw.cpp
imgui/backends/imgui_impl_opengl3.cpp
Add these files to your build system (CMake, Make, Visual Studio project, etc.).
2

Include headers

In your application code:
#include "imgui.h"
#include "imgui_impl_glfw.h"   // Your platform backend
#include "imgui_impl_opengl3.h" // Your renderer backend
3

Initialize at startup

After creating your window and graphics context:
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();

// Optional: enable keyboard/gamepad controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;

// Setup style
ImGui::StyleColorsDark();
// or: ImGui::StyleColorsLight();
// or: ImGui::StyleColorsClassic();

// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 130");
4

Per-frame updates

At the start of your frame, before UI code:
// Poll events (platform-specific)
glfwPollEvents();

// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
5

Submit UI code

Anywhere in your main loop after NewFrame():
// Your UI code here
ImGui::Begin("Debug Window");
ImGui::Text("FPS: %.1f", ImGui::GetIO().Framerate);
ImGui::End();

// Optional: show demo for learning
ImGui::ShowDemoWindow();
6

Render Dear ImGui

At the end of your frame, after your rendering:
// Finalize Dear ImGui frame
ImGui::Render();

// Render your application
glClear(GL_COLOR_BUFFER_BIT);
RenderYourApplication();

// Render Dear ImGui on top
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

// Swap buffers
glfwSwapBuffers(window);
7

Cleanup at shutdown

Before destroying your window:
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();

Platform-specific examples

// Initialization
GLFWwindow* window = glfwCreateWindow(1280, 720, "App", NULL, NULL);
glfwMakeContextCurrent(window);

IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 130");

// Main loop
while (!glfwWindowShouldClose(window)) {
    glfwPollEvents();
    
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();
    
    // Your UI code
    
    ImGui::Render();
    int display_w, display_h;
    glfwGetFramebufferSize(window, &display_w, &display_h);
    glViewport(0, 0, display_w, display_h);
    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
    
    glfwSwapBuffers(window);
}

// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();

Handling input

Dear ImGui needs to know when to capture input. Use these flags:
ImGuiIO& io = ImGui::GetIO();

// Check if Dear ImGui wants keyboard input
if (!io.WantCaptureKeyboard) {
    // Pass keyboard events to your application
}

// Check if Dear ImGui wants mouse input
if (!io.WantCaptureMouse) {
    // Pass mouse events to your application
}

// Check if Dear ImGui wants text input
if (!io.WantTextInput) {
    // Your application logic
}
Important: When io.WantCaptureMouse is true, don’t dispatch mouse input to your application. Similarly for keyboard. This prevents UI interactions from “falling through” to your application.

Configuration options

Set these flags on ImGuiIO after creating the context:
ImGuiIO& io = ImGui::GetIO();

// Enable keyboard navigation
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;

// Enable gamepad navigation
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;

// Enable docking (docking branch only)
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;

// Enable multi-viewport / platform windows (docking branch only)
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;

// Disable .ini file save/load
io.IniFilename = NULL;

// Set custom .ini path
io.IniFilename = "my_app.ini";

Loading fonts

Dear ImGui embeds a default font, but you can load custom fonts:
ImGuiIO& io = ImGui::GetIO();

// Add default font at different size
io.Fonts->AddFontDefault();

// Load TTF font from file
ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/Roboto-Regular.ttf", 16.0f);

// Load with custom glyph ranges (for international text)
ImFontConfig config;
config.MergeMode = true;
io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf", 16.0f, &config,
    io.Fonts->GetGlyphRangesJapanese());

// Use the font
ImGui::PushFont(font);
ImGui::Text("Custom font text");
ImGui::PopFont();
Load fonts before the first frame. After adding fonts, they’re automatically uploaded to the GPU by the renderer backend.

Integration with game engines

Unreal Engine

Use the ImGui for Unreal Engine plugin.

Unity

Use Dear ImGui for Unity package.

Custom engines

For custom engines with their own abstraction layers:
1

Start with standard backends

Use imgui_impl_glfw.cpp + your graphics API backend to get running quickly.
2

Evaluate if custom backend needed

In most cases, standard backends work fine even with engine abstractions.
3

Write custom backend if necessary

See the Backends documentation for implementation details.

Build system integration

set(IMGUI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/imgui)

add_library(imgui STATIC
    ${IMGUI_DIR}/imgui.cpp
    ${IMGUI_DIR}/imgui_draw.cpp
    ${IMGUI_DIR}/imgui_tables.cpp
    ${IMGUI_DIR}/imgui_widgets.cpp
    ${IMGUI_DIR}/imgui_demo.cpp
    ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp
    ${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp
)

target_include_directories(imgui PUBLIC ${IMGUI_DIR} ${IMGUI_DIR}/backends)
target_link_libraries(imgui PUBLIC glfw OpenGL::GL)

# Link to your executable
target_link_libraries(your_app PRIVATE imgui)

Common issues

  • Verify you’re calling ImGui_ImplXXX_NewFrame() for both backends
  • Verify you’re calling ImGui::NewFrame() before UI code
  • Verify you’re calling ImGui::Render() before RenderDrawData()
  • Check that your viewport/scissor state is correct
  • Try calling ImGui::ShowDemoWindow() to test
Font atlas texture wasn’t uploaded to GPU. The renderer backend should handle this automatically after the first frame.
Your renderer may not be handling scissor rectangles correctly. Check that you’re applying the scissor rect from ImDrawCmd.
  • Verify platform backend NewFrame() is called before ImGui::NewFrame()
  • For SDL, ensure you’re calling ImGui_ImplSDL2_ProcessEvent(&event)
  • For Win32, ensure your WndProc calls ImGui_ImplWin32_WndProcHandler()
  • Run IMGUI_CHECKVERSION() at startup
  • Ensure you’re not mixing Debug/Release builds
  • Check that all required backends are initialized
  • Verify you’re not calling UI code before NewFrame()

Next steps

API reference

Explore all available widgets and functions

Examples

See complete example applications

Custom backends

Learn to write your own platform/renderer backend

FAQ

Find answers to common questions

Build docs developers (and LLMs) love