How to Integrate Dear ImGui with OpenGL: Complete Implementation Guide

To integrate Dear ImGui with OpenGL, you must initialize the official OpenGL 3 renderer backend (imgui_impl_opengl3) alongside a platform backend (GLFW, SDL, or Win32), then call ImGui_ImplOpenGL3_NewFrame() at the start of each frame and ImGui_ImplOpenGL3_RenderDrawData() after ImGui::Render() to execute the GPU draw commands.

Dear ImGui is a header-only, immediate-mode GUI library designed to be rendering-API agnostic. When you integrate Dear ImGui with OpenGL, you bridge the library's generic draw lists to your graphics pipeline using the official backend implementations found in the ocornut/imgui repository.

Architecture Overview

Understanding the separation of concerns in the ImGui ecosystem is essential for a correct integration.

Core ImGui Library

The core logic resides in imgui.h and imgui.cpp. This layer is completely unaware of OpenGL; it only produces draw lists containing vertex data, index buffers, and texture references. Your application never calls OpenGL directly to render UI elements—instead, you feed these draw lists into a renderer backend.

OpenGL 3 Renderer Backend

Located in backends/imgui_impl_opengl3.h and backends/imgui_impl_opengl3.cpp, this backend translates ImGui's platform-agnostic draw data into OpenGL 3+ API calls. Key responsibilities include:

  • Loading OpenGL function pointers via imgui_impl_opengl3_loader.h (supports glad, gl3w, glew, etc.)
  • Creating and managing a Vertex Array Object (VAO) and Vertex Buffer Objects (VBO/IBO) for dynamic mesh streaming
  • Uploading vertex and index data to the GPU each frame using glBufferData
  • Compiling and binding a minimal vertex/fragment shader pair that matches ImGui's vertex format (position, UV, color)
  • Issuing glDrawElements calls to render the final UI geometry

Platform Backend

You must pair the renderer with a platform backend such as backends/imgui_impl_glfw.cpp (or SDL2, Win32). This layer feeds windowing events, input state (keyboard/mouse), clipboard access, and delta time into ImGui. The platform backend is independent of the renderer; you can mix GLFW with OpenGL, or SDL with OpenGL, depending on your application's windowing system.

Step-by-Step Integration

Follow this sequence to wire Dear ImGui into an existing OpenGL application. The example below uses GLFW for cross-platform window management, but the pattern is identical for SDL2 or Win32.

1. Include Required Headers

Include the core ImGui headers and both backend headers in your main source file:

#include "imgui.h"
#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_opengl3.h"
#include <GLFW/glfw3.h>  // Include glfw3.h after imgui_impl_glfw.h

2. Create OpenGL Context and ImGui Context

Initialize your window with an OpenGL 3.2+ Core Profile context, then create the ImGui context:

// Setup window
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui + OpenGL", nullptr, nullptr);
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // Enable vsync

// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
ImGui::StyleColorsDark();

3. Initialize Backends

You must initialize the platform backend first, then the renderer backend. The OpenGL backend requires a GLSL version string that matches your OpenGL context:

// Initialize Platform Backend
ImGui_ImplGlfw_InitForOpenGL(window, true);

// Initialize Renderer Backend
// Use "#version 130" for OpenGL 3.0, "#version 150" for 3.2, etc.
const char* glsl_version = "#version 150";
ImGui_ImplOpenGL3_Init(glsl_version);

4. Implement the Main Render Loop

The per-frame lifecycle follows a strict three-phase pattern: New Frame, Build UI, Render. Missing any step results in undefined behavior or blank screens.

while (!glfwWindowShouldClose(window))
{
    // Poll events
    glfwPollEvents();

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

    // (2) Build your UI here
    ImGui::Begin("Hello, OpenGL!");
    ImGui::Text("This window is rendered via the OpenGL 3 backend.");
    if (ImGui::Button("Click Me")) {
        // Handle interaction
    }
    ImGui::End();

    // (3) Rendering
    ImGui::Render();
    
    // Clear framebuffer
    int display_w, display_h;
    glfwGetFramebufferSize(window, &display_w, &display_h);
    glViewport(0, 0, display_w, display_h);
    glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
    glClear(GL_COLOR_BUFFER_BIT);
    
    // Execute draw data
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
    
    glfwSwapBuffers(window);
}

5. Shutdown and Cleanup

Release resources in reverse order of initialization to avoid dangling pointers:

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

glfwDestroyWindow(window);
glfwTerminate();

Key Backend Files Reference

When integrating Dear ImGui with OpenGL, you will work directly with these source files from the ocornut/imgui repository:

Summary

  • Dear ImGui is renderer-agnostic: It outputs draw lists, not pixels. You must provide a backend to execute these on the GPU.
  • Use imgui_impl_opengl3: This official backend handles shaders, VAOs, VBOs, and texture binding for OpenGL 3.0+.
  • Pair with a platform backend: GLFW, SDL2, or Win32 backends handle input and windowing events separately from rendering.
  • Follow the frame lifecycle: Always call NewFrame() on both backends, then ImGui::NewFrame(), build UI, ImGui::Render(), and finally ImGui_ImplOpenGL3_RenderDrawData().
  • Match GLSL versions: Pass a version string (e.g., "#version 150") to ImGui_ImplOpenGL3_Init() that matches your OpenGL context profile.

Frequently Asked Questions

Which OpenGL versions are supported by the Dear ImGui backend?

The imgui_impl_opengl3 backend officially supports OpenGL 3.0 and later. It uses programmable pipeline features (VAOs, VBOs, custom shaders) and is not compatible with legacy OpenGL 2.x fixed-function pipelines. For OpenGL 2.x, use the separate imgui_impl_opengl2 backend found in the same backends/ directory.

Can I integrate Dear ImGui with OpenGL without using GLFW?

Yes. The renderer backend (imgui_impl_opengl3) is completely decoupled from windowing. You can use SDL2 via imgui_impl_sdl2, native Win32 via imgui_impl_win32, or even a custom platform layer. As long as your platform backend feeds input data to ImGuiIO and you call ImGui_ImplOpenGL3_RenderDrawData() with a valid OpenGL context current, the UI will render correctly.

How do I handle high-DPI displays when integrating Dear ImGui with OpenGL?

Handle DPI scaling in your platform layer (e.g., glfwGetWindowContentScale for GLFW) and apply the scale to ImGuiIO::DisplayFramebufferScale before calling ImGui::NewFrame(). The OpenGL backend automatically respects the framebuffer scale when setting up the orthographic projection matrix in ImGui_ImplOpenGL3_RenderDrawData(), ensuring crisp rendering on Retina or 4K displays without additional shader modifications.

What is the purpose of the GLSL version string in ImGui_ImplOpenGL3_Init()?

The GLSL version string (e.g., "#version 150") is prepended to the vertex and fragment shaders that the backend compiles at runtime. It must match the OpenGL context version you created (3.2 Core requires #version 150, 3.3 Core requires #version 330, etc.). If the version string mismatches your context, shader compilation will fail and imgui_impl_opengl3.cpp will assert or log an error during initialization.

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 →