How to Integrate Dear ImGui with SDL: Complete Setup Guide
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.
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.
#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.
// 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 and backends/imgui_impl_opengl3.cpp.
// Initialize backends
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
ImGui_ImplOpenGL3_Init("#version 330");
Key initialization details:
ImGui_ImplSDL2_InitForOpenGLstores the window and GL context handles and sets up platform callbacks for clipboard and cursor management.ImGui_ImplOpenGL3_Initcompiles 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.
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_ProcessEventtranslates SDL input events (keyboard, mouse, gamepad) into ImGui'sImGuiIOstructure.ImGui_ImplSDL2_NewFrameupdates display size, delta time, and mouse position based on SDL window state.ImGui_ImplOpenGL3_RenderDrawDataexecutes the actual GL draw calls using the vertex buffers generated byImGui::Render().
Step 5: Cleanup Resources
Shutdown backends in reverse order and destroy SDL resources.
// 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.cppandbackends/imgui_impl_sdl2.h: ContainsImGui_ImplSDL2_InitForOpenGL(),ImGui_ImplSDL2_ProcessEvent(), andImGui_ImplSDL2_NewFrame(). Handles SDL event translation, DPI scaling, and clipboard integration. -
backends/imgui_impl_opengl3.cppandbackends/imgui_impl_opengl3.h: ImplementsImGui_ImplOpenGL3_Init()andImGui_ImplOpenGL3_RenderDrawData(). Manages shader program compilation (#version 330default), vertex buffer streaming, and orthographic projection setup. -
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_sdl2for platform input andimgui_impl_opengl3(or Vulkan/DirectX) for rendering. - Initialize SDL first, then create the ImGui context, then initialize backends with
ImGui_ImplSDL2_InitForOpenGL()andImGui_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'sRenderDrawData(). - 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 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, your renderer backend, and core 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.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →