在计算机图形学中,视口(Viewport)是一个可观察的多边形区域。
将物体渲染至图像的过程中,会用两种区域表示。世界坐标窗口是用户所关注的区域(即用户想要可视化的东西),坐标系由应用程序确定。例如程序可能会使用米、厘米等单位。此处的“窗口”并非窗口管理器里的视窗,而是借用窗户进行类比,因为它能够限制你所能够观察到的场景的范围。
视口也是一个区域,通常为矩形,且等同于窗口的客户区矩形,但它的坐标系由渲染设备确定。例如将关注的物体渲染至屏幕坐标时,会使用像素为单位。渲染时,通常会先根据世界坐标窗口去裁剪对象,然后再进行窗口至视口的变换。
在 Dear ImGui 的较高版本中,实验性地允许多视口功能。可以简单地理解为允许渲染对象超出主视口(第一个创建的视口)所限定的边界。其基本原理是当检测到 ImGui 窗口超出平台窗口的客户区边界时,自动创建新的平台窗口,并在新的平台窗口下渲染该 ImGui 窗口。在不开启背景 Alpha 的模式下(多视口和背景透明混合一起使用会出现 bug,目前在等待修复),用户几乎不会观察到任何明显的变化或者闪烁。
多视口功能可让我们无缝地从主渲染上下文中提取 Dear ImGui 窗口。在传统游戏编程中,引擎/游戏通常会创建一个与图形上下文相关联的 OS Platform 窗口(例如使用 DirectX、OpenGL),并且所有渲染都必须在此图形上下文中进行。
借助多视口,Dear ImGui 能够根据需要创建新的操作系统平台窗口和图形上下文,以托管已移出主操作系统平台窗口边界的 Dear ImGui。这是通过一组标志和函数(ImGuiPlatformIO
结构内部)实现的,这些标志和函数允许 Dear ImGui 与各个后端进行通信。backends/
文件夹中提供的大多数后端都可以支持多视口。
除此之外,多视口还方便在多台显示器上使用 Dear ImGui。
使用 ImGui 的 docking (停靠)分支,将支持多视口和停靠功能,这个分支目前受到良好的维护和测试,相对稳定。
- 添加配置标志:
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
- 渲染主视口后,在主循环中添加:
// 更新和渲染为多视口扩展的平台窗口
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
// TODO:OpenGL 需要更多操作以便于保存和恢复 GL 上下文
}
注意:在给出的示例中已经实施这些修改,只需要在 main.cpp 中注意取消 ImGuiConfigFlags_ViewportsEnable 的注释即可启用多视口。