How to Integrate ImGui with Modern C++ Frameworks: A Complete Implementation Guide

Dear ImGui integrates into modern C++ frameworks by combining a platform backend (e.g., GLFW, SDL) with a renderer backend (e.g., OpenGL, Vulkan) and linking them to the core library sources.

The Dear ImGui (ocornut/imgui) library provides an immediate-mode graphical user interface for C++ applications. To integrate ImGui with modern C++ frameworks, you combine the core UI library with platform-specific and renderer-specific backends, enabling everything from simple debugging tools to complex docking multi-viewport editors. This architecture keeps the library portable while allowing deep integration with your existing windowing and graphics systems.

Understanding the Two-Layer Architecture

Dear ImGui is deliberately separated into two distinct layers. The core UI library (located in the repository root, including imgui.cpp and imgui.h) handles widget logic, layout, and draw list generation. The backend layer (located in the backends/ folder) implements platform-specific input handling and graphics-API-specific rendering. This separation allows you to mix and match backends to suit your framework's requirements.

Selecting Your Platform Backend

The platform backend provides window creation, input polling, mouse-cursor shaping, and multi-viewport support. Choose based on your target platforms and existing dependencies.

GLFW for Cross-Platform Windowing

GLFW is the most common choice for modern C++ applications on Windows, macOS, and Linux. The implementation resides in backends/imgui_impl_glfw.cpp and backends/imgui_impl_glfw.h. Initialize it with your existing window pointer:

ImGui_ImplGlfw_InitForOpenGL(window, true);

SDL2 and SDL3 for Game-Engine Integration

SDL2 offers robust controller support and is ideal for game engines. Use backends/imgui_impl_sdl2.cpp for SDL2 projects. For newer codebases using SDL3, the backend is implemented in backends/imgui_impl_sdl3.cpp.

Selecting Your Renderer Backend

The renderer backend translates ImGui draw commands into GPU API calls. Modern C++ frameworks typically choose based on their existing graphics abstraction.

OpenGL 3/4 (Core Profile)

The OpenGL 3/4 backend in backends/imgui_impl_opengl3.cpp works with legacy and cross-platform OpenGL projects. Initialize with your shader version string:

ImGui_ImplOpenGL3_Init("#version 330");

Vulkan for High-Performance Rendering

For explicit API control, use the Vulkan backend in backends/imgui_impl_vulkan.cpp. This requires setting up a ImGui_ImplVulkan_InitInfo structure with your existing Vulkan instance, device, and queue:

ImGui_ImplVulkan_InitInfo init_info = {};
init_info.Instance = vkInstance;
init_info.PhysicalDevice = vkPhysicalDevice;
init_info.Device = vkDevice;
init_info.QueueFamily = graphicsQueueFamily;
init_info.Queue = graphicsQueue;
init_info.PipelineCache = vkPipelineCache;
init_info.DescriptorPool = vkDescriptorPool;
init_info.MinImageCount = 2;
init_info.ImageCount = swapchainImageCount;
ImGui_ImplVulkan_Init(&init_info, renderPass);

DirectX 11/12 for Windows-Only Applications

Windows-centric frameworks can use the DirectX 11 or DirectX 12 backends (backends/imgui_impl_dx11.cpp and related files) for native integration with the Windows compositor.

Initializing the ImGui Context

Before using any backends, create an ImGui context and configure modern features like docking and multi-viewport support. In imgui.cpp, ImGui::CreateContext() allocates the global state:

IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;

Wiring the Frame Loop

The integration requires a specific frame sequence in your main loop. According to the source code in imgui_impl_glfw.cpp and imgui_impl_opengl3.cpp, the order is critical:

// Poll window events
glfwPollEvents();

// Start new frames for backends and core
ImGui_ImplGlfw_NewFrame();
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();

// Build your UI
ImGui::ShowDemoWindow();

// Finalize draw data
ImGui::Render();

// Clear and setup viewport
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);

