1 #ifndef DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_IMPL_H
2 #define DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_IMPL_H
5 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
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>
47 using MaterialPtr = IntrusivePtr<Material>;
50 * @brief This is the internal base class for Material of model.
54 class Material : public BaseObject, public ConnectionTracker
57 using ObserverContainer = std::vector<std::pair<MaterialModifyObserver*, bool>>;
61 * @brief Pair of texture handle and it's own scale factor. Texture handle can be empty
63 struct TextureInformation
67 return mLoadingTaskId == 0u;
71 Dali::Texture mTexture;
72 Vector4 mFactor{Vector4::ONE};
73 Dali::Sampler mSampler;
74 uint32_t mLoadingTaskId{0u};
76 Scene3D::Loader::ShaderOption::Type mShaderOptionType;
77 Matrix3 mTransform{Scene3D::Loader::TextureDefinition::DEFAULT_TRANSFORM};
80 using TextureInformationContainer = std::vector<TextureInformation>;
83 // Creation & Destruction
85 * @brief Create a new Material object.
86 * @return A smart-pointer to the newly allocated Material.
88 static MaterialPtr New();
92 * @brief Construct a new Material.
97 * @brief Second-phase constructor.
102 * @brief Virtual destructor.
108 * @copydoc Dali::Scene3D::Material::SetProperty()
110 void SetProperty(Dali::Property::Index index, Dali::Property::Value propertyValue);
113 * @copydoc Dali::Scene3D::Material::GetProperty()
115 Dali::Property::Value GetProperty(Dali::Property::Index index) const;
118 * @brief Sets a texture information for the material.
120 * @param[in] index The index of the texture to set.
121 * @param[in] textureInformation The texture information to set.
123 * @note This function moves the value of textureInformation.
125 void SetTextureInformation(Scene3D::Material::TextureType index, TextureInformation&& textureInformation);
128 * @brief Sets a texture for the material.
130 * @param[in] index The index of the texture to set.
131 * @param[in] texture The texture to set.
133 void SetTexture(Scene3D::Material::TextureType index, Dali::Texture texture);
136 * @brief Retrieves texture for the material.
138 * @param[in] index The index of the texture to get.
140 * @return The texture at the given index.
142 Dali::Texture GetTexture(Scene3D::Material::TextureType index);
145 * @brief Retrieves the texture set for this material.
147 * @return The texture set for this material.
149 TextureSet GetTextureSet();
152 * @brief Sets a sampler for the material.
154 * @param[in] index The index of the sampler to set.
155 * @param[in] sampler The sampler to set.
157 void SetSampler(Scene3D::Material::TextureType index, Dali::Sampler sampler);
160 * @brief Retrieves a sampler for the material.
162 * @param[in] index The index of the sampler to get.
163 * @return The sampler at the given index.
165 Dali::Sampler GetSampler(Scene3D::Material::TextureType index);
168 * @brief Retrieves Shader Option of this Material.
170 * @return Shader Option of this Material.
172 Scene3D::Loader::ShaderOption GetShaderOption() const;
176 * @brief Adds observer to this material.
178 * @param[in] observer Pointer of observer.
180 void AddObserver(MaterialModifyObserver* observer);
183 * @brief Removes observer from this material.
185 * @param[in] observer Pointer of observer.
187 void RemoveObserver(MaterialModifyObserver* observer);
190 * @brief Updates material data.
192 void UpdateMaterialData();
195 * @brief Sets uniform value to the Renderer.
197 * @param[in] renderer Renderer object.
199 void SetRendererUniform(Dali::Renderer renderer);
202 * @brief Sets property value to the Renderer.
204 * @param[in] renderer Renderer object.
206 void SetRendererProperty(Dali::Renderer renderer);
209 * @brief Retrieves shadow map texture offset.
211 * @return shadow map texture offset.
213 uint32_t GetShadowMapTextureOffset();
216 * @brief Retrieves specular image based light texture offset.
218 * @return Specular image based light texture offset.
220 uint32_t GetSpecularImageBasedLightTextureOffset();
223 * @brief Retrieves diffuse image based light texture offset.
225 * @return Diffuse image based light texture offset.
227 uint32_t GetDiffuseImageBasedLightTextureOffset();
230 * @brief Retrieves image based light scale factor name.
232 * @return Image based light scale factor name.
234 std::string_view GetImageBasedLightScaleFactorName();
237 * @brief Retrieves image based light max lod uniform name.
239 * @return Image based light max lod uniform name.
241 std::string_view GetImageBasedLightMaxLodUniformName();
244 * @brief Checks if resource is ready.
246 * @return True if resource is ready, false otherwise.
248 bool IsResourceReady();
251 * @brief Resets dirty flag of this material.
257 * @brief Checks modify flag and send observers the material changeness.
258 * It will clean up modify flag
260 void NotifyObserver();
263 * @brief Requests loading an image from a URL and store it in TextureInformation.
265 * @param[in] textureInformation TextureInformation object to store loaded texture information.
266 * @param[in] url URL of the image to load.
268 void RequestTextureLoad(TextureInformation& textureInformation, const std::string& url);
271 * @brief Called when loading requested by RequestTextureLoad is complete.
273 * @param[in] loadedTaskId ID of the loaded texture.
274 * @param[in] pixelData PixelData of the loaded texture.
276 void TextureLoadComplete(uint32_t loadedTaskId, PixelData pixelData);
279 * @brief Called when all requested textures are loaded.
281 void ResourcesLoadComplete();
284 * @brief Updates the material using each attribute of this material and send a notification to the ModelPrimitive class.
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;
296 ObserverContainer mObservers{}; ///< List of observers who need to be notified after some properties are changed.
298 TextureInformationContainer mTextureInformations;
299 Dali::Toolkit::AsyncImageLoader mAsyncImageLoader;
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
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;
312 int32_t mDepthIndex{Scene3D::DepthIndex::Ranges::SCENE};
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.
319 } // namespace Internal
321 // Helpers for public-api forwarding methods
323 inline Internal::Material& GetImplementation(Dali::Scene3D::Material& material)
325 DALI_ASSERT_ALWAYS(material && "Material handle is empty");
327 BaseObject& handle = material.GetBaseObject();
329 return static_cast<Internal::Material&>(handle);
332 inline const Internal::Material& GetImplementation(const Dali::Scene3D::Material& material)
334 DALI_ASSERT_ALWAYS(material && "Material handle is empty");
336 const BaseObject& handle = material.GetBaseObject();
338 return static_cast<const Internal::Material&>(handle);
341 } // namespace Scene3D
345 #endif // DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_IMPL_H