diff --git a/demos/viewer/src/viewer.cpp b/demos/viewer/src/viewer.cpp index 8a56e775a46169762abd795adc649d41b1a78472..358ba7fa1a55321e6520258f4e8db36726fa35ee 100644 --- a/demos/viewer/src/viewer.cpp +++ b/demos/viewer/src/viewer.cpp @@ -115,15 +115,17 @@ int main(int, char**) { virtual_platform_transform->SetLocalTranslation(glm::vec3(0.f, -1.f, -2.f)); - phx::Entity* camera = scene->CreateEntity(); - auto camera_transform = camera->AddComponent<phx::Transform>(); - auto camera_projection = camera->AddComponent<phx::Projection>(); - camera->AddComponent<NavigationBehavior>( - engine->GetSystem<phx::DisplaySystemOpenVR>()); - camera_projection->SetPerspective(glm::radians(68.0f), 4.0f / 3.0f, 0.01f, - 1000.0f); - camera_transform->SetLocalTranslation(glm::vec3(0, 0, 0)); - camera_transform->SetParent(virtual_platform_transform, false); + phx::Entity* camera = + scene->GetEntitiesWithComponents<phx::RenderTarget>()[0]; + if (camera->GetFirstComponent<phx::RuntimeComponent<phx::LEFT_EYE>>() == + nullptr && + camera->GetFirstComponent<phx::RuntimeComponent<phx::RIGHT_EYE>>() == + nullptr) { + auto camera_projection = camera->GetFirstComponent<phx::Projection>(); + camera_projection->SetPerspective(glm::radians(68.0f), 4.0f / 3.0f, 0.01f, + 1000.0f); + } + auto virtual_platform = scene->GetEntitiesWithComponents< phx::RuntimeComponent<phx::USER_PLATFORM>>()[0]; virtual_platform->AddComponent<NavigationBehavior>( diff --git a/library/phx/display_system.hpp b/library/phx/display_system.hpp index 98b84f3ceb0a433000582e059730885a7e00bb47..08e2d36364fc6747c9cb8d2605b45e990ebeaa9d 100644 --- a/library/phx/display_system.hpp +++ b/library/phx/display_system.hpp @@ -44,8 +44,6 @@ class PHOENIX_EXPORT DisplaySystem : public System { void Update(const FrameTimer::TimeInfo&) override = 0; - virtual std::vector<std::unique_ptr<RenderTarget>> CreateRenderTargets() = 0; - protected: explicit DisplaySystem(Engine* engine); friend DisplaySystem* Engine::CreateSystem<DisplaySystem>(); diff --git a/library/phx/display_system_openvr.cpp b/library/phx/display_system_openvr.cpp index a51efa182b4c6e1eb9b26e863397b55578a454fe..7938a3fce7112a3c5791d209b315c3d5fc4b616e 100644 --- a/library/phx/display_system_openvr.cpp +++ b/library/phx/display_system_openvr.cpp @@ -29,14 +29,25 @@ #include <utility> #include <vector> +#include "engine.hpp" #include "logger.hpp" #include "rendering_system.hpp" +#include "runtime_component.hpp" +#include "scene.hpp" #undef CreateWindow namespace phx { DisplaySystemOpenVR::DisplaySystemOpenVR(Engine* engine) - : DisplaySystem(engine) {} + : DisplaySystem(engine), + left_render_target_(nullptr), + right_render_target_(nullptr) { + scene_changed_connection_ = engine->AddSceneChangedCallback( + [this](std::shared_ptr<Scene>, std::shared_ptr<Scene> new_scene) { + RemoveRenderTargets(); + CreateRenderTargets(new_scene.get()); + }); +} DisplaySystemOpenVR::~DisplaySystemOpenVR() {} phx::HMD* DisplaySystemOpenVR::CreateHMD() { @@ -56,32 +67,59 @@ phx::HMD* DisplaySystemOpenVR::GetHMD() { return hmd_.get(); } void DisplaySystemOpenVR::Update(const FrameTimer::TimeInfo&) { if (hmd_ != nullptr) { - auto rendering_system = engine_->GetSystem<RenderingSystem>(); - if (rendering_system != nullptr) { - auto render_targets = rendering_system->GetRenderTargets(); - if (render_targets.size() >= 2) { - auto right_texture = render_targets[0]->GetColorTexture(); - hmd_->Submit(HMD::RIGHT_EYE, right_texture); - auto left_texture = render_targets[1]->GetColorTexture(); - hmd_->Submit(HMD::LEFT_EYE, left_texture); - } + if (left_render_target_ != nullptr && right_render_target_ != nullptr) { + auto right_texture = right_render_target_->GetColorTexture(); + hmd_->Submit(HMD::RIGHT_EYE, right_texture); + auto left_texture = left_render_target_->GetColorTexture(); + hmd_->Submit(HMD::LEFT_EYE, left_texture); } } } -std::vector<std::unique_ptr<RenderTarget>> -DisplaySystemOpenVR::CreateRenderTargets() { - std::vector<std::unique_ptr<RenderTarget>> render_targets; +void DisplaySystemOpenVR::CreateRenderTargets(Scene* scene) { if (GetHMD() == nullptr) { error("Cannot create render targets: no HMD."); - return render_targets; + return; + } + auto left_eye_components = + scene->GetEntitiesWithComponents<RuntimeComponent<LEFT_EYE>>(); + if (!left_eye_components.empty()) { + left_render_target_ = left_eye_components[0]->AddComponent<RenderTarget>( + GetHMD()->GetViewportSize()); + } + auto right_eye_components = + scene->GetEntitiesWithComponents<RuntimeComponent<RIGHT_EYE>>(); + if (!right_eye_components.empty()) { + right_render_target_ = right_eye_components[0]->AddComponent<RenderTarget>( + GetHMD()->GetViewportSize()); } + SetEyeProjections(scene); +} + +void DisplaySystemOpenVR::RemoveRenderTargets() { + if (left_render_target_) + left_render_target_->GetEntity()->RemoveComponent(left_render_target_); + if (right_render_target_) + right_render_target_->GetEntity()->RemoveComponent(right_render_target_); +} - render_targets.push_back( - std::make_unique<RenderTarget>(GetHMD()->GetViewportSize())); - render_targets.push_back( - std::make_unique<RenderTarget>(GetHMD()->GetViewportSize())); - return render_targets; +void DisplaySystemOpenVR::SetEyeProjections(Scene* scene) { + if (GetHMD() == nullptr) { + error("Cannot set eye projections: no HMD."); + return; + } + auto left_eye_components = + scene->GetEntitiesWithComponents<RuntimeComponent<LEFT_EYE>>(); + if (!left_eye_components.empty()) { + left_eye_components[0]->GetFirstComponent<Projection>()->SetMatrix( + GetHMD()->GetProjectionMatrix(HMD::LEFT_EYE)); + } + auto right_eye_components = + scene->GetEntitiesWithComponents<RuntimeComponent<RIGHT_EYE>>(); + if (!right_eye_components.empty()) { + right_eye_components[0]->GetFirstComponent<Projection>()->SetMatrix( + GetHMD()->GetProjectionMatrix(HMD::RIGHT_EYE)); + } } } // namespace phx diff --git a/library/phx/display_system_openvr.hpp b/library/phx/display_system_openvr.hpp index 8e0962cc327aa78984354bc48b5630f078723cbb..389c6e41dff4208bacd729bc1d63941f0180faaa 100644 --- a/library/phx/display_system_openvr.hpp +++ b/library/phx/display_system_openvr.hpp @@ -29,6 +29,8 @@ #include "phx/display_system.hpp" #include "phx/export.hpp" #include "phx/hmd.hpp" +#include "phx/render_target.hpp" +#include "phx/scene.hpp" #include "phx/window.hpp" namespace phx { @@ -49,10 +51,19 @@ class PHOENIX_EXPORT DisplaySystemOpenVR : public DisplaySystem { void Update(const FrameTimer::TimeInfo&) override; - std::vector<std::unique_ptr<RenderTarget>> CreateRenderTargets() override; + void CreateRenderTargets(Scene* scene); protected: std::unique_ptr<HMD> hmd_; + + private: + void RemoveRenderTargets(); + void SetEyeProjections(Scene* scene); + + boost::signals2::connection scene_changed_connection_; + + RenderTarget* left_render_target_; + RenderTarget* right_render_target_; }; } // namespace phx diff --git a/library/phx/display_system_window.cpp b/library/phx/display_system_window.cpp index d68c4d7f453c12a1b13afb1a3520e691ee03c472..095f56d72197328a03dbd26bfd21ba74abf3350a 100644 --- a/library/phx/display_system_window.cpp +++ b/library/phx/display_system_window.cpp @@ -48,18 +48,9 @@ DisplaySystemWindow::~DisplaySystemWindow() { SDL_VideoQuit(); } void DisplaySystemWindow::DestroyWindow() { window_.reset(); - /*windows_.erase( - std::remove_if(windows_.begin(), windows_.end(), - [window](const std::unique_ptr<Window>& iteratee) { - return window == iteratee.get(); - }));*/ } Window* DisplaySystemWindow::GetWindow() { - /*std::vector<Window*> windows(windows_.size()); - std::transform( - windows_.begin(), windows_.end(), windows.begin(), - [](const std::unique_ptr<Window>& iteratee) { return iteratee.get(); });*/ return window_.get(); } @@ -69,17 +60,4 @@ void DisplaySystemWindow::Update(const FrameTimer::TimeInfo&) { } } -std::vector<std::unique_ptr<RenderTarget>> -DisplaySystemWindow::CreateRenderTargets() { - std::vector<std::unique_ptr<RenderTarget>> render_targets; - if (GetWindow() == nullptr) { - error("Cannot create render target: no window."); - return render_targets; - } - - render_targets.push_back( - std::make_unique<RenderTarget>(GetWindow()->GetSize())); - return render_targets; -} - } // namespace phx diff --git a/library/phx/display_system_window.hpp b/library/phx/display_system_window.hpp index 8abfcee03022c9af1d00355b788690bfbf9ffd55..024c34de643bb5ef6fccc1e82688b435541585f9 100644 --- a/library/phx/display_system_window.hpp +++ b/library/phx/display_system_window.hpp @@ -52,8 +52,6 @@ class PHOENIX_EXPORT DisplaySystemWindow : public DisplaySystem { void Update(const FrameTimer::TimeInfo&) override; - std::vector<std::unique_ptr<RenderTarget>> CreateRenderTargets() override; - protected: std::unique_ptr<Window> window_; }; diff --git a/library/phx/entity.hpp b/library/phx/entity.hpp index d590575e7e1cf6a67d5d0228f8619df9b42a903b..7d9b7939bac276a32122c4fa11ca2ac6fb2141fb 100644 --- a/library/phx/entity.hpp +++ b/library/phx/entity.hpp @@ -52,8 +52,8 @@ class PHOENIX_EXPORT Entity : public Nameable, public Loggable { Entity& operator=(const Entity&) = delete; Entity& operator=(Entity&&) = default; - template <class ComponentType, class... ArgumentTypes> - ComponentType* AddComponent(ArgumentTypes&&... arguments) { + template <class ComponentType, typename... ComponentArguments> + ComponentType* AddComponent(ComponentArguments&&... arguments) { static_assert(std::is_base_of<phx::Component, ComponentType>::value, "ComponentType is not derived from phx::Component."); auto component_ptr = new ComponentType(arguments...); diff --git a/library/phx/projection.cpp b/library/phx/projection.cpp index 9ec2b2bb1c76a2d3a9fd304dee52405428c37db8..81713abd912bc564b7a0615a738cfcc05e7a052c 100644 --- a/library/phx/projection.cpp +++ b/library/phx/projection.cpp @@ -46,6 +46,8 @@ void Projection::SetOrthogonal(float left, float right, float bottom, float top, matrix_ = glm::ortho(left, right, bottom, top, near, far); } +void Projection::SetMatrix(const glm::mat4& matrix) { matrix_ = matrix; } + std::string Projection::ToString() const { return "ProjectionComponent"; } } // namespace phx diff --git a/library/phx/projection.hpp b/library/phx/projection.hpp index c24e22ba8ccba2e843b922621ba99f6f93c13724..17671b52416f0bdda621d5f711670fd7f955a2b9 100644 --- a/library/phx/projection.hpp +++ b/library/phx/projection.hpp @@ -44,6 +44,7 @@ class PHOENIX_EXPORT Projection final : public Component { void SetOrthogonal(float left, float right, float bottom, float top, float near, float far); + void SetMatrix(const glm::mat4& matrix); std::string ToString() const override; diff --git a/library/phx/render_target.cpp b/library/phx/render_target.cpp index 1bfe7ade23e5f7174496529de1cc7c2862ce83a3..02008a7d97e3072cb6c1a7a42ebb34edc9393210 100644 --- a/library/phx/render_target.cpp +++ b/library/phx/render_target.cpp @@ -27,7 +27,10 @@ #include "gl/command_execution.hpp" #include "gl/viewport.hpp" +#include "phx/entity.hpp" #include "phx/logger.hpp" +#include "phx/projection.hpp" +#include "phx/transform.hpp" namespace phx { phx::RenderTarget::RenderTarget(const glm::uvec2 dimensions) @@ -65,18 +68,32 @@ phx::RenderTarget::RenderTarget(const glm::uvec2 dimensions) const glm::uvec2& RenderTarget::GetDimensions() const { return dimensions_; } -const glm::mat4& RenderTarget::GetProjection() const { return projection_; } - -void RenderTarget::SetProjection(const glm::mat4& matrix) { - projection_ = matrix; +gl::texture_2d* RenderTarget::GetColorTexture() const { + return color_texture_.get(); } -const glm::mat4& RenderTarget::GetView() const { return view_; } - -void RenderTarget::SetView(const glm::mat4& matrix) { view_ = matrix; } +const glm::mat4 RenderTarget::GetProjection() const { + auto projection = GetEntity()->GetFirstComponent<Projection>(); + if (projection) { + return projection->GetMatrix(); + } else { + error( + "RenderTarget component may not be added to an Entity without a " + "Projection component!"); + return glm::mat4(); + } +} -gl::texture_2d* RenderTarget::GetColorTexture() const { - return color_texture_.get(); +const glm::mat4 RenderTarget::GetView() const { + auto transform = GetEntity()->GetFirstComponent<Transform>(); + if (transform) { + return inverse(transform->GetGlobalMatrix()); + } else { + error( + "RenderTarget component may not be added to an Entity without a " + "Transform component!"); + return glm::mat4(); + } } void RenderTarget::SetViewport() const { diff --git a/library/phx/render_target.hpp b/library/phx/render_target.hpp index a8ca89bb3e1c15ca7e3b03eabfb2d81bf768b344..f441a947c7a32e831d353f1078bfd6b986bf2d28 100644 --- a/library/phx/render_target.hpp +++ b/library/phx/render_target.hpp @@ -38,13 +38,15 @@ SUPPRESS_WARNINGS_END #include "gl/renderbuffer.hpp" #include "gl/texture.hpp" +#include "phx/component.hpp" #include "phx/export.hpp" namespace phx { SUPPRESS_WARNINGS_BEGIN_PADDED -class PHOENIX_EXPORT RenderTarget : public gl::framebuffer { +class PHOENIX_EXPORT RenderTarget : public Component, public gl::framebuffer { public: + RenderTarget() = delete; explicit RenderTarget(const glm::uvec2 dimensions); RenderTarget(RenderTarget&) = delete; RenderTarget(RenderTarget&&) = default; @@ -54,15 +56,11 @@ class PHOENIX_EXPORT RenderTarget : public gl::framebuffer { RenderTarget& operator=(RenderTarget&&) = default; const glm::uvec2& GetDimensions() const; - - const glm::mat4& GetProjection() const; - void SetProjection(const glm::mat4& matrix); - - const glm::mat4& GetView() const; - void SetView(const glm::mat4& matrix); - gl::texture_2d* GetColorTexture() const; + const glm::mat4 GetProjection() const; + const glm::mat4 GetView() const; + void SetViewport() const; private: @@ -70,8 +68,6 @@ class PHOENIX_EXPORT RenderTarget : public gl::framebuffer { std::unique_ptr<gl::texture_2d> depth_texture_; glm::uvec2 dimensions_; - glm::mat4 projection_; - glm::mat4 view_; }; SUPPRESS_WARNINGS_END diff --git a/library/phx/rendering_system.cpp b/library/phx/rendering_system.cpp index 45d55f276d7a08076cb91a6274c69c4fb5819544..b403cbecc009abe26a32c6b1efd303ffcf73489c 100644 --- a/library/phx/rendering_system.cpp +++ b/library/phx/rendering_system.cpp @@ -29,10 +29,6 @@ #include <utility> #include <vector> -#include "blit_pass.hpp" -#include "clear_pass.hpp" -#include "display_system_openvr.hpp" -#include "display_system_window.hpp" #include "engine.hpp" #include "light.hpp" #include "logger.hpp" @@ -73,42 +69,14 @@ void RenderingSystem::SetupFramegraph() { void RenderingSystem::Update(const FrameTimer::TimeInfo&) { std::vector<GeometryPass::RenderingInstance> rendering_instances; std::vector<std::pair<Light*, Transform*>> light_transform_pairs; - std::vector<std::pair<Projection*, Transform*>> projection_transform_pairs; if (GetEngine()->GetScene() == nullptr) { return; } - if (render_targets_.empty()) { - return; - } - - const auto display_system_window = engine_->GetSystem<DisplaySystemWindow>(); - const auto display_system_hmd = engine_->GetSystem<DisplaySystemOpenVR>(); - - // @TODO(anyone): these render parameters should be extracted from the scene - // somehow, the RenderingSystem shouldn't have to know about this. - if (display_system_hmd != nullptr && render_targets_.size() >= 2) { - auto right_eye_entities = - GetEngine()->GetEntitiesWithComponents<RuntimeComponent<RIGHT_EYE>>(); - if (!right_eye_entities.empty()) { - render_targets_[0]->SetView(inverse(right_eye_entities[0] - ->GetFirstComponent<Transform>() - ->GetGlobalMatrix())); - } - - auto left_eye_entities = - GetEngine()->GetEntitiesWithComponents<RuntimeComponent<LEFT_EYE>>(); - if (!left_eye_entities.empty()) { - render_targets_[1]->SetView(inverse(left_eye_entities[0] - ->GetFirstComponent<Transform>() - ->GetGlobalMatrix())); - } - } for (auto& entity : GetEngine()->GetEntities()) { auto mesh_handle = entity->GetFirstComponent<MeshHandle>(); auto light = entity->GetFirstComponent<Light>(); - auto projection = entity->GetFirstComponent<Projection>(); auto transform = entity->GetFirstComponent<Transform>(); auto material_handle = entity->GetFirstComponent<MaterialHandle>(); if (transform != nullptr) { @@ -121,34 +89,15 @@ void RenderingSystem::Update(const FrameTimer::TimeInfo&) { } else if (light != nullptr) { light_transform_pairs.push_back( std::pair<Light*, Transform*>(light, transform)); - } else if (projection != nullptr) { - projection_transform_pairs.push_back( - std::pair<Projection*, Transform*>(projection, transform)); } } } + auto geometry_passes = frame_graph_->GetRenderPasses<GeometryPass>(); for (auto geometry_pass : geometry_passes) { geometry_pass->SetData(rendering_instances, light_transform_pairs); } - // @TODO(anyone) see above, should also not be in the RenderingSystem, but - // the scene (Camera?) should store the connection between render target - // and Camera - if (display_system_hmd != nullptr && render_targets_.size() >= 2) { - HMD* hmd = display_system_hmd->GetHMD(); - render_targets_[0]->SetProjection(hmd->GetProjectionMatrix(HMD::RIGHT_EYE)); - render_targets_[1]->SetProjection(hmd->GetProjectionMatrix(HMD::LEFT_EYE)); - } - - if (display_system_hmd == nullptr && display_system_window != nullptr && - !render_targets_.empty() && !projection_transform_pairs.empty()) { - render_targets_[0]->SetProjection( - projection_transform_pairs[0].first->GetMatrix()); - render_targets_[0]->SetView( - glm::inverse(projection_transform_pairs[0].second->GetGlobalMatrix())); - } - frame_graph_->Execute(); } @@ -165,18 +114,4 @@ std::string RenderingSystem::ToString() const { std::to_string(frame_graph_->GetNumberOfPasses()); } -void RenderingSystem::SetRenderTargets( - std::vector<std::unique_ptr<RenderTarget>>* render_targets) { - render_targets_ = std::move(*render_targets); -} - -std::vector<RenderTarget*> RenderingSystem::GetRenderTargets() const { - std::vector<RenderTarget*> render_targets; - std::transform( - render_targets_.begin(), render_targets_.end(), - std::back_inserter(render_targets), - [](const std::unique_ptr<RenderTarget>& ptr) { return ptr.get(); }); - return render_targets; -} - } // namespace phx diff --git a/library/phx/rendering_system.hpp b/library/phx/rendering_system.hpp index 886f321b624c15f9b0859086ff2e96c7898fea23..40da48362089f540ebadc82d309a3f3e9874041c 100644 --- a/library/phx/rendering_system.hpp +++ b/library/phx/rendering_system.hpp @@ -56,10 +56,6 @@ class PHOENIX_EXPORT RenderingSystem : public System { RenderingSystem& operator=(const RenderingSystem&) = delete; RenderingSystem& operator=(RenderingSystem&&) = default; - void SetRenderTargets( - std::vector<std::unique_ptr<RenderTarget>>* render_targets); - std::vector<RenderTarget*> GetRenderTargets() const; - protected: template <typename SystemType, typename... SystemArguments> friend SystemType* Engine::CreateSystem(SystemArguments&&... arguments); @@ -70,8 +66,6 @@ class PHOENIX_EXPORT RenderingSystem : public System { void SetupFramegraph(); std::unique_ptr<FrameGraph> frame_graph_; - - std::vector<std::unique_ptr<RenderTarget>> render_targets_; }; } // namespace phx diff --git a/library/phx/setup.cpp b/library/phx/setup.cpp index c20a35426e13877be9e19531e378d0d92e81f3a2..0d5ff27d4693e93541dc5380ecff61f6da41fe47 100644 --- a/library/phx/setup.cpp +++ b/library/phx/setup.cpp @@ -30,6 +30,7 @@ #include "behavior_system.hpp" #include "blit_pass.hpp" #include "clear_pass.hpp" +#include "component.hpp" #include "display_system_openvr.hpp" #include "display_system_window.hpp" #include "engine.hpp" @@ -39,6 +40,8 @@ #include "openvr_controller_system.hpp" #include "render_target.hpp" #include "rendering_system.hpp" +#include "runtime_component.hpp" +#include "scene.hpp" #include "tracking_system_openvr.hpp" #undef CreateWindow @@ -80,61 +83,79 @@ std::unique_ptr<Engine> Setup::CreateDefaultEngine() { // setup rendering and frame graph if (using_hmd) { - // we need the render targets of the DisplaySystemOpenVR, but the - // DisplaySystemWindow only exists for blitting the result of the left eye - // into the window and does not create a render target themselves - auto render_targets = displaysys_hmd->CreateRenderTargets(); - rendering_system->SetRenderTargets(&render_targets); - SetupDefaultFrameGraphOpenVR(rendering_system); auto tracking_system = engine->CreateSystem<TrackingSystemOpenVR>(displaysys_hmd); auto controller_system = engine->CreateSystem<OpenVRControllerSystem>( engine->GetSystem<DisplaySystem>()); + + displaysys_hmd->CreateRenderTargets(engine->GetScene().get()); + SetupDefaultFrameGraphOpenVR(rendering_system, engine.get()); + engine->MoveSystemBefore(tracking_system, rendering_system); engine->MoveSystemAfter(behavior_system, tracking_system); engine->MoveSystemAfter(controller_system, tracking_system); } else { - auto render_targets = displaysys_window->CreateRenderTargets(); - rendering_system->SetRenderTargets(&render_targets); - SetupDefaultFrameGraphWindow(rendering_system); + // TODO(@ALL): This should not be done here. + Entity* platform = + engine->GetScene() + ->GetEntitiesWithComponents<RuntimeComponent<USER_PLATFORM>>()[0]; + Entity* camera = engine->GetScene()->CreateEntity(); + camera->AddComponent<Transform>()->SetParent( + platform->GetFirstComponent<Transform>()); + camera->AddComponent<Projection>(); + camera->AddComponent<RenderTarget>(window_size); + SetupDefaultFrameGraphWindow(rendering_system, engine.get()); } return engine; } -void Setup::SetupDefaultFrameGraphWindow(RenderingSystem* rendering_system) { +void Setup::SetupDefaultFrameGraphWindow(RenderingSystem* rendering_system, + Engine* engine) { auto frame_graph = std::make_unique<FrameGraph>(); - auto render_targets = rendering_system->GetRenderTargets(); - if (render_targets.empty()) { + auto render_target = engine->GetScene() + ->GetEntitiesWithComponents<RenderTarget>()[0] + ->GetFirstComponent<RenderTarget>(); + if (!render_target) { error("Cannot setup default frame graph (window): no render targets."); return; } - frame_graph->AddRenderPass(std::make_unique<ClearPass>(render_targets[0])); - frame_graph->AddRenderPass(std::make_unique<GeometryPass>(render_targets[0])); - frame_graph->AddRenderPass(std::make_unique<BlitPass>(render_targets[0])); + frame_graph->AddRenderPass(std::make_unique<ClearPass>(render_target)); + frame_graph->AddRenderPass(std::make_unique<GeometryPass>(render_target)); + frame_graph->AddRenderPass(std::make_unique<BlitPass>(render_target)); frame_graph->Initialize(); rendering_system->SetFrameGraph(std::move(frame_graph)); } -void Setup::SetupDefaultFrameGraphOpenVR(RenderingSystem* rendering_system) { +void Setup::SetupDefaultFrameGraphOpenVR(RenderingSystem* rendering_system, + Engine* engine) { auto frame_graph = std::make_unique<FrameGraph>(); - auto render_targets = rendering_system->GetRenderTargets(); - if (render_targets.size() < 2) { + auto left_render_target = + engine->GetScene() + ->GetEntitiesWithComponents<RuntimeComponent<LEFT_EYE>>()[0] + ->GetFirstComponent<RenderTarget>(); + auto right_render_target = + engine->GetScene() + ->GetEntitiesWithComponents<RuntimeComponent<RIGHT_EYE>>()[0] + ->GetFirstComponent<RenderTarget>(); + if (!left_render_target || !right_render_target) { error( "Cannot setup default frame graph (OpenVR): not enough render " "targets."); return; } - frame_graph->AddRenderPass(std::make_unique<ClearPass>(render_targets[0])); - frame_graph->AddRenderPass(std::make_unique<ClearPass>(render_targets[1])); - frame_graph->AddRenderPass(std::make_unique<GeometryPass>(render_targets[0])); - frame_graph->AddRenderPass(std::make_unique<GeometryPass>(render_targets[1])); + frame_graph->AddRenderPass(std::make_unique<ClearPass>(right_render_target)); + frame_graph->AddRenderPass(std::make_unique<ClearPass>(left_render_target)); + frame_graph->AddRenderPass( + std::make_unique<GeometryPass>(right_render_target)); + frame_graph->AddRenderPass( + std::make_unique<GeometryPass>(left_render_target)); - frame_graph->AddRenderPass(std::make_unique<BlitPass>(render_targets[0])); + frame_graph->AddRenderPass(std::make_unique<BlitPass>(right_render_target)); frame_graph->Initialize(); diff --git a/library/phx/setup.hpp b/library/phx/setup.hpp index c5fb4a7496c2990dc871484eb020e0c22c0b437b..ee37cf4cf9b4712479652c1d5aa2716bf5b29343 100644 --- a/library/phx/setup.hpp +++ b/library/phx/setup.hpp @@ -43,8 +43,10 @@ class PHOENIX_EXPORT Setup { // also creates an empty scene for the engine static std::unique_ptr<Engine> CreateDefaultEngine(); - static void SetupDefaultFrameGraphWindow(RenderingSystem* rendering_system); - static void SetupDefaultFrameGraphOpenVR(RenderingSystem* rendering_system); + static void SetupDefaultFrameGraphWindow(RenderingSystem* rendering_system, + Engine* engine); + static void SetupDefaultFrameGraphOpenVR(RenderingSystem* rendering_system, + Engine* engine); }; } // namespace phx diff --git a/tests/src/integration_test_model_rendering.cpp b/tests/src/integration_test_model_rendering.cpp index 1dc9ffc83ffbb1e255a8259dca92cce2e1fea930..4b9416dad1fbd4ac028b01a2c67ece54298a56c7 100644 --- a/tests/src/integration_test_model_rendering.cpp +++ b/tests/src/integration_test_model_rendering.cpp @@ -90,9 +90,10 @@ void SetupLightAndCamera(phx::Scene* scene) { light->SetColor(glm::vec3(1.0f, 1.0f, 1.0f)); light->SetIntensity(1.0f); - phx::Entity* camera = scene->CreateEntity(); - auto camera_transform = camera->AddComponent<phx::Transform>(); - auto camera_projection = camera->AddComponent<phx::Projection>(); + phx::Entity* camera = + scene->GetEntitiesWithComponents<phx::RenderTarget>()[0]; + auto camera_transform = camera->GetFirstComponent<phx::Transform>(); + auto camera_projection = camera->GetFirstComponent<phx::Projection>(); camera_projection->SetPerspective(glm::radians(68.0f), 4.0f / 3.0f, 0.01f, 1000.0f); camera_transform->SetLocalTranslation(glm::vec3(0, 0, -0.3)); diff --git a/tests/src/integration_test_rendering.cpp b/tests/src/integration_test_rendering.cpp index eeabd149ba5ab97deb604d1ca8c77e9d277b4e5d..fae6373d2b335894e644afe32725def618896dbb 100644 --- a/tests/src/integration_test_rendering.cpp +++ b/tests/src/integration_test_rendering.cpp @@ -65,9 +65,10 @@ void SetupLightAndCamera(phx::Scene* scene) { light->SetColor(glm::vec3(1.0f, 1.0f, 1.0f)); light->SetIntensity(1.0f); - phx::Entity* camera = scene->CreateEntity(); - auto camera_transform = camera->AddComponent<phx::Transform>(); - auto camera_projection = camera->AddComponent<phx::Projection>(); + phx::Entity* camera = + scene->GetEntitiesWithComponents<phx::RenderTarget>()[0]; + auto camera_transform = camera->GetFirstComponent<phx::Transform>(); + auto camera_projection = camera->GetFirstComponent<phx::Projection>(); camera_projection->SetPerspective(glm::radians(68.0f), 4.0f / 3.0f, 0.01f, 1000.0f); camera_transform->SetLocalTranslation(glm::vec3(0, 0, 2.0)); diff --git a/tests/src/test_geometry_pass.cpp b/tests/src/test_geometry_pass.cpp index 2edd3f931eda628a101e8da96c77b147b8e5bdf0..d8cdc27c771136f87a763a8cb840352afbd17ceb 100644 --- a/tests/src/test_geometry_pass.cpp +++ b/tests/src/test_geometry_pass.cpp @@ -39,7 +39,9 @@ SUPPRESS_WARNINGS_END #include "phx/entity.hpp" #include "phx/geometry_pass.hpp" +#include "phx/projection.hpp" #include "phx/render_target.hpp" +#include "phx/transform.hpp" #include "mocks/opengl_mock.hpp" @@ -57,8 +59,12 @@ SCENARIO( const GLuint index_buffer_id = 4u; GIVEN("A geometry pass") { - phx::RenderTarget renderTarget(glm::uvec2(1024, 768)); - phx::GeometryPass geometry_pass(&renderTarget); + phx::Entity camera; + camera.AddComponent<phx::Transform>(); + camera.AddComponent<phx::Projection>(); + auto render_target = + camera.AddComponent<phx::RenderTarget>(glm::uvec2(1024, 768)); + phx::GeometryPass geometry_pass(render_target); WHEN("We initialize it.") { trompeloeil::sequence seq; @@ -223,8 +229,12 @@ SCENARIO( const GLuint index_buffer_id = 3u; GIVEN("An initialized geometry pass") { - phx::RenderTarget renderTarget(glm::uvec2(1024, 768)); - phx::GeometryPass geometry_pass(&renderTarget); + phx::Entity camera; + camera.AddComponent<phx::Transform>(); + camera.AddComponent<phx::Projection>(); + auto render_target = + camera.AddComponent<phx::RenderTarget>(glm::uvec2(1024, 768)); + phx::GeometryPass geometry_pass(render_target); geometry_pass.Initialize(); WHEN("We add a meshes with two different transformations") {