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.
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
Renderer backends must be paired with a Platform Backend for windowing and input.
Available Renderer Backends
OpenGL3 Backend
File : imgui_impl_opengl3.cpp / imgui_impl_opengl3.h
Best for cross-platform desktop and web Supports modern OpenGL (3.x/4.x), OpenGL ES (2.0/3.0), and WebGL. The most portable renderer backend.
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
#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.45 f , 0.55 f , 0.60 f , 1.00 f );
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:
// 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:
// 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
// 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
Modern explicit graphics API Vulkan backend with full control over rendering pipeline. Best for high-performance applications.
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:
#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:
// 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+)
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
Recommended for Windows desktop DirectX 11 is well-supported, stable, and provides excellent performance on Windows.
Features
✅ User texture binding (use ID3D11ShaderResourceView* as ImTextureID)
✅ Large meshes support (64k+ vertices)
✅ Dynamic texture updates
✅ Exposes render state for callbacks
Basic Usage
#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 , 0 U , 0 U , 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.45 f , 0.55 f , 0.60 f , 1.00 f };
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
// 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.
File : imgui_impl_metal.mm / imgui_impl_metal.h
Apple's modern graphics API Metal backend for macOS and iOS. Supports both Objective-C and C++ APIs.
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)
#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
Next-generation web and native graphics WebGPU is the future of web graphics and also works natively. Supports both desktop and web platforms.
Configuration
Define the WebGPU backend in your imconfig.h:
// 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:
Initialization
Initialize the renderer backend after creating the graphics device: // 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
Per-Frame Update
Call the renderer’s NewFrame() function: ImGui_ImplOpenGL3_NewFrame ();
This prepares the backend for rendering.
Rendering
After ImGui::Render(), call the renderer’s RenderDrawData() function: 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
Shutdown
Clean up resources before destroying the graphics device: ImGui_ImplOpenGL3_Shutdown ();
Custom Texture Usage
All renderer backends support custom textures:
OpenGL3
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
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
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:
// 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):
// 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
Platform Backends Learn about platform backends for windowing
Custom Backend Create your own renderer backend