| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- /*
- * 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 <Utils/Utils.h>
- #include <AtomCore/Instance/InstanceDatabase.h>
- #include <Atom/RHI/RHISystemInterface.h>
- #include <Atom/RPI.Public/RenderPipeline.h>
- #include <Atom/RPI.Public/RPISystemInterface.h>
- #include <Atom/RPI.Public/Scene.h>
- #include <Atom/RPI.Public/Image/ImageSystemInterface.h>
- #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
- #include <Atom/RPI.Reflect/Image/StreamingImageAssetCreator.h>
- #include <Atom/RPI.Reflect/Image/ImageMipChainAssetCreator.h>
- #include <Atom/Utils/DdsFile.h>
- #ifdef AZ_PROFILE_TELEMETRY
- #include <RADTelemetry/ProfileTelemetryBus.h>
- #endif
- #include <AzFramework/CommandLine/CommandLine.h>
- #include <AzFramework/API/ApplicationAPI.h>
- #include <AzFramework/Windowing/NativeWindow.h>
- #include <AzCore/Asset/AssetCommon.h>
- #include <AzCore/PlatformIncl.h>
- #include <AzCore/IO/SystemFile.h>
- #include <AzCore/IO/Path/Path.h>
- #include <Automation/ScriptRepeaterBus.h>
- namespace AtomSampleViewer
- {
- namespace Utils
- {
- AZ::RHI::Ptr<AZ::RHI::Device> GetRHIDevice()
- {
- using namespace AZ;
- auto* rhiSystem = RHI::RHISystemInterface::Get();
- AZ_Assert(rhiSystem, "Failed to retrieve rpi system.");
- return rhiSystem->GetDevice();
- }
- bool AssetEntryNameGetter(void* data, int index, const char** outName)
- {
- const AssetEntry* assetEntries = reinterpret_cast<const AssetEntry*>(data);
- *outName = assetEntries[index].m_name.c_str();
- return true;
- }
- void ToggleRadTMCapture()
- {
- #ifdef AZ_PROFILE_TELEMETRY
- using namespace RADTelemetry;
- using MaskType = AZ::Debug::ProfileCategoryPrimitiveType;
- // Set all the category bits "below" Detailed by default
- static const MaskType defaultCaptureMask = AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(FirstDetailedCategory) - 1;
- static const char* s_telemetryAddress = "127.0.0.1";
- static int32_t s_telemetryPort = 4719;
- static MaskType s_telemetryCaptureMask = defaultCaptureMask;
- static int32_t s_memCaptureEnabled = 0;
- ProfileTelemetryRequestBus::Broadcast(&ProfileTelemetryRequestBus::Events::SetAddress, s_telemetryAddress, s_telemetryPort);
- const MaskType fullCaptureMask = s_telemetryCaptureMask | (s_memCaptureEnabled ? AZ_PROFILE_CAT_TO_RAD_CAPFLAGS(MemoryReserved) : 0);
- ProfileTelemetryRequestBus::Broadcast(&ProfileTelemetryRequestBus::Events::SetCaptureMask, fullCaptureMask);
- ProfileTelemetryRequestBus::Broadcast(&ProfileTelemetryRequestBus::Events::ToggleEnabled);
- #endif // AZ_PROFILE_TELEMETRY
- }
- DefaultIBL::~DefaultIBL()
- {
- Reset();
- }
- void DefaultIBL::PreloadAssets()
- {
- const constexpr char* DiffuseAssetPath = "textures/sampleenvironment/examplespecularhdr_cm_ibldiffuse.dds.streamingimage";
- const constexpr char* SpecularAssetPath = "textures/sampleenvironment/examplespecularhdr_cm_iblspecular.dds.streamingimage";
- auto assertTraceLevel = AZ::RPI::AssetUtils::TraceLevel::Assert;
- if (!m_diffuseImageAsset.IsReady())
- {
- m_diffuseImageAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::StreamingImageAsset>(DiffuseAssetPath, assertTraceLevel);
- m_diffuseImageAsset.QueueLoad();
- m_diffuseImageAsset.BlockUntilLoadComplete();
- }
- if (!m_specularImageAsset.IsReady())
- {
- m_specularImageAsset = AZ::RPI::AssetUtils::GetAssetByProductPath<AZ::RPI::StreamingImageAsset>(SpecularAssetPath, assertTraceLevel);
- m_specularImageAsset.QueueLoad();
- m_specularImageAsset.BlockUntilLoadComplete();
- }
- }
- void DefaultIBL::Init(AZ::RPI::Scene* scene)
- {
- PreloadAssets();
- m_featureProcessor = scene->GetFeatureProcessor<AZ::Render::ImageBasedLightFeatureProcessorInterface>();
- AZ_Assert(m_featureProcessor, "Unabled to find ImageBasedLightFeatureProcessorInterface on scene.");
- m_featureProcessor->SetDiffuseImage(m_diffuseImageAsset);
- m_featureProcessor->SetSpecularImage(m_specularImageAsset);
- }
- void DefaultIBL::SetExposure(float exposure)
- {
- m_featureProcessor->SetExposure(exposure);
- }
- void DefaultIBL::Reset()
- {
- if (m_featureProcessor)
- {
- m_featureProcessor->Reset();
- m_featureProcessor = nullptr;
- }
- }
- void ResizeClientArea(uint32_t width, uint32_t height)
- {
- AzFramework::NativeWindowHandle windowHandle = nullptr;
- AzFramework::WindowSystemRequestBus::BroadcastResult(
- windowHandle,
- &AzFramework::WindowSystemRequestBus::Events::GetDefaultWindowHandle);
- AzFramework::WindowSize clientAreaSize = {width, height};
- AzFramework::WindowRequestBus::Event(windowHandle, &AzFramework::WindowRequestBus::Events::ResizeClientArea, clientAreaSize);
- AzFramework::WindowSize newWindowSize;
- AzFramework::WindowRequestBus::EventResult(newWindowSize, windowHandle, &AzFramework::WindowRequests::GetClientAreaSize);
- AZ_Error("ResizeClientArea", newWindowSize.m_width == width && newWindowSize.m_height == height,
- "Requested window resize to %ux%u but got %ux%u. This display resolution is too low or desktop scaling is too high.",
- width, height, newWindowSize.m_width, newWindowSize.m_height);
- }
- bool SupportsToggleFullScreenOfDefaultWindow()
- {
- return AzFramework::NativeWindow::CanToggleFullScreenStateOfDefaultWindow();
- }
- void ToggleFullScreenOfDefaultWindow()
- {
- AzFramework::NativeWindow::ToggleFullScreenStateOfDefaultWindow();
- }
- void ReportScriptableAction(const char* formatStr, ...)
- {
- va_list args;
- va_start(args, formatStr);
- ScriptRepeaterRequestBus::Broadcast(&ScriptRepeaterRequests::ReportScriptableAction, AZStd::string::format_arg(formatStr, args));
- va_end(args);
- }
- AZ::Data::Instance<AZ::RPI::StreamingImage> GetSolidColorCubemap(uint32_t color)
- {
- constexpr uint32_t width = 4;
- constexpr uint32_t height = 4;
- AZStd::string assetName = AZStd::string::format("SolidColorBackground_%u", color);
- AZ::Data::AssetId assetId = AZ::Uuid::CreateName(assetName.c_str());
- // Check for existing image of the same color
- AZ::Data::Instance<AZ::RPI::StreamingImage> existingImage = AZ::Data::InstanceDatabase<AZ::RPI::StreamingImage>::Instance().Find(AZ::Data::InstanceId::CreateFromAssetId(assetId));
- if (existingImage)
- {
- return existingImage;
- }
- // Build a new cubemap.
- AZ::RHI::Size imageSize = AZ::RHI::Size(width, height, 1);
- const uint32_t pixelSize = sizeof(uint32_t);
- const uint32_t pixelDataSize = width * height * pixelSize;
- AZStd::array<uint32_t, width* height> pixels;
- for (uint32_t& pixelColor : pixels)
- {
- pixelColor = color;
- }
- // Create a new streaming image
- AZ::RPI::StreamingImageAssetCreator imageCreator;
- imageCreator.Begin(assetId);
- int32_t arraySize = 6;
- AZ::RHI::Format format = AZ::RHI::Format::R8G8B8A8_UNORM_SRGB;
- AZ::RHI::ImageBindFlags bindFlag = AZ::RHI::ImageBindFlags::ShaderRead;
- AZ::RHI::ImageDescriptor imageDesc = AZ::RHI::ImageDescriptor::Create2DArray(bindFlag, width, height, static_cast<uint16_t>(arraySize), format);
- imageDesc.m_mipLevels = 1;
- imageDesc.m_isCubemap = true;
- imageCreator.SetImageDescriptor(imageDesc);
- imageCreator.SetImageViewDescriptor(AZ::RHI::ImageViewDescriptor::CreateCubemap());
- // Create the mip chain
- AZ::RPI::ImageMipChainAssetCreator mipChainCreator;
- assetId.m_subId = 1;
- mipChainCreator.Begin(assetId, 1, 6);
- uint32_t pitch = width * pixelSize;
- AZ::RHI::ImageSubresourceLayout layout;
- layout.m_bytesPerImage = pixelDataSize;
- layout.m_rowCount = layout.m_bytesPerImage / pitch;
- layout.m_size = AZ::RHI::Size(width, height, 1);
- layout.m_bytesPerRow = pitch;
- mipChainCreator.BeginMip(layout);
- for (uint32_t i = 0; i < 6; ++i)
- {
- mipChainCreator.AddSubImage(pixels.data(), pixelDataSize);
- }
- mipChainCreator.EndMip();
- AZ::Data::Asset<AZ::RPI::ImageMipChainAsset> mipChainAsset;
- mipChainCreator.End(mipChainAsset);
- imageCreator.AddMipChainAsset(*mipChainAsset);
- // Finalize streaming image asset
- AZ::Data::Asset<AZ::RPI::StreamingImageAsset> imageAsset;
- imageCreator.End(imageAsset);
- return AZ::RPI::StreamingImage::FindOrCreate(imageAsset);
- }
- AZStd::string ResolvePath(const AZStd::string& path)
- {
- char resolvedPath[AZ_MAX_PATH_LEN] = {0};
- AZ::IO::FileIOBase::GetInstance()->ResolvePath(path.c_str(), resolvedPath, AZ_MAX_PATH_LEN);
- return resolvedPath;
- }
- bool IsFileUnderFolder(AZStd::string filePath, AZStd::string folder)
- {
- AzFramework::StringFunc::Path::Normalize(filePath);
- AzFramework::StringFunc::Path::Normalize(folder);
- AZStd::to_lower(filePath.begin(), filePath.end());
- AZStd::to_lower(folder.begin(), folder.end());
- auto relativePath = AZ::IO::FixedMaxPath(filePath.c_str()).LexicallyRelative(folder.c_str());
- if (!relativePath.empty() && !relativePath.Native().starts_with(".."))
- {
- return true;
- }
- return false;
- }
- } // namespace Utils
- } // namespace AtomSampleViewer
|