Dear ImGui Renderer Backends: Complete List and Integration Guide

Dear ImGui provides 13 official renderer backends in the backends/ directory that cover DirectX 9-12, OpenGL 2/3/ES/WebGL, Metal, Vulkan, WebGPU, and SDL abstractions, each implemented as a pair of files (imgui_impl_XXXX.h/imgui_impl_XXXX.cpp) that translate ImDrawData into API-specific draw calls.

Dear ImGui (ocornut/imgui) uses a modular architecture that strictly separates platform interfaces (windowing, input) from graphics rendering. This design allows you to combine any renderer backend with any platform backend—such as pairing Vulkan with GLFW or DirectX 12 with SDL3—without altering your UI code. Each renderer backend handles GPU resource creation, font atlas management, and the translation of ImGui's command lists into native graphics API calls.

Complete List of Dear ImGui Renderer Backends

The official repository maintains renderer backends for all major graphics APIs. Each backend resides in the backends/ folder and exposes a standard lifecycle API: Init, NewFrame, RenderDrawData, and Shutdown.

Microsoft DirectX Family

OpenGL Family

Apple Metal

  • Metal – Standard Objective-C++ implementation via imgui_impl_metal.mm
  • Metal 4 – Optimized for modern Apple GPUs via imgui_impl_metal4.mm

Modern Low-Level APIs

SDL Abstractions

How Renderer Backends Work Internally

Renderer backends perform three critical tasks according to the source code in imgui_impl_*.cpp:

1. Font Atlas Creation During initialization, the backend creates a GPU texture containing the ImGui font atlas and stores the texture handle in ImGui::GetIO().Fonts->TexID. If the backend supports dynamic textures, it sets ImGuiBackendFlags_RendererHasTextures (introduced in v1.92) in io.BackendFlags.

2. Draw Data Translation Each frame, ImGui::Render() generates an ImDrawData* structure containing command lists. The backend's ImGui_ImplXXX_RenderDrawData() function iterates through these lists, binds the appropriate texture (pcmd->GetTexID()), sets scissor rectangles, and issues API-specific draw commands (e.g., glDrawElements, vkCmdDrawIndexed, or ID3D11DeviceContext::DrawIndexed).

3. Multi-Viewport Support When ImGuiConfigFlags_ViewportsEnable is active, the backend must support rendering to multiple OS windows. This requires implementing CreateDeviceObjects and DestroyDeviceObjects for each viewport, allowing ImGui to create additional swap chains and framebuffers automatically.

Integration Examples

OpenGL 3 with GLFW

The most common combination for cross-platform development:

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

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

// Main loop
while (!glfwWindowShouldClose(window))
{
    glfwPollEvents();
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    ImGui::ShowDemoWindow();

    ImGui::Render();
    int display_w, display_h;
    glfwGetFramebufferSize(window, &display_w, &display_h);
    glViewport(0, 0, display_w, display_h);
    glClear(GL_COLOR_BUFFER_BIT);
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

    // Handle multi-viewport
    if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
    {
        GLFWwindow* backup = glfwGetCurrentContext();
        ImGui::UpdatePlatformWindows();
        ImGui::RenderPlatformWindowsDefault();
        glfwMakeContextCurrent(backup);
    }
    glfwSwapBuffers(window);
}

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

Key files: backends/imgui_impl_glfw.cpp (platform), backends/imgui_impl_opengl3.cpp (renderer).

Vulkan with SDL 3

For modern, explicit graphics control:

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

// Platform initialization
ImGui_ImplSDL3_InitForVulkan(window);

// Renderer initialization
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.DescriptorPool = imguiDescriptorPool;
init_info.MinImageCount  = minImageCount;
init_info.ImageCount     = swapchainImageCount;
ImGui_ImplVulkan_Init(&init_info, renderPass);

// Upload fonts
{
    VkCommandBuffer cmd = BeginSingleTimeCommands();
    ImGui_ImplVulkan_CreateFontsTexture(cmd);
    EndSingleTimeCommands(cmd);
    ImGui_ImplVulkan_DestroyFontUploadObjects();
}

