菜单

核心架构

相关源文件

本页面详细介绍了 Dear ImGui 的内部架构,解释了其核心组件、执行流程和基本概念。我们将探讨库的组织方式、主要数据结构以及组件之间的交互模式。

有关与平台和图形 API 集成的信息,请参阅后端系统。有关小部件和界面元素的信息,请参阅小部件系统

概述

Dear ImGui 的设计围绕“即时模式”(immediate mode)用户界面范例,其中 UI 在每一帧都从头开始重建。这与维护持久 UI 对象的“保留模式”(retained mode)库形成对比。这种设计选择影响了架构的各个方面,优先考虑简洁性、最小化的状态重复和直接操作。

来源:imgui.h147-201 imgui.cpp102-125

上下文系统

ImGui 库的状态集中在 ImGuiContext 结构体中。一个上下文封装了 Dear ImGui 实例的全部状态,允许潜在的多上下文应用(尽管大多数应用使用单个上下文)。

ImGuiContext

ImGuiContext 是包含以下内容的中心数据结构:

  1. 全局状态信息
  2. 窗口和控件数据
  3. 输入/输出接口
  4. 渲染信息
  5. 字体图集和样式设置

创建和管理上下文

来源:imgui.h179 imgui.h326-330 imgui_internal.h1145-1185

输入/输出接口

ImGuiIO 结构体负责管理您的应用程序与 Dear ImGui 之间的通信

  1. 输入:鼠标位置、按钮状态、键盘输入等。
  2. 输出:通知标志,例如 ImGui 是否想要捕获鼠标/键盘。
  3. 配置:显示尺寸、时间差、字体设置等。

来源:imgui.h180-181 imgui.h333-334 imgui.cpp472-500

帧生命周期

Dear ImGui 中的每一帧都遵循特定的操作顺序,将用户输入转换为可见的 UI。

来源:imgui.cpp273-307 imgui.cpp354-405 imgui.h335-339

关键帧函数

  1. NewFrame():为新帧准备上下文,验证状态,设置时间和输入数据
  2. Begin()/End():定义窗口边界和属性
  3. Widget Functions:创建 UI 元素并与之交互
  4. Render():处理所有待处理的 UI 元素并生成绘图命令
  5. EndFrame():如果 Render() 尚未完成,则完成帧

来源:imgui.cpp79-98 imgui.h370-371

窗口系统

窗口是 Dear ImGui 中 UI 元素的基本容器。每个窗口都有其位置、大小、内容、绘图上下文和状态。

窗口层级结构

窗口可以拥有子窗口,形成一个层级结构

来源:imgui.h359-371 imgui.h391-393 imgui_internal.h1182-1185

渲染系统

ImGui 不直接渲染到屏幕,而是生成供应用程序执行的渲染命令。

ImDrawList 和绘图命令管道

渲染系统围绕以下内容构建:

  1. ImDrawList:一个窗口的渲染命令列表
  2. ImDrawCmd:单个绘图命令(绘图图元、裁剪矩形、回调)
  3. ImDrawData:包含帧的所有 ImDrawList
  4. Renderer Backend:将 ImDrawData 转换为图形 API 调用

来源:imgui.h162-169 imgui.h338-339 imgui_draw.cpp24-33

ID 系统

Dear ImGui 使用分层 ID 系统来唯一跟踪和标识 UI 元素

ID 由以下方式生成:

  • 字符串标签(哈希值)
  • 整数值
  • 指针值
  • 基于堆栈的 ID 嵌套

此系统对于正确跟踪交互状态(例如,哪个按钮被点击)以及在帧之间保留状态至关重要。

来源:imgui.cpp79-81 imgui_internal.h1145-1150

字体系统

Dear ImGui 包括一个字体系统,允许加载和渲染 TrueType 字体

字体系统处理:

  1. 加载字体文件(TTF、OTF)
  2. 构建字体图集
  3. 计算文本尺寸
  4. 渲染文本字符

来源:imgui.h170-176 imgui_draw.cpp14-23

风格系统

ImGui元素的样式由ImGuiStyle结构控制

风格系统提供:

  1. 默认风格(暗色、亮色、经典)
  2. 颜色自定义
  3. 间距和尺寸参数
  4. 运行时修改功能

来源:imgui.h195-196 imgui.h353-356 imgui_draw.cpp182-226

核心执行流程

典型的ImGui应用程序中的执行流程遵循以下模式:

来源:imgui.cpp273-307 imgui.cpp80-98

内存管理

Dear ImGui 的内存管理旨在最大限度地减少正常运行期间的内存分配。

  1. 内存池分配:常用结构使用对象池来避免频繁分配。
  2. 帧重置:许多临时结构在每帧被重置,而不是被释放。
  3. 向量增长策略:大多数动态数组以1.5倍容量的策略增长。
  4. 自定义分配器:库允许覆盖默认的内存分配函数。

来源:imgui.h271-273 imgui_internal.h346-359

配置与自定义

Dear ImGui 提供了多种方式来配置和定制库。

  1. imconfig.h:用户提供的头文件,用于编译时配置。
  2. ImGuiIO:通过 IO 结构进行运行时配置。
  3. ImGuiStyle:通过 Style 结构进行视觉定制。
  4. 自定义函数:可覆盖的内存分配、文件处理等。

这种多层方法提供了灵活性,同时保持了库的核心简洁性。

来源:imgui.h60-65 imgui.cpp241-254

结论

Dear ImGui 的核心架构体现了其设计理念:

  • 最小化状态重复
  • 直接操作 UI
  • 即时视觉反馈
  • 简洁而非复杂

这种架构使 Dear ImGui 既轻量又强大,适用于从简单工具到复杂调试界面的各种应用程序。