> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ocornut/imgui/llms.txt
> Use this file to discover all available pages before exploring further.

# Renderer Backends

> Renderer backends for graphics API integration and drawing

## Overview

Renderer backends handle the graphics API interface for Dear ImGui. They are responsible for:

* Creating and updating textures (font atlas, user textures)
* Compiling and managing shaders
* Setting up render state (blending, scissor testing, etc.)
* Rendering indexed triangle meshes with clipping
* Managing graphics API resources

<Note>
  Renderer backends must be paired with a [Platform Backend](/backends/platform-backends) for windowing and input.
</Note>

## Available Renderer Backends

### OpenGL3 Backend

**File**: `imgui_impl_opengl3.cpp` / `imgui_impl_opengl3.h`

<Card title="Best for cross-platform desktop and web" icon="globe">
  Supports modern OpenGL (3.x/4.x), OpenGL ES (2.0/3.0), and WebGL. The most portable renderer backend.
</Card>

#### Features

* ✅ User texture binding (use `GLuint` as `ImTextureID`)
* ✅ Large meshes support (64k+ vertices) on desktop OpenGL
* ✅ Dynamic texture updates
* ✅ Supports desktop GL, GLES, and WebGL

#### Supported APIs

* Desktop OpenGL 2.x, 3.x, 4.x
* OpenGL ES 2.0 (WebGL 1.0)
* OpenGL ES 3.0 (WebGL 2.0)

#### Basic Usage

```cpp theme={null}
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include <GLFW/glfw3.h>

int main() {
    // ... GLFW initialization ...
    
    // Decide GL+GLSL versions
    const char* glsl_version = "#version 330";
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    
    GLFWwindow* window = glfwCreateWindow(1280, 720, "App", NULL, NULL);
    glfwMakeContextCurrent(window);
    
    // Setup Dear ImGui
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    
    // Initialize backends
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init(glsl_version);
    
    // Main loop
    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();
        
        // Start frame
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();
        
        // Your UI code
        ImGui::ShowDemoWindow();
        
        // 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);
    }
    
    // Cleanup
    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();
    
    return 0;
}
```

#### GLSL Version Selection

The `glsl_version` parameter should match your OpenGL context:

```cpp theme={null}
// Desktop GL 3.3+
const char* glsl_version = "#version 330";

// Desktop GL 4.1+ (macOS)
const char* glsl_version = "#version 410";

// OpenGL ES 2.0 (WebGL 1.0)
const char* glsl_version = "#version 100";

// OpenGL ES 3.0 (WebGL 2.0)
const char* glsl_version = "#version 300 es";
```

#### Configuration Defines

For OpenGL ES, define in your `imconfig.h` or build system:

```cpp theme={null}
// Enable OpenGL ES 2.0
#define IMGUI_IMPL_OPENGL_ES2

// Enable OpenGL ES 3.0
#define IMGUI_IMPL_OPENGL_ES3
```

These are auto-detected on iOS, Android, and Emscripten.

#### API Functions

```cpp theme={null}
// Initialize with optional GLSL version string
bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);

// Per-frame update
void ImGui_ImplOpenGL3_NewFrame();

// Render Dear ImGui draw data
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);

// Shutdown
void ImGui_ImplOpenGL3_Shutdown();

// Device objects management
bool ImGui_ImplOpenGL3_CreateDeviceObjects();
void ImGui_ImplOpenGL3_DestroyDeviceObjects();

// Manual texture update
void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex);
```

***

### Vulkan Backend

**File**: `imgui_impl_vulkan.cpp` / `imgui_impl_vulkan.h`

<Card title="Modern explicit graphics API" icon="rocket">
  Vulkan backend with full control over rendering pipeline. Best for high-performance applications.
</Card>

#### Features

* ✅ User texture binding (use `VkDescriptorSet` as `ImTextureID`)
* ✅ Large meshes support (64k+ vertices)
* ✅ Dynamic texture updates
* ✅ Dynamic rendering support (Vulkan 1.3)
* ✅ Exposes render state for callbacks

#### Initialization

Vulkan backend requires more setup than other backends:

