diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingBus.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingBus.h index b8deb50cc5..9f6b6e629f 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingBus.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingBus.h @@ -13,8 +13,14 @@ #pragma once #include +#include #include +namespace AssetBuilderSDK +{ + struct JobProduct; +} + namespace ImageProcessingAtom { class ImageProcessingRequests @@ -35,4 +41,39 @@ namespace ImageProcessingAtom virtual IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) = 0; }; using ImageProcessingRequestBus = AZ::EBus; + + class ImageBuilderRequests + : public AZ::EBusTraits + { + public: + ////////////////////////////////////////////////////////////////////////// + // EBusTraits overrides + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; + ///////////////////////////////////////////////////////////////////////// + + //! Create an image object + virtual IImageObjectPtr CreateImage( + AZ::u32 width, + AZ::u32 height, + AZ::u32 maxMipCount, + EPixelFormat pixelFormat) = 0; + + //! Convert an image and save its products to the specified folder + virtual AZStd::vector ConvertImageObject( + IImageObjectPtr imageObject, + const AZStd::string& presetName, + const AZStd::string& platformName, + const AZStd::string& outputDir, + const AZ::Data::AssetId& sourceAssetId, + const AZStd::string& sourceAssetName) = 0; + + //! Return whether the specified platform is supported by the image builder + virtual bool DoesSupportPlatform(const AZStd::string& platformId) = 0; + + //! Return whether the specified preset requires an image to be square and a power of 2 + virtual bool IsPresetFormatSquarePow2(const AZStd::string& presetName, const AZStd::string& platformName) = 0; + }; + + using ImageBuilderRequestBus = AZ::EBus; } // namespace ImageProcessingAtom diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h index acd1d7a2da..5340b0d380 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Include/Atom/ImageProcessing/ImageProcessingEditorBus.h @@ -13,10 +13,15 @@ #include -class QString; +namespace ImageProcessingAtom +{ + class IImageObject; +} namespace ImageProcessingAtomEditor { + typedef AZStd::shared_ptr IImageObjectPtr; + class ImageProcessingEditorRequests : public AZ::EBusTraits { diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp index 59c799a601..a17c094fc7 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.cpp @@ -88,11 +88,13 @@ namespace ImageProcessingAtom m_assetHandlers.emplace_back(AZ::RPI::MakeAssetHandler()); ImageProcessingRequestBus::Handler::BusConnect(); + ImageBuilderRequestBus::Handler::BusConnect(); } void BuilderPluginComponent::Deactivate() { ImageProcessingRequestBus::Handler::BusDisconnect(); + ImageBuilderRequestBus::Handler::BusDisconnect(); m_imageBuilder.BusDisconnect(); BuilderSettingManager::DestroyInstance(); CPixelFormats::DestroyInstance(); @@ -146,6 +148,82 @@ namespace ImageProcessingAtom return image; } + IImageObjectPtr BuilderPluginComponent::CreateImage( + AZ::u32 width, + AZ::u32 height, + AZ::u32 maxMipCount, + EPixelFormat pixelFormat) + { + IImageObjectPtr image(IImageObject::CreateImage(width, height, maxMipCount, pixelFormat)); + return image; + } + + AZStd::vector BuilderPluginComponent::ConvertImageObject( + IImageObjectPtr imageObject, + const AZStd::string& presetName, + const AZStd::string& platformName, + const AZStd::string& outputDir, + const AZ::Data::AssetId& sourceAssetId, + const AZStd::string& sourceAssetName) + { + AZStd::vector outProducts; + + AZStd::string_view presetFilePath; + const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(presetName, platformName, &presetFilePath); + if (preset == nullptr) + { + AZ_Assert(false, "Cannot find preset with name %s.", presetName.c_str()); + return outProducts; + } + + AZStd::unique_ptr desc = AZStd::make_unique(); + TextureSettings& textureSettings = desc->m_textureSetting; + textureSettings.m_preset = preset->m_uuid; + desc->m_inputImage = imageObject; + desc->m_presetSetting = *preset; + desc->m_isPreview = false; + desc->m_platform = platformName; + desc->m_filePath = presetFilePath; + desc->m_isStreaming = BuilderSettingManager::Instance()->GetBuilderSetting(platformName)->m_enableStreaming; + desc->m_imageName = sourceAssetName; + desc->m_outputFolder = outputDir; + desc->m_sourceAssetId = sourceAssetId; + + // Create an image convert process + ImageConvertProcess* process = new ImageConvertProcess(AZStd::move(desc)); + if (process) + { + process->ProcessAll(); + bool result = process->IsSucceed(); + if (result) + { + process->GetAppendOutputProducts(outProducts); + } + delete process; + } + + return outProducts; + } + + bool BuilderPluginComponent::DoesSupportPlatform(const AZStd::string& platformId) + { + return ImageProcessingAtom::BuilderSettingManager::Instance()->DoesSupportPlatform(platformId); + } + + bool BuilderPluginComponent::IsPresetFormatSquarePow2(const AZStd::string& presetName, const AZStd::string& platformName) + { + AZStd::string_view filePath; + const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(presetName, platformName, &filePath); + if (preset == nullptr) + { + AZ_Assert(false, "Cannot find preset with name %s.", presetName.c_str()); + return false; + } + + const PixelFormatInfo* info = CPixelFormats::GetInstance().GetPixelFormatInfo(preset->m_pixelFormat); + return info->bSquarePow2; + } + void ImageBuilderWorker::ShutDown() { // it is important to note that this will be called on a different thread than your process job thread diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.h b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.h index fd099eb08a..9723278380 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.h +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/ImageBuilderComponent.h @@ -17,6 +17,7 @@ #include #include #include +#include namespace ImageProcessingAtom { @@ -47,6 +48,7 @@ namespace ImageProcessingAtom class BuilderPluginComponent : public AZ::Component , protected ImageProcessingRequestBus::Handler + , protected ImageBuilderRequestBus::Handler { public: AZ_COMPONENT(BuilderPluginComponent, "{A227F803-D2E4-406E-93EC-121EF45A64A1}") @@ -71,6 +73,24 @@ namespace ImageProcessingAtom IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) override; //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + // ImageBuilderRequestBus interface implementation + IImageObjectPtr CreateImage( + AZ::u32 width, + AZ::u32 height, + AZ::u32 maxMipCount, + EPixelFormat pixelFormat) override; + AZStd::vector ConvertImageObject( + IImageObjectPtr imageObject, + const AZStd::string& presetName, + const AZStd::string& platformName, + const AZStd::string& outputDir, + const AZ::Data::AssetId& sourceAssetId, + const AZStd::string& sourceAssetName) override; + bool DoesSupportPlatform(const AZStd::string& platformId) override; + bool IsPresetFormatSquarePow2(const AZStd::string& presetName, const AZStd::string& platformName) override; + //////////////////////////////////////////////////////////////////////// + private: BuilderPluginComponent(const BuilderPluginComponent&) = delete;