diff --git a/library/phx/display_system.hpp b/library/phx/display_system.hpp index bca638e4be07da5252da1b1f7b9a1ce95f8743e3..ffcc68492dda98db366bf20f8bf9cd684590e1e8 100644 --- a/library/phx/display_system.hpp +++ b/library/phx/display_system.hpp @@ -26,6 +26,7 @@ #include <memory> #include <vector> +#include "phx/engine.hpp" #include "phx/export.hpp" #include "phx/hmd.hpp" #include "phx/system.hpp" @@ -37,7 +38,6 @@ namespace phx { class PHOENIX_EXPORT DisplaySystem : public System { public: - explicit DisplaySystem(Engine* engine); DisplaySystem(const DisplaySystem&) = delete; DisplaySystem(DisplaySystem&&) = default; ~DisplaySystem(); @@ -57,6 +57,9 @@ class PHOENIX_EXPORT DisplaySystem : public System { void Update(const FrameTimer::TimeInfo&) override; protected: + explicit DisplaySystem(Engine* engine); + friend DisplaySystem* Engine::CreateSystem<DisplaySystem>(); + std::unique_ptr<Window> window_; std::unique_ptr<HMD> hmd_; }; diff --git a/library/phx/engine.cpp b/library/phx/engine.cpp index 0b5b2e55608a7800e61577af524e105965f9381f..315ac6ae015c0562bb1c78c3a0461c275943469b 100644 --- a/library/phx/engine.cpp +++ b/library/phx/engine.cpp @@ -57,27 +57,19 @@ void Engine::Run() { frame_timer_.Start(); - InitializeSystems(); is_running_ = true; while (is_running_) UpdateSystems(); - TerminateSystems(); } void Engine::Stop() { is_running_ = false; } bool Engine::IsRunning() const { return is_running_; } -void Engine::InitializeSystems() { - for (auto& system : systems_) system->Initialize(); -} void Engine::UpdateSystems() { // before updating all systems, update the frame timer frame_timer_.Tick(); for (auto& system : systems_) system->Update(frame_timer_.GetTimeInfo()); } -void Engine::TerminateSystems() { - for (auto& system : systems_) system->Terminate(); -} std::string Engine::ToString() const { return "(Engine, #Systems: " + std::to_string(systems_.size()) + diff --git a/library/phx/engine.hpp b/library/phx/engine.hpp index 81a29919975cb8cfc5ddd2fb18fc7be2d28565fa..481afbe06eac5f947da28688362e5256427d1ad5 100644 --- a/library/phx/engine.hpp +++ b/library/phx/engine.hpp @@ -108,9 +108,7 @@ class PHOENIX_EXPORT Engine final : public Loggable { return typeid(SystemType) == typeid(system); } - void InitializeSystems(); void UpdateSystems(); - void TerminateSystems(); std::vector<std::unique_ptr<System>> systems_; bool is_running_ = false; diff --git a/library/phx/rendering_system.cpp b/library/phx/rendering_system.cpp index 893b5e53071617ce4975dc3d62fedb904fc81b57..15a17eb3ef60a938bec74ec15002c0bc98ff0310 100644 --- a/library/phx/rendering_system.cpp +++ b/library/phx/rendering_system.cpp @@ -47,18 +47,20 @@ namespace phx { -RenderingSystem::RenderingSystem(Engine* engine) : System(engine) {} +RenderingSystem::RenderingSystem(Engine* engine, DisplaySystem* display_system) + : System(engine) { + if (!display_system) error("RenderingSystem needs a valid DisplaySystem."); + InitializeOpenGL(); + InitializeRenderTargets(); + SetupFramegraph(); +} -void RenderingSystem::Initialize() { +void RenderingSystem::InitializeOpenGL() { if (!gl::initialize()) { error("Initializing gl failed"); } std::string prefix = "[RenderingSystem] OpenGl Error: "; gl::print_error(prefix.c_str()); - - InitializeRenderTargets(); - - SetupFramegraph(); } void RenderingSystem::InitializeRenderTargets() { diff --git a/library/phx/rendering_system.hpp b/library/phx/rendering_system.hpp index 460176d84454308362035cc99cfa87e1202bd284..43ca9b6df6fd09ce363ab4c7e2ee76a73fec3ff7 100644 --- a/library/phx/rendering_system.hpp +++ b/library/phx/rendering_system.hpp @@ -28,6 +28,7 @@ #include <string> #include <vector> +#include "phx/display_system.hpp" #include "phx/engine.hpp" #include "phx/export.hpp" #include "phx/frame_graph.hpp" @@ -45,7 +46,6 @@ class PHOENIX_EXPORT RenderingSystem : public System { RenderingSystem(RenderingSystem&&) = default; virtual ~RenderingSystem() = default; - void Initialize() override; void Update(const FrameTimer::TimeInfo& time_info) override; FrameGraph* GetFrameGraph() const; @@ -58,11 +58,16 @@ class PHOENIX_EXPORT RenderingSystem : public System { RenderTarget* GetRightRenderTarget() const; RenderTarget* GetLeftRenderTarget() const; + protected: + RenderingSystem(Engine* engine, DisplaySystem* display_system); + private: + void InitializeOpenGL(); void InitializeRenderTargets(); void SetupFramegraph(); - friend RenderingSystem* Engine::CreateSystem<RenderingSystem>(); + template <typename SystemType, typename... SystemArguments> + friend SystemType* Engine::CreateSystem(SystemArguments&&... arguments); explicit RenderingSystem(Engine* engine); std::unique_ptr<FrameGraph> frame_graph_; diff --git a/library/phx/setup.cpp b/library/phx/setup.cpp index 8e0ef78ea41233dca131eb5818ffa6877fe9c379..28773ff4351a4bf94d37bc9ff23b667c470d208c 100644 --- a/library/phx/setup.cpp +++ b/library/phx/setup.cpp @@ -45,8 +45,6 @@ std::unique_ptr<Engine> Setup::CreateDefaultEngine() { engine->CreateSystem<BehaviorSystem>(); engine->CreateSystem<InputSystem>()->AddQuitCallback( [engine_ptr]() { engine_ptr->Stop(); }); - engine->CreateSystem<TrackingSystem>(); - engine->CreateSystem<RenderingSystem>(); auto displaysys = engine->CreateSystem<DisplaySystem>(); if (HMD::IsHMDPresent()) { @@ -55,6 +53,8 @@ std::unique_ptr<Engine> Setup::CreateDefaultEngine() { } else { displaysys->CreateWindow("Phoenix", glm::uvec2(100, 100)); } + engine->CreateSystem<RenderingSystem>(engine->GetSystem<DisplaySystem>()); + engine->CreateSystem<TrackingSystem>(engine->GetSystem<DisplaySystem>()); return engine; } diff --git a/library/phx/system.hpp b/library/phx/system.hpp index 6a9ff52d872043c01737ae529794da254225775d..ffdf3b01cba3197b9f29417977be323980aa587b 100644 --- a/library/phx/system.hpp +++ b/library/phx/system.hpp @@ -37,9 +37,7 @@ class PHOENIX_EXPORT System : public Loggable { System() = delete; virtual ~System() = default; - virtual void Initialize() {} virtual void Update(const FrameTimer::TimeInfo&) {} - virtual void Terminate() {} Engine* GetEngine() const; diff --git a/library/phx/tracking_system.cpp b/library/phx/tracking_system.cpp index 25562e38ff5eb2481cc63844ecb2d1dfc37cd1d2..ae836ae207255f3163e21681f2e0b1f9b5963a07 100644 --- a/library/phx/tracking_system.cpp +++ b/library/phx/tracking_system.cpp @@ -26,14 +26,41 @@ #include "display_system.hpp" #include "hmd.hpp" +#include "logger.hpp" #include "projection.hpp" #include "runtime_component.hpp" #include "transform.hpp" namespace phx { -TrackingSystem::TrackingSystem(Engine* engine) : System(engine) {} -void TrackingSystem::Initialize() { +TrackingSystem::TrackingSystem(Engine* engine, DisplaySystem* display_system) + : System(engine) { + if (!display_system) error("TrackingSystem needs a valid DisplaySystem."); + CreateRuntimeEntities(); +} + +void TrackingSystem::Update(const FrameTimer::TimeInfo&) { + const auto hmd = engine_->GetSystem<DisplaySystem>()->GetHMD(); + if (hmd == nullptr) return; + hmd->UpdateTrackedDevices(); + const auto head_transformation = hmd->GetHeadTransformation(); + hmd_entity_->GetFirstComponent<Transform>()->SetLocalMatrix( + head_transformation); + const auto left_eye_transformation = hmd->GetEyeToHeadMatrix(HMD::LEFT_EYE); + left_eye_entity_->GetFirstComponent<Transform>()->SetLocalMatrix( + left_eye_transformation); + const auto right_eye_transformation = hmd->GetEyeToHeadMatrix(HMD::RIGHT_EYE); + right_eye_entity_->GetFirstComponent<Transform>()->SetLocalMatrix( + right_eye_transformation); + + left_controller_entity_->GetFirstComponent<Transform>()->SetLocalMatrix( + hmd->GetLeftControllerTransformation()); + + right_controller_entity_->GetFirstComponent<Transform>()->SetLocalMatrix( + hmd->GetRightControllerTransformation()); +} + +void TrackingSystem::CreateRuntimeEntities() { const auto hmd = engine_->GetSystem<DisplaySystem>()->GetHMD(); if (hmd == nullptr) { return; @@ -48,16 +75,19 @@ void TrackingSystem::Initialize() { const auto virtual_platform = virtual_platforms[0]; const auto virtual_platform_transform = virtual_platform->GetFirstComponent<Transform>(); + hmd_entity_ = scene->CreateEntity(); hmd_entity_->AddComponent<RuntimeComponent<HEAD>>(); auto hmd_transform = hmd_entity_->AddComponent<Transform>(); hmd_transform->SetParent(virtual_platform_transform); left_eye_entity_ = scene->CreateEntity(); + left_eye_entity_->AddComponent<RuntimeComponent<LEFT_EYE>>(); auto left_eye_transform = left_eye_entity_->AddComponent<Transform>(); left_eye_transform->SetParent(hmd_transform); left_eye_entity_->AddComponent<Projection>(); right_eye_entity_ = scene->CreateEntity(); + right_eye_entity_->AddComponent<RuntimeComponent<RIGHT_EYE>>(); auto right_eye_transform = right_eye_entity_->AddComponent<Transform>(); right_eye_entity_->AddComponent<Projection>(); @@ -78,32 +108,6 @@ void TrackingSystem::Initialize() { } } -void TrackingSystem::Update(const FrameTimer::TimeInfo&) { - const auto hmd = engine_->GetSystem<DisplaySystem>()->GetHMD(); - if (hmd == nullptr) { - return; - } - hmd->UpdateTrackedDevices(); - const auto head_transformation = hmd->GetHeadTransformation(); - if (hmd_entity_ != nullptr) { - hmd_entity_->GetFirstComponent<Transform>()->SetLocalMatrix( - head_transformation); - const auto left_eye_transformation = hmd->GetEyeToHeadMatrix(HMD::LEFT_EYE); - left_eye_entity_->GetFirstComponent<Transform>()->SetLocalMatrix( - left_eye_transformation); - const auto right_eye_transformation = - hmd->GetEyeToHeadMatrix(HMD::RIGHT_EYE); - right_eye_entity_->GetFirstComponent<Transform>()->SetLocalMatrix( - right_eye_transformation); - - left_controller_entity_->GetFirstComponent<Transform>()->SetLocalMatrix( - hmd->GetLeftControllerTransformation()); - - right_controller_entity_->GetFirstComponent<Transform>()->SetLocalMatrix( - hmd->GetRightControllerTransformation()); - } -} - std::string TrackingSystem::ToString() const { return "Tracking System"; } } // namespace phx diff --git a/library/phx/tracking_system.hpp b/library/phx/tracking_system.hpp index f2bdb4a13c8ab0277c1b38868e614358a9966931..4022d7e7f2c28358e62a4d665862f84ea1228751 100644 --- a/library/phx/tracking_system.hpp +++ b/library/phx/tracking_system.hpp @@ -25,6 +25,7 @@ #include <string> +#include "phx/display_system.hpp" #include "phx/engine.hpp" #include "phx/export.hpp" #include "phx/system.hpp" @@ -41,13 +42,18 @@ class PHOENIX_EXPORT TrackingSystem : public System { TrackingSystem& operator=(const TrackingSystem&) = delete; TrackingSystem& operator=(TrackingSystem&&) = default; - void Initialize() override; void Update(const FrameTimer::TimeInfo&) override; std::string ToString() const override; + protected: + TrackingSystem(Engine* engine, DisplaySystem* display_system); + private: - friend TrackingSystem* Engine::CreateSystem<TrackingSystem>(); + void CreateRuntimeEntities(); + + template <typename SystemType, typename... SystemArguments> + friend SystemType* Engine::CreateSystem(SystemArguments&&... arguments); explicit TrackingSystem(Engine* engine); Entity* hmd_entity_ = nullptr; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f8059bb98542556b0de86c5c1c07cb19d7587dac..0c516001fb8a2bb48d0353a54fac5d8469af3628 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -224,7 +224,7 @@ add_mocked_test(test_geometry_pass MOCK_GLEW MOCK_SDL) add_mocked_test(test_rendering_system MOCK_GLEW MOCK_SDL) add_mocked_test(test_shader MOCK_GLEW) add_mocked_test(test_display_system MOCK_SDL) -add_mocked_test(test_engine MOCK_SDL MOCK_OPENVR) +add_mocked_test(test_engine MOCK_SDL MOCK_OPENVR MOCK_GLEW) add_mocked_test(test_tracking_system MOCK_SDL MOCK_OPENVR) add_mocked_test(integration_test_model_rendering MOCK_OPENVR) diff --git a/tests/src/integration_test_model_rendering.cpp b/tests/src/integration_test_model_rendering.cpp index dd782b0085de13d2e5c8cb1078f5b2259c3899a7..f4d4a601534826ecb357afdc8f5619d314b65221 100644 --- a/tests/src/integration_test_model_rendering.cpp +++ b/tests/src/integration_test_model_rendering.cpp @@ -114,7 +114,6 @@ SCENARIO( auto display_system = engine->GetSystem<phx::DisplaySystem>(); WHEN("We render the scene") { - rendering_system->Initialize(); rendering_system->Update(phx::FrameTimer::TimeInfo()); display_system->Update(phx::FrameTimer::TimeInfo()); THEN("the rendering matches our reference image") { @@ -144,7 +143,6 @@ SCENARIO( auto display_system = engine->GetSystem<phx::DisplaySystem>(); WHEN("We render the scene") { - rendering_system->Initialize(); rendering_system->Update(phx::FrameTimer::TimeInfo{}); display_system->Update(phx::FrameTimer::TimeInfo()); THEN("the rendering matches our reference image") { diff --git a/tests/src/integration_test_rendering.cpp b/tests/src/integration_test_rendering.cpp index a6a3ad0ede817e24eb6e533cb0807a63dc378dc4..a4f6257c7c158ce19978f7480c0aa13d0062f89d 100644 --- a/tests/src/integration_test_rendering.cpp +++ b/tests/src/integration_test_rendering.cpp @@ -117,7 +117,6 @@ SCENARIO("We can render a simple triangle", "[phx][phx::Rendering]") { material_handle->SetMaterialProxy(material_proxy); WHEN("We render the scene") { - rendering_system->Initialize(); rendering_system->Update(phx::FrameTimer::TimeInfo{}); display_system->Update(phx::FrameTimer::TimeInfo{}); THEN("the rendering matches our reference image") { @@ -148,7 +147,6 @@ SCENARIO("If no material given a default red one is taken.", phx::Transform* transform = triangle->AddComponent<phx::Transform>(); WHEN("We render the scene") { - rendering_system->Initialize(); rendering_system->Update(phx::FrameTimer::TimeInfo{}); display_system->Update(phx::FrameTimer::TimeInfo{}); THEN("the rendering matches our reference image") { diff --git a/tests/src/test_display_system.cpp b/tests/src/test_display_system.cpp index a896603b84d89f0c8b089b757cf11d0107f79f98..5c7e6b07219fc8858c4c319cd2e456f06c833d2a 100644 --- a/tests/src/test_display_system.cpp +++ b/tests/src/test_display_system.cpp @@ -52,8 +52,9 @@ SCENARIO( "scope.") { REQUIRE_CALL(sdl_mock.Get(), SDL_VideoInit(nullptr)).RETURN(0); REQUIRE_CALL(sdl_mock.Get(), SDL_VideoQuit()); - phx::DisplaySystem displaySystem(nullptr); - displaySystem.Initialize(); + phx::Engine engine; + phx::DisplaySystem* displaySystem = + engine.CreateSystem<phx::DisplaySystem>(); WHEN("We create a window.") { THEN("The window is created.") { @@ -71,13 +72,13 @@ SCENARIO( .RETURN(0); REQUIRE_CALL(sdl_mock.Get(), SDL_GL_CreateContext(_)) .RETURN(reinterpret_cast<SDL_GLContext>(1u)); - displaySystem.CreateWindow("TestWindow", glm::uvec2(0, 0), - glm::uvec2(640, 480)); + displaySystem->CreateWindow("TestWindow", glm::uvec2(0, 0), + glm::uvec2(640, 480)); WHEN("DisplaySystem Update is called") { THEN("SDL_GL_SwapWindow is called") { REQUIRE_CALL(sdl_mock.Get(), SDL_GL_SwapWindow(_)); - displaySystem.Update(phx::FrameTimer::TimeInfo()); + displaySystem->Update(phx::FrameTimer::TimeInfo()); } } } diff --git a/tests/src/test_engine.cpp b/tests/src/test_engine.cpp index 6281651a5b4cd384b5b131d2363ce46dc83847be..3256e671385c5be1d8f79da1df7c43b876786ea3 100644 --- a/tests/src/test_engine.cpp +++ b/tests/src/test_engine.cpp @@ -43,6 +43,7 @@ SUPPRESS_WARNINGS_BEGIN #include "mocks/openvr_mock.hpp" SUPPRESS_WARNINGS_END #include "mocks/sdl_mock.hpp" +#include "mocks/opengl_mock.hpp" using trompeloeil::_; using trompeloeil::ne; @@ -278,6 +279,7 @@ SCENARIO("An engine provides access to the behaviors", "[phx][phx::Engine]") { SCENARIO("An engine can be setup by the default setup", "[phx][phx::Engine]") { SDL_MOCK_ALLOW_ANY_CALL + OPENGL_MOCK_ALLOW_ANY_CALL ALLOW_CALL(openvr_mock.Get(), VR_IsHmdPresent()).RETURN(false); GIVEN("Nothing") { WHEN("An engine is setup with the default setup") { diff --git a/tests/src/test_rendering_system.cpp b/tests/src/test_rendering_system.cpp index d86db1bf4ba9b7b1857e25d29340f7bb068c4667..4c83660c7f36a14b96d0264636bdf7294d8c2cbd 100644 --- a/tests/src/test_rendering_system.cpp +++ b/tests/src/test_rendering_system.cpp @@ -48,11 +48,11 @@ SCENARIO( phx::Engine engine; GIVEN("A rendering system.") { + auto diplay_system = engine.CreateSystem<phx::DisplaySystem>(); phx::RenderingSystem* rendering_system = - engine.CreateSystem<phx::RenderingSystem>(); + engine.CreateSystem<phx::RenderingSystem>(diplay_system); WHEN("We initialize the system") { - rendering_system->Initialize(); THEN( "a default frame graph is created, that has 0 render passes, " "since there is currently to much inter-relation between the " diff --git a/tests/src/test_tracking_system.cpp b/tests/src/test_tracking_system.cpp index b1e688d45c10a67016824729ff1d5bd6e9e49fa1..ea6f58a16e8e944ec443a99d475d82d88192aeff 100644 --- a/tests/src/test_tracking_system.cpp +++ b/tests/src/test_tracking_system.cpp @@ -81,8 +81,8 @@ SCENARIO( ->GetFirstComponent<phx::Transform>() ->SetLocalMatrix(platform_trans_mat); WHEN("A tracking system is created and initialized.") { - auto tracking_system = engine.CreateSystem<phx::TrackingSystem>(); - tracking_system->Initialize(); + auto tracking_system = + engine.CreateSystem<phx::TrackingSystem>(display_system); THEN("The HMD and the user's eyes are represented in the scene.") { auto entities = scene->GetEntitiesWithComponents<phx::Transform>(); bool platform_present = false;