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>
46 using MaterialPtr = IntrusivePtr<Material>;
49 * @brief This is the internal base class for Material of model.
53 class Material : public BaseObject, public ConnectionTracker
56 using ObserverContainer = std::vector<std::pair<MaterialModifyObserver*, bool>>;
60 * @brief Pair of texture handle and it's own scale factor. Texture handle can be empty
62 struct TextureInformation
66 return mLoadingTaskId == 0u;
70 Dali::Texture mTexture;
71 Vector4 mFactor{Vector4::ONE};
72 Dali::Sampler mSampler;
73 uint32_t mLoadingTaskId{0u};
75 Scene3D::Loader::ShaderOption::Type mShaderOptionType;
78 using TextureInformationContainer = std::vector<TextureInformation>;
81 // Creation & Destruction
83 * @brief Create a new Material object.
84 * @return A smart-pointer to the newly allocated Material.
86 static MaterialPtr New();
90 * @brief Construct a new Material.
95 * @brief Second-phase constructor.
100 * @brief Virtual destructor.
106 * @copydoc Dali::Scene3D::Material::SetProperty()
108 void SetProperty(Dali::Property::Index index, Dali::Property::Value propertyValue);
111 * @copydoc Dali::Scene3D::Material::GetProperty()
113 Dali::Property::Value GetProperty(Dali::Property::Index index) const;
116 * @brief Sets a texture information for the material.
118 * @param[in] index The index of the texture to set.
119 * @param[in] textureInformation The texture information to set.
121 * @note This function moves the value of textureInformation.
123 void SetTextureInformation(Scene3D::Material::TextureType index, TextureInformation&& textureInformation);
126 * @brief Sets a texture for the material.
128 * @param[in] index The index of the texture to set.
129 * @param[in] texture The texture to set.
131 void SetTexture(Scene3D::Material::TextureType index, Dali::Texture texture);
134 * @brief Retrieves texture for the material.
136 * @param[in] index The index of the texture to get.
138 * @return The texture at the given index.
140 Dali::Texture GetTexture(Scene3D::Material::TextureType index);
143 * @brief Retrieves the texture set for this material.
145 * @return The texture set for this material.
147 TextureSet GetTextureSet();
150 * @brief Sets a sampler for the material.
152 * @param[in] index The index of the sampler to set.
153 * @param[in] sampler The sampler to set.
155 void SetSampler(Scene3D::Material::TextureType index, Dali::Sampler sampler);
158 * @brief Retrieves a sampler for the material.
160 * @param[in] index The index of the sampler to get.
161 * @return The sampler at the given index.
163 Dali::Sampler GetSampler(Scene3D::Material::TextureType index);
166 * @brief Retrieves Shader Option of this Material.
168 * @return Shader Option of this Material.
170 Scene3D::Loader::ShaderOption GetShaderOption() const;
174 * @brief Adds observer to this material.
176 * @param[in] observer Pointer of observer.
178 void AddObserver(MaterialModifyObserver* observer);
181 * @brief Removes observer from this material.
183 * @param[in] observer Pointer of observer.
185 void RemoveObserver(MaterialModifyObserver* observer);
188 * @brief Updates material data.
190 void UpdateMaterialData();
193 * @brief Sets uniform value to the Renderer.
195 * @param[in] renderer Renderer object.
197 void SetRendererUniform(Dali::Renderer renderer);
200 * @brief Retrieves shadow map texture offset.
202 * @return shadow map texture offset.
204 uint32_t GetShadowMapTextureOffset();
207 * @brief Retrieves specular image based light texture offset.
209 * @return Specular image based light texture offset.
211 uint32_t GetSpecularImageBasedLightTextureOffset();
214 * @brief Retrieves diffuse image based light texture offset.
216 * @return Diffuse image based light texture offset.
218 uint32_t GetDiffuseImageBasedLightTextureOffset();
221 * @brief Retrieves image based light scale factor name.
223 * @return Image based light scale factor name.
225 std::string_view GetImageBasedLightScaleFactorName();
228 * @brief Retrieves image based light max lod uniform name.
230 * @return Image based light max lod uniform name.
232 std::string_view GetImageBasedLightMaxLodUniformName();
235 * @brief Checks if resource is ready.
237 * @return True if resource is ready, false otherwise.
239 bool IsResourceReady();
242 * @brief Resets dirty flag of this material.
248 * @brief Checks modify flag and send observers the material changeness.
249 * It will clean up modify flag
251 void NotifyObserver();
254 * @brief Requests loading an image from a URL and store it in TextureInformation.
256 * @param[in] textureInformation TextureInformation object to store loaded texture information.
257 * @param[in] url URL of the image to load.
259 void RequestTextureLoad(TextureInformation& textureInformation, const std::string& url);
262 * @brief Called when loading requested by RequestTextureLoad is complete.
264 * @param[in] loadedTaskId ID of the loaded texture.
265 * @param[in] pixelData PixelData of the loaded texture.
267 void TextureLoadComplete(uint32_t loadedTaskId, PixelData pixelData);
270 * @brief Called when all requested textures are loaded.
272 void ResourcesLoadComplete();
275 * @brief Updates the material using each attribute of this material and send a notification to the ModelPrimitive class.
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;
287 ObserverContainer mObservers{}; ///< List of observers who need to be notified after some properties are changed.
289 TextureInformationContainer mTextureInformations;
290 Dali::Toolkit::AsyncImageLoader mAsyncImageLoader;
292 std::string mName; ///< Material name
293 Dali::Scene3D::Material::AlphaModeType mAlphaMode = Scene3D::Material::AlphaModeType::OPAQUE; ///< 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
299 Scene3D::Loader::ShaderOption mShaderOption;
300 uint32_t mMaterialFlag = std::numeric_limits<uint32_t>::max();
301 Scene3D::Loader::RendererState::Type mRendererState = Scene3D::Loader::RendererState::NONE;
303 bool mIsOpaque = true;
304 bool mIsMask = false;
305 bool mObserverNotifying; ///< True if observe is notify now. If then, we should not change the mObservers.
308 } // namespace Internal
310 // Helpers for public-api forwarding methods
312 inline Internal::Material& GetImplementation(Dali::Scene3D::Material& material)
314 DALI_ASSERT_ALWAYS(material && "Material handle is empty");
316 BaseObject& handle = material.GetBaseObject();
318 return static_cast<Internal::Material&>(handle);
321 inline const Internal::Material& GetImplementation(const Dali::Scene3D::Material& material)
323 DALI_ASSERT_ALWAYS(material && "Material handle is empty");
325 const BaseObject& handle = material.GetBaseObject();
327 return static_cast<const Internal::Material&>(handle);
330 } // namespace Scene3D
334 #endif // DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_IMPL_H