# How to Integrate Dear ImGui with SDL: Complete Setup Guide

> Integrate Dear ImGui with SDL using the official imgui_impl_sdl2 backend and a renderer backend. Follow this guide for a complete setup and smooth integration.

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

---

**To integrate Dear ImGui with SDL, use the official `imgui_impl_sdl2` backend for platform input handling paired with a renderer backend such as `imgui_impl_opengl3` for GPU drawing, initializing both after SDL window creation and calling their NewFrame/Render functions each frame.**

Dear ImGui provides production-ready backend implementations that bridge the immediate-mode UI library with SDL2. According to the `ocornut/imgui` source code, the integration relies on a clean separation between platform handling (window events, input, clipboard) and rendering (OpenGL, Vulkan, DirectX), allowing you to mix and match backends based on your graphics requirements.

## Architecture Overview

The SDL integration follows a two-layer backend design that keeps the core ImGui library renderer-agnostic.

**Platform Layer (`imgui_impl_sdl2`)**: Handles OS window management, event polling, mouse/keyboard/gamepad input, clipboard operations, and cursor management. This backend translates SDL events into ImGui's internal input format but performs no drawing.

**Renderer Layer (`imgui_impl_opengl3`, etc.)**: Issues GPU draw calls based on ImGui's generated draw lists. This handles shader compilation, vertex buffer management, and the actual rasterization of UI elements.

This separation means you can swap SDL for GLFW or Win32 by changing only the platform backend, or switch from OpenGL to Vulkan by changing only the renderer backend without modifying your application logic.

## Step-by-Step Implementation

