拓冰建站拓冰建站
首页 / 资讯中心 / 正文

VulkanSceneGraph学习教程(二十二)

第 22 章 与 ImGui 集成本章定位调试面板、实时调参离不开 UI。vsgImGui是独立组件库将 Dear ImGui 叠加到 VSG 渲染之上。本章讲集成模式具体类名随版本可能微调模式稳定。摘要本章介绍如何在 VulkanSceneGraph (VSG) 中集成 Dear ImGui 调试界面。通过vsgImGui外部组件库创建 ImGui 叠加渲染节点实现每帧更新 UI 控件。关键步骤包括1) 安装并链接vsgImGui库2) 继承RenderImGui类重写update方法绘制控件3) 使用CollectEvents转发鼠标键盘事件4) 将 UI 控件绑定到 uniform 值实现实时调参。最终构建带调试面板的查看器支持曝光等参数动态调整。22.1 本章目标了解vsgImGui组件库的作用掌握「ImGui 叠加节点 每帧update绘制控件」的集成模式将 UI 控件绑定到场景参数呼应第 10 章 uniform。22.2 前置准备第 8 章状态命令与第 10 章uniform/描述符已读已安装vsgImGui组件库独立仓库非核心。22.3 组件库与链接vsgImGui是外部组件库与vsgXchange同级需单独安装并链接find_package(vsgImGui REQUIRED) target_link_libraries(my_app PRIVATE vsg::vsg vsgImGui::vsgImGui)若你的版本把 ImGui 整合进核心则无需find_package但按当前仓库现状vsgImGui是独立组件库请以你安装的版本为准。22.4 集成模式ImGui 叠加节点标准做法创建一个渲染 ImGui 的节点通常是vsgImGui::RenderImGui的子类把它加入场景图。它在自己的渲染通道里把 Dear ImGui 的绘制指令输出到屏幕叠加在主场景之上。// 1) 自定义一个 ImGui 节点重写每帧更新classMyGui:publicvsgImGui::RenderImGui{public:MyGui(ref_ptrvsg::Cameracam,ref_ptrvsg::floatValueexposure):camera(cam),exposure(exposure){}voiddoUpdate(boolupdated)override// 每帧调用绘制控件{ImGui::Begin(调试面板);floateexposure-value;if(ImGui::SliderFloat(曝光,e,0.0f,3.0f))exposure-valuee;// 修改 uniform见第 10 章ImGui::Text(FPS: %.1f,ImGui::GetIO().Framerate);ImGui::End();updatedtrue;}ref_ptrvsg::Cameracamera;ref_ptrvsg::floatValueexposure;};方法名doUpdate/update与基类依据vsgImGui版本而定核心是「每帧回调里调用 ImGui 控件 API」。请对照你所用版本的RenderImGui头文件确认重写点。22.5 事件转发要让鼠标/键盘驱动 ImGui需要把 VSG 的PointerEvent/KeyEvent转发给 ImGui。组件库通常提供事件收集器如vsgImGui::CollectEvents将其添加到Viewer的事件处理器viewer-addEventHandlers({vsgImGui::CollectEvents::create(guiNode)});这样 ImGui 能正确响应悬停、点击、输入。22.6 绑定到场景参数实时调参UI 控件直接修改第 10 章的Value类型即可实时生效autoexposurevsg::floatValue::create(1.0f);// 作为 DescriptorBuffer 绑到管线第 10 章autoubovsg::DescriptorBuffer::create(exposure,0);// GUI 里改 exposure-value帧循环里exposure-valuee;ubo-copyDataListToBuffers();// CPU → GPU于是拖动滑块画面曝光立即变化——典型的「调试面板实时参数调整」。22.7 完整示例带调试面板的查看器autoexposurevsg::floatValue::create(1.0f);autoguiMyGui::create(camera,exposure);// 你的 RenderImGui 子类autorootvsg::Group::create();root-addChild(model);root-addChild(gui);// 将 ImGui 叠加到场景图autocommandGraphvsg::createCommandGraphForView(window,camera,root);viewer-assignRecordAndSubmitTaskAndPresentation({commandGraph});viewer-addEventHandlers({vsgImGui::CollectEvents::create(gui)});22.8 常见问题现象原因解决代码/配置示例编译找不到vsgImGui没安装/链接组件库find_package(vsgImGui REQUIRED) 链接错误 CMakeLists.txtcmakebrfind_package(vsg REQUIRED)brtarget_link_libraries(my_app PRIVATE vsg::vsg)br正确 CMakeLists.txtcmakebrfind_package(vsg REQUIRED)brfind_package(vsgImGui REQUIRED) # ← 必须添加brtarget_link_libraries(my_app PRIVATE vsg::vsg vsgImGui::vsgImGui)brImGui 不响应输入没转发事件将CollectEvents或等价事件收集器添加到 Viewer错误写法缺少事件收集器cppbrauto gui MyGui::create(camera, exposure);brroot-addChild(gui);br// 忘记添加事件收集器ImGui 无法接收鼠标/键盘事件br正确写法cppbrauto gui MyGui::create(camera, exposure);brroot-addChild(gui);brviewer-addEventHandlers({ vsgImGui::CollectEvents::create(gui) }); // ← 关键br控件改了无效果没把值同步到 uniform修改value后调用copyDataListToBuffers()错误写法只改值不同步cppbrvoid doUpdate(bool updated) override {br ImGui::SliderFloat(曝光, exposure-value, 0.0f, 3.0f);br // 缺少 copyDataListToBuffers()GPU 未更新br updated true;br}br正确写法cppbrvoid doUpdate(bool updated) override {br float e exposure-value;br if (ImGui::SliderFloat(曝光, e, 0.0f, 3.0f)) {br exposure-value e;br ubo-copyDataListToBuffers(); // ← 同步到 GPUbr }br updated true;br}br面板挡住主场景叠加顺序/通道问题确保 ImGui 在最后渲染叠加通道错误场景图结构cppbrauto root vsg::Group::create();brroot-addChild(gui); // ImGui 节点在前brroot-addChild(model); // 模型节点在后会被 ImGui 遮挡br正确场景图结构cppbrauto root vsg::Group::create();brroot-addChild(model); // 先渲染模型brroot-addChild(gui); // 最后渲染 ImGui叠加在最上层br// 或者使用专门的叠加通道br// auto overlay vsg::OverlayNode::create(gui);br// root-addChild(overlay);br22.9 小结vsgImGui是外部组件库提供 ImGui 叠加渲染节点模式子类RenderImGui→ 每帧update绘制控件 → 加入场景图事件通过收集器转发给 ImGuiUI 控件直接修改Value/uniform配合copyDataListToBuffers()实时生效。22.10 延伸阅读与下一章预告第 10 章《描述符与资源绑定》UI 修改的就是这些 uniform第 24 章《模型查看器》把 ImGui 面板做成完整的查看器控制第 26 章《调试技巧》验证层 RenderDoc 配合参数调整。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门