Merge "Use c-style string when webview loads contents." into 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/model-components/material.h>
38
39 namespace Dali
40 {
41 namespace Scene3D
42 {
43 namespace Internal
44 {
45 using MaterialPtr = IntrusivePtr<Material>;
46
47 /**
48  * @brief This is the internal base class for Material of model.
49  *
50  * @SINCE_2_2.99
51  */
52 class Material : public BaseObject, public ConnectionTracker
53 {
54 private:
55   using ObserverContainer = std::vector<std::pair<MaterialModifyObserver*, bool>>;
56
57 public:
58   /**
59    * @brief Pair of texture handle and it's own scale factor. Texture handle can be empty
60    */
61   struct TextureInformation
62   {
63     bool IsReady()
64     {
65       return mLoadingTaskId == 0u;
66     }
67
68     std::string   mUrl;
69     Dali::Texture mTexture;
70     Vector4       mFactor{Vector4::ONE};
71     Dali::Sampler mSampler;
72     uint32_t      mLoadingTaskId{0u};
73     uint32_t      mSemantic;
74     std::string   mDefineKeyword;
75   };
76
77   using TextureInformationContainer = std::vector<TextureInformation>;
78
79 public:
80   // Creation & Destruction
81   /**
82    * @brief Create a new Material object.
83    * @return A smart-pointer to the newly allocated Material.
84    */
85   static MaterialPtr New();
86
87 protected:
88   /**
89    * @brief Construct a new Material.
90    */
91   Material();
92
93   /**
94    * @brief Second-phase constructor.
95    */
96   void Initialize();
97
98   /**
99    * @brief Virtual destructor.
100    */
101   virtual ~Material();
102
103 public:
104   /**
105    * @copydoc Dali::Scene3D::Material::SetProperty()
106    */
107   void SetProperty(Dali::Property::Index index, Dali::Property::Value propertyValue);
108
109   /**
110    * @copydoc Dali::Scene3D::Material::GetProperty()
111    */
112   Dali::Property::Value GetProperty(Dali::Property::Index index) const;
113
114   /**
115    * @brief Set a texture information for the material.
116    *
117    * @param[in] index The index of the texture to set.
118    * @param[in] textureInformation The texture information to set.
119    *
120    * @note This function moves the value of textureInformation.
121    */
122   void SetTextureInformation(Scene3D::Material::TextureType index, TextureInformation&& textureInformation);
123
124   /**
125    * @brief Set a texture for the material.
126    *
127    * @param[in] index The index of the texture to set.
128    * @param[in] texture The texture to set.
129    */
130   void SetTexture(Scene3D::Material::TextureType index, Dali::Texture texture);
131
132   /**
133    * @brief Get texture for the material.
134    *
135    * @param[in] index The index of the texture to get.
136    *
137    * @return The texture at the given index.
138    */
139   Dali::Texture GetTexture(Scene3D::Material::TextureType index);
140
141   /**
142    * @brief Get the texture set for this material.
143    *
144    * @return The texture set for this material.
145    */
146   TextureSet GetTextureSet();
147
148   /**
149    * @brief Set a sampler for the material.
150    *
151    * @param[in] index The index of the sampler to set.
152    * @param[in] sampler The sampler to set.
153    */
154   void SetSampler(Scene3D::Material::TextureType index, Dali::Sampler sampler);
155
156   /**
157    * @brief Get a sampler for the material.
158
159    * @param[in] index The index of the sampler to get.
160    *
161    * @return The sampler at the given index.
162    */
163   Dali::Sampler GetSampler(Scene3D::Material::TextureType index);
164
165   /**
166    * @brief Get vertex shader code for this material.
167    *
168    * @return Vertex shader code for this material.
169    */
170   std::string GetVertexShader();
171
172   /**
173    * @brief Get fragment shader code for this material.
174    *
175    * @return Fragment shader code for this material.
176    */
177   std::string GetFragmentShader();
178
179 public:
180   /**
181    * @brief Add observer to this material.
182    *
183    * @param[in] observer Pointer of observer.
184    */
185   void AddObserver(MaterialModifyObserver* observer);
186
187   /**
188    * @brief Remove observer from this material.
189    *
190    * @param[in] observer Pointer of observer.
191    */
192   void RemoveObserver(MaterialModifyObserver* observer);
193
194   /**
195    * @brief Update material data.
196    */
197   void UpdateMaterialData();
198
199   /**
200    * @brief Set uniform value to the Renderer.
201    *
202    * @param[in] renderer Renderer object.
203    */
204   void SetRendererUniform(Dali::Renderer renderer);
205
206   /**
207    * @brief Get specular image based light texture offset.
208    *
209    * @return Specular image based light texture offset.
210    */
211   uint32_t GetSpecularImageBasedLightTextureOffset();
212
213   /**
214    * @brief Get diffuse image based light texture offset.
215    *
216    * @return Diffuse image based light texture offset.
217    */
218   uint32_t GetDiffuseImageBasedLightTextureOffset();
219
220   /**
221    * @brief Get image based light scale factor name.
222    *
223    * @return Image based light scale factor name.
224    */
225   std::string_view GetImageBasedLightScaleFactorName();
226
227   /**
228    * @brief Get image based light max lod uniform name.
229    *
230    * @return Image based light max lod uniform name.
231    */
232   std::string_view GetImageBasedLightMaxLodUniformName();
233
234   /**
235    * @brief Check if resource is ready.
236    *
237    * @return True if resource is ready, false otherwise.
238    */
239   bool IsResourceReady();
240
241   /**
242    * @brief Reset dirty flag of this material.
243    */
244   void ResetFlag();
245
246 private:
247   /**
248    * @brief Check modify flag and send observers the material changeness.
249    * It will clean up modify flag
250    */
251   void NotifyObserver();
252
253   /**
254    * @brief Request loading an image from a URL and store it in TextureInformation.
255    *
256    * @param[in] textureInformation TextureInformation object to store loaded texture information.
257    * @param[in] url URL of the image to load.
258    */
259   void RequestTextureLoad(TextureInformation& textureInformation, const std::string& url);
260
261   /**
262    * @brief Called when loading requested by RequestTextureLoad is complete.
263    *
264    * @param[in] loadedTaskId ID of the loaded texture.
265    * @param[in] pixelData PixelData of the loaded texture.
266    */
267   void TextureLoadComplete(uint32_t loadedTaskId, PixelData pixelData);
268
269   /**
270    * @brief Called when all requested textures are loaded.
271    */
272   void ResourcesLoadComplete();
273
274   /**
275    * @brief Update the material using each attribute of this material and send a notification to the ModelPrimitive class.
276    */
277   void Apply();
278
279 private:
280   // Delete copy & move operator
281   Material(const Material&)                = delete;
282   Material(Material&&)                     = delete;
283   Material& operator=(const Material& rhs) = delete;
284   Material& operator=(Material&& rhs)      = delete;
285
286 private:
287   ObserverContainer mObservers{};     ///< List of observers who need to be notified after some properties are changed.
288
289   TextureInformationContainer     mTextureInformations;
290   Dali::Toolkit::AsyncImageLoader mAsyncImageLoader;
291
292   std::string                            mName;                                                   ///< Material name
293   Dali::Scene3D::Material::AlphaModeType mAlphaMode;                                              ///< Alpha mode
294   float                                  mAlphaCutoff = 0.5f;                                     ///< Alpha cutoff value
295   bool                                   mDoubleSided = false;                                    ///< Whether to render both sides
296   float                                  mIor         = -1.0f;                                    ///< Index of refraction (TODO: Magic number)
297   MaterialModifyObserver::ModifyFlag     mModifyFlag  = MaterialModifyObserver::ModifyFlag::NONE; ///< Modified dirty flags
298
299   Scene3D::Loader::ShaderDefinition::RawData mShaderData;
300
301   uint32_t                             mMaterialFlag;
302   Scene3D::Loader::RendererState::Type mRendererState;
303
304   bool mIsOpaque = true;
305   bool mIsMask   = false;
306   bool mObserverNotifying; ///< True if observe is notify now. If then, we should not change the mObservers.
307 };
308
309 } // namespace Internal
310
311 // Helpers for public-api forwarding methods
312
313 inline Internal::Material& GetImplementation(Dali::Scene3D::Material& material)
314 {
315   DALI_ASSERT_ALWAYS(material && "Material handle is empty");
316
317   BaseObject& handle = material.GetBaseObject();
318
319   return static_cast<Internal::Material&>(handle);
320 }
321
322 inline const Internal::Material& GetImplementation(const Dali::Scene3D::Material& material)
323 {
324   DALI_ASSERT_ALWAYS(material && "Material handle is empty");
325
326   const BaseObject& handle = material.GetBaseObject();
327
328   return static_cast<const Internal::Material&>(handle);
329 }
330
331 } // namespace Scene3D
332
333 } // namespace Dali
334
335 #endif // DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_IMPL_H