```cpp theme={null}
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_vulkan.h"
#include <vulkan/vulkan.h>

// Vulkan error check callback
static void check_vk_result(VkResult err) {
    if (err == 0) return;
    fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err);
    if (err < 0) abort();
}

int main() {
    // ... Create Vulkan instance, device, queues, etc. ...
    
    // Setup Dear ImGui
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    
    // Initialize platform backend
    ImGui_ImplGlfw_InitForVulkan(window, true);
    
    // Initialize Vulkan backend
    ImGui_ImplVulkan_InitInfo init_info = {};
    init_info.Instance = instance;
    init_info.PhysicalDevice = physical_device;
    init_info.Device = device;
    init_info.QueueFamily = queue_family;
    init_info.Queue = queue;
    init_info.DescriptorPool = descriptor_pool;
    init_info.MinImageCount = min_image_count;
    init_info.ImageCount = image_count;
    init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
    init_info.PipelineInfoMain.RenderPass = render_pass;
    init_info.PipelineInfoMain.Subpass = 0;
    init_info.CheckVkResultFn = check_vk_result;
    
    ImGui_ImplVulkan_Init(&init_info);
    
    // Main loop
    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();
        
        // Start frame
        ImGui_ImplVulkan_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();
        
        // Your UI code
        ImGui::ShowDemoWindow();
        
        // Render
        ImGui::Render();
        ImDrawData* draw_data = ImGui::GetDrawData();
        
        // Record command buffer
        VkCommandBufferBeginInfo begin_info = {};
        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
        vkBeginCommandBuffer(command_buffer, &begin_info);
        
        // Begin render pass
        VkRenderPassBeginInfo render_pass_info = {};
        // ... setup render pass ...
        vkCmdBeginRenderPass(command_buffer, &render_pass_info, VK_SUBPASS_CONTENTS_INLINE);
        
        // Render Dear ImGui
        ImGui_ImplVulkan_RenderDrawData(draw_data, command_buffer);
        
        vkCmdEndRenderPass(command_buffer);
        vkEndCommandBuffer(command_buffer);
        
        // Submit and present
        // ...
    }
    
    // Cleanup
    vkDeviceWaitIdle(device);
    ImGui_ImplVulkan_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();
    
    return 0;
}
```

#### Texture Management

Register custom textures with Vulkan:

```cpp theme={null}
// Add a texture
VkDescriptorSet my_texture_id = ImGui_ImplVulkan_AddTexture(
    sampler,
    image_view,
    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
);

// Use in Dear ImGui
ImGui::Image((ImTextureID)my_texture_id, ImVec2(width, height));

// Remove texture when done
ImGui_ImplVulkan_RemoveTexture(my_texture_id);
```

#### Dynamic Rendering (Vulkan 1.3+)

```cpp theme={null}
ImGui_ImplVulkan_InitInfo init_info = {};
// ... other setup ...
init_info.UseDynamicRendering = true;

// Setup pipeline info for dynamic rendering
VkPipelineRenderingCreateInfoKHR rendering_info = {};
rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR;
rendering_info.colorAttachmentCount = 1;
rendering_info.pColorAttachmentFormats = &color_format;
init_info.PipelineInfoMain.PipelineRenderingCreateInfo = rendering_info;

ImGui_ImplVulkan_Init(&init_info);
```

***

### DirectX 11 Backend

**File**: `imgui_impl_dx11.cpp` / `imgui_impl_dx11.h`

<Card title="Recommended for Windows desktop" icon="windows">
  DirectX 11 is well-supported, stable, and provides excellent performance on Windows.
</Card>

#### Features

* ✅ User texture binding (use `ID3D11ShaderResourceView*` as `ImTextureID`)
* ✅ Large meshes support (64k+ vertices)
* ✅ Dynamic texture updates
* ✅ Exposes render state for callbacks

#### Basic Usage