// Main loop
while (!quit)
{
    SDL_Event event;
    while (SDL_PollEvent(&event))
        ImGui_ImplSDL3_ProcessEvent(&event);
    
    ImGui_ImplVulkan_NewFrame();
    ImGui_ImplSDL3_NewFrame();
    ImGui::NewFrame();

    ImGui::ShowDemoWindow();

    ImGui::Render();
    VkCommandBuffer cmd = BeginFrameCommandBuffer();
    vkCmdBeginRenderPass(cmd, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
    ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);
    vkCmdEndRenderPass(cmd);
    EndFrameCommandBuffer(cmd);

    if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
        ImGui::UpdatePlatformWindows();
}

Key files: backends/imgui_impl_sdl3.cpp (platform), backends/imgui_impl_vulkan.cpp (renderer).

DirectX 11 with Win32

For native Windows applications:

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

// Initialize backends
ImGui_ImplWin32_Init(hwnd);
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);

// Main loop
while (!done)
{
    MSG msg;
    while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    ImGui_ImplDX11_NewFrame();
    ImGui_ImplWin32_NewFrame();
    ImGui::NewFrame();

    ImGui::ShowDemoWindow();

    ImGui::Render();
    const float clear_color[4] = {0.45f, 0.55f, 0.60f, 1.00f};
    g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);
    g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color);
    ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());

    g_pSwapChain->Present(1, 0);
}

// Cleanup
ImGui_ImplDX11_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();

Key files: backends/imgui_impl_win32.cpp (platform), backends/imgui_impl_dx11.cpp (renderer).

Summary

  • Dear ImGui provides 13 official renderer backends located in the backends/ directory, covering every major graphics API from legacy OpenGL 2 to modern Vulkan and WebGPU.
  • Backends are interchangeable—you can mix any renderer (e.g., imgui_impl_vulkan.cpp) with any platform backend (e.g., imgui_impl_glfw.cpp) without modifying your UI code.
  • Renderer backends handle GPU resources, including font atlas texture creation in ImGui_ImplXXX_Init and translation of ImDrawData into native draw calls via ImGui_ImplXXX_RenderDrawData.
  • Multi-viewport support requires the backend to manage per-viewport device objects, enabled via ImGuiConfigFlags_ViewportsEnable.

Frequently Asked Questions

Can I mix any renderer backend with any platform backend?

Yes. Dear ImGui's architecture decouples platform and renderer responsibilities. You can pair imgui_impl_vulkan.cpp with imgui_impl_sdl3.cpp, imgui_impl_dx11.cpp with imgui_impl_win32.cpp, or any other combination. The only requirement is that the platform backend passes window events and the renderer backend receives valid ImDrawData.

What is the difference between SDL GPU and SDL Renderer backends?

SDL GPU (imgui_impl_sdlgpu3.cpp) targets SDL 3's new cross-platform GPU abstraction layer and provides better performance with modern graphics APIs. SDL Renderer (imgui_impl_sdlrenderer2.cpp and imgui_impl_sdlrenderer3.cpp) uses SDL's high-level 2D renderer, which acts as a fallback for simpler applications but may not support all ImGui features efficiently.

How do I enable multi-viewport rendering in a backend?

Set io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable before initializing the backend. The renderer must support ImGuiBackendFlags_RendererHasViewports and implement device object creation for additional viewports. Most modern backends including Vulkan, DirectX 11/12, OpenGL 3, and Metal support this feature.

Which backend provides the best performance?

Vulkan and DirectX 12 backends offer the lowest CPU overhead for high-frequency UI updates due to explicit command buffer management. However, for most applications, the performance difference is negligible compared to OpenGL 3 or DirectX 11. Choose based on your application's existing graphics API rather than perceived performance differences, as ImGui's draw call overhead is minimal compared to typical game rendering.

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 →