Reorganize directory layout: editor panels/, grouped shaders, drop stale header

- App/editor: move 7 panels into panels/ (Editor core stays at root)
- shaders/: group into pbr/ post/ debug/ env/ (runtime load paths updated)
- Delete outdated duplicate Engine/src/Renderer/VulkanAssetUploader.h
This commit is contained in:
2026-10-07 09:52:17 +08:00
parent cc837bc605
commit f73e52926f
55 changed files with 23 additions and 83 deletions
+214
View File
@@ -0,0 +1,214 @@
//
// StatsPanel.cpp:遥测与全局设置实现(原 main.cpp Scene Debug 搬迁)。
// 面板按 View / Scene / Rendering / Physics / Performance 分组——
// 环境贴图/环境光已实体化(Skybox/SkyLight 组件,Details 配置),
// 此处只留场景级 ClearColor。
//
#include "StatsPanel.h"
#include "Engine/ECS/Components.h"
#include "Engine/Physics/PhysicsWorld.h"
#include "Engine/Core/Time.h"
#include <imgui.h>
#include <glm/gtc/type_ptr.hpp>
using namespace Engine; // f32(Engine/Core/Types.h)
void StatsPanel::Draw(const EditorContext& ctx)
{
ImGui::Begin("Stats");
auto& renderer = *ctx.renderer;
auto& app = *ctx.app;
// ---- View:看哪里(渲染目标)+ 相机位姿(跟随渲染源分派)----
if (ImGui::CollapsingHeader("View", ImGuiTreeNodeFlags_DefaultOpen))
{
// 渲染源分派与 SceneRenderer::BuildFrame 同规则:PIE 内嵌播放
// 或 kDisplayDirect 全屏预览 = primary 相机,否则编辑器相机
const bool playing = ctx.playState && *ctx.playState;
static const char* displayTarget[] = {
"Fullscreen",
"Viewport",
};
int mode = renderer.GetDisplayMode();
if (ImGui::Combo("Display Target", &mode, displayTarget,
IM_ARRAYSIZE(displayTarget)))
{
renderer.SetDisplayMode(mode);
}
if ((playing || renderer.GetDisplayMode() == kDisplayDirect))
{
Engine::ECS::TransformComponent* camT = nullptr;
if (ctx.scene->GetPrimaryCamera(&camT) != nullptr && camT != nullptr)
{
// world 位姿(相机实体可能挂父层级下)
const glm::vec3& pos = camT->GetWorldPosition();
ImGui::Text("Game Camera Pos");
ImGui::Text("(%.3f, %.3f, %.3f)", pos.x, pos.y, pos.z);
}
else
{
ImGui::TextDisabled("(no primary camera)");
}
}
else if (ctx.editorCamera)
{
const glm::vec3& pos = ctx.editorCamera->GetTransform().GetPosition();
ImGui::Text("Editor Camera Pos");
ImGui::Text("(%.3f, %.3f, %.3f)", pos.x, pos.y, pos.z);
}
else
{
ImGui::TextDisabled("(no camera)");
}
}
// ---- Scene:模拟控制 + 场景级设置。PIE 暂停在主工具栏(UE 语义)----
if (ImGui::CollapsingHeader("Scene", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::ColorEdit4("Clear Color",
glm::value_ptr(ctx.scene->GetSettings().ClearColor));
}
// ---- Rendering:渲染管线参数与开关 ----
if (ImGui::CollapsingHeader("Rendering", ImGuiTreeNodeFlags_DefaultOpen))
{
f32 exposure = renderer.GetExposure();
if (ImGui::SliderFloat("Exposure", &exposure, 0.1f, 4.0f))
{
renderer.SetExposure(exposure);
}
bool aces = renderer.GetUseACES();
if (ImGui::Checkbox("ACES", &aces))
{
renderer.SetUseACES(aces);
}
// Bloom:开关即显隐——勾上才显示参数
bool bloom = renderer.GetBloomEnabled();
if (ImGui::Checkbox("Bloom", &bloom))
{
renderer.SetBloomEnabled(bloom);
}
if (bloom)
{
f32 threshold = renderer.GetBloomThreshold();
if (ImGui::SliderFloat("Threshold", &threshold, 0.0f, 8.0f,
"%.1f", ImGuiSliderFlags_Logarithmic))
{
renderer.SetBloomThreshold(threshold);
}
f32 strength = renderer.GetBloomStrength();
if (ImGui::SliderFloat("Strength", &strength, 0.0f, 2.0f))
{
renderer.SetBloomStrength(strength);
}
}
// 无参数的纯开关:横排平铺
bool shadows = renderer.GetShadowsEnabled();
if (ImGui::Checkbox("Shadows", &shadows))
{
renderer.SetShadowsEnabled(shadows);
}
ImGui::SameLine();
bool taa = renderer.GetTAAEnabled();
if (ImGui::Checkbox("TAA", &taa))
{
renderer.SetTAAEnabled(taa);
}
ImGui::SameLine();
bool lod = renderer.GetLodEnabled();
if (ImGui::Checkbox("LOD", &lod))
{
renderer.SetLodEnabled(lod); // 关 = 恒绘原网格
}
// 调试视图:单看某个 pass 的中间输出(类 UE pass debug)
const auto& viewNames = renderer.GetDebugViewNames();
int view = renderer.GetDebugView();
if (ImGui::Combo("Debug View", &view, viewNames.data(),
static_cast<int>(viewNames.size())))
{
renderer.SetDebugView(view);
}
}
// ---- Physics:调试可视化(collider/约束/重力/速度/加速度)----
if (ImGui::CollapsingHeader("Physics"))
{
auto& physics = app.GetPhysics();
u32 bits = physics.GetDebugDrawBits();
bool master = bits != 0;
if (ImGui::Checkbox("Debug Draw##Phys", &master))
{
bits = master ? kPhyDbgDefault : 0;
}
if (master)
{
ImGui::Indent();
auto toggle = [&bits](const char* label, u32 bit) {
bool on = (bits & bit) != 0;
if (ImGui::Checkbox(label, &on))
{
bits = on ? (bits | bit) : (bits & ~bit);
}
};
toggle("Colliders", kPhyDbgColliders);
toggle("Constraints", kPhyDbgConstraints);
toggle("Gravity", kPhyDbgGravity);
toggle("Velocity", kPhyDbgVelocity);
toggle("Acceleration", kPhyDbgAccel);
ImGui::Unindent();
}
physics.SetDebugDrawBits(bits);
// 碰撞事件计数(最近一次步进;掉落物触地时应 > 0)
ImGui::Text("contacts (frame): %zu", physics.GetEvents().size());
}
// ---- Performance:帧率控制 + GPU 遥测(默认折叠,不占面板高度)----
if (ImGui::CollapsingHeader("Performance"))
{
bool vsync = app.GetVSync();
if (ImGui::Checkbox("VSync", &vsync))
{
app.SetVSync(vsync);
if (!vsync)
{
const f32 target = app.GetTargetFps();
app.SetTargetFps(target);
}
}
if (!vsync)
{
f32 target = app.GetTargetFps();
if (ImGui::SliderFloat("Target FPS", &target, 24.0f, 360.0f, "%.0f"))
{
app.SetTargetFps(target);
}
}
ImGui::Text("fps: %.1f frame: %llu",
1.0f / Time::Current().UnscaledDt(),
static_cast<unsigned long long>(app.GetFrameCount()));
ImGui::Separator();
ImGui::Text("instances: %u main / %u shadow",
renderer.GetMainInstanceCount(),
renderer.GetShadowInstanceCount());
if (renderer.GetInstancesTruncated())
{
ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f),
"TRUNCATED: instance buffer full!");
}
const auto& names = renderer.GetPassNames();
const auto& times = renderer.GetPassGpuMs();
for (size_t i = 0; i < names.size() && i < times.size(); ++i)
{
ImGui::Text(" %-12s %.3f ms", names[i].c_str(), times[i]);
}
}
ImGui::End();
}