// // Created by atdunbg on 2026/9/20. // // SandboxApp:第一个基于 Application 框架的程序。 // // main 的全部职责:定义一个 Application 派生类并运行它。 // 窗口、渲染器、事件泵、帧计时、场景容器全部由框架管理; // 这里只写"程序逻辑":创建实体、逐帧更新组件、事件响应。 // #include #include #include #include #include #include #include #include #include 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(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(e); transform.world = glm::translate( glm::mat4(1.0f), glm::vec3((i - 1) * 1.5f, 0.0f, 0.0f)); scene.AddComponent(e, MeshRendererComponent{backpack}); m_Spinners.push_back(e); } // 灯光实体 Entity keyLight = scene.CreateEntity("KeyLight"); scene.AddComponent(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(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(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(i) * 0.7f; auto& transform = scene.GetComponent(m_Spinners[i]); glm::mat4 t = glm::translate( glm::mat4(1.0f), glm::vec3((static_cast(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 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; }