How to Use ImGui with OpenGL 4.x: Complete Backend Integration Guide

To use ImGui with OpenGL 4.x, create a core profile context, pass a GLSL version string (e.g., "#version 450 core") to ImGui_ImplOpenGL3_Init, and render frames using the standard ImGui_ImplOpenGL3_RenderDrawData function.

Dear ImGui is a renderer-agnostic immediate-mode GUI library that integrates with OpenGL 4.x through the imgui_impl_opengl3.* backend in the ocornut/imgui repository. While the backend works with any OpenGL version 2.0 or higher, explicitly configuring a 4.x core context and GLSL version enables automatic utilization of modern features like glClipControl and sampler objects. The implementation preserves all existing GL state, making it safe to insert into existing OpenGL 4.x rendering pipelines.

Create an OpenGL 4.x Core Context

Before initializing ImGui, request an OpenGL 4.x core profile context from your windowing library. When using GLFW, set window hints prior to window creation:

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on macOS

GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui + OpenGL 4.5", nullptr, nullptr);
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // Enable vsync

This follows the same pattern as the reference example in examples/example_glfw_opengl3/main.cpp, modified to request version 4.5 instead of the default 3.x.

Initialize the ImGui OpenGL Backend

After creating the context, initialize ImGui's platform and renderer backends. The critical step for OpenGL 4.x is passing an explicit GLSL version string to ImGui_ImplOpenGL3_Init:

// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;

// Platform backend (GLFW shown here)
ImGui_ImplGlfw_InitForOpenGL(window, true);

// Renderer backend with explicit GLSL 4.5
const char* glsl_version = "#version 450 core";
ImGui_ImplOpenGL3_Init(glsl_version);

If you pass nullptr instead of a version string, the backend auto-detects the context and selects a compatible GLSL version. However, explicitly requesting "#version 450 core" or "#version 410 core" ensures the shader compiler uses modern core-profile syntax.

OpenGL 4.x Features Enabled Automatically

The imgui_impl_opengl3.cpp backend automatically detects and enables OpenGL 4.x optimizations when available:

  • glClipControl (GL 4.5): Supports upper-left clip origins for high-DPI multi-viewport setups. The backend checks HasClipOrigin in ImGui_ImplOpenGL3_SetupRenderState (lines 55-63) and calls glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE) when supported.

  • glBindSampler (GL 3.3+): Enables sampler objects for linear and nearest texture filtering without modifying texture parameters. The backend uses ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear/Nearest (lines 13-33) when IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER is defined.

  • glDrawElementsBaseVertex (GL 3.2+): Allows rendering meshes exceeding 64,000 vertices via vertex offset rendering. The code path at lines 200-207 in ImGui_ImplOpenGL3_RenderDrawData activates when IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET is defined and the driver supports the feature.

  • Programmatic GLSL Selection: ImGui_ImplOpenGL3_CreateDeviceObjects (lines 104-126) prepends your GLSL version string to the shader source, enabling layout(location = ...) attributes required for core profiles.

Implement the Render Loop

The frame rendering sequence remains identical across OpenGL versions. Call the NewFrame functions in order, build your UI, then render:

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

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

    // Your UI code
    ImGui::Begin("OpenGL 4.5 Demo");
    ImGui::Text("Running OpenGL %s", glGetString(GL_VERSION));
    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.1f, 0.1f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
    glfwSwapBuffers(window);
}

The backend preserves all GL state it modifies—including VAO, VBO, shader program, blend mode, and scissor settings—ensuring your existing OpenGL 4.x draw calls remain unaffected.

Cleanup

Shutdown follows the reverse order of initialization:

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

Complete Minimal Example

Below is a self-contained main.cpp demonstrating OpenGL 4.5 integration with GLFW:

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

int main()
{
    // Create GL 4.5 core context
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui + OpenGL 4.5", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    // Setup ImGui
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGui::StyleColorsDark();
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init("#version 450 core");

    // Main loop
    while (!glfwWindowShouldClose(window))
    {
        glfwPollEvents();
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        ImGui::Begin("Hello OpenGL 4.5");
        ImGui::Text("GPU: %s", glGetString(GL_RENDERER));
        ImGui::End();

        ImGui::Render();
        int w, h;
        glfwGetFramebufferSize(window, &w, &h);
        glViewport(0, 0, w, h);
        glClearColor(0.12f, 0.13f, 0.15f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        glfwSwapBuffers(window);
    }

    // Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();
    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

Compile with:

g++ -std=c++17 main.cpp -Ipath/to/imgui -Ipath/to/imgui/backends -lglfw -lGL -ldl -o imgui_gl45

Summary

  • Use imgui_impl_opengl3.cpp as the renderer backend for all OpenGL versions 2.0 through 4.6.
  • Pass a GLSL version string (e.g., "#version 450 core") to ImGui_ImplOpenGL3_Init to enable core-profile shader compilation.
  • Create a core profile context using GLFW hints or equivalent SDL/Win32 calls before initializing ImGui.
  • The backend automatically enables OpenGL 4.x features including glClipControl, glBindSampler, and glDrawElementsBaseVertex when driver support is detected.
  • State preservation ensures the backend does not interfere with your existing OpenGL 4.x rendering code.

Frequently Asked Questions

Does ImGui require a separate backend for OpenGL 4.x?

No. The same imgui_impl_opengl3.cpp backend handles OpenGL 2.0 through 4.6. It detects runtime capabilities via compile-time macros like IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET and runtime flags like HasClipOrigin, automatically enabling modern features when available.

What GLSL version should I use for OpenGL 4.5?

Pass "#version 450 core" to ImGui_ImplOpenGL3_Init. This ensures the backend generates shaders using core-profile syntax with explicit layout locations, which is required for OpenGL 4.5 core contexts. The function prepends this string to the shader source in ImGui_ImplOpenGL3_CreateDeviceObjects.

Can I use ImGui with existing OpenGL 4.x rendering code?

Yes. The backend saves and restores all GL state it touches, including the current VAO, VBO, shader program, blend state, and scissor settings. This makes it safe to call ImGui_ImplOpenGL3_RenderDrawData between your own OpenGL 4.x draw calls without state corruption.

How do I enable glClipControl for upper-left origin rendering?

You do not need manual intervention. When ImGui_ImplOpenGL3_Init detects OpenGL 4.5 or the GL_ARB_clip_control extension, it sets HasClipOrigin = true. The ImGui_ImplOpenGL3_SetupRenderState function (lines 55-63) then automatically calls glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE) when setting up the render state.

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 →