```cpp theme={null}
#include "imgui.h"
#include "imgui_impl_win32.h"
#include "imgui_impl_dx11.h"
#include <d3d11.h>

ID3D11Device* g_pd3dDevice = nullptr;
ID3D11DeviceContext* g_pd3dDeviceContext = nullptr;
IDXGISwapChain* g_pSwapChain = nullptr;
ID3D11RenderTargetView* g_mainRenderTargetView = nullptr;

void CreateRenderTarget() {
    ID3D11Texture2D* pBackBuffer;
    g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
    g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView);
    pBackBuffer->Release();
}

int main() {
    // Create D3D11 device
    DXGI_SWAP_CHAIN_DESC sd = {};
    sd.BufferCount = 2;
    sd.BufferDesc.Width = 1280;
    sd.BufferDesc.Height = 720;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = hwnd;
    sd.SampleDesc.Count = 1;
    sd.Windowed = TRUE;
    sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    
    D3D_FEATURE_LEVEL featureLevel;
    D3D11CreateDeviceAndSwapChain(
        NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
        NULL, 0, D3D11_SDK_VERSION, &sd,
        &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext
    );
    
    CreateRenderTarget();
    
    // Setup Dear ImGui
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    
    // Initialize backends
    ImGui_ImplWin32_Init(hwnd);
    ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
    
    // Main loop
    MSG msg = {};
    while (msg.message != WM_QUIT) {
        if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            continue;
        }
        
        // Start frame
        ImGui_ImplDX11_NewFrame();
        ImGui_ImplWin32_NewFrame();
        ImGui::NewFrame();
        
        // Your UI code
        ImGui::ShowDemoWindow();
        
        // Render
        ImGui::Render();
        const float clear_color[4] = { 0.45f, 0.55f, 0.60f, 1.00f };
        g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL);
        g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color);
        ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
        
        g_pSwapChain->Present(1, 0);
    }
    
    // Cleanup
    ImGui_ImplDX11_Shutdown();
    ImGui_ImplWin32_Shutdown();
    ImGui::DestroyContext();
    
    return 0;
}
```

#### API Functions

```cpp theme={null}
// Initialize with D3D11 device and context
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);

// Per-frame update
void ImGui_ImplDX11_NewFrame();

// Render Dear ImGui draw data
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);

// Shutdown
void ImGui_ImplDX11_Shutdown();

// Device objects (for device reset)
bool ImGui_ImplDX11_CreateDeviceObjects();
void ImGui_ImplDX11_InvalidateDeviceObjects();

// Manual texture update
void ImGui_ImplDX11_UpdateTexture(ImTextureData* tex);
```

***

### DirectX 12 Backend

**File**: `imgui_impl_dx12.cpp` / `imgui_impl_dx12.h`

Modern explicit DirectX API, similar complexity to Vulkan. Best for applications that need fine-grained control over GPU resources.

***

### Metal Backend

**File**: `imgui_impl_metal.mm` / `imgui_impl_metal.h`

<Card title="Apple's modern graphics API" icon="apple">
  Metal backend for macOS and iOS. Supports both Objective-C and C++ APIs.
</Card>

#### Features

* ✅ User texture binding (use `MTLTexture` as `ImTextureID`)
* ✅ Large meshes support (64k+ vertices)
* ✅ Dynamic texture updates
* ✅ ObjC and C++ API support

#### Basic Usage (Objective-C)

```objc theme={null}
#include "imgui.h"
#include "imgui_impl_osx.h"
#include "imgui_impl_metal.h"
#import <Metal/Metal.h>

id<MTLDevice> device;
id<MTLCommandQueue> commandQueue;

int main() {
    // Create Metal device
    device = MTLCreateSystemDefaultDevice();
    commandQueue = [device newCommandQueue];
    
    // Setup Dear ImGui
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    
    // Initialize backends
    ImGui_ImplOSX_Init(view);
    ImGui_ImplMetal_Init(device);
    
    // In your render loop:
    MTLRenderPassDescriptor* renderPassDescriptor = // ... your render pass
    id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
    id<MTLRenderCommandEncoder> renderEncoder =
        [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
    
    // Start frame
    ImGui_ImplMetal_NewFrame(renderPassDescriptor);
    ImGui_ImplOSX_NewFrame(view);
    ImGui::NewFrame();
    
    // Your UI code
    ImGui::ShowDemoWindow();
    
    // Render
    ImGui::Render();
    ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
    
    [renderEncoder endEncoding];
    [commandBuffer presentDrawable:drawable];
    [commandBuffer commit];
    
    return 0;
}
```

***

### WebGPU Backend

**File**: `imgui_impl_wgpu.cpp` / `imgui_impl_wgpu.h`

<Card title="Next-generation web and native graphics" icon="globe">
  WebGPU is the future of web graphics and also works natively. Supports both desktop and web platforms.
</Card>

#### Configuration

Define the WebGPU backend in your `imconfig.h`:

```cpp theme={null}
// For Dawn (Emscripten 4.0.10+)
#define IMGUI_IMPL_WEBGPU_BACKEND_DAWN

// For wgpu-native
#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU
```

***

## Renderer Backend Lifecycle

All renderer backends follow this pattern:

<Steps>
  <Step title="Initialization">
    Initialize the renderer backend after creating the graphics device:

    ```cpp theme={null}
    // Example: OpenGL3
    ImGui_ImplOpenGL3_Init("#version 330");

    // Example: DirectX 11
    ImGui_ImplDX11_Init(device, device_context);
    ```

    The backend sets up:

    * Shaders and pipeline state
    * Default texture (font atlas)
    * Vertex/index buffers
    * Backend flags
  </Step>

  <Step title="Per-Frame Update">
    Call the renderer's `NewFrame()` function:

    ```cpp theme={null}
    ImGui_ImplOpenGL3_NewFrame();
    ```

    This prepares the backend for rendering.
  </Step>

  <Step title="Rendering">
    After `ImGui::Render()`, call the renderer's `RenderDrawData()` function:

    ```cpp theme={null}
    ImGui::Render();
    ImDrawData* draw_data = ImGui::GetDrawData();
    ImGui_ImplOpenGL3_RenderDrawData(draw_data);
    ```

    The backend:

    * Sets up render state
    * Binds textures and buffers
    * Submits draw calls
    * Restores previous state
  </Step>

  <Step title="Shutdown">
    Clean up resources before destroying the graphics device:

    ```cpp theme={null}
    ImGui_ImplOpenGL3_Shutdown();
    ```
  </Step>
</Steps>

## Custom Texture Usage

All renderer backends support custom textures:

### OpenGL3

```cpp theme={null}
GLuint my_texture;
glGenTextures(1, &my_texture);
glBindTexture(GL_TEXTURE_2D, my_texture);
// ... upload texture data ...

ImGui::Image((ImTextureID)(intptr_t)my_texture, ImVec2(width, height));
```

### Vulkan

```cpp theme={null}
VkDescriptorSet my_texture = ImGui_ImplVulkan_AddTexture(
    sampler, image_view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);

ImGui::Image((ImTextureID)my_texture, ImVec2(width, height));
```

### DirectX 11

```cpp theme={null}
ID3D11ShaderResourceView* my_texture;
// ... create texture and SRV ...

ImGui::Image((ImTextureID)my_texture, ImVec2(width, height));
```

## Render State Access

Some backends expose render state for custom draw callbacks:

```cpp theme={null}
// Get render state during rendering
auto* state = (ImGui_ImplDX11_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
ID3D11Device* device = state->Device;
ID3D11DeviceContext* context = state->DeviceContext;

// Use in ImDrawCallback
ImGui::GetWindowDrawList()->AddCallback([](const ImDrawList*, const ImDrawCmd*) {
    auto* state = (ImGui_ImplDX11_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
    // Custom rendering using state->Device, state->DeviceContext, etc.
}, nullptr);
```

## Advanced: Manual Texture Updates

For precise control over texture update timing (e.g., for staged rendering):

```cpp theme={null}
// Disable automatic texture updates
ImDrawData* draw_data = ImGui::GetDrawData();
draw_data->Textures = nullptr;

// Manually update textures
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures) {
    if (tex->Status != ImTextureStatus_OK)
        ImGui_ImplOpenGL3_UpdateTexture(tex);
}
```

## Backend Comparison

| Feature     | OpenGL3   | Vulkan    | DX11     | DX12      | Metal     | WebGPU    |
| ----------- | --------- | --------- | -------- | --------- | --------- | --------- |
| Complexity  | Low       | High      | Low      | High      | Medium    | Medium    |
| Portability | Excellent | Good      | Windows  | Windows   | Apple     | Excellent |
| Performance | Good      | Excellent | Good     | Excellent | Excellent | Good      |
| Setup Code  | Minimal   | Extensive | Moderate | Extensive | Moderate  | Moderate  |
| WebAssembly | Yes       | No        | No       | No        | No        | Yes       |

## Next Steps

<CardGroup cols={2}>
  <Card title="Platform Backends" icon="desktop" href="/backends/platform-backends">
    Learn about platform backends for windowing
  </Card>

  <Card title="Custom Backend" icon="code" href="/backends/custom-backend">
    Create your own renderer backend
  </Card>
</CardGroup>
