MultiViewSingleSceneAuxGeomExampleComponent.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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 = 1;
  63. SampleComponentManagerRequestBus::BroadcastResult(
  64. pipelineDesc.m_renderSettings.m_multisampleState.m_samples,
  65. &SampleComponentManagerRequests::GetNumMSAASamples);
  66. m_pipeline = AZ::RPI::RenderPipeline::CreateRenderPipelineForWindow(pipelineDesc, *m_windowContext);
  67. scene->AddRenderPipeline(m_pipeline);
  68. // Create a camera entity, hook it up to the RenderPipeline
  69. m_cameraEntity = CreateEntity("WindowedViewCamera", contextId);
  70. AZ::Debug::CameraComponentConfig cameraConfig(m_windowContext);
  71. cameraConfig.m_fovY = AZ::Constants::QuarterPi;
  72. AZ::Debug::CameraComponent* camComponent = static_cast<AZ::Debug::CameraComponent*>(m_cameraEntity->CreateComponent(azrtti_typeid<AZ::Debug::CameraComponent>()));
  73. camComponent->SetConfiguration(cameraConfig);
  74. m_cameraEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
  75. m_cameraEntity->CreateComponent(azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
  76. m_cameraEntity->Activate();
  77. m_pipeline->SetDefaultViewFromEntity(m_cameraEntity->GetId());
  78. m_view = camComponent->GetView();
  79. AzFramework::WindowNotificationBus::Handler::BusConnect(m_nativeWindow->GetWindowHandle());
  80. }
  81. ~WindowedView()
  82. {
  83. AzFramework::WindowNotificationBus::Handler::BusDisconnect(m_nativeWindow->GetWindowHandle());
  84. DestroyEntity(m_cameraEntity);
  85. m_pipeline->RemoveFromScene();
  86. m_pipeline = nullptr;
  87. m_windowContext->Shutdown();
  88. m_windowContext = nullptr;
  89. }
  90. // AzFramework::WindowNotificationBus::Handler overrides ...
  91. void OnWindowClosed() override
  92. {
  93. m_parent->OnChildWindowClosed();
  94. }
  95. AzFramework::NativeWindowHandle GetNativeWindowHandle()
  96. {
  97. if (m_nativeWindow)
  98. {
  99. return m_nativeWindow->GetWindowHandle();
  100. }
  101. else
  102. {
  103. return nullptr;
  104. }
  105. }
  106. };
  107. //////////////////////////////////////////////////////////////////////////
  108. // MultiViewSingleSceneAuxGeomExampleComponent
  109. void MultiViewSingleSceneAuxGeomExampleComponent::Reflect(AZ::ReflectContext* context)
  110. {
  111. if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  112. {
  113. serializeContext->Class<MultiViewSingleSceneAuxGeomExampleComponent, AZ::Component>()
  114. ->Version(0)
  115. ;
  116. }
  117. }
  118. MultiViewSingleSceneAuxGeomExampleComponent::MultiViewSingleSceneAuxGeomExampleComponent()
  119. {
  120. }
  121. void MultiViewSingleSceneAuxGeomExampleComponent::Activate()
  122. {
  123. // Setup primary camera controls
  124. AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Enable,
  125. azrtti_typeid<AZ::Debug::NoClipControllerComponent>());
  126. OpenSecondSceneWindow();
  127. AZ::TickBus::Handler::BusConnect();
  128. }
  129. void MultiViewSingleSceneAuxGeomExampleComponent::Deactivate()
  130. {
  131. AZ::TickBus::Handler::BusDisconnect();
  132. AZ::Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &AZ::Debug::CameraControllerRequestBus::Events::Disable);
  133. if(m_windowedView)
  134. {
  135. m_windowedView = nullptr;
  136. }
  137. }
  138. void MultiViewSingleSceneAuxGeomExampleComponent::OnChildWindowClosed()
  139. {
  140. m_windowedView = nullptr;
  141. }
  142. void MultiViewSingleSceneAuxGeomExampleComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
  143. {
  144. DrawAuxGeom();
  145. if (SupportsMultipleWindows() && ImGui::Begin("Multi View Panel"))
  146. {
  147. if(m_windowedView)
  148. {
  149. if (ImGui::Button("Close Second View Window"))
  150. {
  151. m_windowedView = nullptr;
  152. }
  153. }
  154. else
  155. {
  156. if (ImGui::Button("Open Second View Window"))
  157. {
  158. OpenSecondSceneWindow();
  159. }
  160. }
  161. ImGui::End();
  162. }
  163. if (m_windowedView)
  164. {
  165. // duplicate first camera changes to the 2nd camera
  166. AZ::Transform mainCameraTransform;
  167. AZ::TransformBus::EventResult(mainCameraTransform, GetCameraEntityId(), &AZ::TransformBus::Events::GetWorldTM);
  168. Camera::CameraComponentRequests* cameraInterface = Camera::CameraRequestBus::FindFirstHandler(GetCameraEntityId());
  169. float fovRadians = cameraInterface->GetFovRadians();
  170. float nearClipDistance = cameraInterface->GetNearClipDistance();
  171. float farClipDistance = cameraInterface->GetFarClipDistance();
  172. AZ::EntityId secondCameraEntityId = m_windowedView->m_cameraEntity->GetId();
  173. AZ::TransformBus::Event(secondCameraEntityId, &AZ::TransformBus::Events::SetWorldTM, mainCameraTransform);
  174. Camera::CameraComponentRequests* secondCamInterface = Camera::CameraRequestBus::FindFirstHandler(secondCameraEntityId);
  175. secondCamInterface->SetFovRadians(fovRadians);
  176. secondCamInterface->SetNearClipDistance(nearClipDistance);
  177. secondCamInterface->SetFarClipDistance(farClipDistance);
  178. }
  179. }
  180. void MultiViewSingleSceneAuxGeomExampleComponent::OpenSecondSceneWindow()
  181. {
  182. if (SupportsMultipleWindows() && !m_windowedView)
  183. {
  184. m_windowedView = AZStd::make_unique<WindowedView>(GetEntityContextId(), this);
  185. }
  186. }
  187. void MultiViewSingleSceneAuxGeomExampleComponent::DrawAuxGeom() const
  188. {
  189. auto auxGeomFP = m_scene->GetFeatureProcessor<AZ::RPI::AuxGeomFeatureProcessorInterface>();
  190. if (auto auxGeom = auxGeomFP->GetDrawQueue())
  191. {
  192. DrawBackgroundBox(auxGeom);
  193. DrawThreeGridsOfPoints(auxGeom);
  194. DrawAxisLines(auxGeom);
  195. DrawLines(auxGeom);
  196. DrawBoxes(auxGeom, -20.0f);
  197. Draw2DWireRect(auxGeom, AZ::Colors::Red, 1.0f);
  198. }
  199. if (m_windowedView)
  200. {
  201. if (auto auxGeom = auxGeomFP->GetDrawQueueForView(m_windowedView->m_view.get()))
  202. {
  203. DrawTriangles(auxGeom);
  204. DrawShapes(auxGeom);
  205. DrawBoxes(auxGeom, 10.0f);
  206. DrawDepthTestPrimitives(auxGeom);
  207. Draw2DWireRect(auxGeom, AZ::Colors::Yellow, 0.9f);
  208. }
  209. }
  210. }
  211. } // namespace AtomSampleViewer