# How to Integrate Dear ImGui with OpenGL: Complete Implementation Guide

> Learn to integrate Dear ImGui with OpenGL using the official backend. Follow this guide for a complete implementation, from initialization to rendering draw data, and enhance your graphics applications.

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

---

**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`](https://github.com/ocornut/imgui/blob/main/imgui.h) and [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/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`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.h) and [`backends/imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/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`](https://github.com/ocornut/imgui/blob/main/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`](https://github.com/ocornut/imgui/blob/main/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:

```cpp
#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:

```cpp
// 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:

```cpp
// 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.

```cpp
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:

```cpp
// 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:

- **[`backends/imgui_impl_opengl3.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.h)** – Renderer interface declaring `ImGui_ImplOpenGL3_Init`, `ImGui_ImplOpenGL3_NewFrame`, and `ImGui_ImplOpenGL3_RenderDrawData`.
- **[`backends/imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.cpp)** – Implementation containing the shader compilation logic and `glDrawElements` submission.
- **[`backends/imgui_impl_opengl3_loader.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3_loader.h)** – Embedded GL loader supporting `glad`, `gl3w`, `glew`, or custom loaders via `IMGUI_IMPL_OPENGL_LOADER_CUSTOM`.
- **[`backends/imgui_impl_glfw.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.h)** – Platform backend for GLFW (alternative: [`imgui_impl_sdl2.h`](https://github.com/ocornut/imgui/blob/main/imgui_impl_sdl2.h) or [`imgui_impl_win32.h`](https://github.com/ocornut/imgui/blob/main/imgui_impl_win32.h)).
- **[`examples/example_glfw_opengl3/main.cpp`](https://github.com/ocornut/imgui/blob/main/examples/example_glfw_opengl3/main.cpp)** – Complete, compilable reference implementation demonstrating the full initialization flow.

## 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`](https://github.com/ocornut/imgui/blob/main/imgui_impl_opengl3.cpp) will assert or log an error during initialization.