Files
HelloVulkan/App/main.cpp
T
atdunbg a3037cd401 Input facade: add cursor capture, mouse delta and scroll delta
SetCursorCaptured / IsCursorCaptured / GetMouseDelta / ConsumeScrollDelta
now route through the Input facade, so the editor camera no longer takes
a Window& at all: Camera::Update and EditorCamera::Update lose their
window parameter and SandboxApp calls Update(dt) directly. App layer
now has zero Window/GLFW usage for input - everything goes through
Engine::Input.
2026-10-05 11:45:57 +08:00

164 lines
5.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// Created by atdunbg on 2026/9/20.
//
// SandboxApp:基于 Application 框架的编辑器宿主程序。
//
// main 的职责边界:
// - 定义 Application 派生类并运行它
// - 编辑器形态驱动 EditorCamera(Scene view 专用相机,非场景对象)
// - 异步环境加载、全局热键、输入归属门控
// - UI 全部委托 App/editor/ 的 docking Editor(本文件不再出现
// 任何 ImGui 控件)
//
// 场景内容(实体/组件)由编辑器 File 菜单 Save/Load 场景文件管理,
// 相机实体属于场景数据、只在游戏形态参与渲染(UE 语义)。
//
// 窗口、渲染器、事件泵、帧计时、场景容器全部由框架管理。
//
#include <Engine/Core/Application.h>
#include <Engine/Core/Time.h>
#include <Engine/Core/Window.h> // SetInputCapture(Application.h 只前置声明)
#include <Engine/Core/Log.h>
#include <Engine/Core/Stats.h>
#include <Engine/Renderer/Renderer.h>
#include <Engine/Renderer/EditorCamera.h>
#include <Engine/Core/Input.h>
#include "Editor.h"
#include "EditorContext.h"
using namespace Engine;
namespace
{
class SandboxApp final : public Application
{
public:
SandboxApp()
: Application("HelloVulkan", 1920, 1080)
{
}
~SandboxApp() override
{
}
protected:
// ---- 生命周期 ----
void OnInit() override
{
Renderer& renderer = GetRenderer();
renderer.SetDisplayMode(kDisplayViewport);
// ImGui 叠加层(框架只做管线桥接;UI 内容 = docking Editor)
EnableImGui();
// Editor 注入:引擎门面 + 沙盒能力回调(环境异步切换等)
InitEditor();
}
void OnUpdate(const FrameTime& frameTime) override
{
// 编辑器形态:驱动编辑器相机(RMB 飞行 / MMB 焦点环绕 /
// 滚轮推拉)。暂停(timeScale=0)时仍可飞行——unscaled dt。
// PIE 内嵌播放:渲染源已切 primary 相机,编辑器相机停驱
//(否则与游戏脚本抢 WASD,Stop 后视角也被偷跑)。
// 游戏形态:相机实体由游戏逻辑驱动(本沙盒无逻辑 = 静止)
if (GetRenderer().GetDisplayMode() == kDisplayViewport &&
!m_Editor->IsPlaying())
{
GetRenderer().GetEditorCamera().Update(frameTime.UnscaledDt());
}
}
// ---- UI(全部委托 docking Editor;本文件零 ImGui 控件)----
void OnImGuiRender() override
{
m_Editor->Draw();
}
// ---- 事件 ----
void OnWindowClose(const Event& event) override
{
// 退出确认走 Editor 的模态框(ImGui 必须可见才有 UI)
SetImGuiEnabled(true);
m_Editor->RequestQuit();
}
void OnKeyPress(const Event& event) override
{
// 键码统一走 Input::Key(App 层零 GLFW 依赖)
if (event.key == static_cast<int>(Input::Key::GraveAccent))
{
SetImGuiEnabled(!GetImGuiEnabled());
}
if (event.key == static_cast<int>(Input::Key::F1))
{
STATS.PrintComparison();
}
}
void OnWindowResize(const Event& event) override
{
ENGINE_INFO("App: window resized to {}x{}", event.width, event.height);
}
private:
// Editor 注入:门面指针 + 反向能力回调(面板 → 沙盒)
void InitEditor()
{
EditorContext ctx;
ctx.renderer = &GetRenderer();
ctx.scene = &GetScene();
ctx.assets = &GetAssets();
ctx.app = this;
ctx.editorCamera = &GetRenderer().GetEditorCamera();
// 继承原沙盒默认:初始暂停(StatsPanel 的 Pause Simulation 开关恢复)
Time::SetTimeScale(0.0f);
m_Editor->Init(ctx);
// 输入归属:覆盖 EnableImGui 的全局 WantCapture* 谓词
//(全屏 dock host 让它恒真,输入全死)。改为 Editor 按帧
// 判定——Viewport hover/focus 拥有输入(Hazel/UE 语义);
// UI 隐藏(反引号)时 Draw 不再执行,直接全放行
GetWindow().SetInputCapture(
[this] { return GetImGuiEnabled() && m_Editor->BlockingKeyboard(); },
[this] { return GetImGuiEnabled() && m_Editor->BlockingMouse(); });
}
private:
std::unique_ptr<Editor> m_Editor = std::make_unique<Editor>();
};
}
int main()
{
Logger::Initialize();
{
SandboxApp app;
try
{
app.Run();
}
catch (const std::exception& e)
{
ENGINE_FATAL("Exception: {}", e.what());
Logger::Shutdown();
return -1;
}
} // app 析构:成员(Device/Renderer/Window…)全部销毁完毕
Logger::Shutdown();
return 0;
}