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/model-components/material.h>
45 using MaterialPtr = IntrusivePtr<Material>;
48 * @brief This is the internal base class for Material of model.
52 class Material : public BaseObject, public ConnectionTracker
55 using ObserverContainer = std::vector<std::pair<MaterialModifyObserver*, bool>>;
59 * @brief Pair of texture handle and it's own scale factor. Texture handle can be empty
61 struct TextureInformation
65 return mLoadingTaskId == 0u;
69 Dali::Texture mTexture;
70 Vector4 mFactor{Vector4::ONE};
71 Dali::Sampler mSampler;
72 uint32_t mLoadingTaskId{0u};
74 std::string mDefineKeyword;
77 using TextureInformationContainer = std::vector<TextureInformation>;
80 // Creation & Destruction
82 * @brief Create a new Material object.
83 * @return A smart-pointer to the newly allocated Material.
85 static MaterialPtr New();
89 * @brief Construct a new Material.
94 * @brief Second-phase constructor.
99 * @brief Virtual destructor.
105 * @copydoc Dali::Scene3D::Material::SetProperty()
107 void SetProperty(Dali::Property::Index index, Dali::Property::Value propertyValue);
110 * @copydoc Dali::Scene3D::Material::GetProperty()
112 Dali::Property::Value GetProperty(Dali::Property::Index index) const;
115 * @brief Set a texture information for the material.
117 * @param[in] index The index of the texture to set.
118 * @param[in] textureInformation The texture information to set.
120 * @note This function moves the value of textureInformation.
122 void SetTextureInformation(Scene3D::Material::TextureType index, TextureInformation&& textureInformation);
125 * @brief Set a texture for the material.
127 * @param[in] index The index of the texture to set.
128 * @param[in] texture The texture to set.
130 void SetTexture(Scene3D::Material::TextureType index, Dali::Texture texture);
133 * @brief Get texture for the material.
135 * @param[in] index The index of the texture to get.
137 * @return The texture at the given index.
139 Dali::Texture GetTexture(Scene3D::Material::TextureType index);
142 * @brief Get the texture set for this material.
144 * @return The texture set for this material.
146 TextureSet GetTextureSet();
149 * @brief Set a sampler for the material.
151 * @param[in] index The index of the sampler to set.
152 * @param[in] sampler The sampler to set.
154 void SetSampler(Scene3D::Material::TextureType index, Dali::Sampler sampler);
157 * @brief Get a sampler for the material.
159 * @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 Get vertex shader code for this material.
168 * @return Vertex shader code for this material.
170 std::string GetVertexShader();
173 * @brief Get fragment shader code for this material.
175 * @return Fragment shader code for this material.
177 std::string GetFragmentShader();
181 * @brief Add observer to this material.
183 * @param[in] observer Pointer of observer.
185 void AddObserver(MaterialModifyObserver* observer);
188 * @brief Remove observer from this material.
190 * @param[in] observer Pointer of observer.
192 void RemoveObserver(MaterialModifyObserver* observer);
195 * @brief Update material data.
197 void UpdateMaterialData();
200 * @brief Set uniform value to the Renderer.
202 * @param[in] renderer Renderer object.
204 void SetRendererUniform(Dali::Renderer renderer);
207 * @brief Get specular image based light texture offset.
209 * @return Specular image based light texture offset.
211 uint32_t GetSpecularImageBasedLightTextureOffset();
214 * @brief Get diffuse image based light texture offset.
216 * @return Diffuse image based light texture offset.
218 uint32_t GetDiffuseImageBasedLightTextureOffset();
221 * @brief Get image based light scale factor name.
223 * @return Image based light scale factor name.
225 std::string_view GetImageBasedLightScaleFactorName();
228 * @brief Get image based light max lod uniform name.
230 * @return Image based light max lod uniform name.
232 std::string_view GetImageBasedLightMaxLodUniformName();
235 * @brief Check if resource is ready.
237 * @return True if resource is ready, false otherwise.
239 bool IsResourceReady();
242 * @brief Reset dirty flag of this material.
248 * @brief Check modify flag and send observers the material changeness.
249 * It will clean up modify flag
251 void NotifyObserver();
254 * @brief Request 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 Update 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; ///< 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::ShaderDefinition::RawData mShaderData;
301 uint32_t mMaterialFlag;
302 Scene3D::Loader::RendererState::Type mRendererState;
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.
309 } // namespace Internal
311 // Helpers for public-api forwarding methods
313 inline Internal::Material& GetImplementation(Dali::Scene3D::Material& material)
315 DALI_ASSERT_ALWAYS(material && "Material handle is empty");
317 BaseObject& handle = material.GetBaseObject();
319 return static_cast<Internal::Material&>(handle);
322 inline const Internal::Material& GetImplementation(const Dali::Scene3D::Material& material)
324 DALI_ASSERT_ALWAYS(material && "Material handle is empty");
326 const BaseObject& handle = material.GetBaseObject();
328 return static_cast<const Internal::Material&>(handle);
331 } // namespace Scene3D
335 #endif // DALI_SCENE3D_MODEL_COMPONENTS_MATERIAL_IMPL_H