2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-scene3d/internal/model-components/material-impl.h>
22 #include <dali/integration-api/debug.h>
23 #include <dali/public-api/object/type-registry-helper.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/public-api/rendering/sampler.h>
28 #include <dali-scene3d/internal/graphics/builtin-shader-extern-gen.h>
29 #include <dali-scene3d/internal/light/light-impl.h>
30 #include <dali-scene3d/internal/model-components/material-modify-observer.h>
31 #include <dali-scene3d/public-api/loader/node-definition.h>
32 #include <dali-scene3d/public-api/loader/renderer-state.h>
33 #include <dali-scene3d/public-api/loader/shader-option.h>
34 #include <dali-scene3d/public-api/loader/utils.h>
45 * Creates Material through type registry
49 return Scene3D::Material::New();
52 // Setup properties, signals and actions using the type-registry.
53 DALI_TYPE_REGISTRATION_BEGIN(Scene3D::Material, Dali::BaseHandle, Create);
54 DALI_TYPE_REGISTRATION_END()
56 static constexpr uint32_t OFFSET_FOR_DIFFUSE_CUBE_TEXTURE = 2u;
57 static constexpr uint32_t OFFSET_FOR_SPECULAR_CUBE_TEXTURE = 1u;
58 static constexpr uint32_t INVALID_INDEX = 0u;
59 static constexpr uint32_t ALPHA_CUTOFF_FLAG = Scene3D::Loader::MaterialDefinition::Flags::SUBSURFACE << 1;
60 static constexpr std::string_view THREE_TEX_KEYWORD = "THREE_TEX";
61 static constexpr std::string_view GLTF_CHANNELS_KEYWORD = "GLTF_CHANNELS";
75 } // unnamed namespace
77 MaterialPtr Material::New()
79 MaterialPtr material = new Material();
81 material->Initialize();
88 mModifyFlag(MaterialModifyObserver::ModifyFlag::NONE),
89 mObserverNotifying(false)
91 mAsyncImageLoader = Dali::Toolkit::AsyncImageLoader::New();
92 mAsyncImageLoader.ImageLoadedSignal().Connect(this, &Material::TextureLoadComplete);
93 mTextureInformations.assign(TEXTURE_TYPE_NUMBER, TextureInformation());
94 mTextureInformations[BASE_COLOR].mSemantic = Scene3D::Loader::MaterialDefinition::ALBEDO;
95 // TODO : How we support dli manner
96 mTextureInformations[METALLIC_ROUGHNESS].mSemantic = Scene3D::Loader::MaterialDefinition::METALLIC | Scene3D::Loader::MaterialDefinition::ROUGHNESS |
97 Scene3D::Loader::MaterialDefinition::GLTF_CHANNELS;
98 mTextureInformations[NORMAL].mSemantic = Scene3D::Loader::MaterialDefinition::NORMAL;
99 mTextureInformations[OCCLUSION].mSemantic = Scene3D::Loader::MaterialDefinition::OCCLUSION;
100 mTextureInformations[EMISSIVE].mSemantic = Scene3D::Loader::MaterialDefinition::EMISSIVE;
101 mTextureInformations[SPECULAR].mSemantic = Scene3D::Loader::MaterialDefinition::SPECULAR;
102 mTextureInformations[SPECULAR_COLOR].mSemantic = Scene3D::Loader::MaterialDefinition::SPECULAR_COLOR;
104 mTextureInformations[BASE_COLOR].mShaderOptionType = Loader::ShaderOption::Type::BASE_COLOR_TEXTURE;
105 mTextureInformations[METALLIC_ROUGHNESS].mShaderOptionType = Loader::ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE;
106 mTextureInformations[NORMAL].mShaderOptionType = Loader::ShaderOption::Type::NORMAL_TEXTURE;
107 mTextureInformations[OCCLUSION].mShaderOptionType = Loader::ShaderOption::Type::OCCLUSION;
108 mTextureInformations[EMISSIVE].mShaderOptionType = Loader::ShaderOption::Type::EMISSIVE;
109 mTextureInformations[SPECULAR].mShaderOptionType = Loader::ShaderOption::Type::SPECULAR;
110 mTextureInformations[SPECULAR_COLOR].mShaderOptionType = Loader::ShaderOption::Type::SPECULAR_COLOR;
112 mTextureInformations[TextureIndex::EMISSIVE].mFactor = Vector4::ZERO;
115 Material::~Material() = default;
117 void Material::Initialize()
121 void Material::SetProperty(Dali::Property::Index index, Dali::Property::Value propertyValue)
123 bool needToApply = true;
126 case Dali::Scene3D::Material::Property::NAME:
129 if(propertyValue.Get(name))
136 case Dali::Scene3D::Material::Property::BASE_COLOR_URL:
138 std::string baseColorUrl;
139 if(propertyValue.Get(baseColorUrl))
141 RequestTextureLoad(mTextureInformations[TextureIndex::BASE_COLOR], baseColorUrl);
146 case Dali::Scene3D::Material::Property::BASE_COLOR_FACTOR:
148 Vector4 baseColorFactor;
149 if(propertyValue.Get(baseColorFactor))
151 mTextureInformations[TextureIndex::BASE_COLOR].mFactor = baseColorFactor;
152 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
156 case Dali::Scene3D::Material::Property::METALLIC_ROUGHNESS_URL:
158 std::string metallicRoughnessUrl;
159 if(propertyValue.Get(metallicRoughnessUrl))
161 RequestTextureLoad(mTextureInformations[TextureIndex::METALLIC_ROUGHNESS], metallicRoughnessUrl);
166 case Dali::Scene3D::Material::Property::METALLIC_FACTOR:
168 float metallicFactor;
169 if(propertyValue.Get(metallicFactor))
171 mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.x = metallicFactor;
172 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
176 case Dali::Scene3D::Material::Property::ROUGHNESS_FACTOR:
178 float roughnessFactor;
179 if(propertyValue.Get(roughnessFactor))
181 mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.y = roughnessFactor;
182 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
186 case Dali::Scene3D::Material::Property::NORMAL_URL:
188 std::string normalUrl;
189 if(propertyValue.Get(normalUrl))
191 RequestTextureLoad(mTextureInformations[TextureIndex::NORMAL], normalUrl);
196 case Dali::Scene3D::Material::Property::NORMAL_SCALE:
199 if(propertyValue.Get(normalScale))
201 mTextureInformations[TextureIndex::NORMAL].mFactor.x = normalScale;
202 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
206 case Dali::Scene3D::Material::Property::OCCLUSION_URL:
208 std::string occlusionUrl;
209 if(propertyValue.Get(occlusionUrl))
211 RequestTextureLoad(mTextureInformations[TextureIndex::OCCLUSION], occlusionUrl);
216 case Dali::Scene3D::Material::Property::OCCLUSION_STRENGTH:
218 float occlusionStrength;
219 if(propertyValue.Get(occlusionStrength))
221 mTextureInformations[TextureIndex::OCCLUSION].mFactor.x = occlusionStrength;
222 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
226 case Dali::Scene3D::Material::Property::EMISSIVE_URL:
228 std::string emissiveUrl;
229 if(propertyValue.Get(emissiveUrl))
231 RequestTextureLoad(mTextureInformations[TextureIndex::EMISSIVE], emissiveUrl);
236 case Dali::Scene3D::Material::Property::EMISSIVE_FACTOR:
238 Vector3 emissiveFactor;
239 if(propertyValue.Get(emissiveFactor))
241 mTextureInformations[TextureIndex::EMISSIVE].mFactor = emissiveFactor;
242 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
246 case Dali::Scene3D::Material::Property::ALPHA_MODE:
248 Dali::Scene3D::Material::AlphaModeType alphaMode;
249 if(propertyValue.Get(alphaMode))
251 mAlphaMode = alphaMode;
252 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
256 case Dali::Scene3D::Material::Property::ALPHA_CUTOFF:
259 if(propertyValue.Get(alphaCutoff))
261 mAlphaCutoff = alphaCutoff;
262 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
266 case Dali::Scene3D::Material::Property::DOUBLE_SIDED:
269 if(propertyValue.Get(doubleSided))
271 mDoubleSided = doubleSided;
272 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
276 case Dali::Scene3D::Material::Property::IOR:
279 if(propertyValue.Get(ior))
282 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
286 case Dali::Scene3D::Material::Property::SPECULAR_URL:
288 std::string specularUrl;
289 if(propertyValue.Get(specularUrl))
291 RequestTextureLoad(mTextureInformations[TextureIndex::SPECULAR], specularUrl);
296 case Dali::Scene3D::Material::Property::SPECULAR_FACTOR:
298 float specularFactor;
299 if(propertyValue.Get(specularFactor))
301 mTextureInformations[TextureIndex::SPECULAR].mFactor.x = specularFactor;
302 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
306 case Dali::Scene3D::Material::Property::SPECULAR_COLOR_URL:
308 std::string specularColorUrl;
309 if(propertyValue.Get(specularColorUrl))
311 RequestTextureLoad(mTextureInformations[TextureIndex::SPECULAR_COLOR], specularColorUrl);
316 case Dali::Scene3D::Material::Property::SPECULAR_COLOR_FACTOR:
318 Vector3 specularColorFactor;
319 if(propertyValue.Get(specularColorFactor))
321 mTextureInformations[TextureIndex::SPECULAR_COLOR].mFactor = specularColorFactor;
322 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
334 Dali::Property::Value Material::GetProperty(Dali::Property::Index index) const
336 Dali::Property::Value value;
339 case Dali::Scene3D::Material::Property::NAME:
344 case Dali::Scene3D::Material::Property::BASE_COLOR_URL:
346 value = mTextureInformations[TextureIndex::BASE_COLOR].mUrl;
349 case Dali::Scene3D::Material::Property::BASE_COLOR_FACTOR:
351 value = mTextureInformations[TextureIndex::BASE_COLOR].mFactor;
354 case Dali::Scene3D::Material::Property::METALLIC_ROUGHNESS_URL:
356 value = mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mUrl;
359 case Dali::Scene3D::Material::Property::METALLIC_FACTOR:
361 value = mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.x;
364 case Dali::Scene3D::Material::Property::ROUGHNESS_FACTOR:
366 value = mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.y;
369 case Dali::Scene3D::Material::Property::NORMAL_URL:
371 value = mTextureInformations[TextureIndex::NORMAL].mUrl;
374 case Dali::Scene3D::Material::Property::NORMAL_SCALE:
376 value = mTextureInformations[TextureIndex::NORMAL].mFactor.x;
379 case Dali::Scene3D::Material::Property::OCCLUSION_URL:
381 value = mTextureInformations[TextureIndex::OCCLUSION].mUrl;
384 case Dali::Scene3D::Material::Property::OCCLUSION_STRENGTH:
386 value = mTextureInformations[TextureIndex::OCCLUSION].mFactor.x;
389 case Dali::Scene3D::Material::Property::EMISSIVE_URL:
391 value = mTextureInformations[TextureIndex::EMISSIVE].mUrl;
394 case Dali::Scene3D::Material::Property::EMISSIVE_FACTOR:
396 value = Vector3(mTextureInformations[TextureIndex::EMISSIVE].mFactor);
399 case Dali::Scene3D::Material::Property::ALPHA_MODE:
404 case Dali::Scene3D::Material::Property::ALPHA_CUTOFF:
406 value = mAlphaCutoff;
409 case Dali::Scene3D::Material::Property::DOUBLE_SIDED:
411 value = mDoubleSided;
414 case Dali::Scene3D::Material::Property::IOR:
419 case Dali::Scene3D::Material::Property::SPECULAR_URL:
421 value = mTextureInformations[TextureIndex::SPECULAR].mUrl;
424 case Dali::Scene3D::Material::Property::SPECULAR_FACTOR:
426 value = mTextureInformations[TextureIndex::SPECULAR].mFactor.x;
429 case Dali::Scene3D::Material::Property::SPECULAR_COLOR_URL:
431 value = mTextureInformations[TextureIndex::SPECULAR_COLOR].mUrl;
434 case Dali::Scene3D::Material::Property::SPECULAR_COLOR_FACTOR:
436 value = Vector3(mTextureInformations[TextureIndex::SPECULAR_COLOR].mFactor);
443 void Material::SetTextureInformation(Scene3D::Material::TextureType index, TextureInformation&& textureInformation)
445 mTextureInformations[index].mFactor = textureInformation.mFactor;
446 mTextureInformations[index].mSampler = textureInformation.mSampler;
447 mTextureInformations[index].mTexture = textureInformation.mTexture;
448 mTextureInformations[index].mUrl = std::move(textureInformation.mUrl);
451 void Material::SetTexture(Scene3D::Material::TextureType index, Dali::Texture texture)
453 if(static_cast<uint32_t>(index) < static_cast<uint32_t>(TextureIndex::TEXTURE_TYPE_NUMBER))
455 if(mTextureInformations[index].mTexture != texture)
457 if(mTextureInformations[index].mLoadingTaskId != INVALID_INDEX)
459 mAsyncImageLoader.Cancel(mTextureInformations[index].mLoadingTaskId);
460 mTextureInformations[index].mLoadingTaskId = INVALID_INDEX;
462 mTextureInformations[index].mTexture = texture;
463 if(IsResourceReady())
465 ResourcesLoadComplete();
471 Dali::Texture Material::GetTexture(Scene3D::Material::TextureType index)
473 if(static_cast<uint32_t>(index) < static_cast<uint32_t>(TextureIndex::TEXTURE_TYPE_NUMBER))
475 return mTextureInformations[index].mTexture;
477 return Dali::Texture();
480 TextureSet Material::GetTextureSet()
482 TextureSet textures = TextureSet::New();
483 for(uint32_t i = 0, count = 0; i < TEXTURE_TYPE_NUMBER; ++i)
485 if(!mTextureInformations[i].mTexture)
489 textures.SetTexture(count, mTextureInformations[i].mTexture);
490 Sampler sampler = mTextureInformations[i].mSampler;
493 auto samplerFlag = Scene3D::Loader::SamplerFlags::FILTER_LINEAR | (Scene3D::Loader::SamplerFlags::FILTER_LINEAR << Scene3D::Loader::SamplerFlags::FILTER_MAG_SHIFT) |
494 (Scene3D::Loader::SamplerFlags::WRAP_REPEAT << Scene3D::Loader::SamplerFlags::WRAP_S_SHIFT) | (Scene3D::Loader::SamplerFlags::WRAP_REPEAT << Scene3D::Loader::SamplerFlags::WRAP_T_SHIFT);
495 sampler = Scene3D::Loader::SamplerFlags::MakeSampler(samplerFlag);
497 textures.SetSampler(count, sampler);
503 void Material::SetSampler(Scene3D::Material::TextureType index, Dali::Sampler sampler)
505 if(static_cast<uint32_t>(index) < static_cast<uint32_t>(TextureIndex::TEXTURE_TYPE_NUMBER))
507 mTextureInformations[index].mSampler = sampler;
511 Dali::Sampler Material::GetSampler(Scene3D::Material::TextureType index)
513 if(static_cast<uint32_t>(index) < static_cast<uint32_t>(TextureIndex::TEXTURE_TYPE_NUMBER))
515 return mTextureInformations[index].mSampler;
517 return Dali::Sampler();
520 Scene3D::Loader::ShaderOption Material::GetShaderOption() const
522 return mShaderOption;
525 void Material::Apply()
527 if(IsResourceReady())
529 UpdateMaterialData();
533 // The cases this material is applied to primitive are,
534 // 1. material is added on Primitive.
535 // When material is added on Primitive (1 case)
536 // 1-1. when IsResourceReady() returns true,
537 // Primitive can takes information from Material
539 // Material will noti to primitives when all resources are ready.
540 // 2. Some properties are changed
541 // 2-1. when IsResourceReady() returns true,
542 // Call NotifyObserver directly.
544 // Material will noti to primitives when all resources are ready.
547 void Material::AddObserver(MaterialModifyObserver* observer)
549 for(auto& observerEntity : mObservers)
551 if(observerEntity.first == observer)
553 observerEntity.second = true;
557 mObservers.push_back({observer, true});
560 void Material::RemoveObserver(MaterialModifyObserver* observer)
562 // Block during notifying to observer
563 if(mObserverNotifying)
565 for(uint32_t i = 0; i < mObservers.size(); ++i)
567 if(mObservers[i].first == observer)
569 mObservers[i].second = false;
576 for(uint32_t i = 0; i < mObservers.size(); ++i)
578 if(mObservers[i].first == observer)
580 mObservers.erase(mObservers.begin() + i);
587 void Material::UpdateMaterialData()
589 uint32_t materialFlag = 0u;
590 if(mAlphaMode == Dali::Scene3D::Material::AlphaModeType::BLEND)
594 materialFlag |= Scene3D::Loader::MaterialDefinition::TRANSPARENCY;
596 else if(mAlphaMode == Dali::Scene3D::Material::AlphaModeType::MASK)
601 const bool hasTransparency = MaskMatch(materialFlag, Scene3D::Loader::MaterialDefinition::TRANSPARENCY);
603 for(auto&& textureInformation : mTextureInformations)
605 if(!textureInformation.mTexture)
609 materialFlag |= textureInformation.mSemantic;
612 if(mMaterialFlag != materialFlag)
614 mModifyFlag |= MaterialModifyObserver::ModifyFlag::SHADER;
616 mMaterialFlag = materialFlag;
618 mShaderOption = Loader::ShaderOption();
619 for(auto&& textureInformation : mTextureInformations)
621 if(!textureInformation.mTexture)
625 mShaderOption.AddOption(textureInformation.mShaderOptionType);
627 mShaderOption.AddOption(Loader::ShaderOption::Type::THREE_TEXTURE);
628 mShaderOption.AddOption(Loader::ShaderOption::Type::GLTF_CHANNELS);
629 if(materialFlag & Scene3D::Loader::MaterialDefinition::TRANSPARENCY)
631 mShaderOption.SetTransparency();
635 // Finish to make all the material flag according to the gltf2-util.
636 // Then make defines as fallowing shader-manager.
638 // The renderer State below can be used in primitive to set renderer properties.
640 // for renderer setting
641 mRendererState = Scene3D::Loader::RendererState::DEPTH_TEST;
644 mRendererState |= Scene3D::Loader::RendererState::CULL_BACK;
649 mRendererState = (mRendererState | Scene3D::Loader::RendererState::ALPHA_BLEND);
653 bool Material::IsResourceReady()
655 for(auto&& textureInformation : mTextureInformations)
657 if(!textureInformation.IsReady())
665 void Material::SetRendererUniform(Dali::Renderer renderer)
667 renderer.RegisterProperty("uColorFactor", mTextureInformations[TextureIndex::BASE_COLOR].mFactor);
668 renderer.RegisterProperty("uMetallicFactor", mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.x);
669 renderer.RegisterProperty("uRoughnessFactor", mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.y);
670 renderer.RegisterProperty("uNormalScale", mTextureInformations[TextureIndex::NORMAL].mFactor.x);
671 if(mTextureInformations[TextureIndex::OCCLUSION].mTexture)
673 renderer.RegisterProperty("uOcclusionStrength", mTextureInformations[TextureIndex::OCCLUSION].mFactor.x);
675 renderer.RegisterProperty("uEmissiveFactor", Vector3(mTextureInformations[TextureIndex::EMISSIVE].mFactor));
676 float dielectricSpecular = (Dali::Equals(mIor, -1.0)) ? 0.04f : powf((mIor - 1.0f) / (mIor + 1.0f), 2.0f);
677 renderer.RegisterProperty("uDielectricSpecular", dielectricSpecular);
678 renderer.RegisterProperty("uSpecularFactor", mTextureInformations[TextureIndex::SPECULAR].mFactor.x);
679 renderer.RegisterProperty("uSpecularColorFactor", Vector3(mTextureInformations[TextureIndex::SPECULAR_COLOR].mFactor));
681 float opaque = mIsOpaque ? 1.0f : 0.0f;
682 float mask = mIsMask ? 1.0f : 0.0f;
683 renderer.RegisterProperty("uOpaque", opaque);
684 renderer.RegisterProperty("uMask", mask);
685 renderer.RegisterProperty("uAlphaThreshold", mAlphaCutoff);
687 renderer.RegisterProperty("uCubeMatrix", Matrix::IDENTITY);
689 renderer.RegisterProperty(Scene3D::Loader::NodeDefinition::GetIblMaxLodUniformName().data(), 6.f);
690 renderer.RegisterProperty(Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), 1.0f);
691 renderer.RegisterProperty(Scene3D::Loader::NodeDefinition::GetIblYDirectionUniformName().data(), Vector3(1.0f, -1.0, 1.0));
693 std::string lightCountPropertyName(Scene3D::Internal::Light::GetLightCountUniformName());
694 renderer.RegisterProperty(lightCountPropertyName, 0);
696 uint32_t maxLightCount = Scene3D::Internal::Light::GetMaximumEnabledLightCount();
697 for(uint32_t i = 0; i < maxLightCount; ++i)
699 std::string lightDirectionPropertyName(Scene3D::Internal::Light::GetLightDirectionUniformName());
700 lightDirectionPropertyName += "[" + std::to_string(i) + "]";
701 renderer.RegisterProperty(lightDirectionPropertyName, Vector3::ZAXIS);
703 std::string lightColorPropertyName(Scene3D::Internal::Light::GetLightColorUniformName());
704 lightColorPropertyName += "[" + std::to_string(i) + "]";
705 renderer.RegisterProperty(lightColorPropertyName, Vector3(Color::WHITE));
708 Scene3D::Loader::RendererState::Apply(mRendererState, renderer);
711 uint32_t Material::GetSpecularImageBasedLightTextureOffset()
713 return OFFSET_FOR_SPECULAR_CUBE_TEXTURE;
716 uint32_t Material::GetDiffuseImageBasedLightTextureOffset()
718 return OFFSET_FOR_DIFFUSE_CUBE_TEXTURE;
721 std::string_view Material::GetImageBasedLightScaleFactorName()
723 return Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName();
726 std::string_view Material::GetImageBasedLightMaxLodUniformName()
728 return Dali::Scene3D::Loader::NodeDefinition::GetIblMaxLodUniformName();
731 void Material::ResetFlag()
733 mModifyFlag = MaterialModifyObserver::ModifyFlag::NONE;
736 void Material::NotifyObserver()
738 if(mModifyFlag != MaterialModifyObserver::ModifyFlag::NONE && IsResourceReady())
740 if(mObserverNotifying)
742 DALI_LOG_ERROR("Notify during observing is not allowed.");
746 Dali::Scene3D::Material handle(this); // Keep itself's life during notify
748 // Copy the flag due to the flag can be changed during observe.
749 MaterialModifyObserver::ModifyFlag copiedFlag = mModifyFlag;
750 mModifyFlag = MaterialModifyObserver::ModifyFlag::NONE;
752 // Need to block mObserver container change during observe
753 mObserverNotifying = true;
754 for(uint32_t i = 0; i < mObservers.size(); ++i)
756 if(mObservers[i].second)
758 mObservers[i].first->OnMaterialModified(handle, copiedFlag);
761 mObserverNotifying = false;
763 // Resolve observer queue during notify
764 mObservers.erase(std::remove_if(mObservers.begin(), mObservers.end(), [](auto& e)
765 { return !e.second; }),
770 void Material::RequestTextureLoad(TextureInformation& textureInformation, const std::string& url)
772 if(textureInformation.mUrl == url)
777 textureInformation.mUrl = url;
778 if(textureInformation.mLoadingTaskId != INVALID_INDEX)
780 mAsyncImageLoader.Cancel(textureInformation.mLoadingTaskId);
781 textureInformation.mLoadingTaskId = INVALID_INDEX;
786 textureInformation.mTexture.Reset();
789 textureInformation.mLoadingTaskId = mAsyncImageLoader.Load(url);
792 void Material::TextureLoadComplete(uint32_t loadedTaskId, PixelData pixelData)
794 for(auto&& textureInformation : mTextureInformations)
796 if(textureInformation.mLoadingTaskId != loadedTaskId)
803 textureInformation.mTexture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight());
804 textureInformation.mTexture.Upload(pixelData);
806 textureInformation.mLoadingTaskId = INVALID_INDEX;
810 if(IsResourceReady())
812 ResourcesLoadComplete();
816 void Material::ResourcesLoadComplete()
818 mModifyFlag |= MaterialModifyObserver::ModifyFlag::TEXTURE;
822 } // namespace Internal
824 } // namespace Scene3D