渲染器后端是 Dear ImGui 中用于将抽象绘图命令转换为特定图形 API 调用的组件。它们负责 ImGui 的即时模式 GUI 系统与 DirectX、OpenGL、Vulkan、Metal 和 WebGPU 等各种图形 API 之间的通信。本页将介绍 ImGui 渲染器后端的架构、实现和用法。
有关平台后端(处理窗口创建、输入等)的信息,请参阅 平台后端。
渲染器后端充当 Dear ImGui 的通用绘图命令与特定图形 API 之间的桥梁。它们负责以下任务:
来源:backends/imgui_impl_vulkan.cpp92-111 backends/imgui_impl_opengl3.cpp224-255 backends/imgui_impl_dx11.cpp53-72
Dear ImGui 为不同的图形 API 提供了多个渲染器后端
| 后端 | 文件 | 图形 API | 主要功能 |
|---|---|---|---|
| DirectX 9 | imgui_impl_dx9.cpp | DirectX 9.0 | 旧版支持,BGRA 颜色 |
| DirectX 10 | imgui_impl_dx10.cpp | DirectX 10 | 现代 DirectX 功能 |
| DirectX 11 | imgui_impl_dx11.cpp | DirectX 11 | 现代管线,着色器资源 |
| DirectX 12 | imgui_impl_dx12.cpp | DirectX 12 | 现代,基于描述符的方法 |
| OpenGL 2 | imgui_impl_opengl2.cpp | OpenGL 2.x | 旧版固定功能管线 |
| OpenGL 3 | imgui_impl_opengl3.cpp | OpenGL 3+/ES2/ES3 | 基于着色器的现代 OpenGL |
| Vulkan | imgui_impl_vulkan.cpp | Vulkan | 显式 GPU 控制,现代 |
| Metal | imgui_impl_metal.mm | Metal (Apple) | iOS/macOS 原生渲染器 |
| WebGPU | imgui_impl_wgpu.cpp | WebGPU | Web/原生跨平台 |
大多数后端都支持带有 ImGuiBackendFlags_RendererHasVtxOffset 标志和用户纹理绑定的超大网格(64k+ 顶点)。
来源:backends/imgui_impl_vulkan.cpp1-8 backends/imgui_impl_opengl3.cpp1-9 backends/imgui_impl_dx11.cpp1-7 backends/imgui_impl_dx12.cpp1-8 backends/imgui_impl_metal.mm1-6 backends/imgui_impl_wgpu.cpp1-8
所有渲染器后端都遵循类似的 API 模式
初始化通常涉及存储设备引用、设置后端功能以及创建初始资源。例如,在 Vulkan 后端中,初始化会设置描述符布局和管线状态。
来源:backends/imgui_impl_vulkan.cpp111-131 backends/imgui_impl_opengl3.cpp297-400 backends/imgui_impl_dx11.cpp142-206
NewFrame() 为新帧准备后端,通常会检查设备对象是否需要创建。RenderDrawData() 将 ImGui 命令列表转换为 API 特定的绘图命令。
来源:backends/imgui_impl_vulkan.cpp491-623 backends/imgui_impl_opengl3.cpp503-637 backends/imgui_impl_dx11.cpp146-315
这些函数管理着色器、缓冲区和纹理等 GPU 资源。字体纹理是单独处理的,因为在运行时重新创建它是一个常见的用例。
来源:backends/imgui_impl_vulkan.cpp537-579 backends/imgui_impl_opengl3.cpp640-731 backends/imgui_impl_dx12.cpp317-427
核心渲染流程在所有后端中遵循类似的流程
此流程将 ImGui 的抽象绘图命令转换为特定图形后端的具体 API 调用。
来源:backends/imgui_impl_vulkan.cpp491-623 backends/imgui_impl_opengl3.cpp503-637 backends/imgui_impl_dx11.cpp146-315
所有后端都管理顶点和索引缓冲区,以将几何数据传输到 GPU
缓冲区管理的关键方面
来源:backends/imgui_impl_vulkan.cpp519-537 backends/imgui_impl_opengl3.cpp503-541 backends/imgui_impl_dx11.cpp155-243
每个后端都定义了适合其图形 API 的着色器
大多数后端使用简单的着色器对,它们
例如,Vulkan 后端定义了 GLSL 着色器,它们
OpenGL 3 同样提供了 GLSL 着色器,适用于桌面和移动端。
后端配置通用渲染状态
| 状态管理 | 典型配置 |
|---|---|
| 混合 | Alpha 混合(SrcAlpha, OneMinusSrcAlpha) |
| 深度测试 | 禁用(UI 是 2D 的) |
| 剔除 | 禁用(显示所有三角形) |
| 裁剪 | 启用(用于裁剪) |
| 基本类型 | 三角形列表 |
| 视口 | 设置为帧缓冲大小 |
| 采样器 | 线性过滤,夹取寻址 |
来源:backends/imgui_impl_vulkan.cpp447-489 backends/imgui_impl_opengl3.cpp429-501 backends/imgui_impl_dx11.cpp88-142
ImGui 至少需要一个纹理用于其字体图集,并且应用程序通常希望绑定自己的纹理。
字体纹理的工作流程对于所有后端都是通用的
来源: backends/imgui_impl_vulkan.cpp537-579 backends/imgui_impl_opengl3.cpp640-687 backends/imgui_impl_dx11.cpp322-377
后端支持使用正确的 API 对象作为 ImTextureID 来绑定用户纹理
| 后端 | ImTextureID 类型 |
|---|---|
| DirectX 9 | LPDIRECT3DTEXTURE9 |
| DirectX 11 | ID3D11ShaderResourceView* |
| DirectX 12 | D3D12_GPU_DESCRIPTOR_HANDLE |
| OpenGL 2/3 | GLuint (纹理 ID) |
| Vulkan | VkDescriptorSet |
| Metal | MTLTexture |
| WebGPU | WGPUTextureView |
来源: backends/imgui_impl_vulkan.h119-123 backends/imgui_impl_dx12.h4-7 backends/imgui_impl_opengl3.h7-8
要在您的应用程序中使用渲染器后端
来源: backends/imgui_impl_vulkan.h111-117 backends/imgui_impl_opengl3.h33-37 backends/imgui_impl_dx11.h27-34
所有渲染器后端都支持通过 ImDrawList::AddCallback() 注册特殊的绘制回调。特殊值 ImDrawCallback_ResetRenderState 告知渲染器重置其状态。
来源: backends/imgui_impl_vulkan.cpp581-590 backends/imgui_impl_dx11.cpp287-290
许多后端通过 ImGuiPlatformIO.Renderer_RenderState 结构在绘制回调期间公开其渲染状态,以实现高级集成。
来源: backends/imgui_impl_vulkan.h129-137 backends/imgui_impl_dx12.h69-73 backends/imgui_impl_wgpu.h58-65
后端在资源管理上有不同的方法
ImGui_ImplVulkan_AddTexture()来源: backends/imgui_impl_vulkan.h119-123 backends/imgui_impl_dx12.h37-44
ImGui_ImplXXX_GetBackendData() 访问io.BackendFlags 中设置适当的标志以指示其功能来源: backends/imgui_impl_vulkan.cpp380-383 backends/imgui_impl_opengl3.cpp252-255 backends/imgui_impl_dx11.cpp97-100
Dear ImGui 中的渲染器后端为将即时模式 GUI 渲染与各种图形 API 集成提供了一种灵活的方式。通过抽象化这些 API 之间的差异,ImGui 允许开发者编写一次 UI 代码即可在任何地方进行渲染。
在实现您自己的渲染器后端或扩展现有后端时,请遵循既定的模式,并专注于在 ImGui 的绘制抽象与目标 API 的特定要求之间进行转换。