# How to Set Up Dear ImGui with OpenGL: Complete Integration Guide

> Integrate Dear ImGui with OpenGL easily. Follow our guide to set up the ImGui context, OpenGL 3 renderer, and main loop for seamless UI rendering.

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

---

**To set up Dear ImGui with OpenGL, create an OpenGL 3+ context, initialize the core ImGui context with `ImGui::CreateContext()`, initialize the platform backend (e.g., GLFW) and the OpenGL 3 renderer backend (`ImGui_ImplOpenGL3_Init`), then execute the per-frame sequence of `ImGui_ImplOpenGL3_NewFrame`, `ImGui::NewFrame`, `ImGui::Render`, and `ImGui_ImplOpenGL3_RenderDrawData` in your main loop.**

Dear ImGui is a bloat-free, immediate-mode graphical user interface library for C++ that outputs geometry and draw commands rather than rendering pixels directly. To set up Dear ImGui with OpenGL, you must integrate the official OpenGL 3 backend provided in the `ocornut/imgui` repository, which translates ImGui's draw lists into OpenGL API calls using vertex buffer objects and shaders.

## Dear ImGui OpenGL Architecture Overview

The integration follows a strict separation between UI logic, platform handling, and rendering. Understanding these layers ensures you initialize components in the correct order.

### Core ImGui Library

The **core ImGui** logic lives 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 code is graphics-API agnostic—it calculates layouts, handles user input state, and produces **draw lists** containing vertices, indices, and texture coordinates. It does not perform any actual rendering.

### OpenGL Renderer Backend

The **renderer backend** 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) implements the actual GPU communication:

- Creates a vertex array object (VAO) and vertex/index buffer objects (VBO/IBO) that persist across frames
- Compiles and links a minimal vertex/fragment shader pair internally (you do not write these shaders)
- Uploads vertex data via `glBufferData` and issues `glDrawElements` calls
- Manages font texture creation via `glTexImage2D`