Follow these steps to create a minimal SDL2 + OpenGL3 + Dear ImGui application. The example mirrors the official reference located at [`examples/example_sdl2_opengl3/main.cpp`](https://github.com/ocornut/imgui/blob/main/examples/example_sdl2_opengl3/main.cpp).

### Step 1: Initialize SDL and Create the OpenGL Context

First, initialize SDL with video and controller support, configure OpenGL attributes, and create the window and context.

```cpp
#include <SDL.h>
#include <SDL_opengl.h>
#include "imgui.h"
#include "backends/imgui_impl_sdl2.h"
#include "backends/imgui_impl_opengl3.h"

int main(int, char**)
{
    // Initialize SDL
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER);
    
    // Configure OpenGL 3.3 Core Profile
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);

    // Create window with OpenGL context
    SDL_Window* window = SDL_CreateWindow("Dear ImGui + SDL2", 
                                          SDL_WINDOWPOS_CENTERED, 
                                          SDL_WINDOWPOS_CENTERED, 
                                          1280, 720, 
                                          SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
    SDL_GLContext gl_context = SDL_GL_CreateContext(window);
    SDL_GL_MakeCurrent(window, gl_context);
    SDL_GL_SetSwapInterval(1); // Enable vsync

```

### Step 2: Initialize the ImGui Context

Create the global ImGui context and configure the style before binding any backends.

```cpp
    // Setup Dear ImGui context
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;
    
    // Set style
    ImGui::StyleColorsDark();
    // ImGui::StyleColorsClassic();

```

### Step 3: Initialize Platform and Renderer Backends

Bind ImGui to your SDL window and OpenGL context using the backend initialization functions defined in [`backends/imgui_impl_sdl2.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl2.cpp) and [`backends/imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.cpp).

```cpp
    // Initialize backends
    ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
    ImGui_ImplOpenGL3_Init("#version 330");

```

**Key initialization details**:
- `ImGui_ImplSDL2_InitForOpenGL` stores the window and GL context handles and sets up platform callbacks for clipboard and cursor management.
- `ImGui_ImplOpenGL3_Init` compiles the internal GLSL shaders and creates the vertex array objects (VAOs) and buffers needed for rendering.

### Step 4: Implement the Main Loop

Each frame, poll SDL events, process them through the ImGui backend, build your UI, and render.

```cpp
    bool done = false;
    while (!done)
    {
        // Poll and handle SDL events
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            ImGui_ImplSDL2_ProcessEvent(&event);
            if (event.type == SDL_QUIT)
                done = true;
            if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE 
                && event.window.windowID == SDL_GetWindowID(window))
                done = true;
        }

        // Start new ImGui frame
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplSDL2_NewFrame(window);
        ImGui::NewFrame();

        // Build your UI here
        ImGui::Begin("Hello, SDL2!");
        ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 
                    1000.0f / io.Framerate, io.Framerate);
        ImGui::End();

        // Rendering
        ImGui::Render();
        glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
        glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
        glClear(GL_COLOR_BUFFER_BIT);
        
        // Draw ImGui data
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        
        SDL_GL_SwapWindow(window);
    }

```

**Critical loop functions**:
- `ImGui_ImplSDL2_ProcessEvent` translates SDL input events (keyboard, mouse, gamepad) into ImGui's `ImGuiIO` structure.
- `ImGui_ImplSDL2_NewFrame` updates display size, delta time, and mouse position based on SDL window state.
- `ImGui_ImplOpenGL3_RenderDrawData` executes the actual GL draw calls using the vertex buffers generated by `ImGui::Render()`.

### Step 5: Cleanup Resources

Shutdown backends in reverse order and destroy SDL resources.

```cpp
    // Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplSDL2_Shutdown();
    ImGui::DestroyContext();

    SDL_GL_DeleteContext(gl_context);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

```

## Key Source Files and Functions

Understanding these specific files from the `ocornut/imgui` repository helps when debugging or extending the integration:

- **[`backends/imgui_impl_sdl2.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl2.cpp)** and **[`backends/imgui_impl_sdl2.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_sdl2.h)**: Contains `ImGui_ImplSDL2_InitForOpenGL()`, `ImGui_ImplSDL2_ProcessEvent()`, and `ImGui_ImplSDL2_NewFrame()`. Handles SDL event translation, DPI scaling, and clipboard integration.

- **[`backends/imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.cpp)** and **[`backends/imgui_impl_opengl3.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.h)**: Implements `ImGui_ImplOpenGL3_Init()` and `ImGui_ImplOpenGL3_RenderDrawData()`. Manages shader program compilation (`#version 330` default), vertex buffer streaming, and orthographic projection setup.

- **[`examples/example_sdl2_opengl3/main.cpp`](https://github.com/ocornut/imgui/blob/main/examples/example_sdl2_opengl3/main.cpp)**: Full-featured reference demonstrating multi-viewport support, docking, and platform-specific optimizations.

## Summary

- **Dear ImGui SDL integration requires two backends**: `imgui_impl_sdl2` for platform input and `imgui_impl_opengl3` (or Vulkan/DirectX) for rendering.
- **Initialize SDL first**, then create the ImGui context, then initialize backends with `ImGui_ImplSDL2_InitForOpenGL()` and `ImGui_ImplOpenGL3_Init()`.
- **Process events** through `ImGui_ImplSDL2_ProcessEvent()` in your event loop to capture input.
- **Call NewFrame functions** in order (renderer first, then platform) before building UI, then `ImGui::Render()` followed by the renderer's `RenderDrawData()`.
- **Cleanup in reverse initialization order** to prevent memory leaks and OpenGL context errors.

## Frequently Asked Questions

### Can I use Dear ImGui with SDL without OpenGL?

Yes, but you must pair the SDL platform backend with a different renderer backend. Dear ImGui provides official backends for **Vulkan** (`imgui_impl_vulkan`), **DirectX 11/12** (`imgui_impl_dx11`, `imgui_impl_dx12`), and **Metal** (`imgui_impl_metal`). The SDL backend handles window and input events regardless of which renderer you choose.

### Why is my ImGui window not receiving mouse clicks?

Ensure you call `ImGui_ImplSDL2_ProcessEvent()` for every SDL event in your polling loop, and verify that `ImGui_ImplSDL2_NewFrame()` is called every frame before `ImGui::NewFrame()`. If using custom SDL event handling, confirm that `SDL_Event` structures are not being consumed before reaching the ImGui processor.

### How do I handle high-DPI displays with SDL and ImGui?

The SDL backend in [`imgui_impl_sdl2.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_sdl2.cpp) automatically queries `SDL_GetDisplayDPI` and scales the `io.DisplayFramebufferScale` vector accordingly. Ensure you create your SDL window with the `SDL_WINDOW_ALLOW_HIGHDPI` flag, and check that your OpenGL viewport accounts for the framebuffer scale returned in `ImGuiIO`.

### Can I integrate ImGui into an existing SDL application?

Yes. Include the backend files ([`imgui_impl_sdl2.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_sdl2.cpp), your renderer backend, and core [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp)) in your build system. Initialize the ImGui context and backends after your existing SDL and graphics setup. Replace your current event loop with one that calls `ImGui_ImplSDL2_ProcessEvent()`, and insert the NewFrame/Render calls into your existing frame update logic without removing your current rendering code.