| 1 | _(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md or view this file with any Markdown viewer)_ |
| 2 | |
| 3 | # Dear ImGui: Backends |
| 4 | |
| 5 | ## Index |
| 6 | |
| 7 | - [Introduction](#introduction) |
| 8 | - [Getting Started](#getting-started) |
| 9 | - [What are Backends?](#what-are-backends) |
| 10 | - [Using standard Backends](#using-standard-backends) |
| 11 | - [Using third-party Backends](#using-third-party-backends) |
| 12 | - [Writing your own Backend](#writing-your-own-backend) |
| 13 | - [Using a custom engine?](#using-a-custom-engine) |
| 14 | - [Platform: Implementing your Platform Backend](#platform-implementing-your-platform-backend) |
| 15 | - [Rendering: Implementing your RenderDrawData function](#rendering-implementing-your-renderdrawdata-function) |
| 16 | - [Rendering: Adding support for `ImGuiBackendFlags_RendererHasTextures` (1.92+)](#rendering-adding-support-for-imguibackendflags_rendererhastextures-192) |
| 17 | |
| 18 | ## Introduction |
| 19 | |
| 20 | ### Getting Started |
| 21 | |
| 22 | 💡 The **[Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) wiki guide** has examples of how to integrate Dear ImGui into an existing application. |
| 23 | <BR> The [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) documentation may also be worth a read. |
| 24 | |
| 25 | ### What are Backends? |
| 26 | |
| 27 | Dear ImGui is highly portable and only requires a few things to run and render, typically: |
| 28 | |
| 29 | - Required: providing mouse/keyboard inputs (fed into the `ImGuiIO` structure). |
| 30 | - Required: creating, updating and destroying textures. |
| 31 | - Required: rendering indexed textured triangles with a clipping rectangle. |
| 32 | |
| 33 | Extra features are opt-in, our backends try to support as many as possible: |
| 34 | |
| 35 | - Optional: custom texture binding support. |
| 36 | - Optional: clipboard support. |
| 37 | - Optional: gamepad support. |
| 38 | - Optional: mouse cursor shape support. |
| 39 | - Optional: IME support. |
| 40 | - Optional: multi-viewports support. |
| 41 | etc. |
| 42 | |
| 43 | This is essentially what each backend is doing + obligatory portability cruft. Using standard backends ensure you can get all those features including the ones that would be harder to implement on your side (e.g. multi-viewports support). |
| 44 | |
| 45 | It is important to understand the difference between the core Dear ImGui library (files in the root folder) |
| 46 | and the backends which we are describing here (backends/ folder). |
| 47 | |
| 48 | - Some issues may only be backend or platform specific. |
| 49 | - You should be able to write backends for pretty much any platform and any 3D graphics API. |
| 50 | e.g. you can get creative and use software rendering or render remotely on a different machine. |
| 51 | |
| 52 | ## Using standard Backends |
| 53 | |
| 54 | **The [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder contains backends for popular platforms/graphics API, which you can use in |
| 55 | your application or engine to easily integrate Dear ImGui.** Each backend is typically self-contained in a pair of files: imgui_impl_XXXX.cpp + imgui_impl_XXXX.h. |
| 56 | |
| 57 | - The 'Platform' backends are in charge of: mouse/keyboard/gamepad inputs, cursor shape, timing, and windowing.<BR> |
| 58 | e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), SDL3 ([imgui_impl_sdl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl3.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), etc. |
| 59 | |
| 60 | - The 'Renderer' backends are in charge of: creating atlas texture, and rendering imgui draw data.<BR> |
| 61 | e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp)), Vulkan ([imgui_impl_vulkan.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp)), etc. |
| 62 | |
| 63 | - For some high-level frameworks, a single backend usually handles both 'Platform' and 'Renderer' parts.<BR> |
| 64 | e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)). If you end up creating a custom backend for your engine, you may want to do the same. |
| 65 | |
| 66 | An application usually combines one Platform backend + one Renderer backend + main Dear ImGui sources. |
| 67 | For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. There are 20+ examples in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details. |
| 68 | |
| 69 | **Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.** |
| 70 | |
| 71 | ### List of standard Backends |
| 72 | |
| 73 | In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder: |
| 74 | |
| 75 | List of Platforms Backends: |
| 76 | |
| 77 | imgui_impl_android.cpp ; Android native app API |
| 78 | imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/ |
| 79 | imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl backends) |
| 80 | imgui_impl_sdl2.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org |
| 81 | imgui_impl_sdl3.cpp ; SDL3 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org |
| 82 | imgui_impl_win32.cpp ; Win32 native API (Windows) |
| 83 | imgui_impl_glut.cpp ; GLUT/FreeGLUT (this is prehistoric software and absolutely not recommended today!) |
| 84 | |
| 85 | List of Renderer Backends: |
| 86 | |
| 87 | imgui_impl_dx9.cpp ; DirectX9 |
| 88 | imgui_impl_dx10.cpp ; DirectX10 |
| 89 | imgui_impl_dx11.cpp ; DirectX11 |
| 90 | imgui_impl_dx12.cpp ; DirectX12 |
| 91 | imgui_impl_metal.mm ; Metal (ObjC or C++) |
| 92 | imgui_impl_opengl2.cpp ; OpenGL 2 (legacy fixed pipeline. Don't use with modern OpenGL code!) |
| 93 | imgui_impl_opengl3.cpp ; OpenGL 3/4, OpenGL ES 2/3, WebGL |
| 94 | imgui_impl_sdlgpu3.cpp ; SDL_GPU (portable 3D graphics API of SDL3) |
| 95 | imgui_impl_sdlrenderer2.cpp ; SDL_Renderer (optional component of SDL2 available from SDL 2.0.18+) |
| 96 | imgui_impl_sdlrenderer3.cpp ; SDL_Renderer (optional component of SDL3. Prefer using SDL_GPU!). |
| 97 | imgui_impl_vulkan.cpp ; Vulkan |
| 98 | imgui_impl_wgpu.cpp ; WebGPU (web + desktop) |
| 99 | |
| 100 | List of high-level Frameworks Backends (combining Platform + Renderer): |
| 101 | |
| 102 | imgui_impl_allegro5.cpp |
| 103 | imgui_impl_null.cpp |
| 104 | |
| 105 | Emscripten is also supported! |
| 106 | The SDL2+GL, SDL3+GL, GLFW+GL and GLFW+WebGPU examples are all ready to build and run with Emscripten. |
| 107 | |
| 108 | ### Recommended Backends |
| 109 | |
| 110 | If you are not sure which backend to use, the recommended platform/frameworks for portable applications: |
| 111 | |
| 112 | |Library |Website |Backend |Note | |
| 113 | |--------|--------|--------|-----| |
| 114 | | SDL3 | https://www.libsdl.org | imgui_impl_sdl3.cpp | Recommended | |
| 115 | | SDL2 | https://www.libsdl.org | imgui_impl_sdl2.cpp | | |
| 116 | | GLFW | https://github.com/glfw/glfw | imgui_impl_glfw.cpp | | |
| 117 | | Sokol | https://github.com/floooh/sokol | [util/sokol_imgui.h](https://github.com/floooh/sokol/blob/master/util/sokol_imgui.h) | Lower-level than GLFW/SDL | |
| 118 | |
| 119 | If your application runs on Windows or if you are using multi-viewport, the win32 backend handles some details a little better than other backends. |
| 120 | |
| 121 | ## Using third-party Backends |
| 122 | |
| 123 | See https://github.com/ocornut/imgui/wiki/Bindings for the full list (e.g. Adventure Game Studio, Cinder, Cocos2d-x, Game Maker Studio2, Godot, LÖVE+LUA, Magnum, Monogame, Ogre, openFrameworks, OpenSceneGraph, SFML, Sokol, Unity, Unreal Engine and many others). |
| 124 | |
| 125 | ## Writing your own Backend |
| 126 | |
| 127 | ### Using a custom engine? |
| 128 | |
| 129 | You will likely be tempted to start by rewrite your own backend using your own custom/high-level facilities...<BR> |
| 130 | Think twice! |
| 131 | |
| 132 | TL;DR; |
| 133 | - Writing your own Renderer Backend is easy. |
| 134 | - Writing your own Platform Backend is harder and you are more likely to introduce bugs. |
| 135 | - **It is unlikely you will add value to your project by creating your own backend.** |
| 136 | |
| 137 | **Consider using the existing backends as-is**. |
| 138 | You will save lots of time integrating the library. |
| 139 | Standard backends are battle-tested and handle subtleties that you are likely to implement incorrectly. |
| 140 | You can LATER decide to rewrite yourself a custom backend if you really need to. |
| 141 | In most situations, custom backends have fewer features and more bugs than the standard backends we provide. |
| 142 | If you want portability, you can use multiple backends and choose between them either at compile time |
| 143 | or at runtime. |
| 144 | |
| 145 | **Example A**: your engine is built over Windows + DirectX11 but you have your own high-level rendering |
| 146 | system layered over DirectX11.<BR> |
| 147 | Suggestion: try using imgui_impl_win32.cpp + imgui_impl_dx11.cpp first. |
| 148 | Once it works, if you really need it, you can replace the imgui_impl_dx11.cpp code with a |
| 149 | custom renderer using your own rendering functions, and keep using the standard Win32 code etc. |
| 150 | |
| 151 | **Example B**: your engine runs on Windows, Mac, Linux and uses DirectX11, Metal, and Vulkan respectively.<BR> |
| 152 | Suggestion: use multiple generic backends! |
| 153 | Once it works, if you really need it, you can replace parts of backends with your own abstractions. |
| 154 | |
| 155 | **Example C**: your engine runs on platforms we can't provide public backends for (e.g. PS4/PS5, Switch), |
| 156 | and you have high-level systems everywhere.<BR> |
| 157 | Suggestion: try using a non-portable backend first (e.g. win32 + underlying graphics API) to get |
| 158 | your desktop builds working first. This will get you running faster and get your acquainted with |
| 159 | how Dear ImGui works and is setup. You can then rewrite a custom backend using your own engine API... |
| 160 | |
| 161 | Also: |
| 162 | The [multi-viewports feature](https://github.com/ocornut/imgui/wiki/Multi-Viewports) of the 'docking' branch allows |
| 163 | Dear ImGui windows to be seamlessly detached from the main application window. This is achieved using an |
| 164 | extra layer to the Platform and Renderer backends, which allows Dear ImGui to communicate platform-specific |
| 165 | requests such as: "create an additional OS window", "create a render context", "get the OS position of this |
| 166 | window", but some things are more difficult "find OS window under mouse position BUT with some windows marked as passthrough". See 'ImGuiPlatformIO' for details. |
| 167 | Supporting the multi-viewports feature correctly using 100% of your own abstractions is more difficult |
| 168 | than supporting single-viewport. |
| 169 | If you decide to use unmodified imgui_impl_XXXX.cpp files, you can automatically benefit from |
| 170 | improvements and fixes related to viewports and platform windows without extra work on your side. |
| 171 | |
| 172 | ### Platform: Implementing your Platform Backend |
| 173 | |
| 174 | The Platform backends in impl_impl_XXX.cpp files contain many implementations. |
| 175 | |
| 176 | **In your `ImGui_ImplXXX_Init()` function:** |
| 177 | - You can allocate your backend data and use `io.BackendPlatformUserData` to store/retrieve it later. |
| 178 | - Set `io.BackendPlatformName` to a name `"imgui_impl_xxxx"` which will be available in e.g. About box. |
| 179 | - Set `io.BackendPlatformUserData` to your backend data. |
| 180 | - Set `io.BackendFlags` with supported optional features: |
| 181 | - `ImGuiBackendFlags_HasGamepad`: supports gamepad and currently has one connected. |
| 182 | - `ImGuiBackendFlags_HasMouseCursors`: supports honoring GetMouseCursor() value to change the OS cursor shape. |
| 183 | - `ImGuiBackendFlags_HasSetMousePos`: supports io.WantSetMousePos requests to reposition the OS mouse position (only used if io.ConfigNavMoveSetMousePos is set). |
| 184 | - `ImGuiBackendFlags_PlatformHasViewports` supports multiple viewports. (multi-viewports only) |
| 185 | - `ImGuiBackendFlags_HasMouseHoveredViewport` supports calling io.AddMouseViewportEvent() with the viewport under the mouse. IF POSSIBLE, ignore viewports with the ImGuiViewportFlags_NoInputs flag. If this cannot be done, Dear ImGui needs to use a flawed heuristic to find the viewport under mouse position, as it doesn't know about foreign windows. (multi-viewports only) |
| 186 | - `ImGuiBackendFlags_HasParentViewport` supports honoring viewport->ParentViewportId value, by applying the corresponding parent/child relation at the Platform level. |
| 187 | |
| 188 | **In your `ImGui_ImplXXX_NewFrame()` function:** |
| 189 | - Set `io.DeltaTime` to the time elapsed (in seconds) since last frame. |
| 190 | - Set `io.DisplaySize` to your window size. |
| 191 | - Set `io.DisplayFrameBufferSize` to your window pixel density (macOS/iOS only). |
| 192 | - Update mouse cursor shape is supported. |
| 193 | |
| 194 | **In your `ImGui_ImplXXX_NewFrame()` function or event handlers:** |
| 195 | - **Mouse Support** |
| 196 | - Use `io.AddMousePosEvent()`, `io.AddMouseButtonEvent()`, `io.AddMouseWheelEvent()` to pass mouse events. |
| 197 | - Use `io.AddMouseSourceEvent()` if you are able to distinguish Mouse from TouchScreen from Pen inputs. TouchScreen and Pen inputs requires different logic for some Dear ImGui features. |
| 198 | - Use `io.AddMouseViewportEvent()` to specify which viewport/OS window is being hovered by the mouse. Read instructions carefully as this is not as simple as it seems! (multi-viewports only) |
| 199 | - **Keyboard Support** |
| 200 | - Use `io.AddKeyEvent()` to pass key events. |
| 201 | - Use `io.AddInputCharacter()` to pass text/character events. |
| 202 | - **Gamepad Support** |
| 203 | - Use `io.AddKeyEvent()` and `io.AddKeyAnalogEvent()` to pass gamepad events, using `ImGuiKey_GamepadXXX` values. |
| 204 | - **Miscellaneous** |
| 205 | - Clipboard Support: setup `Platform_GetClipboardTextFn()`, `Platform_SetClipboardTextFn()` handlers in `ImGuiPlatformIO`. |
| 206 | - Open in Shell support: setup `Platform_OpenInShellFn()` handler in `ImGuiPlatformIO`. |
| 207 | - IME Support: setup `Platform_SetImeDataFn()` handler in `ImGuiPlatformIO`. |
| 208 | - Use `io.AddFocusEvent()` to notify when application window gets focused/unfocused. |
| 209 | - **Multi-viewport Support** |
| 210 | - Update monitor list if supported. |
| 211 | - Setup all required handlers in `ImGuiPlatformIO` to create/destroy/move/resize/title/focus/etc. windows. |
| 212 | |
| 213 | ### Rendering: Implementing your RenderDrawData function |
| 214 | |
| 215 | Note: set `ImGuiBackendFlags_RendererHasVtxOffset` to signify your backend can handle rendering with a vertex offset (`ImDrawCmd::VtxOffset` field). |
| 216 | Otherwise, rendering will be limited to 64K vertices per window, which may be limiting for advanced plot. |
| 217 | As an alternative, you may also use `#define ImDrawIdx unsigned int` in your `imconfig.h` file to support 32-bit indices. |
| 218 | |
| 219 | ```cpp |
| 220 | void MyImGuiBackend_RenderDrawData(ImDrawData* draw_data) |
| 221 | { |
| 222 | // TODO: Update textures. |
| 223 | // - Most of the times, the list will have 1 element with an OK status, aka nothing to do. |
| 224 | // - This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates. |
| 225 | if (draw_data->Textures != nullptr) |
| 226 | for (ImTextureData* tex : *draw_data->Textures) |
| 227 | if (tex->Status != ImTextureStatus_OK) |
| 228 | MyImGuiBackend_UpdateTexture(tex); |
| 229 | |
| 230 | // TODO: Setup render state: |
| 231 | // - Alpha-blending enabled |
| 232 | // - No backface culling |
| 233 | // - No depth testing, no depth writing |
| 234 | // - Scissor enabled |
| 235 | MyEngineSetupenderState(); |
| 236 | |
| 237 | // TODO: Setup texture sampling state |
| 238 | // - Sample with bilinear filtering (NOT point/nearest filtering). |
| 239 | // - Use 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines;' to allow point/nearest filtering. |
| 240 | |
| 241 | // TODO: Setup viewport covering draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize |
| 242 | |
| 243 | // TODO: Setup orthographic projection matrix cover draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize |
| 244 | |
| 245 | // TODO: Setup shader: vertex { float2 pos, float2 uv, u32 color }, fragment shader sample color from 1 texture, multiply by vertex color. |
| 246 | |
| 247 | // Render command lists |
| 248 | ImVec2 clip_off = draw_data->DisplayPos; |
| 249 | ImVec2 clip_scale = draw_data->FramebufferScale; |
| 250 | for (const ImDrawList* draw_list : draw_data->CmdLists) |
| 251 | { |
| 252 | const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; // vertex buffer generated by Dear ImGui |
| 253 | const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; // index buffer generated by Dear ImGui |
| 254 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) |
| 255 | { |
| 256 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; |
| 257 | if (pcmd->UserCallback) |
| 258 | { |
| 259 | if (pcmd->UserCallback == platform_io.DrawCallback_ResetRenderState) |
| 260 | MyEngineSetupSenderState(); |
| 261 | else |
| 262 | pcmd->UserCallback(cmd_list, pcmd); |
| 263 | } |
| 264 | else |
| 265 | { |
| 266 | // Project scissor/clipping rectangles into framebuffer space |
| 267 | // - Clipping coordinates are provided in imgui coordinates space: |
| 268 | // - For a given viewport, draw_data->DisplayPos == viewport->Pos and draw_data->DisplaySize == viewport->Size |
| 269 | // - In a single viewport application, draw_data->DisplayPos == (0,0) and draw_data->DisplaySize == io.DisplaySize, but always use GetMainViewport()->Pos/Size instead of hardcoding those values. |
| 270 | // - In the interest of supporting multi-viewport applications (see 'docking' branch on github), |
| 271 | // always subtract draw_data->DisplayPos from clipping bounds to convert them to your viewport space. |
| 272 | // - Note that pcmd->ClipRect contains Min+Max bounds. Some graphics API may use Min+Max, other may use Min+Size (size being Max-Min) |
| 273 | ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y); |
| 274 | ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y); |
| 275 | if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) |
| 276 | continue; |
| 277 | |
| 278 | // We are using scissoring to clip some objects. All low-level graphics API should support it. |
| 279 | // - If your engine doesn't support scissoring yet, you may ignore this at first. You will get some small glitches |
| 280 | // (some elements visible outside their bounds) but you can fix that once everything else works! |
| 281 | MyEngineSetScissor(clip_min.x, clip_min.y, clip_max.x, clip_max.y); |
| 282 | |
| 283 | // The texture for the draw call is specified by pcmd->GetTexID(). |
| 284 | // The vast majority of draw calls will use the Dear ImGui texture atlas, which value you have set yourself during initialization. |
| 285 | MyEngineBindTexture((MyTexture*)pcmd->GetTexID()); |
| 286 | |
| 287 | // Render 'pcmd->ElemCount/3' indexed triangles. |
| 288 | // By default the indices ImDrawIdx are 16-bit, you can change them to 32-bit in imconfig.h if your engine doesn't support 16-bit indices. |
| 289 | MyEngineDrawIndexedTriangles(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset, vtx_buffer, pcmd->VtxOffset); |
| 290 | } |
| 291 | } |
| 292 | } |
| 293 | } |
| 294 | ``` |
| 295 | |
| 296 | ### Rendering: Adding support for `ImGuiBackendFlags_RendererHasTextures` (1.92+) |
| 297 | |
| 298 | Version [1.92.0](https://github.com/ocornut/imgui/releases/tag/v1.92.0) (June 2025), added texture support in Rendering Backends, which is the backbone for supporting dynamic font scaling among other things. |
| 299 | |
| 300 | **In order to move forward and take advantage of all new features, support for `ImGuiBackendFlags_RendererHasTextures` will likely be REQUIRED for all backends before June 2026.** |
| 301 | |
| 302 | `ImFontAtlas` functions such as `Build()`, `GetTexDataAsRGBA32()`, `GetTexDataAsAlpha8()`, `SetTexID()`, `IsBuilt()` were obsoleted in favor if iterating a `Textures[]` array and updating their state when requested by Dear ImGui. |
| 303 | |
| 304 | **TD;DR: List of commits which added support for `ImGuiBackendFlags_RendererHasTextures` in standard backends:** |
| 305 | |
| 306 | - Allegro5: [ee8941e](https://github.com/ocornut/imgui/commit/ee8941e) (+35 lines) |
| 307 | - DirectX9: [75efba7](https://github.com/ocornut/imgui/commit/75efba7) (+48 lines) |
| 308 | - DirectX10: [2d2b1bc](https://github.com/ocornut/imgui/commit/2d2b1bc) (+40 lines) |
| 309 | - DirectX11: [372fd27](https://github.com/ocornut/imgui/commit/372fd27) (+40 lines) |
| 310 | - DirectX12: [eefe5d5](https://github.com/ocornut/imgui/commit/eefe5d5) (+87 lines) |
| 311 | - Metal: [26c017d](https://github.com/ocornut/imgui/commit/26c017d) (+55 lines) |
| 312 | - OpenGL Legacy: [0430c55](https://github.com/ocornut/imgui/commit/0430c55) (+25 lines) |
| 313 | - OpenGL3/WebGL/ES: [dbb91a5](https://github.com/ocornut/imgui/commit/dbb91a5) (+47 lines) |
| 314 | - SDL_Renderer2: [9fa65cd](https://github.com/ocornut/imgui/commit/9fa65cd) (+20 lines) |
| 315 | - SDL_Renderer3: [e538883](https://github.com/ocornut/imgui/commit/e538883) (+19 lines) |
| 316 | - SDL_GPU: [16fe666](https://github.com/ocornut/imgui/commit/16fe666) (+41 lines) |
| 317 | - Vulkan: [abe294b](https://github.com/ocornut/imgui/commit/abe294b) (+33 lines) |
| 318 | - WGPU: [571dae9](https://github.com/ocornut/imgui/commit/571dae9) (+30 lines) |
| 319 | |
| 320 | **Instructions:** |
| 321 | |
| 322 | - Set `ImGuiBackendFlags_RendererHasTextures` to signify your backend can handle the feature. |
| 323 | - During rendering, e.g. in your RenderDrawData function, iterate `ImDrawData->Textures` array and process all textures. |
| 324 | - During shutdown, iterate the `ImGui::GetPlatformIO().Textures` and destroy all textures. |
| 325 | - (Both arrays are `ImVector<ImTextureData*>`. They are only in different location because: to allow advanced users to perform multi-threaded rendering, we store a pointer to the texture list in ImDrawData, with the aim that multi-threaded rendering users replace it with their own pointer.) |
| 326 | |
| 327 | Pseudo-code for processing a texture: |
| 328 | ```cpp |
| 329 | if (draw_data->Textures != nullptr) |
| 330 | for (ImTextureData* tex : *draw_data->Textures) |
| 331 | if (tex->Status != ImTextureStatus_OK) |
| 332 | MyImGuiBackend_UpdateTexture(tex); |
| 333 | ``` |
| 334 | ```cpp |
| 335 | void MyImGuiBackend_UpdateTexture(ImTextureData* tex) |
| 336 | { |
| 337 | if (tex->Status == ImTextureStatus_WantCreate) |
| 338 | { |
| 339 | // Create texture based on tex->Width, tex->Height. |
| 340 | // - Most backends only support tex->Format == ImTextureFormat_RGBA32. |
| 341 | // - Backends for particularly memory constrained platforms may support tex->Format == ImTextureFormat_Alpha8. |
| 342 | |
| 343 | // Upload all texture pixels |
| 344 | // - Read from our CPU-side copy of the texture and copy to your graphics API. |
| 345 | // - Use tex->Width, tex->Height, tex->GetPixels(), tex->GetPixelsAt(), tex->GetPitch() as needed. |
| 346 | |
| 347 | // Store your data, and acknowledge creation. |
| 348 | tex->SetTexID(xxxx); // Specify backend-specific ImTextureID identifier which will be stored in ImDrawCmd. |
| 349 | tex->SetStatus(ImTextureStatus_OK); |
| 350 | tex->BackendUserData = xxxx; // Store more backend data if needed (most backend allocate a small texture to store data in there) |
| 351 | } |
| 352 | if (tex->Status == ImTextureStatus_WantUpdates) |
| 353 | { |
| 354 | // Upload a rectangle of pixels to the existing texture |
| 355 | // - We only ever write to textures regions which have never been used before! |
| 356 | // - Use tex->TexID or tex->BackendUserData to retrieve your stored data. |
| 357 | // - Use tex->UpdateRect.x/y, tex->UpdateRect.w/h to obtain the block position and size. |
| 358 | // - Use tex->Updates[] to obtain individual sub-regions within tex->UpdateRect. Not recommended. |
| 359 | // - Read from our CPU-side copy of the texture and copy to your graphics API. |
| 360 | // - Use tex->Width, tex->Height, tex->GetPixels(), tex->GetPixelsAt(), tex->GetPitch() as needed. |
| 361 | |
| 362 | // Acknowledge update |
| 363 | tex->SetStatus(ImTextureStatus_OK); |
| 364 | } |
| 365 | if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames > 0) |
| 366 | { |
| 367 | // If you use staged rendering and have in-flight renders, changed tex->UnusedFrames > 0 check to higher count as needed e.g. > 2 |
| 368 | |
| 369 | // Destroy texture |
| 370 | // - Use tex->TexID or tex->BackendUserData to retrieve your stored data. |
| 371 | // - Destroy texture in your graphics API. |
| 372 | |
| 373 | // Acknowledge destruction |
| 374 | tex->SetTexID(ImTextureID_Invalid); |
| 375 | tex->SetStatus(ImTextureStatus_Destroyed); |
| 376 | } |
| 377 | } |
| 378 | ``` |
| 379 | Refer to "List of commits which added support for `ImGuiBackendFlags_RendererHasTextures` in standard backends" above for concrete examples of this. |