The backend includes [`imgui_impl_opengl3_loader.h`](https://github.com/ocornut/imgui/blob/main/imgui_impl_opengl3_loader.h), which abstracts GL function pointer loading and supports **glad**, **gl3w**, **GLEW**, or custom loaders.

### Platform Backend

The **platform backend** (e.g., [`backends/imgui_impl_glfw.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.h) for GLFW) handles OS windowing events, including mouse position, keyboard input, window resizing, clipboard access, and timing. You can substitute GLFW with SDL2 ([`imgui_impl_sdl2.h`](https://github.com/ocornut/imgui/blob/main/imgui_impl_sdl2.h)) or Win32 ([`imgui_impl_win32.h`](https://github.com/ocornut/imgui/blob/main/imgui_impl_win32.h)) depending on your application.

## Required Files for OpenGL Integration

To set up Dear ImGui with OpenGL in your build system, include these specific files from the `ocornut/imgui` repository:

- [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) / [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) - Core immediate-mode UI logic
- [`backends/imgui_impl_opengl3.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.h) / [`backends/imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3.cpp) - OpenGL 3.0+ renderer implementation
- [`backends/imgui_impl_opengl3_loader.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_opengl3_loader.h) - GL function loader abstraction
- [`backends/imgui_impl_glfw.h`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.h) / [`backends/imgui_impl_glfw.cpp`](https://github.com/ocornut/imgui/blob/main/backends/imgui_impl_glfw.cpp) - GLFW platform implementation (or equivalent SDL2/Win32 files)

Reference implementations are available in [`examples/example_glfw_opengl3/main.cpp`](https://github.com/ocornut/imgui/blob/main/examples/example_glfw_opengl3/main.cpp) and [`examples/example_sdl2_opengl3/main.cpp`](https://github.com/ocornut/imgui/blob/main/examples/example_sdl2_opengl3/main.cpp).

## Step-by-Step Integration Guide

### 1. Create an OpenGL Context

First, initialize your windowing library and request an OpenGL 3.2+ core profile context. The following example uses GLFW:

```cpp
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, "ImGui + OpenGL3", nullptr, nullptr);
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // Enable vsync

```

### 2. Initialize the ImGui Context

Create the global ImGui context and configure default styling:

```cpp
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
ImGui::StyleColorsDark();

```

### 3. Initialize Platform and Renderer Backends

Initialize the platform backend first, then the OpenGL backend. The `ImGui_ImplOpenGL3_Init` function requires a GLSL version string matching your OpenGL context:

```cpp
// Initialize GLFW platform backend
ImGui_ImplGlfw_InitForOpenGL(window, true);

// Initialize OpenGL renderer backend with appropriate GLSL version
const char* glsl_version = "#version 150"; // OpenGL 3.2 core
ImGui_ImplOpenGL3_Init(glsl_version);

```

Valid GLSL strings include `"#version 130"` (OpenGL 3.0), `"#version 150"` (OpenGL 3.2), or `"#version 330 core"` (OpenGL 3.3).

### 4. Implement the Main Render Loop

Each frame follows a strict three-part new-frame sequence, UI construction, and rendering phase:

```cpp
while (!glfwWindowShouldClose(window))
{
    glfwPollEvents();

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

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

    // Rendering
    ImGui::Render();
    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 ImGui draw commands
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
    
    glfwSwapBuffers(window);
}

```

### 5. Cleanup and Shutdown

Release resources in reverse initialization order to prevent memory leaks:

```cpp
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();

```

## Complete Working Example

Here is a minimal, compilable program integrating Dear ImGui with OpenGL 3 and GLFW, based on the official example in [`examples/example_glfw_opengl3/main.cpp`](https://github.com/ocornut/imgui/blob/main/examples/example_glfw_opengl3/main.cpp):

```cpp
#include <GLFW/glfw3.h>
#include "imgui.h"
#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_opengl3.h"

int main()
{
    // 1. 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 + OpenGL3 Example", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

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

    // 3. Setup Platform/Renderer backends
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    const char* glsl_version = "#version 150";
    ImGui_ImplOpenGL3_Init(glsl_version);

    // 4. Main loop
    while (!glfwWindowShouldClose(window))
    {
        glfwPollEvents();

        // Frame start
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        // UI Construction
        ImGui::Begin("Demo Window");
        ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
        ImGui::End();

        // Render
        ImGui::Render();
        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);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

        glfwSwapBuffers(window);
    }

    // 5. Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

```

## Selecting the Correct GLSL Version

The `glsl_version` parameter passed to `ImGui_ImplOpenGL3_Init` must match the OpenGL context version you created:

- **OpenGL 3.0**: `"#version 130"`
- **OpenGL 3.2** (core profile): `"#version 150"`
- **OpenGL 3.3+**: `"#version 330 core"` or higher

Mismatching these versions results in shader compilation errors during `ImGui_ImplOpenGL3_Init`.

## Summary

- **Dear ImGui requires two backends**: a platform backend (GLFW/SDL/Win32) for input/windowing and the `imgui_impl_opengl3` renderer backend for GPU output.
- **Initialization order matters**: Create OpenGL context → Create ImGui context → Init platform backend → Init OpenGL backend.
- **Per-frame sequence**: Call `ImGui_ImplOpenGL3_NewFrame()`, then platform `NewFrame()`, then `ImGui::NewFrame()`, build UI, call `ImGui::Render()`, and finally `ImGui_ImplOpenGL3_RenderDrawData()`.
- **Cleanup in reverse**: Shutdown OpenGL backend → Shutdown platform backend → Destroy ImGui context.
- **GLSL version strings** must match your OpenGL context profile to ensure internal shaders compile correctly.

## Frequently Asked Questions

### Do I need to write custom OpenGL shaders to use Dear ImGui?

No. The [`imgui_impl_opengl3.cpp`](https://github.com/ocornut/imgui/blob/main/imgui_impl_opengl3.cpp) backend contains its own minimal vertex and fragment shaders that it compiles automatically during `ImGui_ImplOpenGL3_Init`. These shaders handle the anti-aliased font rendering and vertex color interpolation required by ImGui's draw lists. You only need to provide the correct GLSL version string.

### Can I use Dear ImGui with OpenGL 2.1 or OpenGL ES?

Yes. The repository provides separate backends for legacy OpenGL 2 (`imgui_impl_opengl2.h/cpp`) and OpenGL ES 2/3 (`imgui_impl_opengl3.h/cpp` with appropriate GL loader configuration). Use `imgui_impl_opengl2` for compatibility with older hardware, or ensure your GL loader in [`imgui_impl_opengl3_loader.h`](https://github.com/ocornut/imgui/blob/main/imgui_impl_opengl3_loader.h) defines the necessary ES symbols when targeting mobile platforms.

### Why is my Dear ImGui window blank or not rendering?

A blank screen typically indicates a mismatch between your OpenGL context version and the GLSL version string passed to `ImGui_ImplOpenGL3_Init`, or failure to call `glfwMakeContextCurrent` before initializing the backend. Ensure you have created a valid OpenGL context, specified the correct GLSL version (e.g., `"#version 150"` for OpenGL 3.2 core), and included the `ImGui_ImplOpenGL3_RenderDrawData` call after `ImGui::Render` in your main loop.

### How do I handle DPI scaling with Dear ImGui and OpenGL?

Handle DPI scaling by detecting the framebuffer scale via your platform backend (e.g., `glfwGetWindowContentScale` for GLFW), then set `io.DisplayFramebufferScale` to the appropriate scale factor before calling `ImGui::NewFrame`. The OpenGL backend automatically adjusts vertex positions and font texture sampling to account for high-DPI displays when this scale is configured correctly.