// Render draw data
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

// Handle multi-viewport rendering
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
    ImGui::UpdatePlatformWindows();
    ImGui::RenderPlatformWindowsDefault();
}

glfwSwapBuffers(window);

CMake Integration for Modern C++

Modern C++ projects typically use CMake. A minimal CMakeLists.txt that compiles the required sources from the ocornut/imgui repository looks like this:

cmake_minimum_required(VERSION 3.15)
project(MyApp LANGUAGES CXX)

set(IMGUI_DIR "${CMAKE_CURRENT_SOURCE_DIR}/imgui")
file(GLOB IMGUI_SOURCES
    "${IMGUI_DIR}/*.cpp"
    "${IMGUI_DIR}/backends/imgui_impl_glfw.cpp"
    "${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp"
)
add_executable(MyApp main.cpp ${IMGUI_SOURCES})
target_include_directories(MyApp PRIVATE "${IMGUI_DIR}" "${IMGUI_DIR}/backends")
find_package(glfw3 REQUIRED)
find_package(OpenGL REQUIRED)
target_link_libraries(MyApp PRIVATE glfw OpenGL::GL)
target_compile_features(MyApp PRIVATE cxx_std_17)

Advanced Features

Multi-Viewport Support

Enable multi-viewport support by setting ImGuiConfigFlags_ViewportsEnable in the ImGuiIO structure. The platform backend automatically creates additional OS windows. Ensure your renderer backend supports ImGuiBackendFlags_RendererHasVtxOffset and ImGuiBackendFlags_RendererHasTextures flags (added in v1.92) as documented in docs/BACKENDS.md.

Custom Engine Integration

If your framework already has a rendering abstraction, you can use the standard backends as reference implementations. Replace the RenderDrawData implementation with calls into your own engine. The documentation in docs/BACKENDS.md provides a complete template for MyImGuiBackend_RenderDrawData.

Summary

  • Dear ImGui uses a two-layer architecture separating the core library from platform and renderer backends.
  • Choose a platform backend (GLFW, SDL2, SDL3) for windowing and input, and a renderer backend (OpenGL 3, Vulkan, DirectX) for drawing.
  • Initialize the context with ImGui::CreateContext() and configure modern features via ImGuiIO flags.
  • Implement the frame loop sequence: platform NewFrame(), renderer NewFrame(), ImGui::NewFrame(), UI construction, ImGui::Render(), then platform/renderer RenderDrawData.
  • Use CMake to compile the core files (imgui.cpp) alongside your selected backend implementations from the backends/ folder.

Frequently Asked Questions

What is the minimum code needed to integrate ImGui into a GLFW application?

You need to include imgui.h, backends/imgui_impl_glfw.h, and backends/imgui_impl_opengl3.h. Call ImGui::CreateContext(), then ImGui_ImplGlfw_InitForOpenGL(window, true) and ImGui_ImplOpenGL3_Init(glsl_version). In your loop, call the respective NewFrame() functions, build your UI, call ImGui::Render(), and finally ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()).

Can I use ImGui with a custom engine that doesn't use standard backends?

Yes. The docs/BACKENDS.md file in the ocornut/imgui repository provides a template for creating custom backends. You implement functions to handle input events and render draw data (ImDrawData) using your engine's rendering API, using the standard backends in backends/imgui_impl_*.cpp as reference implementations.

How do I enable docking and multi-viewport support in ImGui?

Set the configuration flags in your ImGuiIO structure after creating the context: io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; and io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;. The platform backend handles window creation, while the renderer backend must support the required flags for vertex offsets and textures.

Which renderer backend offers the best performance for modern C++ applications?

Vulkan and DirectX 12 offer the best performance for CPU-bound applications due to lower driver overhead and explicit control over command buffers. However, OpenGL 3/4 remains sufficient for most tools and is easier to integrate with existing cross-platform C++ frameworks. The choice depends on your existing graphics infrastructure and performance requirements.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →