// // ViewportPanel.cpp:显示模式单选 + ImGui::Image + 分辨率上报。 // 逻辑照搬原 main.cpp 的 Viewport 窗口(行为不变)。 // #include "ViewportPanel.h" #include #include // vk::Extent2D 经 Renderer 头已带入,显式无妨 using namespace Engine; // u32 / f32(Engine/Core/Types.h) void ViewportPanel::Draw(const EditorContext &ctx, ViewportInputState &out) { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); { ImGui::Begin("Viewport", nullptr, ImGuiWindowFlags_NoCollapse); // 输入焦点上报(悬停计入遮挡:模态框盖住时不误报) out.hovered = ImGui::IsWindowHovered(); out.focused = ImGui::IsWindowFocused(); auto &renderer = *ctx.renderer; const int mode = renderer.GetDisplayMode(); const void *sceneTex = renderer.GetSceneTexture(); if (sceneTex != nullptr && mode == kDisplayViewport) { // 面板可用区域(物理像素)上报为渲染分辨率 → 画面精确填满 // 面板;下一帧帧首 BeginFrameSync 生效(一帧延迟,不可见) const ImVec2 avail = ImGui::GetContentRegionAvail(); const ImVec2 fb = ImGui::GetIO().DisplayFramebufferScale; const u32 wantW = static_cast(avail.x * fb.x + 0.5f); const u32 wantH = static_cast(avail.y * fb.y + 0.5f); if (wantW >= 16 && wantH >= 16) { renderer.SetViewportSize(wantW, wantH); } // 纹理 = 渲染分辨率:等比适配面板可用区域 const vk::Extent2D ext = renderer.GetRenderExtent(); const f32 aspect = ext.height != 0 ? f32(ext.width) / f32(ext.height) : 1.0f; ImVec2 size = avail; if (avail.x / avail.y > aspect) size.x = avail.y * aspect; else size.y = avail.x / aspect; ImGui::Image((ImTextureID) (intptr_t) sceneTex, size); } else { ImGui::TextDisabled("(scene texture not ready)"); } ImGui::End(); } ImGui::PopStyleVar(); }