MaterialHotReloadTestComponent.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. #pragma once
  9. #include <CommonSampleComponentBase.h>
  10. #include <Utils/ImGuiSidebar.h>
  11. #include <AzCore/Component/TickBus.h>
  12. #include <Atom/RPI.Reflect/Material/MaterialAsset.h>
  13. #include <Atom/RPI.Reflect/Model/ModelAsset.h>
  14. #include <AzFramework/Asset/AssetSystemTypes.h>
  15. namespace AtomSampleViewer
  16. {
  17. //! This test renders a simple material and exposes controls that can update the source data for that material and its shaders
  18. //! to demonstrate and test hot-reloading. It works by copying entire files from a test data folder into a material source folder
  19. //! and waiting for the Asset Processor to build the updates files.
  20. class MaterialHotReloadTestComponent final
  21. : public CommonSampleComponentBase
  22. , public AZ::TickBus::Handler
  23. , public AZ::Data::AssetBus::Handler
  24. {
  25. public:
  26. AZ_COMPONENT(MaterialHotReloadTestComponent, "{EA684B21-9E39-4210-A640-AFBC28B2E683}", CommonSampleComponentBase);
  27. MaterialHotReloadTestComponent();
  28. static void Reflect(AZ::ReflectContext* context);
  29. // AZ::Component overrides...
  30. void Activate() override;
  31. void Deactivate() override;
  32. private:
  33. AZ_DISABLE_COPY_MOVE(MaterialHotReloadTestComponent);
  34. // AZ::TickBus::Handler overrides...
  35. void OnTick(float deltaTime, AZ::ScriptTimePoint scriptTime) override;
  36. // Finds the paths m_testDataFolder and m_tempSourceFolder
  37. void InitTestDataFolders();
  38. // Deletes a file from m_tempSourceFolder
  39. void DeleteTestFile(const char* tempSourceFile);
  40. // Copies a file from m_testDataFolder to m_tempSourceFolder
  41. void CopyTestFile(const AZStd::string& testDataFile, const AZStd::string& tempSourceFile);
  42. // Returns the AssetStatus of a file in m_tempSourceFolder
  43. AzFramework::AssetSystem::AssetStatus GetTestAssetStatus(const char* tempSourceFile) const;
  44. // Draws ImGui indicating the Asset Processor status of a file in m_tempSourceFolder
  45. void DrawAssetStatus(const char* tempSourceFile, bool includeFileName = false);
  46. AZ::Data::AssetId GetAssetId(const char* productFilePath);
  47. void OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset) override;
  48. enum class ShaderVariantStatus
  49. {
  50. None,
  51. Root,
  52. PartiallyBaked,
  53. FullyBaked
  54. };
  55. ShaderVariantStatus GetShaderVariantStatus() const;
  56. static constexpr float LongTimeout = 30.0f;
  57. // Tracks initialization that starts when the component is activated
  58. enum class InitStatus
  59. {
  60. None,
  61. ClearingTestAssets,
  62. CopyingDefaultShaderTestFile,
  63. CopyingDefaultMaterialTypeTestFile,
  64. WaitingForDefaultMaterialToRegister,
  65. WaitingForDefaultMaterialToLoad,
  66. Ready
  67. };
  68. InitStatus m_initStatus = InitStatus::None;
  69. AZStd::string m_testDataFolder; //< Stores several txt files with contents to be copied over various source asset files.
  70. AZStd::string m_tempSourceFolder; //< Folder for temp source asset files. These are what the sample edits and reloads.
  71. ImGuiSidebar m_imguiSidebar;
  72. AZ::Render::MeshFeatureProcessorInterface* m_meshFeatureProcessor = nullptr;
  73. AZ::Data::Asset<AZ::RPI::MaterialAsset> m_materialAsset;
  74. AZ::Data::Instance<AZ::RPI::Material> m_material;
  75. AZ::Data::Asset<AZ::RPI::ModelAsset> m_modelAsset;
  76. AZ::Render::MeshFeatureProcessorInterface::MeshHandle m_meshHandle;
  77. AZ::Render::MeshFeatureProcessorInterface::ModelChangedEvent::Handler m_meshChangedHandler;
  78. // These are used to render a secondary mesh that indicates which shader variant is being used to render the primary mesh
  79. AZ::Transform m_shaderVariantIndicatorMeshTransform;
  80. AZ::Vector3 m_shaderVariantIndicatorMeshNonUniformScale = AZ::Vector3::CreateOne();
  81. AZ::Render::MeshFeatureProcessorInterface::MeshHandle m_shaderVariantIndicatorMeshHandle;
  82. AZ::Data::Instance<AZ::RPI::Material> m_shaderVariantIndicatorMaterial_root;
  83. AZ::Data::Instance<AZ::RPI::Material> m_shaderVariantIndicatorMaterial_fullyBaked;
  84. AZ::Data::Instance<AZ::RPI::Material> m_shaderVariantIndicatorMaterial_current;
  85. float m_clearAssetsTimeout = 0.0f;
  86. };
  87. } // namespace AtomSampleViewer