使用ImGui调试物理模拟
我们在写物理引擎和Demo时,或者研究Box2D和Bullet等物理引擎时,我们都会遇到一个问题:大量的参数调整,通过改参数来观察物理现象,来进行调试。这个过程,不断的改代码,编译,特别耗费时间。使用ImgGui可以很大程度解决这个问题。
ImGui介绍
ImGui = Immediate Mode GUI(即时模式 GUI),和传统 UI(按钮是一个对象、生命周期很长)不同,每一帧都会被“重新声明一遍”。UI 不保存状态,状态只存在于业务代码中。它是为调试、工具、实验而生的,不是为产品 UI 生的。ImGui的Git项目,在这里。
ImGui工作原理
ImGui的核心工作原理,本质上是一个每帧循环,流程如下:
- 平台层输入:操作系统或平台(SDL、GLFW、Win32 等)收集鼠标、键盘、滚轮、窗口尺寸等输入信息。
- ImGui IO 更新:平台层把这些输入写入 ImGuiIO,供 ImGui 内部使用。
- ImGui::NewFrame():开始新的一帧,清理上一帧临时数据,初始化布局、活跃控件状态和帧上下文。
- 构建 UI(Immediate Mode):通过函数调用声明界面元素(按钮、滑条等),每一帧重新生成 UI,而不是依赖长期对象。
- 布局 + 交互 + ID 解析:计算控件位置和大小,判断输入是否命中控件,并根据 ID 系统处理交互状态(激活、拖拽等)。
- ImGui::Render():把当前帧的 UI 信息转换成纯渲染数据(Draw Data),不再包含 UI 逻辑。
- 生成 Draw Data:整理顶点、索引和绘制命令,形成渲染用的数据列表。
- 后端渲染执行:渲染后端(OpenGL、Vulkan、DirectX 等)读取 Draw Data,上传 GPU 并执行绘制,将 UI 显示在屏幕上。
物理模拟调试分类
这是我会长期使用、也非常适合物理模拟研究的一种划分。
- 物体系统控制(Simulation Control)
物理系统基本控制:包括 Pause / Step / Fixed dt/ Sub step。
- 世界级参数(World / Environment)
物理参数:重力 / 全局阻尼 / 全局速度和角速度控制 / Sleeping阈值
- 刚体与形状(Rigid Body & Shape)
刚体参数:Mass / Damping / Friction / Locked Freedom
- 约束与求解器(Constraint & Solver)
求解约束器相关参数:solver interation, Baumgarte, Warming start, 约束切换
- 可视化与诊断(Debug Visualization & Diagnostics)
显示开关:AABB, 接触点,法线,睡眠状态.
- 统计信息(Debug Info)
刚体个数、接触点数、约束个数、FPS等。