UiImageComponent.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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 "EditorPropertyTypes.h"
  10. #include <LyShine/Bus/UiVisualBus.h>
  11. #include <LyShine/Bus/UiRenderBus.h>
  12. #include <LyShine/Bus/UiImageBus.h>
  13. #include <LyShine/Bus/UiCanvasBus.h>
  14. #include <LyShine/Bus/UiTransformBus.h>
  15. #include <LyShine/Bus/UiAnimateEntityBus.h>
  16. #include <LyShine/Bus/UiLayoutCellDefaultBus.h>
  17. #include <LyShine/Bus/Sprite/UiSpriteBus.h>
  18. #include <LyShine/Bus/UiIndexableImageBus.h>
  19. #include <LyShine/UiComponentTypes.h>
  20. #include <LyShine/UiRenderFormats.h>
  21. #include <AzCore/Component/Component.h>
  22. #include <AzCore/Serialization/SerializeContext.h>
  23. #include <AzCore/Math/Vector3.h>
  24. #include <Atom/RPI.Public/Image/AttachmentImage.h>
  25. #include <LmbrCentral/Rendering/TextureAsset.h>
  26. class ITexture;
  27. class ISprite;
  28. ////////////////////////////////////////////////////////////////////////////////////////////////////
  29. class UiImageComponent
  30. : public AZ::Component
  31. , public UiVisualBus::Handler
  32. , public UiRenderBus::Handler
  33. , public UiImageBus::Handler
  34. , public UiAnimateEntityBus::Handler
  35. , public UiTransformChangeNotificationBus::Handler
  36. , public UiLayoutCellDefaultBus::Handler
  37. , public UiCanvasPixelAlignmentNotificationBus::Handler
  38. , public UiSpriteSettingsChangeNotificationBus::Handler
  39. , public UiIndexableImageBus::Handler
  40. {
  41. public: // member functions
  42. AZ_COMPONENT(UiImageComponent, LyShine::UiImageComponentUuid, AZ::Component);
  43. UiImageComponent();
  44. ~UiImageComponent() override;
  45. // UiVisualInterface
  46. void ResetOverrides() override;
  47. void SetOverrideColor(const AZ::Color& color) override;
  48. void SetOverrideAlpha(float alpha) override;
  49. void SetOverrideSprite(ISprite* sprite, AZ::u32 cellIndex = 0) override;
  50. // ~UiVisualInterface
  51. // UiRenderInterface
  52. void Render(LyShine::IRenderGraph* renderGraph) override;
  53. // ~UiRenderInterface
  54. // UiImageInterface
  55. AZ::Color GetColor() override;
  56. void SetColor(const AZ::Color& color) override;
  57. float GetAlpha() override;
  58. void SetAlpha(float alpha) override;
  59. ISprite* GetSprite() override;
  60. void SetSprite(ISprite* sprite) override;
  61. AZStd::string GetSpritePathname() override;
  62. void SetSpritePathname(AZStd::string spritePath) override;
  63. bool SetSpritePathnameIfExists(AZStd::string spritePath) override;
  64. AZ::Data::Asset<AZ::RPI::AttachmentImageAsset> GetAttachmentImageAsset() override;
  65. void SetAttachmentImageAsset(const AZ::Data::Asset<AZ::RPI::AttachmentImageAsset>& attachmentImageAsset) override;
  66. bool GetIsRenderTargetSRGB() override;
  67. void SetIsRenderTargetSRGB(bool isSRGB) override;
  68. SpriteType GetSpriteType() override;
  69. void SetSpriteType(SpriteType spriteType) override;
  70. ImageType GetImageType() override;
  71. void SetImageType(ImageType imageType) override;
  72. FillType GetFillType() override;
  73. void SetFillType(FillType fillType) override;
  74. float GetFillAmount() override;
  75. void SetFillAmount(float fillAmount) override;
  76. float GetRadialFillStartAngle() override;
  77. void SetRadialFillStartAngle(float radialFillStartAngle) override;
  78. FillCornerOrigin GetCornerFillOrigin() override;
  79. void SetCornerFillOrigin(FillCornerOrigin cornerOrigin) override;
  80. FillEdgeOrigin GetEdgeFillOrigin() override;
  81. void SetEdgeFillOrigin(FillEdgeOrigin edgeOrigin) override;
  82. bool GetFillClockwise() override;
  83. void SetFillClockwise(bool fillClockwise) override;
  84. bool GetFillCenter() override;
  85. void SetFillCenter(bool fillCenter) override;
  86. // ~UiImageInterface
  87. // UiIndexableImageBus
  88. void SetImageIndex(AZ::u32 index) override;
  89. const AZ::u32 GetImageIndex() override;
  90. const AZ::u32 GetImageIndexCount() override;
  91. AZStd::string GetImageIndexAlias(AZ::u32 index) override;
  92. void SetImageIndexAlias(AZ::u32 index, const AZStd::string& alias) override;
  93. AZ::u32 GetImageIndexFromAlias(const AZStd::string& alias) override;
  94. // ~UiIndexableImageBus
  95. // UiAnimateEntityInterface
  96. void PropertyValuesChanged() override;
  97. // ~UiAnimateEntityInterface
  98. // UiTransformChangeNotification
  99. void OnCanvasSpaceRectChanged(AZ::EntityId entityId, const UiTransformInterface::Rect& oldRect, const UiTransformInterface::Rect& newRect) override;
  100. void OnTransformToViewportChanged() override;
  101. // ~UiTransformChangeNotification
  102. // UiLayoutCellDefaultInterface
  103. float GetMinWidth() override;
  104. float GetMinHeight() override;
  105. float GetTargetWidth(float maxWidth) override;
  106. float GetTargetHeight(float maxHeight) override;
  107. float GetExtraWidthRatio() override;
  108. float GetExtraHeightRatio() override;
  109. // ~UiLayoutCellDefaultInterface
  110. // UiCanvasPixelAlignmentNotification
  111. void OnCanvasPixelAlignmentChange() override;
  112. // ~UiCanvasPixelAlignmentNotification
  113. // UiSpriteSettingsChangeNotification
  114. void OnSpriteSettingsChanged() override;
  115. // ~UiSpriteSettingsChangeNotification
  116. public: // static member functions
  117. static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  118. {
  119. provided.push_back(AZ_CRC_CE("UiVisualService"));
  120. provided.push_back(AZ_CRC_CE("UiImageService"));
  121. provided.push_back(AZ_CRC_CE("UiIndexableImageService"));
  122. }
  123. static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  124. {
  125. incompatible.push_back(AZ_CRC_CE("UiVisualService"));
  126. }
  127. static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
  128. {
  129. required.push_back(AZ_CRC_CE("UiElementService"));
  130. required.push_back(AZ_CRC_CE("UiTransformService"));
  131. }
  132. static void Reflect(AZ::ReflectContext* context);
  133. protected: // member functions
  134. // AZ::Component
  135. void Init() override;
  136. void Activate() override;
  137. void Deactivate() override;
  138. // ~AZ::Component
  139. //! Resets the current sprite-sheet cell index based on whether we're showing a sprite or a sprite-sheet.
  140. //!
  141. //! This is necessary since the render routines reference the sprite-sheet cell index regardless of
  142. //! whether a sprite-sheet is being displayed or not. It's possible to have a sprite-sheet asset loaded
  143. //! but the image component sprite type be a basic sprite. In that case, indexing the sprite-sheet is
  144. //! still technically possible, so we assign a special index (-1) to indicate not to index a particular
  145. //! cell, but rather the whole image.
  146. void ResetSpriteSheetCellIndex();
  147. private: // member functions
  148. void RenderStretchedSprite(ISprite* sprite, int cellIndex, uint32 packedColor);
  149. void RenderSlicedSprite(ISprite* sprite, int cellIndex, uint32 packedColor);
  150. void RenderFixedSprite(ISprite* sprite, int cellIndex, uint32 packedColor);
  151. void RenderTiledSprite(ISprite* sprite, uint32 packedColor);
  152. void RenderStretchedToFitOrFillSprite(ISprite* sprite, int cellIndex, uint32 packedColor, bool toFit);
  153. void RenderSingleQuad(const AZ::Vector2* positions, const AZ::Vector2* uvs, uint32 packedColor);
  154. void RenderFilledQuad(const AZ::Vector2* positions, const AZ::Vector2* uvs, uint32 packedColor);
  155. void RenderLinearFilledQuad(const AZ::Vector2* positions, const AZ::Vector2* uvs, uint32 packedColor);
  156. void RenderRadialFilledQuad(const AZ::Vector2* positions, const AZ::Vector2* uvs, uint32 packedColor);
  157. void RenderRadialCornerFilledQuad(const AZ::Vector2* positions, const AZ::Vector2* uvs, uint32 packedColor);
  158. void RenderRadialEdgeFilledQuad(const AZ::Vector2* positions, const AZ::Vector2* uvs, uint32 packedColor);
  159. void RenderSlicedStretchedSprite(ISprite* sprite, int cellIndex, uint32 packedColor, const AZ::Matrix4x4& transform,
  160. const AZ::Vector2& textureSize, const UiTransformInterface::RectPoints& points,
  161. float leftBorder, float rightBorder, float topBorder, float bottomBorder);
  162. void RenderSlicedFixedSprite(ISprite* sprite, int cellIndex, uint32 packedColor, const AZ::Matrix4x4& transform,
  163. const AZ::Vector2& textureSize, const UiTransformInterface::RectPoints& points,
  164. float leftBorder, float rightBorder, float topBorder, float bottomBorder,
  165. float rectWidth, float rectHeight, float centerUvWidth, float centerUvHeight);
  166. template<uint32 numValues> void RenderSlicedFillModeNoneSprite(uint32 packedColor, const AZ::Matrix4x4& transform, float* xValues, float* yValues, float* sValues, float* tValues);
  167. template<uint32 numValues> void RenderSlicedLinearFilledSprite(uint32 packedColor, const AZ::Matrix4x4& transform, float* xValues, float* yValues, float* sValues, float* tValues);
  168. template<uint32 numValues> void RenderSlicedRadialFilledSprite(uint32 packedColor, const AZ::Matrix4x4& transform, float* xValues, float* yValues, float* sValues, float* tValues);
  169. template<uint32 numValues> void RenderSlicedRadialCornerOrEdgeFilledSprite(uint32 packedColor, const AZ::Matrix4x4& transform, float* xValues, float* yValues, float* sValues, float* tValues);
  170. void ClipValuesForSlicedLinearFill(uint32 numValues, float* xValues, float* yValues, float* sValues, float* tValues);
  171. void ClipAndRenderForSlicedRadialFill(uint32 numVertsPerside, uint32 numVerts, const LyShine::UiPrimitiveVertex* verts, uint32 totalIndices, const uint16* indices);
  172. void ClipAndRenderForSlicedRadialCornerOrEdgeFill(uint32 numVertsPerside, uint32 numVerts, const LyShine::UiPrimitiveVertex* verts, uint32 totalIndices, const uint16* indices);
  173. int ClipToLine(const LyShine::UiPrimitiveVertex* vertices, const uint16* indices, LyShine::UiPrimitiveVertex* newVertex, uint16* renderIndices, int& vertexOffset, int idxOffset, const Vec2& lineOrigin, const Vec2& lineEnd);
  174. void RenderTriangleList(const LyShine::UiPrimitiveVertex* vertices, const uint16* indices, int numVertices, int numIndices);
  175. void ClearCachedVertices();
  176. void ClearCachedIndices();
  177. void MarkRenderCacheDirty();
  178. void MarkRenderGraphDirty();
  179. void SnapOffsetsToFixedImage();
  180. bool IsPixelAligned();
  181. bool IsSpriteTypeAsset();
  182. bool IsSpriteTypeSpriteSheet();
  183. bool IsSpriteTypeRenderTarget();
  184. bool IsFilled();
  185. bool IsLinearFilled();
  186. bool IsRadialFilled();
  187. bool IsRadialAnyFilled();
  188. bool IsCornerFilled();
  189. bool IsEdgeFilled();
  190. bool IsSliced();
  191. AZ_DISABLE_COPY_MOVE(UiImageComponent);
  192. void OnEditorSpritePathnameChange();
  193. void OnEditorSpriteTypeChange();
  194. void OnEditorImageTypeChange();
  195. void OnEditorRenderSettingChange();
  196. void OnSpritePathnameChange();
  197. void OnSpriteAttachmentImageAssetChange();
  198. void OnSpriteTypeChange();
  199. //! ChangeNotify callback for color change
  200. void OnColorChange();
  201. //! Invalidate this element and its parent's layouts. Called when a property that
  202. //! is used to calculate default layout cell values has changed
  203. void InvalidateLayouts();
  204. //! Refresh the transform properties in the editor's properties pane
  205. void CheckLayoutFitterAndRefreshEditorTransformProperties() const;
  206. //! ChangeNotify callback for when the index string value selection changes.
  207. void OnIndexChange();
  208. //! Returns a string representation of the indices used to index sprite-sheet types.
  209. LyShine::AZu32ComboBoxVec PopulateIndexStringList() const;
  210. private: // static member functions
  211. static bool VersionConverter(AZ::SerializeContext& context,
  212. AZ::SerializeContext::DataElementNode& classElement);
  213. private: // data
  214. AzFramework::SimpleAssetReference<LmbrCentral::TextureAsset> m_spritePathname;
  215. AZ::Data::Asset<AZ::RPI::AttachmentImageAsset> m_attachmentImageAsset;
  216. bool m_isRenderTargetSRGB = false;
  217. SpriteType m_spriteType = SpriteType::SpriteAsset;
  218. AZ::Color m_color = AZ::Color(1.0f, 1.0f, 1.0f, 1.0f);
  219. float m_alpha = 1.0f;
  220. ImageType m_imageType = ImageType::Stretched;
  221. LyShine::BlendMode m_blendMode = LyShine::BlendMode::Normal;
  222. ISprite* m_sprite = nullptr;
  223. ISprite* m_overrideSprite = nullptr;
  224. AZ::u32 m_overrideSpriteCellIndex = 0;
  225. AZ::Color m_overrideColor = m_color;
  226. float m_overrideAlpha = m_alpha;
  227. AZ::u32 m_spriteSheetCellIndex = 0; //!< Current index for sprite-sheet (if this sprite is a sprite-sheet type).
  228. FillType m_fillType = FillType::None;
  229. float m_fillAmount = 1.0f;
  230. float m_fillStartAngle = 0.0f; // Start angle for fill measured in degrees clockwise.
  231. FillCornerOrigin m_fillCornerOrigin = FillCornerOrigin::TopLeft;
  232. FillEdgeOrigin m_fillEdgeOrigin = FillEdgeOrigin::Left;
  233. bool m_fillClockwise = true;
  234. bool m_fillCenter = true;
  235. bool m_isSlicingStretched = true; //!< When true the central parts of a 9-slice are stretched, when false the have the same pixel to texel ratio as the corners.
  236. bool m_isColorOverridden;
  237. bool m_isAlphaOverridden;
  238. // cached rendering data for performance optimization
  239. LyShine::UiPrimitive m_cachedPrimitive;
  240. bool m_isRenderCacheDirty = true;
  241. };