[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / model-components / material-impl.h
1 #ifndef DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_IMPL_H
2 #define DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_IMPL_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali-toolkit/public-api/image-loader/async-image-loader.h>
23 #include <dali/public-api/common/dali-common.h>
24 #include <dali/public-api/common/intrusive-ptr.h>
25 #include <dali/public-api/common/vector-wrapper.h>
26 #include <dali/public-api/object/base-object.h>
27 #include <dali/public-api/object/property-value.h>
28 #include <dali/public-api/object/property.h>
29 #include <dali/public-api/rendering/texture.h>
30 #include <set>
31 #include <utility>
32
33 // INTERNAL INCLUDES
34 #include <dali-scene3d/internal/model-components/material-modify-observer.h>
35 #include <dali-scene3d/public-api/loader/material-definition.h>
36 #include <dali-scene3d/public-api/loader/shader-definition.h>
37 #include <dali-scene3d/public-api/loader/shader-option.h>
38 #include <dali-scene3d/public-api/model-components/material.h>
39 #include <dali-scene3d/public-api/common/scene-depth-index-ranges.h>
40
41 namespace Dali
42 {
43 namespace Scene3D
44 {
45 namespace Internal
46 {
47 using MaterialPtr = IntrusivePtr<Material>;
48
49 /**
50  * @brief This is the internal base class for Material of model.
51  *
52  * @SINCE_2_2.99
53  */
54 class Material : public BaseObject, public ConnectionTracker
55 {
56 private:
57   using ObserverContainer = std::vector<std::pair<MaterialModifyObserver*, bool>>;
58
59 public:
60   /**
61    * @brief Pair of texture handle and it's own scale factor. Texture handle can be empty
62    */
63   struct TextureInformation
64   {
65     bool IsReady()
66     {
67       return mLoadingTaskId == 0u;
68     }
69
70     std::string                         mUrl;
71     Dali::Texture                       mTexture;
72     Vector4                             mFactor{Vector4::ONE};
73     Dali::Sampler                       mSampler;
74     uint32_t                            mLoadingTaskId{0u};
75     uint32_t                            mSemantic;
76     Scene3D::Loader::ShaderOption::Type mShaderOptionType;
77     Matrix3                             mTransform{Scene3D::Loader::TextureDefinition::DEFAULT_TRANSFORM};
78   };
79
80   using TextureInformationContainer = std::vector<TextureInformation>;
81
82 public:
83   // Creation & Destruction
84   /**
85    * @brief Create a new Material object.
86    * @return A smart-pointer to the newly allocated Material.
87    */
88   static MaterialPtr New();
89
90 protected:
91   /**
92    * @brief Construct a new Material.
93    */
94   Material();
95
96   /**
97    * @brief Second-phase constructor.
98    */
99   void Initialize();
100
101   /**
102    * @brief Virtual destructor.
103    */
104   virtual ~Material();
105
106 public:
107   /**
108    * @copydoc Dali::Scene3D::Material::SetProperty()
109    */
110   void SetProperty(Dali::Property::Index index, Dali::Property::Value propertyValue);
111
112   /**
113    * @copydoc Dali::Scene3D::Material::GetProperty()
114    */
115   Dali::Property::Value GetProperty(Dali::Property::Index index) const;
116
117   /**
118    * @brief Sets a texture information for the material.
119    *
120    * @param[in] index The index of the texture to set.
121    * @param[in] textureInformation The texture information to set.
122    *
123    * @note This function moves the value of textureInformation.
124    */
125   void SetTextureInformation(Scene3D::Material::TextureType index, TextureInformation&& textureInformation);
126
127   /**
128    * @brief Sets a texture for the material.
129    *
130    * @param[in] index The index of the texture to set.
131    * @param[in] texture The texture to set.
132    */
133   void SetTexture(Scene3D::Material::TextureType index, Dali::Texture texture);
134
135   /**
136    * @brief Retrieves texture for the material.
137    *
138    * @param[in] index The index of the texture to get.
139    *
140    * @return The texture at the given index.
141    */
142   Dali::Texture GetTexture(Scene3D::Material::TextureType index);
143
144   /**
145    * @brief Retrieves the texture set for this material.
146    *
147    * @return The texture set for this material.
148    */
149   TextureSet GetTextureSet();
150
151   /**
152    * @brief Sets a sampler for the material.
153    *
154    * @param[in] index The index of the sampler to set.
155    * @param[in] sampler The sampler to set.
156    */
157   void SetSampler(Scene3D::Material::TextureType index, Dali::Sampler sampler);
158
159   /**
160    * @brief Retrieves a sampler for the material.
161    *
162    * @param[in] index The index of the sampler to get.
163    * @return The sampler at the given index.
164    */
165   Dali::Sampler GetSampler(Scene3D::Material::TextureType index);
166
167   /**
168    * @brief Retrieves Shader Option of this Material.
169    *
170    * @return Shader Option of this Material.
171    */
172   Scene3D::Loader::ShaderOption GetShaderOption() const;
173
174 public:
175   /**
176    * @brief Adds observer to this material.
177    *
178    * @param[in] observer Pointer of observer.
179    */
180   void AddObserver(MaterialModifyObserver* observer);
181
182   /**
183    * @brief Removes observer from this material.
184    *
185    * @param[in] observer Pointer of observer.
186    */
187   void RemoveObserver(MaterialModifyObserver* observer);
188
189   /**
190    * @brief Updates material data.
191    */
192   void UpdateMaterialData();
193
194   /**
195    * @brief Sets uniform value to the Renderer.
196    *
197    * @param[in] renderer Renderer object.
198    */
199   void SetRendererUniform(Dali::Renderer renderer);
200
201   /**
202    * @brief Sets property value to the Renderer.
203    *
204    * @param[in] renderer Renderer object.
205    */
206   void SetRendererProperty(Dali::Renderer renderer);
207
208   /**
209    * @brief Retrieves shadow map texture offset.
210    *
211    * @return shadow map texture offset.
212    */
213   uint32_t GetShadowMapTextureOffset();
214
215   /**
216    * @brief Retrieves specular image based light texture offset.
217    *
218    * @return Specular image based light texture offset.
219    */
220   uint32_t GetSpecularImageBasedLightTextureOffset();
221
222   /**
223    * @brief Retrieves diffuse image based light texture offset.
224    *
225    * @return Diffuse image based light texture offset.
226    */
227   uint32_t GetDiffuseImageBasedLightTextureOffset();
228
229   /**
230    * @brief Retrieves image based light scale factor name.
231    *
232    * @return Image based light scale factor name.
233    */
234   std::string_view GetImageBasedLightScaleFactorName();
235
236   /**
237    * @brief Retrieves image based light max lod uniform name.
238    *
239    * @return Image based light max lod uniform name.
240    */
241   std::string_view GetImageBasedLightMaxLodUniformName();
242
243   /**
244    * @brief Checks if resource is ready.
245    *
246    * @return True if resource is ready, false otherwise.
247    */
248   bool IsResourceReady();
249
250   /**
251    * @brief Resets dirty flag of this material.
252    */
253   void ResetFlag();
254
255 private:
256   /**
257    * @brief Checks modify flag and send observers the material changeness.
258    * It will clean up modify flag
259    */
260   void NotifyObserver();
261
262   /**
263    * @brief Requests loading an image from a URL and store it in TextureInformation.
264    *
265    * @param[in] textureInformation TextureInformation object to store loaded texture information.
266    * @param[in] url URL of the image to load.
267    */
268   void RequestTextureLoad(TextureInformation& textureInformation, const std::string& url);
269
270   /**
271    * @brief Called when loading requested by RequestTextureLoad is complete.
272    *
273    * @param[in] loadedTaskId ID of the loaded texture.
274    * @param[in] pixelData PixelData of the loaded texture.
275    */
276   void TextureLoadComplete(uint32_t loadedTaskId, PixelData pixelData);
277
278   /**
279    * @brief Called when all requested textures are loaded.
280    */
281   void ResourcesLoadComplete();
282
283   /**
284    * @brief Updates the material using each attribute of this material and send a notification to the ModelPrimitive class.
285    */
286   void Apply();
287
288 private:
289   // Delete copy & move operator
290   Material(const Material&) = delete;
291   Material(Material&&)      = delete;
292   Material& operator=(const Material& rhs) = delete;
293   Material& operator=(Material&& rhs) = delete;
294
295 private:
296   ObserverContainer mObservers{}; ///< List of observers who need to be notified after some properties are changed.
297
298   TextureInformationContainer     mTextureInformations;
299   Dali::Toolkit::AsyncImageLoader mAsyncImageLoader;
300
301   std::string                            mName;                                                   ///< Material name
302   Dali::Scene3D::Material::AlphaModeType mAlphaMode   = Scene3D::Material::AlphaModeType::OPAQUE; ///< Alpha mode
303   float                                  mAlphaCutoff = 0.5f;                                     ///< Alpha cutoff value
304   bool                                   mDoubleSided = false;                                    ///< Whether to render both sides
305   float                                  mIor         = -1.0f;                                    ///< Index of refraction (TODO: Magic number)
306   MaterialModifyObserver::ModifyFlag     mModifyFlag  = MaterialModifyObserver::ModifyFlag::NONE; ///< Modified dirty flags
307
308   Scene3D::Loader::ShaderOption        mShaderOption;
309   uint32_t                             mMaterialFlag  = std::numeric_limits<uint32_t>::max();
310   Scene3D::Loader::RendererState::Type mRendererState = Scene3D::Loader::RendererState::NONE;
311
312   int32_t mDepthIndex{Scene3D::DepthIndex::Ranges::SCENE};
313
314   bool mIsOpaque = true;
315   bool mIsMask   = false;
316   bool mObserverNotifying; ///< True if observe is notify now. If then, we should not change the mObservers.
317 };
318
319 } // namespace Internal
320
321 // Helpers for public-api forwarding methods
322
323 inline Internal::Material& GetImplementation(Dali::Scene3D::Material& material)
324 {
325   DALI_ASSERT_ALWAYS(material && "Material handle is empty");
326
327   BaseObject& handle = material.GetBaseObject();
328
329   return static_cast<Internal::Material&>(handle);
330 }
331
332 inline const Internal::Material& GetImplementation(const Dali::Scene3D::Material& material)
333 {
334   DALI_ASSERT_ALWAYS(material && "Material handle is empty");
335
336   const BaseObject& handle = material.GetBaseObject();
337
338   return static_cast<const Internal::Material&>(handle);
339 }
340
341 } // namespace Scene3D
342
343 } // namespace Dali
344
345 #endif // DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_IMPL_H