123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <AtomSampleViewerOptions.h>
- #include <MultiSceneExampleComponent.h>
- #include <Atom/Component/DebugCamera/CameraComponent.h>
- #include <Atom/Component/DebugCamera/NoClipControllerComponent.h>
- #include <Atom/RPI.Public/RenderPipeline.h>
- #include <Atom/RPI.Public/Scene.h>
- #include <Atom/RHI/RHISystemInterface.h>
- #include <Atom/RPI.Public/RPISystemInterface.h>
- #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
- #include <Atom/RPI.Reflect/Model/ModelAsset.h>
- #include <Automation/ScriptRunnerBus.h>
- #include <AzCore/Math/MatrixUtils.h>
- #include <AzCore/Component/Entity.h>
- #include <AzFramework/Components/TransformComponent.h>
- #include <AzFramework/Scene/SceneSystemInterface.h>
- #include <AzFramework/Entity/GameEntityContextComponent.h>
- #include <SampleComponentConfig.h>
- #include <SampleComponentManager.h>
- #include <EntityUtilityFunctions.h>
- #include <RHI/BasicRHIComponent.h>
- namespace AtomSampleViewer
- {
- using namespace AZ;
- //////////////////////////////////////////////////////////////////////////
- // SecondWindowedScene
- SecondWindowedScene::SecondWindowedScene(AZStd::string_view sceneName, MultiSceneExampleComponent* parent)
- {
- using namespace AZ;
- m_sceneName = sceneName;
- m_parent = parent;
- // Create a new EntityContext and AzFramework::Scene, and link them together via SetSceneForEntityContextId
- m_entityContext = AZStd::make_unique<AzFramework::EntityContext>();
- m_entityContext->InitContext();
- // Create the scene
- auto sceneSystem = AzFramework::SceneSystemInterface::Get();
- AZ_Assert(sceneSystem, "Unable to retrieve scene system.");
- Outcome<AZStd::shared_ptr<AzFramework::Scene>, AZStd::string> createSceneOutcome = sceneSystem->CreateScene(m_sceneName);
- AZ_Assert(createSceneOutcome, "%s", createSceneOutcome.GetError().data());
- m_frameworkScene = createSceneOutcome.TakeValue();
- m_frameworkScene->SetSubsystem<AzFramework::EntityContext::SceneStorageType>(m_entityContext.get());
-
- // Create a NativeWindow and WindowContext
- m_nativeWindow = AZStd::make_unique<AzFramework::NativeWindow>("Multi Scene: Second Window", AzFramework::WindowGeometry(0, 0, 1280, 720));
- m_nativeWindow->Activate();
- RHI::Ptr<RHI::Device> device = RHI::RHISystemInterface::Get()->GetDevice();
- m_windowContext = AZStd::make_shared<RPI::WindowContext>();
- m_windowContext->Initialize(*device, m_nativeWindow->GetWindowHandle());
- // Create the RPI::Scene, add some feature processors
- RPI::SceneDescriptor sceneDesc;
- sceneDesc.m_nameId = AZ::Name("SecondScene");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::SimplePointLightFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::SimpleSpotLightFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::CapsuleLightFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::DecalTextureArrayFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::DirectionalLightFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::DiskLightFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::ImageBasedLightFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::MeshFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::PointLightFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::PostProcessFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::QuadLightFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::ReflectionProbeFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::SkyBoxFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::TransformServiceFeatureProcessor");
- sceneDesc.m_featureProcessorNames.push_back("AZ::Render::ProjectedShadowFeatureProcessor");
- m_scene = RPI::Scene::CreateScene(sceneDesc);
- // Link our RPI::Scene to the AzFramework::Scene
- m_frameworkScene->SetSubsystem(m_scene);
- // Create a custom pipeline descriptor
- RPI::RenderPipelineDescriptor pipelineDesc;
- pipelineDesc.m_mainViewTagName = "MainCamera"; // Surface shaders render to the "MainCamera" tag
- pipelineDesc.m_name = "SecondPipeline"; // Sets the debug name for this pipeline
- pipelineDesc.m_rootPassTemplate = "MainPipeline"; // References a template in AtomSampleViewer\Passes\MainPipeline.pass
- pipelineDesc.m_renderSettings.m_multisampleState.m_samples = 1;
- SampleComponentManagerRequestBus::BroadcastResult(
- pipelineDesc.m_renderSettings.m_multisampleState.m_samples,
- &SampleComponentManagerRequests::GetNumMSAASamples);
- pipelineDesc.m_allowModification = true;
- m_pipeline = RPI::RenderPipeline::CreateRenderPipelineForWindow(pipelineDesc, *m_windowContext);
- m_scene->AddRenderPipeline(m_pipeline);
- m_scene->Activate();
- RPI::RPISystemInterface::Get()->RegisterScene(m_scene);
- // Create a camera entity, hook it up to the RenderPipeline
- m_cameraEntity = CreateEntity("WindowedSceneCamera", m_entityContext->GetContextId());
- Debug::CameraComponentConfig cameraConfig(m_windowContext);
- cameraConfig.m_fovY = Constants::HalfPi;
- m_cameraEntity->CreateComponent(azrtti_typeid<Debug::CameraComponent>())->SetConfiguration(cameraConfig);
- m_cameraEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
- m_cameraEntity->CreateComponent(azrtti_typeid<Debug::NoClipControllerComponent>());
- m_cameraEntity->Init();
- m_cameraEntity->Activate();
- m_pipeline->SetDefaultViewFromEntity(m_cameraEntity->GetId());
- // Create a Depth of Field entity
- m_depthOfFieldEntity = CreateEntity("DepthOfField", m_entityContext->GetContextId());
- m_depthOfFieldEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
- // Get the FeatureProcessors
- m_meshFeatureProcessor = m_scene->GetFeatureProcessor<Render::MeshFeatureProcessorInterface>();
- m_skyBoxFeatureProcessor = m_scene->GetFeatureProcessor<Render::SkyBoxFeatureProcessorInterface>();
- m_pointLightFeatureProcessor = m_scene->GetFeatureProcessor<Render::PointLightFeatureProcessorInterface>();
- m_diskLightFeatureProcessor = m_scene->GetFeatureProcessor<Render::DiskLightFeatureProcessorInterface>();
- m_directionalLightFeatureProcessor = m_scene->GetFeatureProcessor<Render::DirectionalLightFeatureProcessorInterface>();
- m_reflectionProbeFeatureProcessor = m_scene->GetFeatureProcessor<Render::ReflectionProbeFeatureProcessorInterface>();
- m_postProcessFeatureProcessor = m_scene->GetFeatureProcessor<Render::PostProcessFeatureProcessorInterface>();
- // Helper function to load meshes
- const auto LoadMesh = [this](const char* modelPath) -> Render::MeshFeatureProcessorInterface::MeshHandle
- {
- AZ_Assert(m_meshFeatureProcessor, "Cannot find mesh feature processor on scene");
- auto meshAsset = RPI::AssetUtils::GetAssetByProductPath<RPI::ModelAsset>(modelPath, RPI::AssetUtils::TraceLevel::Assert);
- auto materialAsset = RPI::AssetUtils::LoadAssetByProductPath<RPI::MaterialAsset>(DefaultPbrMaterialPath,
- RPI::AssetUtils::TraceLevel::Assert);
- auto material = AZ::RPI::Material::FindOrCreate(materialAsset);
- Render::MeshFeatureProcessorInterface::MeshHandle meshHandle = m_meshFeatureProcessor->AcquireMesh(Render::MeshHandleDescriptor{ meshAsset }, material);
- return meshHandle;
- };
- // Create the ShaderBalls
- {
- for (uint32_t i = 0u; i < ShaderBallCount; i++)
- {
- m_shaderBallMeshHandles.push_back(LoadMesh(ShaderBallModelFilePath));
- auto updateShaderBallTransform = [this, i](Data::Instance<RPI::Model> model)
- {
- const Aabb& aabb = model->GetModelAsset()->GetAabb();
- const Vector3 translation{ 0.0f, -aabb.GetMin().GetZ() * aznumeric_cast<float>(i), -aabb.GetMin().GetY() };
- const auto transform = Transform::CreateTranslation(translation);
- m_meshFeatureProcessor->SetTransform(m_shaderBallMeshHandles[i], transform);
- };
- // If the model is available already, set the tranform immediately, else utilize the EBus::Event feature
- Data::Instance<RPI::Model> shaderBallModel = m_meshFeatureProcessor->GetModel(m_shaderBallMeshHandles[i]);
- if (shaderBallModel)
- {
- updateShaderBallTransform(shaderBallModel);
- }
- else
- {
- m_shaderBallChangedHandles.push_back(ModelChangedHandler(updateShaderBallTransform));
- m_meshFeatureProcessor->ConnectModelChangeEventHandler(m_shaderBallMeshHandles[i], m_shaderBallChangedHandles.back());
- }
- }
- }
- // Create the floor
- {
- const Vector3 nonUniformScale{ 24.f, 24.f, 1.0f };
- const Vector3 translation{ 0.f, 0.f, 0.0f };
- const auto transform = Transform::CreateTranslation(translation);
- m_floorMeshHandle = LoadMesh(CubeModelFilePath);
- m_meshFeatureProcessor->SetTransform(m_floorMeshHandle, transform, nonUniformScale);
- }
- // Create the Skybox
- {
- m_skyBoxFeatureProcessor->SetSkyboxMode(Render::SkyBoxMode::PhysicalSky);
- m_skyBoxFeatureProcessor->Enable(true);
- }
- // Create PointLight
- {
- m_pointLightHandle = m_pointLightFeatureProcessor->AcquireLight();
- const Vector3 pointLightPosition(4.0f, 0.0f, 5.0f);
- m_pointLightFeatureProcessor->SetPosition(m_pointLightHandle, pointLightPosition);
- Render::PhotometricValue rgbIntensity;
- rgbIntensity.SetEffectiveSolidAngle(Render::PhotometricValue::OmnidirectionalSteradians);
- m_pointLightFeatureProcessor->SetRgbIntensity(m_pointLightHandle, rgbIntensity.GetCombinedRgb<Render::PhotometricUnit::Candela>());
- m_pointLightFeatureProcessor->SetBulbRadius(m_pointLightHandle, 4.0f);
- }
- // Create DiskLight
- {
- m_diskLightHandle = m_diskLightFeatureProcessor->AcquireLight();
- const Vector3 diskLightPosition(3.0f, 0.0f, 4.0f);
- m_diskLightFeatureProcessor->SetPosition(m_diskLightHandle, diskLightPosition);
- Render::PhotometricValue rgbIntensity;
- m_diskLightFeatureProcessor->SetRgbIntensity(m_diskLightHandle, Render::PhotometricColor<Render::PhotometricUnit::Candela>(Color::CreateOne() * 2000.0f));
- const auto lightDir = Transform::CreateLookAt(
- diskLightPosition,
- Vector3::CreateZero());
- m_diskLightFeatureProcessor->SetDirection(m_diskLightHandle, lightDir.GetBasis(1));
- const float radius = sqrtf(2000.0f / 0.5f);
- m_diskLightFeatureProcessor->SetAttenuationRadius(m_diskLightHandle, radius);
- m_diskLightFeatureProcessor->SetShadowsEnabled(m_diskLightHandle, true);
- m_diskLightFeatureProcessor->SetShadowmapMaxResolution(m_diskLightHandle, Render::ShadowmapSize::Size512);
- m_diskLightFeatureProcessor->SetConeAngles(m_diskLightHandle, DegToRad(22.5f), DegToRad(27.5f));
- }
- // Create DirectionalLight
- {
- m_directionalLightHandle = m_directionalLightFeatureProcessor->AcquireLight();
- // Get the camera configuration
- {
- Camera::Configuration config;
- Camera::CameraRequestBus::EventResult(
- config,
- m_cameraEntity->GetId(),
- &Camera::CameraRequestBus::Events::GetCameraConfiguration);
- m_directionalLightFeatureProcessor->SetCameraConfiguration(
- m_directionalLightHandle,
- config);
- }
- // Camera Transform
- {
- Transform transform = Transform::CreateIdentity();
- TransformBus::EventResult(
- transform,
- m_cameraEntity->GetId(),
- &TransformBus::Events::GetWorldTM);
- m_directionalLightFeatureProcessor->SetCameraTransform(
- m_directionalLightHandle, transform);
- }
- Render::PhotometricColor<Render::PhotometricUnit::Lux> lightColor(Color::CreateOne() * 50.0f);
- m_directionalLightFeatureProcessor->SetRgbIntensity(m_directionalLightHandle, lightColor);
- const Vector3 helperPosition(-3.0f, 0.0f, 4.0f);
- const auto lightDir = Transform::CreateLookAt(
- helperPosition,
- Vector3::CreateZero());
- m_directionalLightFeatureProcessor->SetDirection(m_directionalLightHandle, lightDir.GetBasis(1));
- m_directionalLightFeatureProcessor->SetShadowmapSize(m_directionalLightHandle, Render::ShadowmapSize::Size512);
- m_directionalLightFeatureProcessor->SetCascadeCount(m_directionalLightHandle, 2);
- }
- // Create ReflectionProbe
- {
- const Vector3 probePosition{ -5.0f, 0.0f, 1.5f };
- const Transform probeTransform = Transform::CreateTranslation(probePosition);
- m_reflectionProbeHandle = m_reflectionProbeFeatureProcessor->AddReflectionProbe(probeTransform, true);
- m_reflectionProbeFeatureProcessor->ShowVisualization(m_reflectionProbeHandle, true);
- }
- // Enable Depth of Field
- {
- // Setup the depth of field
- auto* postProcessSettings = m_postProcessFeatureProcessor->GetOrCreateSettingsInterface(m_depthOfFieldEntity->GetId());
- m_depthOfFieldSettings = postProcessSettings->GetOrCreateDepthOfFieldSettingsInterface();
- m_depthOfFieldSettings->SetQualityLevel(1u);
- m_depthOfFieldSettings->SetApertureF(0.5f);
- m_depthOfFieldSettings->SetEnableDebugColoring(false);
- m_depthOfFieldSettings->SetEnableAutoFocus(true);
- m_depthOfFieldSettings->SetAutoFocusScreenPosition(Vector2{ 0.5f, 0.5f });
- m_depthOfFieldSettings->SetAutoFocusSensitivity(1.0f);
- m_depthOfFieldSettings->SetAutoFocusSpeed(Render::DepthOfField::AutoFocusSpeedMax);
- m_depthOfFieldSettings->SetAutoFocusDelay(0.2f);
- m_depthOfFieldSettings->SetCameraEntityId(m_cameraEntity->GetId());
- m_depthOfFieldSettings->SetEnabled(true);
- m_depthOfFieldSettings->OnConfigChanged();
- m_depthOfFieldEntity->Init();
- m_depthOfFieldEntity->Activate();
- }
- // IBL
- m_defaultIbl.Init(m_scene.get());
- TickBus::Handler::BusConnect();
- AzFramework::WindowNotificationBus::Handler::BusConnect(m_nativeWindow->GetWindowHandle());
- }
- SecondWindowedScene::~SecondWindowedScene()
- {
- using namespace AZ;
- // Disconnect hte busses
- TickBus::Handler::BusDisconnect();
- AzFramework::WindowNotificationBus::Handler::BusDisconnect(m_nativeWindow->GetWindowHandle());
- m_defaultIbl.Reset();
- // Release all the light types
- m_pointLightFeatureProcessor->ReleaseLight(m_pointLightHandle);
- m_diskLightFeatureProcessor->ReleaseLight(m_diskLightHandle);
- m_directionalLightFeatureProcessor->ReleaseLight(m_directionalLightHandle);
- // Release the probe
- m_reflectionProbeFeatureProcessor->RemoveReflectionProbe(m_reflectionProbeHandle);
- m_reflectionProbeHandle = {};
- // Release all meshes
- for (auto& shaderBallMeshHandle : m_shaderBallMeshHandles)
- {
- m_meshFeatureProcessor->ReleaseMesh(shaderBallMeshHandle);
- }
- m_meshFeatureProcessor->ReleaseMesh(m_floorMeshHandle);
- DestroyEntity(m_cameraEntity);
- DestroyEntity(m_depthOfFieldEntity);
- m_frameworkScene->UnsetSubsystem<RPI::Scene>();
- // Remove the scene
- m_scene->Deactivate();
- m_scene->RemoveRenderPipeline(m_pipeline->GetId());
- RPI::RPISystemInterface::Get()->UnregisterScene(m_scene);
- auto sceneSystem = AzFramework::SceneSystemInterface::Get();
- AZ_Assert(sceneSystem, "Scene system wasn't found to remove scene '%s' from.", m_sceneName.c_str());
- [[maybe_unused]] bool sceneRemovedSuccessfully = sceneSystem->RemoveScene(m_sceneName);
- AZ_Assert(sceneRemovedSuccessfully, "Unable to remove scene '%s'.", m_sceneName.c_str());
- m_scene = nullptr;
- m_windowContext->Shutdown();
- }
- void SecondWindowedScene::MoveCamera(bool enabled)
- {
- m_moveCamera = enabled;
- }
- // AZ::TickBus::Handler overrides ...
- void SecondWindowedScene::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
- {
- using namespace AZ;
- // Move the camera a bit each frame
- // Note: view space in this scene is right-handed, Z-up, Y-forward
- const float dynamicOffsetScale = 4.0f;
- if (m_moveCamera)
- {
- m_dynamicCameraOffset = Vector3(dynamicOffsetScale * sinf(aznumeric_cast<float>(timePoint.GetSeconds())), 0.0f, 0.0f);
- }
- Vector3 cameraPosition = m_cameraOffset + m_dynamicCameraOffset;
- TransformBus::Event(m_cameraEntity->GetId(), &TransformBus::Events::SetLocalTranslation, cameraPosition);
- const auto cameraDirection = Transform::CreateLookAt(
- cameraPosition,
- Vector3::CreateZero());
- TransformBus::Event(m_cameraEntity->GetId(), &TransformBus::Events::SetLocalRotationQuaternion, cameraDirection.GetRotation());
- }
- void SecondWindowedScene::OnWindowClosed()
- {
- m_parent->OnChildWindowClosed();
- }
- AzFramework::NativeWindowHandle SecondWindowedScene::GetNativeWindowHandle()
- {
- if (m_nativeWindow)
- {
- return m_nativeWindow->GetWindowHandle();
- }
- else
- {
- return nullptr;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- // MultiSceneExampleComponent
- void MultiSceneExampleComponent::Reflect(AZ::ReflectContext* context)
- {
- if (auto* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
- {
- serializeContext->Class<MultiSceneExampleComponent, AZ::Component>()
- ->Version(0)
- ;
- }
- }
- MultiSceneExampleComponent::MultiSceneExampleComponent()
- {
- }
- void MultiSceneExampleComponent::Activate()
- {
- using namespace AZ;
- // Setup primary camera controls
- Debug::CameraControllerRequestBus::Event(
- GetCameraEntityId(), &Debug::CameraControllerRequestBus::Events::Enable, azrtti_typeid<Debug::NoClipControllerComponent>());
-
- m_defaultIbl.PreloadAssets();
- // preload assets
- AZStd::vector<AssetCollectionAsyncLoader::AssetToLoadInfo> assetList = {
- { DefaultPbrMaterialPath, azrtti_typeid<RPI::MaterialAsset>() },
- { BunnyModelFilePath, azrtti_typeid<RPI::ModelAsset>() },
- { CubeModelFilePath, azrtti_typeid<RPI::ModelAsset>() },
- { ShaderBallModelFilePath, azrtti_typeid<RPI::ModelAsset>() }
- };
- PreloadAssets(assetList);
- ScriptRunnerRequestBus::Broadcast(&ScriptRunnerRequests::PauseScriptWithTimeout, 120.0f);
- }
-
- void MultiSceneExampleComponent::OnAllAssetsReadyActivate()
- {
- using namespace AZ;
- // Setup Main Mesh Entity
- {
- auto materialAsset = RPI::AssetUtils::LoadAssetByProductPath<RPI::MaterialAsset>(DefaultPbrMaterialPath,
- RPI::AssetUtils::TraceLevel::Assert);
- auto material = AZ::RPI::Material::FindOrCreate(materialAsset);
- auto bunnyAsset = RPI::AssetUtils::LoadAssetByProductPath<RPI::ModelAsset>(BunnyModelFilePath,
- RPI::AssetUtils::TraceLevel::Assert);
- m_meshHandle = GetMeshFeatureProcessor()->AcquireMesh(Render::MeshHandleDescriptor{ bunnyAsset }, material);
- GetMeshFeatureProcessor()->SetTransform(m_meshHandle, Transform::CreateRotationZ(Constants::Pi));
- }
- // IBL
- {
- m_defaultIbl.Init(m_scene);
- }
- if (SupportsMultipleWindows())
- {
- OpenSecondSceneWindow();
- }
-
- ScriptRunnerRequestBus::Broadcast(&ScriptRunnerRequests::ResumeScript);
- TickBus::Handler::BusConnect();
- }
- void MultiSceneExampleComponent::Deactivate()
- {
- using namespace AZ;
- TickBus::Handler::BusDisconnect();
- Debug::CameraControllerRequestBus::Event(GetCameraEntityId(), &Debug::CameraControllerRequestBus::Events::Disable);
- m_defaultIbl.Reset();
- GetMeshFeatureProcessor()->ReleaseMesh(m_meshHandle);
- if (m_windowedScene)
- {
- m_windowedScene = nullptr;
- }
- }
- void MultiSceneExampleComponent::OnChildWindowClosed()
- {
- m_windowedScene = nullptr;
- }
- void MultiSceneExampleComponent::OnTick([[maybe_unused]] float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint timePoint)
- {
- if (ImGui::Begin("Multi Scene Panel"))
- {
- if (m_windowedScene)
- {
- static bool moveCamera = false;
- if (ImGui::Button("Close Second Scene Window"))
- {
- m_windowedScene = nullptr;
- moveCamera = false;
- }
- if (ImGui::Checkbox("Move camera##MultiSceneExample", &moveCamera))
- {
- if (m_windowedScene)
- {
- m_windowedScene->MoveCamera(moveCamera);
- }
- }
- }
- else
- {
- if (ImGui::Button("Open Second Scene Window"))
- {
- OpenSecondSceneWindow();
- }
- }
- }
- ImGui::End();
- }
- void MultiSceneExampleComponent::OpenSecondSceneWindow()
- {
- if (!m_windowedScene)
- {
- m_windowedScene = AZStd::make_unique<SecondWindowedScene>("SecondScene", this);
- }
- }
- } // namespace AtomSampleViewer
|