2
0

MultiViewSingleSceneAuxGeomExampleComponent.cpp 9.6 KB

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