Skip to content
Snippets Groups Projects
Select Git revision
  • c06bd998dd75ab178f81445e77178f3ce10f617c
  • 5.4 default protected
  • 5.5
  • dev/5.5
  • dev/5.4
  • dev/5.3_downgrade
  • feature/experimenttime_hack
  • 5.3 protected
  • _IntenSelect5.3
  • IntenSelect5.3
  • 4.27 protected
  • 4.26 protected
  • 5.0 protected
  • 4.22 protected
  • 4.21 protected
  • UE5.4-2024.1
  • UE5.4-2024.1-rc1
  • UE5.3-2023.1-rc3
  • UE5.3-2023.1-rc2
  • UE5.3-2023.1-rc
20 results

ClickMeWidget.uasset

Blame
  • rendering_system.cpp 7.12 KiB
    //------------------------------------------------------------------------------
    // Project Phoenix
    //
    // Copyright (c) 2017-2018 RWTH Aachen University, Germany,
    // Virtual Reality & Immersive Visualization Group.
    //------------------------------------------------------------------------------
    //                                 License
    //
    // Licensed under the 3-Clause BSD License (the "License");
    // you may not use this file except in compliance with the License.
    // See the file LICENSE for the full text.
    // You may obtain a copy of the License at
    //
    //     https://opensource.org/licenses/BSD-3-Clause
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    //------------------------------------------------------------------------------
    
    #include "rendering_system.hpp"
    
    #include <iostream>
    #include <memory>
    #include <string>
    #include <tuple>
    #include <utility>
    #include <vector>
    
    #include "blit_pass.hpp"
    #include "clear_pass.hpp"
    #include "display_system.hpp"
    #include "engine.hpp"
    #include "light.hpp"
    #include "logger.hpp"
    #include "material_handle.hpp"
    #include "mesh.hpp"
    #include "mesh_handle.hpp"
    #include "projection.hpp"
    #include "scene.hpp"
    #include "system.hpp"
    #include "transform.hpp"
    
    #include "gl/opengl.hpp"
    
    namespace phx {
    
    RenderingSystem::RenderingSystem(Engine* engine, DisplaySystem* display_system)
        : System(engine) {
      if (!display_system) error("RenderingSystem needs a valid DisplaySystem.");
      InitializeOpenGL();
      InitializeRenderTargets();
      SetupFramegraph();
    }
    
    void RenderingSystem::InitializeOpenGL() {
      if (!gl::initialize()) {
        error("Initializing gl failed");
      }
      std::string prefix = "[RenderingSystem] OpenGl Error: ";
      gl::print_error(prefix.c_str());
    }
    
    void RenderingSystem::InitializeRenderTargets() {
      const auto displaySystem = engine_->GetSystem<DisplaySystem>();
      if (displaySystem == nullptr) {
        error(
            "The Rendering System cannot be initialized without a display system");
        return;
      }
    
      // TODO(all) Support multiple windows and HMD?
      if (displaySystem->GetHMD() != nullptr) {
        HMD* hmd = displaySystem->GetHMD();
        right_render_target_ =
            std::make_unique<RenderTarget>(hmd->GetViewportSize());
        left_render_target_ =
            std::make_unique<RenderTarget>(hmd->GetViewportSize());
      } else if (displaySystem->GetWindow() != nullptr) {
        auto window = displaySystem->GetWindow();
        window_render_target_ = std::make_unique<RenderTarget>(window->GetSize());
      }
    }
    
    void RenderingSystem::SetupFramegraph() {
      frame_graph_ = std::make_unique<FrameGraph>();
    
      if (right_render_target_ != nullptr && left_render_target_ != nullptr) {
        frame_graph_->AddRenderPass(
            std::make_unique<ClearPass>(right_render_target_.get()));
        frame_graph_->AddRenderPass(
            std::make_unique<ClearPass>(left_render_target_.get()));
        auto geometry_pass = static_cast<GeometryPass*>(frame_graph_->AddRenderPass(
            std::make_unique<GeometryPass>(right_render_target_.get())));
        geometry_passes_.push_back(geometry_pass);
        geometry_pass = static_cast<GeometryPass*>(frame_graph_->AddRenderPass(
            std::make_unique<GeometryPass>(left_render_target_.get())));
        geometry_passes_.push_back(geometry_pass);
    
        frame_graph_->AddRenderPass(
            std::make_unique<BlitPass>(right_render_target_.get()));
      } else if (window_render_target_ != nullptr) {
        frame_graph_->AddRenderPass(
            std::make_unique<ClearPass>(window_render_target_.get()));
        auto geometry_pass = static_cast<GeometryPass*>(frame_graph_->AddRenderPass(
            std::make_unique<GeometryPass>(window_render_target_.get())));
        geometry_passes_.push_back(geometry_pass);
        frame_graph_->AddRenderPass(
            std::make_unique<BlitPass>(window_render_target_.get()));
      } else {
        error(
            "[RenderingSystem] No Render Targets are defined, so no framegraph "
            "will be created.");
        return;
      }
    
      frame_graph_->Initialize();
    }
    
    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;
      }
    
      // TODO(@all) refactor this part, once there is a way to get entities by name
      for (auto& entity : GetEngine()->GetEntities()) {
        if (entity->GetName() == "RuntimeEntityEyeLeft") {
          left_render_target_->SetView(
              inverse(entity->GetFirstComponent<Transform>()->GetGlobalMatrix()));
        }
        if (entity->GetName() == "RuntimeEntityEyeRight") {
          right_render_target_->SetView(
              inverse(entity->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) {
          if (mesh_handle != nullptr) {
            Material* material = nullptr;
            if (material_handle != nullptr)
              material = material_handle->GetMaterial();
            rendering_instances.push_back(
                {mesh_handle->GetMesh(), material, transform});
          } 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));
          }
        }
      }
      for (auto geometry_pass : geometry_passes_) {
        geometry_pass->SetData(rendering_instances, light_transform_pairs);
      }
    
      HMD* hmd = engine_->GetSystem<DisplaySystem>()->GetHMD();
      if (left_render_target_ != nullptr) {
        left_render_target_->SetProjection(hmd->GetProjectionMatrix(HMD::LEFT_EYE));
      }
      if (right_render_target_ != nullptr) {
        right_render_target_->SetProjection(
            hmd->GetProjectionMatrix(HMD::RIGHT_EYE));
      }
      if (window_render_target_ != nullptr && !projection_transform_pairs.empty()) {
        window_render_target_->SetProjection(
            projection_transform_pairs[0].first->GetMatrix());
        window_render_target_->SetView(
            glm::inverse(projection_transform_pairs[0].second->GetGlobalMatrix()));
      }
    
      frame_graph_->Execute();
    }
    
    FrameGraph* RenderingSystem::GetFrameGraph() const {
      return frame_graph_.get();
    }
    
    std::string RenderingSystem::ToString() const {
      return "RenderingSystem with #FrameGraph-Passes: " +
             std::to_string(frame_graph_->GetNumberOfPasses());
    }
    
    phx::RenderTarget* RenderingSystem::GetRightRenderTarget() const {
      return right_render_target_.get();
    }
    
    phx::RenderTarget* RenderingSystem::GetLeftRenderTarget() const {
      return left_render_target_.get();
    }
    
    }  // namespace phx