Files
HelloVulkan/App/main.cpp
T
atdunbg 8afdd9b245 feat: 引入 RenderGraph、Application 框架、ECS 与资产句柄系统
架构分层(自上而下):
  App(SandboxApp) → Application(生命周期+事件) → Scene(ECS) / AssetManager(句柄) → Renderer → RenderGraph → Vulkan 模块

- RenderGraph:声明式帧图。虚拟资源+生成号句柄、死 pass 剔除、
  拓扑排序、资源生命周期、barrier 编译期预算(Synchronization2)、
  物理镜像池按帧槽位隔离(帧间竞争从根上消除)
- 帧同步修复:per-frame-slot 命令缓冲与 UBO ring(原先单份存在
  数据竞争);统一 kMaxFramesInFlight / FrameContext
- Application:生命周期钩子(OnInit/OnUpdate/OnRender/OnShutdown)
  + 事件系统(GLFW 回调 → POD 事件 → 类型化钩子);main 只 new 派生类
- ECS:自研稀疏集 Registry(Entity=(index,generation) 防悬空,
  O(1) 增删查,Each 取最小池遍历);Scene 延迟销毁队列;
  IdComponent{UUID} 稳定外部身份
- Assets:AssetManager + AssetHandle。组件存句柄不存裸指针/Ref
  (单一所有者 + 多使用者),Renderer 删除 LoadModel 改为纯消费
- 修复退出析构:成员析构前 GPU waitIdle(资产层先于 Renderer
  析构导致 VUID-00922 资源销毁时仍在使用)
- 引入 entt 子模块备用

validation 全程零错误零警告(RTX 5060 实测)
2026-09-22 13:46:05 +08:00

137 lines
3.9 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 派生类并运行它。
// 窗口、渲染器、事件泵、帧计时、场景容器全部由框架管理;
// 这里只写"程序逻辑":创建实体、逐帧更新组件、事件响应。
//
#include <Engine/Core/Application.h>
#include <Engine/Core/Log.h>
#include <Engine/Core/Stats.h>
#include <Engine/ECS/Scene.h>
#include <Engine/ECS/Components.h>
#include <Engine/Assets/AssetManager.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <GLFW/glfw3.h>
using namespace Engine;
using namespace Engine::ECS;
class SandboxApp final : public Application
{
public:
SandboxApp()
: Application("HelloVulkan", 1280, 720)
{
}
protected:
// ---- 生命周期 ----
void OnInit() override
{
Scene& scene = GetScene();
// 模型资产(AssetManager 负责加载/缓存/生命周期,返回句柄)
auto backpack = GetAssets().LoadModel("assets/models/backpack/backpack.obj");
// 相机实体(primary = 当前渲染视角)
m_CameraEntity = scene.CreateEntity("MainCamera");
auto& camera = scene.AddComponent<CameraComponent>(m_CameraEntity);
camera.primary = true;
camera.camera.SetPosition(glm::vec3(0.0f, 0.0f, 7.0f));
// 背包实体 × 3
for (int i = 0; i < 3; ++i) {
Entity e = scene.CreateEntity("Backpack" + std::to_string(i));
auto& transform = scene.AddComponent<TransformComponent>(e);
transform.world = glm::translate(
glm::mat4(1.0f),
glm::vec3((i - 1) * 1.5f, 0.0f, 0.0f));
scene.AddComponent<MeshRendererComponent>(e, MeshRendererComponent{backpack});
m_Spinners.push_back(e);
}
// 灯光实体
Entity keyLight = scene.CreateEntity("KeyLight");
scene.AddComponent<LightComponent>(keyLight,
LightComponent{glm::vec3(-0.5f, -1.0f, -0.3f),
glm::vec4(1.0f, 0.95f, 0.9f, 1.0f)});
Entity fillLight = scene.CreateEntity("FillLight");
scene.AddComponent<LightComponent>(fillLight,
LightComponent{glm::vec3(0.5f, -0.5f, 0.3f),
glm::vec4(0.3f, 0.5f, 1.0f, 0.8f)});
}
void OnUpdate(f32 deltaTime) override
{
Scene& scene = GetScene();
m_Time += deltaTime;
// 相机(WASD/Space/Shift 移动)
scene.GetComponent<CameraComponent>(m_CameraEntity)
.camera.Update(GetWindow(), deltaTime);
// 旋转动画:直接写实体组件
for (size_t i = 0; i < m_Spinners.size(); ++i) {
f32 angle = m_Time * glm::radians(60.0f) + static_cast<f32>(i) * 0.7f;
auto& transform = scene.GetComponent<TransformComponent>(m_Spinners[i]);
glm::mat4 t = glm::translate(
glm::mat4(1.0f),
glm::vec3((static_cast<f32>(i) - 1.0f) * 1.5f, 0.0f, 0.0f));
glm::mat4 r = glm::rotate(glm::mat4(1.0f), angle, glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 s = glm::scale(glm::mat4(1.0f), glm::vec3(0.5));
transform.world = t * r * s;
}
}
// ---- 事件 ----
void OnKeyPress(const Event& event) override
{
if (event.key == GLFW_KEY_F1) {
STATS.PrintComparison();
}
if (event.key == GLFW_KEY_ESCAPE) {
Close();
}
}
void OnWindowResize(const Event& event) override
{
ENGINE_INFO("App: window resized to {}x{}", event.width, event.height);
}
private:
Entity m_CameraEntity{};
std::vector<Entity> m_Spinners;
f32 m_Time = 0.0f;
};
int main()
{
SandboxApp app;
try {
app.Run();
}
catch (const std::exception& e) {
ENGINE_FATAL("Exception: {}", e.what());
return -1;
}
return 0;
}