MultiViewSingleSceneAuxGeomExampleComponent.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <MultiViewSingleSceneAuxGeomExampleComponent.h>
  9. #include <AuxGeomSharedDrawFunctions.h>
  10. #include <Atom/Component/DebugCamera/CameraComponent.h>
  11. #include <Atom/Component/DebugCamera/NoClipControllerComponent.h>
  12. #include <Atom/Feature/PostProcessing/PostProcessingConstants.h>
  13. #include <Atom/RPI.Public/RenderPipeline.h>
  14. #include <Atom/RPI.Public/Scene.h>
  15. #include <Atom/RHI/RHISystemInterface.h>
  16. #include <Atom/RPI.Public/RPISystemInterface.h>
  17. #include <Atom/RPI.Public/AuxGeom/AuxGeomDraw.h>
  18. #include <Atom/RPI.Public/AuxGeom/AuxGeomFeatureProcessorInterface.h>
  19. #include <Atom/RPI.Reflect/Model/ModelAsset.h>
  20. #include <AzCore/Math/MatrixUtils.h>
  21. #include <AzCore/Component/Entity.h>
  22. #include <AzFramework/Components/TransformComponent.h>
  23. #include <AzFramework/Scene/SceneSystemInterface.h>
  24. #include <SampleComponentConfig.h>
  25. #include <SampleComponentManager.h>
  26. #include <EntityUtilityFunctions.h>
  27. #include <RHI/BasicRHIComponent.h>
  28. #include <AtomSampleViewerOptions.h>
  29. namespace AtomSampleViewer
  30. {
  31. //////////////////////////////////////////////////////////////////////////
  32. // WindowedView
  33. //! A simple example for how to set up a second window, view, renderPipeline, and basic entities.
  34. class WindowedView final
  35. : public AzFramework::WindowNotificationBus::Handler
  36. {
  37. friend MultiViewSingleSceneAuxGeomExampleComponent;
  38. protected:
  39. AZStd::unique_ptr<AzFramework::NativeWindow> m_nativeWindow;
  40. AZStd::shared_ptr<AZ::RPI::WindowContext> m_windowContext;
  41. AZ::RPI::RenderPipelinePtr m_pipeline;
  42. AZ::Entity* m_cameraEntity = nullptr;
  43. AZ::RPI::ViewPtr m_view;
  44. MultiViewSingleSceneAuxGeomExampleComponent* m_parent;
  45. public:
  46. WindowedView(AzFramework::EntityContextId contextId, MultiViewSingleSceneAuxGeomExampleComponent *parent)
  47. : m_parent(parent)
  48. {
  49. m_parent = parent;
  50. // Create a NativeWindow and WindowContext
  51. m_nativeWindow = AZStd::make_unique<AzFramework::NativeWindow>("Multi View Single Scene: Second Window", AzFramework::WindowGeometry(0, 0, 640, 480));
  52. m_nativeWindow->Activate();
  53. AZ::RHI::Ptr<AZ::RHI::Device> device = AZ::RHI::RHISystemInterface::Get()->GetDevice();
  54. m_windowContext = AZStd::make_shared<AZ::RPI::WindowContext>();
  55. m_windowContext->Initialize(*device, m_nativeWindow->GetWindowHandle());
  56. auto scene = AZ::RPI::RPISystemInterface::Get()->GetSceneByName(AZ::Name("RPI"));
  57. // Create a custom pipeline descriptor
  58. AZ::RPI::RenderPipelineDescriptor pipelineDesc;
  59. pipelineDesc.m_mainViewTagName = "MainCamera"; //Surface shaders render to the "MainCamera" tag
  60. pipelineDesc.m_name = "SecondPipeline"; //Sets the debug name for this pipeline
  61. pipelineDesc.m_rootPassTemplate = "MainPipeline"; //References a template in AtomSampleViewer\Passes\PassTemplates.azasset
  62. pipelineDesc.m_renderSettings.m_multisampleState.m_samples = 4;
  63. m_pipeline = AZ::RPI::RenderPipeline::CreateRenderPipelineForWindow(pipelineDesc, *m_windowContext);
  64. scene->AddRenderPipeline(m_pipeline);
  65. // Create a camera entity, hook it up to the RenderPipeline
  66. m_cameraEntity = CreateEntity("WindowedViewCamera", contextId);
  67. AZ::Debug::CameraComponentConfig cameraConfig(m_windowContext);
  68. cameraConfig.m_fovY = AZ::Constants::QuarterPi;
  69. AZ::Debug::CameraComponent* camComponent = static_cast<AZ::Debug::CameraComponent*>(m_cameraEntity->CreateComponent(azrtti_typeid<AZ::Debug::CameraComponent>()));
  70. camComponent->SetConfiguration(cameraConfig);
  71. m_cameraEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
  72. m_cameraEntity->CreateComponent(azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
  73. m_cameraEntity->Activate();
  74. m_pipeline->SetDefaultViewFromEntity(m_cameraEntity->GetId());
  75. m_view = camComponent->GetView();
  76. AzFramework::WindowNotificationBus::Handler::BusConnect(m_nativeWindow->GetWindowHandle());
  77. }
  78. ~WindowedView()
  79. {
  80. AzFramework::WindowNotificationBus::Handler::BusDisconnect(m_nativeWindow->GetWindowHandle());
  81. DestroyEntity(m_cameraEntity);
  82. m_pipeline->RemoveFromScene();
  83. m_pipeline = nullptr;
  84. m_windowContext->Shutdown();
  85. m_windowContext = nullptr;
  86. }
  87. // AzFramework::WindowNotificationBus::Handler overrides ...
  88. void OnWindowClosed() override
  89. {
  90. m_parent->OnChildWindowClosed();
  91. }
  92. AzFramework::NativeWindowHandle GetNativeWindowHandle()
  93. {
  94. if (m_nativeWindow)
  95. {
  96. return m_nativeWindow->GetWindowHandle();
  97. }
  98. else
  99. {
  100. return nullptr;
  101. }
  102. }
  103. };
  104. //////////////////////////////////////////////////////////////////////////
  105. // MultiViewSingleSceneAuxGeomExampleComponent
  106. void MultiViewSingleSceneAuxGeomExampleComponent::Reflect(AZ::ReflectContext* context)
  107. {
  108. if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  109. {
  110. serializeContext->Class<MultiViewSingleSceneAuxGeomExampleComponent, AZ::Component>()
  111. ->Version(0)
  112. ;
  113. }
  114. }
  115. MultiViewSingleSceneAuxGeomExampleComponent::MultiViewSingleSceneAuxGeomExampleComponent()
  116. {
  117. }
  118. void MultiViewSingleSceneAuxGeomExampleComponent::Activate()
  119. {
  120. // Setup primary camera controls
  121. AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Enable,
  122. azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
  123. OpenSecondSceneWindow();
  124. AZ::TickBus::Handler::BusConnect();
  125. }
  126. void MultiViewSingleSceneAuxGeomExampleComponent::Deactivate()
  127. {
  128. AZ::TickBus::Handler::BusDisconnect();
  129. AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Disable);
  130. if(m_windowedView)
  131. {
  132. m_windowedView = nullptr;
  133. }
  134. }
  135. void MultiViewSingleSceneAuxGeomExampleComponent::OnChildWindowClosed()
  136. {
  137. m_windowedView = nullptr;
  138. }
  139. void MultiViewSingleSceneAuxGeomExampleComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
  140. {
  141. DrawAuxGeom();
  142. if (SupportsMultipleWindows() && ImGui::Begin("Multi View Panel"))
  143. {
  144. if(m_windowedView)
  145. {
  146. if (ImGui::Button("Close Second View Window"))
  147. {
  148. m_windowedView = nullptr;
  149. }
  150. }
  151. else
  152. {
  153. if (ImGui::Button("Open Second View Window"))
  154. {
  155. OpenSecondSceneWindow();
  156. }
  157. }
  158. ImGui::End();
  159. }
  160. if (m_windowedView)
  161. {
  162. // duplicate first camera changes to the 2nd camera
  163. AZ::Transform mainCameraTransform;
  164. AZ::TransformBus::EventResult(mainCameraTransform, GetCameraEntityId(), &AZ::TransformBus::Events::GetWorldTM);
  165. Camera::CameraComponentRequests* cameraInterface = Camera::CameraRequestBus::FindFirstHandler(GetCameraEntityId());
  166. float fovRadians = cameraInterface->GetFovRadians();
  167. float nearClipDistance = cameraInterface->GetNearClipDistance();
  168. float farClipDistance = cameraInterface->GetFarClipDistance();
  169. AZ::EntityId secondCameraEntityId = m_windowedView->m_cameraEntity->GetId();
  170. AZ::TransformBus::Event(secondCameraEntityId, &AZ::TransformBus::Events::SetWorldTM, mainCameraTransform);
  171. Camera::CameraComponentRequests* secondCamInterface = Camera::CameraRequestBus::FindFirstHandler(secondCameraEntityId);
  172. secondCamInterface->SetFovRadians(fovRadians);
  173. secondCamInterface->SetNearClipDistance(nearClipDistance);
  174. secondCamInterface->SetFarClipDistance(farClipDistance);
  175. }
  176. }
  177. void MultiViewSingleSceneAuxGeomExampleComponent::OpenSecondSceneWindow()
  178. {
  179. if (SupportsMultipleWindows() && !m_windowedView)
  180. {
  181. m_windowedView = AZStd::make_unique<WindowedView>(GetEntityContextId(), this);
  182. }
  183. }
  184. void MultiViewSingleSceneAuxGeomExampleComponent::DrawAuxGeom() const
  185. {
  186. auto auxGeomFP = m_scene->GetFeatureProcessor<AZ::RPI::AuxGeomFeatureProcessorInterface>();
  187. if (auto auxGeom = auxGeomFP->GetDrawQueue())
  188. {
  189. DrawBackgroundBox(auxGeom);
  190. DrawThreeGridsOfPoints(auxGeom);
  191. DrawAxisLines(auxGeom);
  192. DrawLines(auxGeom);
  193. DrawBoxes(auxGeom, -20.0f);
  194. Draw2DWireRect(auxGeom, AZ::Colors::Red, 1.0f);
  195. }
  196. if (m_windowedView)
  197. {
  198. if (auto auxGeom = auxGeomFP->GetDrawQueueForView(m_windowedView->m_view.get()))
  199. {
  200. DrawTriangles(auxGeom);
  201. DrawShapes(auxGeom);
  202. DrawBoxes(auxGeom, 10.0f);
  203. DrawDepthTestPrimitives(auxGeom);
  204. Draw2DWireRect(auxGeom, AZ::Colors::Yellow, 0.9f);
  205. }
  206. }
  207. }
  208. } // namespace AtomSampleViewer