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_SHADOW_MAP_TEXTURE = 4u;
57 static constexpr uint32_t OFFSET_FOR_DIFFUSE_CUBE_TEXTURE = 2u;
58 static constexpr uint32_t OFFSET_FOR_SPECULAR_CUBE_TEXTURE = 1u;
59 static constexpr uint32_t INVALID_INDEX = 0u;
60 static constexpr uint32_t ALPHA_CUTOFF_FLAG = Scene3D::Loader::MaterialDefinition::Flags::SUBSURFACE << 1;
61 static constexpr std::string_view THREE_TEX_KEYWORD = "THREE_TEX";
62 static constexpr std::string_view GLTF_CHANNELS_KEYWORD = "GLTF_CHANNELS";
76 } // unnamed namespace
78 MaterialPtr Material::New()
80 MaterialPtr material = new Material();
82 material->Initialize();
89 mModifyFlag(MaterialModifyObserver::ModifyFlag::NONE),
90 mObserverNotifying(false)
92 mAsyncImageLoader = Dali::Toolkit::AsyncImageLoader::New();
93 mAsyncImageLoader.ImageLoadedSignal().Connect(this, &Material::TextureLoadComplete);
94 mTextureInformations.assign(TEXTURE_TYPE_NUMBER, TextureInformation());
95 mTextureInformations[BASE_COLOR].mSemantic = Scene3D::Loader::MaterialDefinition::ALBEDO;
96 // TODO : How we support dli manner
97 mTextureInformations[METALLIC_ROUGHNESS].mSemantic = Scene3D::Loader::MaterialDefinition::METALLIC | Scene3D::Loader::MaterialDefinition::ROUGHNESS |
98 Scene3D::Loader::MaterialDefinition::GLTF_CHANNELS;
99 mTextureInformations[NORMAL].mSemantic = Scene3D::Loader::MaterialDefinition::NORMAL;
100 mTextureInformations[OCCLUSION].mSemantic = Scene3D::Loader::MaterialDefinition::OCCLUSION;
101 mTextureInformations[EMISSIVE].mSemantic = Scene3D::Loader::MaterialDefinition::EMISSIVE;
102 mTextureInformations[SPECULAR].mSemantic = Scene3D::Loader::MaterialDefinition::SPECULAR;
103 mTextureInformations[SPECULAR_COLOR].mSemantic = Scene3D::Loader::MaterialDefinition::SPECULAR_COLOR;
105 mTextureInformations[BASE_COLOR].mShaderOptionType = Loader::ShaderOption::Type::BASE_COLOR_TEXTURE;
106 mTextureInformations[METALLIC_ROUGHNESS].mShaderOptionType = Loader::ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE;
107 mTextureInformations[NORMAL].mShaderOptionType = Loader::ShaderOption::Type::NORMAL_TEXTURE;
108 mTextureInformations[OCCLUSION].mShaderOptionType = Loader::ShaderOption::Type::OCCLUSION;
109 mTextureInformations[EMISSIVE].mShaderOptionType = Loader::ShaderOption::Type::EMISSIVE;
110 mTextureInformations[SPECULAR].mShaderOptionType = Loader::ShaderOption::Type::SPECULAR;
111 mTextureInformations[SPECULAR_COLOR].mShaderOptionType = Loader::ShaderOption::Type::SPECULAR_COLOR;
113 mTextureInformations[TextureIndex::EMISSIVE].mFactor = Vector4::ZERO;
116 Material::~Material() = default;
118 void Material::Initialize()
122 void Material::SetProperty(Dali::Property::Index index, Dali::Property::Value propertyValue)
124 bool needToApply = true;
127 case Dali::Scene3D::Material::Property::NAME:
130 if(propertyValue.Get(name))
137 case Dali::Scene3D::Material::Property::BASE_COLOR_URL:
139 std::string baseColorUrl;
140 if(propertyValue.Get(baseColorUrl))
142 RequestTextureLoad(mTextureInformations[TextureIndex::BASE_COLOR], baseColorUrl);
147 case Dali::Scene3D::Material::Property::BASE_COLOR_FACTOR:
149 Vector4 baseColorFactor;
150 if(propertyValue.Get(baseColorFactor))
152 mTextureInformations[TextureIndex::BASE_COLOR].mFactor = baseColorFactor;
153 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
157 case Dali::Scene3D::Material::Property::METALLIC_ROUGHNESS_URL:
159 std::string metallicRoughnessUrl;
160 if(propertyValue.Get(metallicRoughnessUrl))
162 RequestTextureLoad(mTextureInformations[TextureIndex::METALLIC_ROUGHNESS], metallicRoughnessUrl);
167 case Dali::Scene3D::Material::Property::METALLIC_FACTOR:
169 float metallicFactor;
170 if(propertyValue.Get(metallicFactor))
172 mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.x = metallicFactor;
173 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
177 case Dali::Scene3D::Material::Property::ROUGHNESS_FACTOR:
179 float roughnessFactor;
180 if(propertyValue.Get(roughnessFactor))
182 mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.y = roughnessFactor;
183 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
187 case Dali::Scene3D::Material::Property::NORMAL_URL:
189 std::string normalUrl;
190 if(propertyValue.Get(normalUrl))
192 RequestTextureLoad(mTextureInformations[TextureIndex::NORMAL], normalUrl);
197 case Dali::Scene3D::Material::Property::NORMAL_SCALE:
200 if(propertyValue.Get(normalScale))
202 mTextureInformations[TextureIndex::NORMAL].mFactor.x = normalScale;
203 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
207 case Dali::Scene3D::Material::Property::OCCLUSION_URL:
209 std::string occlusionUrl;
210 if(propertyValue.Get(occlusionUrl))
212 RequestTextureLoad(mTextureInformations[TextureIndex::OCCLUSION], occlusionUrl);
217 case Dali::Scene3D::Material::Property::OCCLUSION_STRENGTH:
219 float occlusionStrength;
220 if(propertyValue.Get(occlusionStrength))
222 mTextureInformations[TextureIndex::OCCLUSION].mFactor.x = occlusionStrength;
223 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
227 case Dali::Scene3D::Material::Property::EMISSIVE_URL:
229 std::string emissiveUrl;
230 if(propertyValue.Get(emissiveUrl))
232 RequestTextureLoad(mTextureInformations[TextureIndex::EMISSIVE], emissiveUrl);
237 case Dali::Scene3D::Material::Property::EMISSIVE_FACTOR:
239 Vector3 emissiveFactor;
240 if(propertyValue.Get(emissiveFactor))
242 mTextureInformations[TextureIndex::EMISSIVE].mFactor = emissiveFactor;
243 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
247 case Dali::Scene3D::Material::Property::ALPHA_MODE:
249 Dali::Scene3D::Material::AlphaModeType alphaMode;
250 if(propertyValue.Get(alphaMode))
252 mAlphaMode = alphaMode;
253 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
257 case Dali::Scene3D::Material::Property::ALPHA_CUTOFF:
260 if(propertyValue.Get(alphaCutoff))
262 mAlphaCutoff = alphaCutoff;
263 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
267 case Dali::Scene3D::Material::Property::DOUBLE_SIDED:
270 if(propertyValue.Get(doubleSided))
272 mDoubleSided = doubleSided;
273 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
277 case Dali::Scene3D::Material::Property::IOR:
280 if(propertyValue.Get(ior))
283 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
287 case Dali::Scene3D::Material::Property::SPECULAR_URL:
289 std::string specularUrl;
290 if(propertyValue.Get(specularUrl))
292 RequestTextureLoad(mTextureInformations[TextureIndex::SPECULAR], specularUrl);
297 case Dali::Scene3D::Material::Property::SPECULAR_FACTOR:
299 float specularFactor;
300 if(propertyValue.Get(specularFactor))
302 mTextureInformations[TextureIndex::SPECULAR].mFactor.x = specularFactor;
303 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
307 case Dali::Scene3D::Material::Property::SPECULAR_COLOR_URL:
309 std::string specularColorUrl;
310 if(propertyValue.Get(specularColorUrl))
312 RequestTextureLoad(mTextureInformations[TextureIndex::SPECULAR_COLOR], specularColorUrl);
317 case Dali::Scene3D::Material::Property::SPECULAR_COLOR_FACTOR:
319 Vector3 specularColorFactor;
320 if(propertyValue.Get(specularColorFactor))
322 mTextureInformations[TextureIndex::SPECULAR_COLOR].mFactor = specularColorFactor;
323 mModifyFlag |= MaterialModifyObserver::ModifyFlag::UNIFORM;
335 Dali::Property::Value Material::GetProperty(Dali::Property::Index index) const
337 Dali::Property::Value value;
340 case Dali::Scene3D::Material::Property::NAME:
345 case Dali::Scene3D::Material::Property::BASE_COLOR_URL:
347 value = mTextureInformations[TextureIndex::BASE_COLOR].mUrl;
350 case Dali::Scene3D::Material::Property::BASE_COLOR_FACTOR:
352 value = mTextureInformations[TextureIndex::BASE_COLOR].mFactor;
355 case Dali::Scene3D::Material::Property::METALLIC_ROUGHNESS_URL:
357 value = mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mUrl;
360 case Dali::Scene3D::Material::Property::METALLIC_FACTOR:
362 value = mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.x;
365 case Dali::Scene3D::Material::Property::ROUGHNESS_FACTOR:
367 value = mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.y;
370 case Dali::Scene3D::Material::Property::NORMAL_URL:
372 value = mTextureInformations[TextureIndex::NORMAL].mUrl;
375 case Dali::Scene3D::Material::Property::NORMAL_SCALE:
377 value = mTextureInformations[TextureIndex::NORMAL].mFactor.x;
380 case Dali::Scene3D::Material::Property::OCCLUSION_URL:
382 value = mTextureInformations[TextureIndex::OCCLUSION].mUrl;
385 case Dali::Scene3D::Material::Property::OCCLUSION_STRENGTH:
387 value = mTextureInformations[TextureIndex::OCCLUSION].mFactor.x;
390 case Dali::Scene3D::Material::Property::EMISSIVE_URL:
392 value = mTextureInformations[TextureIndex::EMISSIVE].mUrl;
395 case Dali::Scene3D::Material::Property::EMISSIVE_FACTOR:
397 value = Vector3(mTextureInformations[TextureIndex::EMISSIVE].mFactor);
400 case Dali::Scene3D::Material::Property::ALPHA_MODE:
405 case Dali::Scene3D::Material::Property::ALPHA_CUTOFF:
407 value = mAlphaCutoff;
410 case Dali::Scene3D::Material::Property::DOUBLE_SIDED:
412 value = mDoubleSided;
415 case Dali::Scene3D::Material::Property::IOR:
420 case Dali::Scene3D::Material::Property::SPECULAR_URL:
422 value = mTextureInformations[TextureIndex::SPECULAR].mUrl;
425 case Dali::Scene3D::Material::Property::SPECULAR_FACTOR:
427 value = mTextureInformations[TextureIndex::SPECULAR].mFactor.x;
430 case Dali::Scene3D::Material::Property::SPECULAR_COLOR_URL:
432 value = mTextureInformations[TextureIndex::SPECULAR_COLOR].mUrl;
435 case Dali::Scene3D::Material::Property::SPECULAR_COLOR_FACTOR:
437 value = Vector3(mTextureInformations[TextureIndex::SPECULAR_COLOR].mFactor);
444 void Material::SetTextureInformation(Scene3D::Material::TextureType index, TextureInformation&& textureInformation)
446 mTextureInformations[index].mFactor = textureInformation.mFactor;
447 mTextureInformations[index].mSampler = textureInformation.mSampler;
448 mTextureInformations[index].mTexture = textureInformation.mTexture;
449 mTextureInformations[index].mUrl = std::move(textureInformation.mUrl);
452 void Material::SetTexture(Scene3D::Material::TextureType index, Dali::Texture texture)
454 if(static_cast<uint32_t>(index) < static_cast<uint32_t>(TextureIndex::TEXTURE_TYPE_NUMBER))
456 if(mTextureInformations[index].mTexture != texture)
458 if(mTextureInformations[index].mLoadingTaskId != INVALID_INDEX)
460 mAsyncImageLoader.Cancel(mTextureInformations[index].mLoadingTaskId);
461 mTextureInformations[index].mLoadingTaskId = INVALID_INDEX;
463 mTextureInformations[index].mTexture = texture;
464 if(IsResourceReady())
466 ResourcesLoadComplete();
472 Dali::Texture Material::GetTexture(Scene3D::Material::TextureType index)
474 if(static_cast<uint32_t>(index) < static_cast<uint32_t>(TextureIndex::TEXTURE_TYPE_NUMBER))
476 return mTextureInformations[index].mTexture;
478 return Dali::Texture();
481 TextureSet Material::GetTextureSet()
483 TextureSet textures = TextureSet::New();
484 for(uint32_t i = 0, count = 0; i < TEXTURE_TYPE_NUMBER; ++i)
486 if(!mTextureInformations[i].mTexture)
490 textures.SetTexture(count, mTextureInformations[i].mTexture);
491 Sampler sampler = mTextureInformations[i].mSampler;
494 auto samplerFlag = Scene3D::Loader::SamplerFlags::FILTER_LINEAR | (Scene3D::Loader::SamplerFlags::FILTER_LINEAR << Scene3D::Loader::SamplerFlags::FILTER_MAG_SHIFT) |
495 (Scene3D::Loader::SamplerFlags::WRAP_REPEAT << Scene3D::Loader::SamplerFlags::WRAP_S_SHIFT) | (Scene3D::Loader::SamplerFlags::WRAP_REPEAT << Scene3D::Loader::SamplerFlags::WRAP_T_SHIFT);
496 sampler = Scene3D::Loader::SamplerFlags::MakeSampler(samplerFlag);
498 textures.SetSampler(count, sampler);
504 void Material::SetSampler(Scene3D::Material::TextureType index, Dali::Sampler sampler)
506 if(static_cast<uint32_t>(index) < static_cast<uint32_t>(TextureIndex::TEXTURE_TYPE_NUMBER))
508 mTextureInformations[index].mSampler = sampler;
512 Dali::Sampler Material::GetSampler(Scene3D::Material::TextureType index)
514 if(static_cast<uint32_t>(index) < static_cast<uint32_t>(TextureIndex::TEXTURE_TYPE_NUMBER))
516 return mTextureInformations[index].mSampler;
518 return Dali::Sampler();
521 Scene3D::Loader::ShaderOption Material::GetShaderOption() const
523 return mShaderOption;
526 void Material::Apply()
528 if(IsResourceReady())
530 UpdateMaterialData();
534 // The cases this material is applied to primitive are,
535 // 1. material is added on Primitive.
536 // When material is added on Primitive (1 case)
537 // 1-1. when IsResourceReady() returns true,
538 // Primitive can takes information from Material
540 // Material will noti to primitives when all resources are ready.
541 // 2. Some properties are changed
542 // 2-1. when IsResourceReady() returns true,
543 // Call NotifyObserver directly.
545 // Material will noti to primitives when all resources are ready.
548 void Material::AddObserver(MaterialModifyObserver* observer)
550 for(auto& observerEntity : mObservers)
552 if(observerEntity.first == observer)
554 observerEntity.second = true;
558 mObservers.push_back({observer, true});
561 void Material::RemoveObserver(MaterialModifyObserver* observer)
563 // Block during notifying to observer
564 if(mObserverNotifying)
566 for(uint32_t i = 0; i < mObservers.size(); ++i)
568 if(mObservers[i].first == observer)
570 mObservers[i].second = false;
577 for(uint32_t i = 0; i < mObservers.size(); ++i)
579 if(mObservers[i].first == observer)
581 mObservers.erase(mObservers.begin() + i);
588 void Material::UpdateMaterialData()
590 uint32_t materialFlag = 0u;
591 if(mAlphaMode == Dali::Scene3D::Material::AlphaModeType::BLEND)
595 materialFlag |= Scene3D::Loader::MaterialDefinition::TRANSPARENCY;
597 else if(mAlphaMode == Dali::Scene3D::Material::AlphaModeType::MASK)
602 const bool hasTransparency = MaskMatch(materialFlag, Scene3D::Loader::MaterialDefinition::TRANSPARENCY);
604 for(auto&& textureInformation : mTextureInformations)
606 if(!textureInformation.mTexture)
610 materialFlag |= textureInformation.mSemantic;
613 if(mMaterialFlag != materialFlag)
615 mModifyFlag |= MaterialModifyObserver::ModifyFlag::SHADER;
617 mMaterialFlag = materialFlag;
619 mShaderOption = Loader::ShaderOption();
620 for(auto&& textureInformation : mTextureInformations)
622 if(!textureInformation.mTexture)
626 mShaderOption.AddOption(textureInformation.mShaderOptionType);
628 mShaderOption.AddOption(Loader::ShaderOption::Type::THREE_TEXTURE);
629 mShaderOption.AddOption(Loader::ShaderOption::Type::GLTF_CHANNELS);
630 if(materialFlag & Scene3D::Loader::MaterialDefinition::TRANSPARENCY)
632 mShaderOption.SetTransparency();
636 // Finish to make all the material flag according to the gltf2-util.
637 // Then make defines as fallowing shader-manager.
639 // The renderer State below can be used in primitive to set renderer properties.
641 // for renderer setting
642 mRendererState = Scene3D::Loader::RendererState::DEPTH_TEST;
645 mRendererState |= Scene3D::Loader::RendererState::CULL_BACK;
650 mRendererState = (mRendererState | Scene3D::Loader::RendererState::ALPHA_BLEND);
654 bool Material::IsResourceReady()
656 for(auto&& textureInformation : mTextureInformations)
658 if(!textureInformation.IsReady())
666 void Material::SetRendererUniform(Dali::Renderer renderer)
668 renderer.RegisterProperty("uColorFactor", mTextureInformations[TextureIndex::BASE_COLOR].mFactor);
669 renderer.RegisterProperty("uMetallicFactor", mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.x);
670 renderer.RegisterProperty("uRoughnessFactor", mTextureInformations[TextureIndex::METALLIC_ROUGHNESS].mFactor.y);
671 renderer.RegisterProperty("uNormalScale", mTextureInformations[TextureIndex::NORMAL].mFactor.x);
672 if(mTextureInformations[TextureIndex::OCCLUSION].mTexture)
674 renderer.RegisterProperty("uOcclusionStrength", mTextureInformations[TextureIndex::OCCLUSION].mFactor.x);
676 renderer.RegisterProperty("uEmissiveFactor", Vector3(mTextureInformations[TextureIndex::EMISSIVE].mFactor));
677 float dielectricSpecular = (Dali::Equals(mIor, -1.0)) ? 0.04f : powf((mIor - 1.0f) / (mIor + 1.0f), 2.0f);
678 renderer.RegisterProperty("uDielectricSpecular", dielectricSpecular);
679 renderer.RegisterProperty("uSpecularFactor", mTextureInformations[TextureIndex::SPECULAR].mFactor.x);
680 renderer.RegisterProperty("uSpecularColorFactor", Vector3(mTextureInformations[TextureIndex::SPECULAR_COLOR].mFactor));
682 float opaque = mIsOpaque ? 1.0f : 0.0f;
683 float mask = mIsMask ? 1.0f : 0.0f;
684 renderer.RegisterProperty("uOpaque", opaque);
685 renderer.RegisterProperty("uMask", mask);
686 renderer.RegisterProperty("uAlphaThreshold", mAlphaCutoff);
688 renderer.RegisterProperty("uCubeMatrix", Matrix::IDENTITY);
690 renderer.RegisterProperty(Scene3D::Loader::NodeDefinition::GetIblMaxLodUniformName().data(), 6.f);
691 renderer.RegisterProperty(Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), 1.0f);
692 renderer.RegisterProperty(Scene3D::Loader::NodeDefinition::GetIblYDirectionUniformName().data(), Vector3(1.0f, -1.0, 1.0));
694 Scene3D::Loader::RendererState::Apply(mRendererState, renderer);
697 uint32_t Material::GetShadowMapTextureOffset()
699 return OFFSET_FOR_SHADOW_MAP_TEXTURE;
702 uint32_t Material::GetSpecularImageBasedLightTextureOffset()
704 return OFFSET_FOR_SPECULAR_CUBE_TEXTURE;
707 uint32_t Material::GetDiffuseImageBasedLightTextureOffset()
709 return OFFSET_FOR_DIFFUSE_CUBE_TEXTURE;
712 std::string_view Material::GetImageBasedLightScaleFactorName()
714 return Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName();
717 std::string_view Material::GetImageBasedLightMaxLodUniformName()
719 return Dali::Scene3D::Loader::NodeDefinition::GetIblMaxLodUniformName();
722 void Material::ResetFlag()
724 mModifyFlag = MaterialModifyObserver::ModifyFlag::NONE;
727 void Material::NotifyObserver()
729 if(mModifyFlag != MaterialModifyObserver::ModifyFlag::NONE && IsResourceReady())
731 if(mObserverNotifying)
733 DALI_LOG_ERROR("Notify during observing is not allowed.");
737 Dali::Scene3D::Material handle(this); // Keep itself's life during notify
739 // Copy the flag due to the flag can be changed during observe.
740 MaterialModifyObserver::ModifyFlag copiedFlag = mModifyFlag;
741 mModifyFlag = MaterialModifyObserver::ModifyFlag::NONE;
743 // Need to block mObserver container change during observe
744 mObserverNotifying = true;
745 for(uint32_t i = 0; i < mObservers.size(); ++i)
747 if(mObservers[i].second)
749 mObservers[i].first->OnMaterialModified(handle, copiedFlag);
752 mObserverNotifying = false;
754 // Resolve observer queue during notify
755 mObservers.erase(std::remove_if(mObservers.begin(), mObservers.end(), [](auto& e)
756 { return !e.second; }),
761 void Material::RequestTextureLoad(TextureInformation& textureInformation, const std::string& url)
763 if(textureInformation.mUrl == url)
768 textureInformation.mUrl = url;
769 if(textureInformation.mLoadingTaskId != INVALID_INDEX)
771 mAsyncImageLoader.Cancel(textureInformation.mLoadingTaskId);
772 textureInformation.mLoadingTaskId = INVALID_INDEX;
777 textureInformation.mTexture.Reset();
780 textureInformation.mLoadingTaskId = mAsyncImageLoader.Load(url);
783 void Material::TextureLoadComplete(uint32_t loadedTaskId, PixelData pixelData)
785 for(auto&& textureInformation : mTextureInformations)
787 if(textureInformation.mLoadingTaskId != loadedTaskId)
794 textureInformation.mTexture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight());
795 textureInformation.mTexture.Upload(pixelData);
797 textureInformation.mLoadingTaskId = INVALID_INDEX;
801 if(IsResourceReady())
803 ResourcesLoadComplete();
807 void Material::ResourcesLoadComplete()
809 mModifyFlag |= MaterialModifyObserver::ModifyFlag::TEXTURE;
813 } // namespace Internal
815 } // namespace Scene3D