From 4e0cc5969cece69de5948be184a3af174ee1e567 Mon Sep 17 00:00:00 2001 From: seungho baek Date: Mon, 19 Jun 2023 22:43:00 +0900 Subject: [PATCH] Makes Models use common shader manager - In Scene3D, the responsibility for modifying the shader code or setting the shader's uniform variables was scattered across many classes. - When a uniform variable is added or the name of a uniform variable is changed in the shader code, there was a problem of repeating the same modification in multiple codes. - In this patch, one class is responsible for creating or managing Shader code, and the class name is changed to ShaderManager. - And by using one ShaderManager per SceneView, it is easy to manage properties that should be applied in common within SceneView. - Although there is no difference in use in terms of Model/SceneView API, it is helpful for code management, and performance can be improved when many Renderers share a small number of Shaders. Change-Id: I0975921a1a7e40c453156cf9bd0b1890fc8e6526 Signed-off-by: seungho baek --- .../utc-Dali-GlbLoaderImpl.cpp | 10 +- .../utc-Dali-Gltf2LoaderImpl.cpp | 26 +- .../utc-Dali-MaterialImpl.cpp | 38 +-- automated-tests/src/dali-scene3d/CMakeLists.txt | 4 +- .../utc-Dali-ShaderDefinitionFactory.cpp | 345 --------------------- .../utc-Dali-ShaderDefinitionOption.cpp | 134 -------- .../src/dali-scene3d/utc-Dali-ShaderManager.cpp | 285 +++++++++++++++++ .../src/dali-scene3d/utc-Dali-ShaderOption.cpp | 134 ++++++++ dali-scene3d/dali-scene3d.h | 2 +- .../internal/controls/model/model-impl.cpp | 88 ++++-- dali-scene3d/internal/controls/model/model-impl.h | 2 + .../controls/scene-view/scene-view-impl.cpp | 20 +- .../internal/controls/scene-view/scene-view-impl.h | 12 +- dali-scene3d/internal/loader/gltf2-util.cpp | 27 +- dali-scene3d/internal/loader/gltf2-util.h | 7 +- .../internal/model-components/material-impl.cpp | 50 ++- .../internal/model-components/material-impl.h | 80 +++-- .../internal/model-components/model-node-impl.cpp | 16 + .../internal/model-components/model-node-impl.h | 35 ++- .../model-components/model-primitive-impl.cpp | 67 ++-- .../model-components/model-primitive-impl.h | 22 +- dali-scene3d/public-api/file.list | 4 +- dali-scene3d/public-api/loader/node-definition.cpp | 22 +- dali-scene3d/public-api/loader/node-definition.h | 6 +- .../public-api/loader/scene-definition.cpp | 86 +++-- .../loader/shader-definition-factory.cpp | 259 ---------------- .../public-api/loader/shader-definition-factory.h | 60 ---- dali-scene3d/public-api/loader/shader-definition.h | 2 +- dali-scene3d/public-api/loader/shader-manager.cpp | 223 +++++++++++++ dali-scene3d/public-api/loader/shader-manager.h | 83 +++++ ...der-definition-option.cpp => shader-option.cpp} | 16 +- ...{shader-definition-option.h => shader-option.h} | 16 +- 32 files changed, 1105 insertions(+), 1076 deletions(-) delete mode 100644 automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionFactory.cpp delete mode 100644 automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionOption.cpp create mode 100644 automated-tests/src/dali-scene3d/utc-Dali-ShaderManager.cpp create mode 100644 automated-tests/src/dali-scene3d/utc-Dali-ShaderOption.cpp delete mode 100644 dali-scene3d/public-api/loader/shader-definition-factory.cpp delete mode 100644 dali-scene3d/public-api/loader/shader-definition-factory.h create mode 100644 dali-scene3d/public-api/loader/shader-manager.cpp create mode 100644 dali-scene3d/public-api/loader/shader-manager.h rename dali-scene3d/public-api/loader/{shader-definition-option.cpp => shader-option.cpp} (73%) rename dali-scene3d/public-api/loader/{shader-definition-option.h => shader-option.h} (80%) diff --git a/automated-tests/src/dali-scene3d-internal/utc-Dali-GlbLoaderImpl.cpp b/automated-tests/src/dali-scene3d-internal/utc-Dali-GlbLoaderImpl.cpp index f3d8a93..14f5864 100644 --- a/automated-tests/src/dali-scene3d-internal/utc-Dali-GlbLoaderImpl.cpp +++ b/automated-tests/src/dali-scene3d-internal/utc-Dali-GlbLoaderImpl.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -123,10 +123,6 @@ int UtcDaliGlbLoaderFailedToLoad(void) int UtcDaliGlbLoaderFailedToParse(void) { Context ctx; - - ShaderDefinitionFactory sdf; - sdf.SetResources(ctx.resources); - DALI_TEST_EQUAL(ctx.loader.LoadModel(TEST_RESOURCE_DIR "/invalid.glb", ctx.loadResult), false); DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size()); @@ -135,7 +131,6 @@ int UtcDaliGlbLoaderFailedToParse(void) DALI_TEST_EQUAL(0, ctx.resources.mEnvironmentMaps.size()); DALI_TEST_EQUAL(0, ctx.resources.mMaterials.size()); DALI_TEST_EQUAL(0, ctx.resources.mMeshes.size()); - DALI_TEST_EQUAL(0, ctx.resources.mShaders.size()); DALI_TEST_EQUAL(0, ctx.resources.mSkeletons.size()); DALI_TEST_EQUAL(0, ctx.cameras.size()); @@ -149,9 +144,6 @@ int UtcDaliGlbLoaderFailedToParse(void) int UtcDaliGlbLoaderSuccess1(void) { Context ctx; - ShaderDefinitionFactory sdf; - sdf.SetResources(ctx.resources); - ctx.loader.LoadModel(TEST_RESOURCE_DIR "/BoxAnimated.glb", ctx.loadResult); DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size()); diff --git a/automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp b/automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp index 1f274d0..adf95eb 100644 --- a/automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp +++ b/automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -125,9 +125,6 @@ int UtcDaliGltfLoaderFailedToParse(void) { Context ctx; - ShaderDefinitionFactory sdf; - sdf.SetResources(ctx.resources); - DALI_TEST_EQUAL(ctx.loader.LoadModel(TEST_RESOURCE_DIR "/invalid.gltf", ctx.loadResult), false); DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size()); @@ -136,7 +133,6 @@ int UtcDaliGltfLoaderFailedToParse(void) DALI_TEST_EQUAL(0, ctx.resources.mEnvironmentMaps.size()); DALI_TEST_EQUAL(0, ctx.resources.mMaterials.size()); DALI_TEST_EQUAL(0, ctx.resources.mMeshes.size()); - DALI_TEST_EQUAL(0, ctx.resources.mShaders.size()); DALI_TEST_EQUAL(0, ctx.resources.mSkeletons.size()); DALI_TEST_EQUAL(0, ctx.cameras.size()); @@ -193,7 +189,7 @@ int UtcDaliGltfLoaderSuccess1(void) nullptr, MaterialDefinition::ALBEDO | MaterialDefinition::EMISSIVE | MaterialDefinition::OCCLUSION | MaterialDefinition::NORMAL | MaterialDefinition::SPECULAR | MaterialDefinition::SPECULAR_COLOR | - (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT), + MaterialDefinition::GLTF_CHANNELS | (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT), 0, Color::WHITE, 1.f, @@ -306,7 +302,7 @@ int UtcDaliGltfLoaderSuccess1(void) }, }, { - MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | MaterialDefinition::GLTF_CHANNELS, + MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS, { "AnimatedCube_MetallicRoughness.png", SamplerFlags::Encode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::MIRRORED_REPEAT), @@ -448,7 +444,6 @@ int UtcDaliGltfLoaderSuccess1(void) ++iMesh; } - DALI_TEST_EQUAL(2u, ctx.resources.mShaders.size()); DALI_TEST_EQUAL(0u, ctx.resources.mSkeletons.size()); DALI_TEST_EQUAL(6u, ctx.cameras.size()); @@ -462,8 +457,6 @@ int UtcDaliGltfLoaderSuccess1(void) int UtcDaliGltfLoaderSuccess2(void) { Context ctx; - ShaderDefinitionFactory sdf; - sdf.SetResources(ctx.resources); ctx.loader.LoadModel(TEST_RESOURCE_DIR "/AnimatedCubeStride.gltf", ctx.loadResult); @@ -577,9 +570,6 @@ int UtcDaliGltfLoaderSuccessShort(void) int UtcDaliGltfLoaderMRendererTest(void) { Context ctx; - - ShaderDefinitionFactory sdf; - sdf.SetResources(ctx.resources); auto& resources = ctx.resources; ctx.loader.LoadModel(TEST_RESOURCE_DIR "/MRendererTest.gltf", ctx.loadResult); @@ -592,6 +582,7 @@ int UtcDaliGltfLoaderMRendererTest(void) DALI_TEST_EQUAL(scene.GetNodeCount(), 1u); + Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager(); ViewProjection viewProjection; Transforms xforms{ MatrixStack{}, @@ -599,6 +590,7 @@ int UtcDaliGltfLoaderMRendererTest(void) NodeDefinition::CreateParams nodeParams{ resources, xforms, + shaderManager, }; Customization::Choices choices; @@ -649,6 +641,7 @@ int UtcDaliGltfLoaderAnimationLoadingTest(void) auto& roots = scene.GetRoots(); DALI_TEST_EQUAL(roots.size(), 1u); + Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager(); ViewProjection viewProjection; Transforms xforms{ MatrixStack{}, @@ -656,6 +649,7 @@ int UtcDaliGltfLoaderAnimationLoadingTest(void) NodeDefinition::CreateParams nodeParams{ resources, xforms, + shaderManager, }; Customization::Choices choices; @@ -690,8 +684,6 @@ int UtcDaliGltfLoaderImageFromBufferView(void) { Context ctx; - ShaderDefinitionFactory sdf; - sdf.SetResources(ctx.resources); auto& resources = ctx.resources; ctx.loader.LoadModel(TEST_RESOURCE_DIR "/EnvironmentTest_b.gltf", ctx.loadResult); @@ -700,6 +692,7 @@ int UtcDaliGltfLoaderImageFromBufferView(void) auto& roots = scene.GetRoots(); DALI_TEST_EQUAL(roots.size(), 1u); + Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager(); ViewProjection viewProjection; Transforms xforms{ MatrixStack{}, @@ -707,6 +700,7 @@ int UtcDaliGltfLoaderImageFromBufferView(void) NodeDefinition::CreateParams nodeParams{ resources, xforms, + shaderManager, }; Customization::Choices choices; @@ -749,6 +743,7 @@ int UtcDaliGltfLoaderUint8Indices(void) auto& roots = scene.GetRoots(); DALI_TEST_EQUAL(roots.size(), 1u); + Scene3D::Loader::ShaderManagerPtr shaderManager = new Scene3D::Loader::ShaderManager(); ViewProjection viewProjection; Transforms xforms{ MatrixStack{}, @@ -756,6 +751,7 @@ int UtcDaliGltfLoaderUint8Indices(void) NodeDefinition::CreateParams nodeParams{ resources, xforms, + shaderManager, }; Customization::Choices choices; diff --git a/automated-tests/src/dali-scene3d-internal/utc-Dali-MaterialImpl.cpp b/automated-tests/src/dali-scene3d-internal/utc-Dali-MaterialImpl.cpp index 34a82b2..e3bc2d2 100644 --- a/automated-tests/src/dali-scene3d-internal/utc-Dali-MaterialImpl.cpp +++ b/automated-tests/src/dali-scene3d-internal/utc-Dali-MaterialImpl.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include using namespace Dali; using namespace Dali::Toolkit; @@ -96,20 +96,14 @@ int UtcDaliMaterialImplSetGetTextureInformation(void) DALI_TEST_EQUALS(true, GetImplementation(material).IsResourceReady(), TEST_LOCATION); GetImplementation(material).UpdateMaterialData(); - std::vector defines; - defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::THREE_TEXTURE).data()); - defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::GLTF_CHANNELS).data()); - defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::BASE_COLOR_TEXTURE).data()); - defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::METALLIC_ROUGHNESS_TEXTURE).data()); - defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::NORMAL_TEXTURE).data()); + Scene3D::Loader::ShaderOption option; + option.AddOption(Scene3D::Loader::ShaderOption::Type::THREE_TEXTURE); + option.AddOption(Scene3D::Loader::ShaderOption::Type::GLTF_CHANNELS); + option.AddOption(Scene3D::Loader::ShaderOption::Type::BASE_COLOR_TEXTURE); + option.AddOption(Scene3D::Loader::ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE); + option.AddOption(Scene3D::Loader::ShaderOption::Type::NORMAL_TEXTURE); - std::string fragmentShader = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_FRAG.data(); - for(const auto& define : defines) - { - Scene3D::Loader::ShaderDefinition::ApplyDefine(fragmentShader, define); - } - - DALI_TEST_EQUALS(fragmentShader, GetImplementation(material).GetFragmentShader(), TEST_LOCATION); + DALI_TEST_EQUALS(option.GetOptionHash(), GetImplementation(material).GetShaderOption().GetOptionHash(), TEST_LOCATION); Scene3D ::Internal ::Material ::TextureInformation occlusion; Dali ::Texture occlusiontexture = Dali ::Texture ::New(TextureType ::TEXTURE_2D, Pixel ::RGBA8888, 100, 100); @@ -176,18 +170,12 @@ int UtcDaliMaterialImplSetGetTextureInformation(void) DALI_TEST_EQUALS(true, GetImplementation(material).IsResourceReady(), TEST_LOCATION); GetImplementation(material).UpdateMaterialData(); - defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::OCCLUSION).data()); - defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::EMISSIVE).data()); - defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR).data()); - defines.push_back(Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR_COLOR).data()); - - fragmentShader = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_FRAG.data(); - for(const auto& define : defines) - { - Scene3D::Loader::ShaderDefinition::ApplyDefine(fragmentShader, define); - } + option.AddOption(Scene3D::Loader::ShaderOption::Type::OCCLUSION); + option.AddOption(Scene3D::Loader::ShaderOption::Type::EMISSIVE); + option.AddOption(Scene3D::Loader::ShaderOption::Type::SPECULAR); + option.AddOption(Scene3D::Loader::ShaderOption::Type::SPECULAR_COLOR); - DALI_TEST_EQUALS(fragmentShader, GetImplementation(material).GetFragmentShader(), TEST_LOCATION); + DALI_TEST_EQUALS(option.GetOptionHash(), GetImplementation(material).GetShaderOption().GetOptionHash(), TEST_LOCATION); END_TEST; } diff --git a/automated-tests/src/dali-scene3d/CMakeLists.txt b/automated-tests/src/dali-scene3d/CMakeLists.txt index 1eed33c..1cb9f3c 100755 --- a/automated-tests/src/dali-scene3d/CMakeLists.txt +++ b/automated-tests/src/dali-scene3d/CMakeLists.txt @@ -36,8 +36,8 @@ SET(TC_SOURCES utc-Dali-ResourceBundle.cpp utc-Dali-SceneDefinition.cpp utc-Dali-ShaderDefinition.cpp - utc-Dali-ShaderDefinitionFactory.cpp - utc-Dali-ShaderDefinitionOption.cpp + utc-Dali-ShaderManager.cpp + utc-Dali-ShaderOption.cpp utc-Dali-StringCallback.cpp utc-Dali-Utils.cpp utc-Dali-ViewProjection.cpp diff --git a/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionFactory.cpp b/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionFactory.cpp deleted file mode 100644 index 0a269a5..0000000 --- a/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionFactory.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// Enable debug log for test coverage -#define DEBUG_ENABLED 1 - -// Disable this UTC until shader definition factory refactorize -#define ENABLE_SHADER_DEFINITION_FACTORY_UTC 0 - -#include -#include -#include -#include "dali-scene3d/public-api/loader/node-definition.h" -#include "dali-scene3d/public-api/loader/resource-bundle.h" -#include "dali-scene3d/public-api/loader/shader-definition-factory.h" - -using namespace Dali; -using namespace Dali::Scene3D::Loader; - -namespace -{ -#if ENABLE_SHADER_DEFINITION_FACTORY_UTC -MaterialDefinition& NewMaterialDefinition(ResourceBundle& resources) -{ - resources.mMaterials.push_back({}); - return resources.mMaterials.back().first; -} - -MeshDefinition& NewMeshDefinition(ResourceBundle& resources) -{ - resources.mMeshes.push_back({}); - return resources.mMeshes.back().first; -} - -void ClearMeshesAndMaterials(ResourceBundle& resources) -{ - resources.mMaterials.clear(); - resources.mMeshes.clear(); -} -#endif - -struct Context -{ - ResourceBundle resources; - ShaderDefinitionFactory factory; - - Context() - { - factory.SetResources(resources); - } -}; - -#if ENABLE_SHADER_DEFINITION_FACTORY_UTC -struct ShaderParameters -{ - MeshDefinition& meshDef; - MaterialDefinition& materialDef; - NodeDefinition& nodeDef; -}; - -struct Permutation -{ - using ConfigureFn = void (*)(ShaderParameters&); - - ConfigureFn configureFn; - - std::set defines; - RendererState::Type rendererStateSet = 0; - RendererState::Type rendererStateClear = 0; -}; - -struct PermutationSet -{ - std::vector permutations; - Index shaderIdx; -}; -#endif - -} // namespace - -int UtcDaliShaderDefinitionFactoryProduceShaderInvalid(void) -{ - Context ctx; - - NodeDefinition nodeDef; - std::unique_ptr renderable = std::unique_ptr(new NodeDefinition::Renderable()); - nodeDef.mRenderables.push_back(std::move(renderable)); - - DALI_TEST_CHECK(ctx.resources.mShaders.empty()); - - END_TEST; -} - -int UtcDaliShaderDefinitionFactoryProduceShader(void) -{ -#if ENABLE_SHADER_DEFINITION_FACTORY_UTC - Context ctx; - ctx.resources.mMaterials.push_back({}); - ctx.resources.mMeshes.push_back({}); - - Permutation permutations[]{ - { - [](ShaderParameters& p) {}, - {}, - RendererState::DEPTH_TEST | RendererState::DEPTH_WRITE | RendererState::CULL_BACK, - }, - { - [](ShaderParameters& p) { - p.materialDef.mFlags |= MaterialDefinition::TRANSPARENCY; - }, - {"THREE_TEX"}, - RendererState::ALPHA_BLEND, - RendererState::DEPTH_WRITE, - }, - {[](ShaderParameters& p) { - p.materialDef.mFlags |= MaterialDefinition::ALBEDO; - p.materialDef.mTextureStages.push_back({MaterialDefinition::ALBEDO, {}}); - }, - {"THREE_TEX", "BASECOLOR_TEX"}}, - {[](ShaderParameters& p) { - p.materialDef.mTextureStages.push_back({MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS, {}}); - }, - {"THREE_TEX", "METALLIC_ROUGHNESS_TEX"}}, - {[](ShaderParameters& p) { - p.materialDef.mFlags |= MaterialDefinition::NORMAL; - p.materialDef.mTextureStages.push_back({MaterialDefinition::NORMAL, {}}); - }, - {"THREE_TEX", "NORMAL_TEX"}}, - {[](ShaderParameters& p) { - p.materialDef.mFlags |= MaterialDefinition::SUBSURFACE; - }, - {"SSS"}}, - {[](ShaderParameters& p) { - p.materialDef.SetAlphaCutoff(.5f); - }, - {"ALPHA_TEST"}}, - {[](ShaderParameters& p) { - p.materialDef.SetAlphaCutoff(1.f); - }, - {"ALPHA_TEST"}}, - {[](ShaderParameters& p) { - p.materialDef.mFlags |= MaterialDefinition::GLTF_CHANNELS; - }, - {"GLTF_CHANNELS"}}, - {[](ShaderParameters& p) { - p.meshDef.mJoints0.mBlob.mOffset = 0; - p.meshDef.mWeights0.mBlob.mOffset = 0; - }, - {"SKINNING"}}, - {[](ShaderParameters& p) { - p.meshDef.mFlags |= MeshDefinition::FLIP_UVS_VERTICAL; - }, - {"FLIP_V"}}, - { - [](ShaderParameters& p) { - p.meshDef.mBlendShapes.push_back({}); - }, - }, - {[](ShaderParameters& p) { - p.meshDef.mBlendShapes.back().deltas.mBlob.mOffset = 0; - }, - {"MORPH_POSITION", "MORPH"}}, - {[](ShaderParameters& p) { - p.meshDef.mBlendShapes.back().normals.mBlob.mOffset = 0; - }, - {"MORPH_NORMAL", "MORPH"}}, - {[](ShaderParameters& p) { - p.meshDef.mBlendShapes.back().tangents.mBlob.mOffset = 0; - }, - {"MORPH_TANGENT", "MORPH"}}, - {[](ShaderParameters& p) { - auto& blendShapes = p.meshDef.mBlendShapes; - DALI_ASSERT_ALWAYS(!blendShapes.empty() && - (blendShapes.back().deltas.mBlob.mOffset != MeshDefinition::INVALID || - blendShapes.back().normals.mBlob.mOffset != MeshDefinition::INVALID || - blendShapes.back().tangents.mBlob.mOffset != MeshDefinition::INVALID)); - p.meshDef.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0; - }, - {"MORPH_VERSION_2_0"}}, - - {[](ShaderParameters& p) { - p.materialDef.mFlags |= MaterialDefinition::OCCLUSION; - }, - - {"OCCLUSION"}}, - - {[](ShaderParameters& p) { - p.meshDef.mColors.mBlob.mOffset = 0; - }, - {"COLOR_ATTRIBUTE"}}, - {[](ShaderParameters& p) { - p.meshDef.mTangentType = Property::VECTOR4; - }, - {"VEC4_TANGENT"}}, - }; - - PermutationSet permSets[]{ - // default - {{&permutations[0]}, 0}, - - // alpha - {{&permutations[0], &permutations[1]}, 1}, - - // three-texture setups - {{&permutations[0], &permutations[2]}, 2}, - {{&permutations[0], &permutations[3]}, 2}, - {{&permutations[0], &permutations[4]}, 2}, - {{&permutations[0], &permutations[2], &permutations[3]}, 2}, - {{&permutations[0], &permutations[3], &permutations[4]}, 2}, - {{&permutations[0], &permutations[4], &permutations[2]}, 2}, - {{&permutations[0], &permutations[2], &permutations[3], &permutations[4]}, 2}, - - // subsurface scattering - {{&permutations[0], &permutations[5]}, 3}, - - // alpha test - {{&permutations[0], &permutations[6]}, 4}, - {{&permutations[0], &permutations[7]}, 4}, - - // glTF channels - {{&permutations[0], &permutations[8]}, 5}, - - // skinning - {{&permutations[0], &permutations[9]}, 6}, - - // flip uvs - {{&permutations[0], &permutations[10]}, 7}, - - // morphing - {{&permutations[0], &permutations[11], &permutations[12]}, 8}, - {{&permutations[0], &permutations[11], &permutations[13]}, 9}, - {{&permutations[0], &permutations[11], &permutations[14]}, 10}, - {{&permutations[0], &permutations[11], &permutations[12], &permutations[13]}, 11}, - {{&permutations[0], &permutations[11], &permutations[13], &permutations[14]}, 12}, - {{&permutations[0], &permutations[11], &permutations[14], &permutations[12]}, 13}, - {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14]}, 14}, - - {{&permutations[0], &permutations[11], &permutations[12], &permutations[15]}, 15}, - {{&permutations[0], &permutations[11], &permutations[13], &permutations[15]}, 16}, - {{&permutations[0], &permutations[11], &permutations[14], &permutations[15]}, 17}, - {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[15]}, 18}, - {{&permutations[0], &permutations[11], &permutations[13], &permutations[14], &permutations[15]}, 19}, - {{&permutations[0], &permutations[11], &permutations[14], &permutations[12], &permutations[15]}, 20}, - {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14], &permutations[15]}, 21}, - - // etc. - {{&permutations[0], &permutations[1], &permutations[2]}, 1}, - {{&permutations[0], &permutations[1], &permutations[3]}, 1}, - {{&permutations[0], &permutations[1], &permutations[2], &permutations[3]}, 1}, - - // occlusion - {{&permutations[0], &permutations[16]}, 22}, - }; - - for(auto& ps : permSets) - { - static int tc = 0; - tet_printf("Test %d's tc\n", ++tc); - auto modelRenderable = new ModelRenderable(); - modelRenderable->mMeshIdx = 0; - modelRenderable->mMaterialIdx = 0; - - NodeDefinition nodeDef; - std::unique_ptr renderable; - renderable.reset(modelRenderable); - nodeDef.mRenderables.push_back(std::move(renderable)); - - auto& meshDef = NewMeshDefinition(ctx.resources); - auto& materialDef = NewMaterialDefinition(ctx.resources); - ShaderParameters sp{meshDef, materialDef, nodeDef}; - - std::set defines; - RendererState::Type rendererState = 0; - for(auto p : ps.permutations) - { - p->configureFn(sp); - defines.insert(p->defines.begin(), p->defines.end()); - rendererState = (rendererState | p->rendererStateSet) & ~p->rendererStateClear; - } - - for(auto& renderable : nodeDef.mRenderables) - { - auto shaderIdx = ctx.factory.ProduceShader(*renderable); - DALI_TEST_EQUAL(ps.shaderIdx, shaderIdx); - - auto& shaderDef = ctx.resources.mShaders[shaderIdx].first; - DALI_TEST_EQUAL(shaderDef.mRendererState, rendererState); - - uint32_t definesUnmatched = shaderDef.mDefines.size(); - for(auto& define : shaderDef.mDefines) - { - auto iFind = defines.find(define); - if(iFind != defines.end()) - { - defines.erase(iFind); - --definesUnmatched; - } - else - { - break; - } - } - if(!defines.empty()) - { - std::ostringstream oss; - oss << "Need to check below defines :\n"; - for(auto& it : defines) - { - oss << it << "\n"; - } - tet_printf("%s\n", oss.str().c_str()); - } - - DALI_TEST_CHECK(defines.empty()); - DALI_TEST_EQUAL(0, definesUnmatched); - - auto uMaxLOD = shaderDef.mUniforms["uMaxLOD"]; - DALI_TEST_EQUAL(uMaxLOD.GetType(), Property::FLOAT); - - auto uCubeMatrix = shaderDef.mUniforms["uCubeMatrix"]; - DALI_TEST_EQUAL(uCubeMatrix.GetType(), Property::MATRIX); - } - - ClearMeshesAndMaterials(ctx.resources); - } -#else - DALI_TEST_CHECK(true); -#endif - - END_TEST; -} \ No newline at end of file diff --git a/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionOption.cpp b/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionOption.cpp deleted file mode 100644 index 0f320a8..0000000 --- a/automated-tests/src/dali-scene3d/utc-Dali-ShaderDefinitionOption.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include -#include "dali-scene3d/public-api/loader/shader-definition-option.h" - -using namespace Dali; -using namespace Dali::Toolkit; - -void shader_definition_option_startup(void) -{ - test_return_value = TET_UNDEF; -} - -void shader_definition_option_cleanup(void) -{ - test_return_value = TET_PASS; -} - -int UtcDaliShaderDefinitionOptionInit(void) -{ - Scene3D::Loader::ShaderDefinitionOption option; - DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION); - END_TEST; -} - -int UtcDaliShaderDefinitionOptionSetTransparency(void) -{ - Scene3D::Loader::ShaderDefinitionOption option; - DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION); - - option.SetTransparency(); - DALI_TEST_NOT_EQUALS(option.GetOptionHash(), static_cast(0u), 0.1f, TEST_LOCATION); - - END_TEST; -} - -int UtcDaliShaderDefinitionOptionAddOption(void) -{ - Scene3D::Loader::ShaderDefinitionOption option; - DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION); - - Scene3D::Loader::ShaderDefinitionOption::Type types[19] = { - Scene3D::Loader::ShaderDefinitionOption::Type::GLTF_CHANNELS, - Scene3D::Loader::ShaderDefinitionOption::Type::THREE_TEXTURE, - Scene3D::Loader::ShaderDefinitionOption::Type::BASE_COLOR_TEXTURE, - Scene3D::Loader::ShaderDefinitionOption::Type::METALLIC_ROUGHNESS_TEXTURE, - Scene3D::Loader::ShaderDefinitionOption::Type::NORMAL_TEXTURE, - Scene3D::Loader::ShaderDefinitionOption::Type::OCCLUSION, - Scene3D::Loader::ShaderDefinitionOption::Type::EMISSIVE, - Scene3D::Loader::ShaderDefinitionOption::Type::ALPHA_TEST, - Scene3D::Loader::ShaderDefinitionOption::Type::SUBSURFACE, - Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR, - Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR_COLOR, - Scene3D::Loader::ShaderDefinitionOption::Type::SKINNING, - Scene3D::Loader::ShaderDefinitionOption::Type::FLIP_UVS_VERTICAL, - Scene3D::Loader::ShaderDefinitionOption::Type::COLOR_ATTRIBUTE, - Scene3D::Loader::ShaderDefinitionOption::Type::VEC4_TANGENT, - Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_POSITION, - Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_NORMAL, - Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_TANGENT, - Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_VERSION_2_0}; - - uint64_t hash = 0u; - for(uint32_t i = 0; i < 19; ++i) - { - hash |= (1 << static_cast(types[i])); - option.AddOption(types[i]); - DALI_TEST_EQUALS(option.GetOptionHash(), hash, TEST_LOCATION); - } - - END_TEST; -} - -int UtcDaliShaderDefinitionOptionGetDefines(void) -{ - Scene3D::Loader::ShaderDefinitionOption option; - DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION); - - Scene3D::Loader::ShaderDefinitionOption::Type types[19] = { - Scene3D::Loader::ShaderDefinitionOption::Type::GLTF_CHANNELS, - Scene3D::Loader::ShaderDefinitionOption::Type::THREE_TEXTURE, - Scene3D::Loader::ShaderDefinitionOption::Type::BASE_COLOR_TEXTURE, - Scene3D::Loader::ShaderDefinitionOption::Type::METALLIC_ROUGHNESS_TEXTURE, - Scene3D::Loader::ShaderDefinitionOption::Type::NORMAL_TEXTURE, - Scene3D::Loader::ShaderDefinitionOption::Type::OCCLUSION, - Scene3D::Loader::ShaderDefinitionOption::Type::EMISSIVE, - Scene3D::Loader::ShaderDefinitionOption::Type::ALPHA_TEST, - Scene3D::Loader::ShaderDefinitionOption::Type::SUBSURFACE, - Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR, - Scene3D::Loader::ShaderDefinitionOption::Type::SPECULAR_COLOR, - Scene3D::Loader::ShaderDefinitionOption::Type::SKINNING, - Scene3D::Loader::ShaderDefinitionOption::Type::FLIP_UVS_VERTICAL, - Scene3D::Loader::ShaderDefinitionOption::Type::COLOR_ATTRIBUTE, - Scene3D::Loader::ShaderDefinitionOption::Type::VEC4_TANGENT, - Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_POSITION, - Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_NORMAL, - Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_TANGENT, - Scene3D::Loader::ShaderDefinitionOption::Type::MORPH_VERSION_2_0}; - - uint64_t hash = 0u; - for(uint32_t i = 0; i < 19; ++i) - { - hash |= (1 << static_cast(types[i])); - option.AddOption(types[i]); - DALI_TEST_EQUALS(option.GetOptionHash(), hash, TEST_LOCATION); - - std::vector defines; - option.GetDefines(defines); - DALI_TEST_EQUALS(defines.size(), i + 1, TEST_LOCATION); - for(uint32_t j = 0; j < defines.size(); ++j) - { - DALI_TEST_EQUALS(defines[j], option.GetDefineKeyword(types[j]), TEST_LOCATION); - } - } - - END_TEST; -} \ No newline at end of file diff --git a/automated-tests/src/dali-scene3d/utc-Dali-ShaderManager.cpp b/automated-tests/src/dali-scene3d/utc-Dali-ShaderManager.cpp new file mode 100644 index 0000000..b8c3b35 --- /dev/null +++ b/automated-tests/src/dali-scene3d/utc-Dali-ShaderManager.cpp @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Enable debug log for test coverage +#define DEBUG_ENABLED 1 + +#include +#include +#include +#include +#include +#include + +using namespace Dali; +using namespace Dali::Scene3D::Loader; + +namespace +{ +struct Context +{ + ResourceBundle resources; +}; + +struct ShaderParameters +{ + MeshDefinition& meshDefinition; + MaterialDefinition& materialDefinition; + NodeDefinition& nodeDefinition; +}; + +struct Permutation +{ + using ConfigureFn = void (*)(ShaderParameters&); + + ConfigureFn configureFn; + + std::set options; + RendererState::Type rendererStateSet = 0; + RendererState::Type rendererStateClear = 0; +}; + +struct PermutationSet +{ + std::vector permutations; +}; + +} // namespace + +int UtcDaliShaderDefinitionFactoryProduceShader(void) +{ + Context ctx; + ctx.resources.mMaterials.push_back({}); + ctx.resources.mMeshes.push_back({}); + + Permutation permutations[]{ + { + [](ShaderParameters& p) {}, + {}, + RendererState::DEPTH_TEST | RendererState::CULL_BACK, + }, + { + [](ShaderParameters& p) + { + p.materialDefinition.mFlags |= MaterialDefinition::TRANSPARENCY; + }, + {ShaderOption::Type::THREE_TEXTURE}, + RendererState::ALPHA_BLEND, + }, + {[](ShaderParameters& p) + { + p.materialDefinition.mFlags |= MaterialDefinition::ALBEDO; + p.materialDefinition.mTextureStages.push_back({MaterialDefinition::ALBEDO, {}}); + }, + {ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::BASE_COLOR_TEXTURE}}, + {[](ShaderParameters& p) + { + p.materialDefinition.mTextureStages.push_back({MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS, {}}); + }, + {ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE}}, + {[](ShaderParameters& p) + { + p.materialDefinition.mFlags |= MaterialDefinition::NORMAL; + p.materialDefinition.mTextureStages.push_back({MaterialDefinition::NORMAL, {}}); + }, + {ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::NORMAL_TEXTURE}}, + {[](ShaderParameters& p) + { + p.materialDefinition.mFlags |= MaterialDefinition::SUBSURFACE; + }, + {ShaderOption::Type::SUBSURFACE}}, + {[](ShaderParameters& p) + { + p.materialDefinition.SetAlphaCutoff(.5f); + }, + {ShaderOption::Type::ALPHA_TEST}}, + {[](ShaderParameters& p) + { + p.materialDefinition.SetAlphaCutoff(1.f); + }, + {ShaderOption::Type::ALPHA_TEST}}, + {[](ShaderParameters& p) + { + p.materialDefinition.mFlags |= MaterialDefinition::GLTF_CHANNELS; + }, + {ShaderOption::Type::GLTF_CHANNELS}}, + {[](ShaderParameters& p) + { + p.meshDefinition.mJoints0.mBlob.mOffset = 0; + p.meshDefinition.mWeights0.mBlob.mOffset = 0; + }, + {ShaderOption::Type::SKINNING}}, + {[](ShaderParameters& p) + { + p.meshDefinition.mFlags |= MeshDefinition::FLIP_UVS_VERTICAL; + }, + {ShaderOption::Type::FLIP_UVS_VERTICAL}}, + { + [](ShaderParameters& p) + { + p.meshDefinition.mBlendShapes.push_back({}); + }, + }, + {[](ShaderParameters& p) + { + p.meshDefinition.mBlendShapes.back().deltas.mBlob.mOffset = 0; + }, + {ShaderOption::Type::MORPH_POSITION}}, + {[](ShaderParameters& p) + { + p.meshDefinition.mBlendShapes.back().normals.mBlob.mOffset = 0; + }, + {ShaderOption::Type::MORPH_NORMAL}}, + {[](ShaderParameters& p) + { + p.meshDefinition.mBlendShapes.back().tangents.mBlob.mOffset = 0; + }, + {ShaderOption::Type::MORPH_TANGENT}}, + {[](ShaderParameters& p) + { + auto& blendShapes = p.meshDefinition.mBlendShapes; + DALI_ASSERT_ALWAYS(!blendShapes.empty() && + (blendShapes.back().deltas.mBlob.mOffset != MeshDefinition::INVALID || + blendShapes.back().normals.mBlob.mOffset != MeshDefinition::INVALID || + blendShapes.back().tangents.mBlob.mOffset != MeshDefinition::INVALID)); + p.meshDefinition.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0; + }, + {ShaderOption::Type::MORPH_VERSION_2_0}}, + + {[](ShaderParameters& p) + { + p.materialDefinition.mFlags |= MaterialDefinition::OCCLUSION; + }, + {ShaderOption::Type::OCCLUSION}}, + + {[](ShaderParameters& p) + { + p.meshDefinition.mColors.mBlob.mOffset = 0; + }, + {ShaderOption::Type::COLOR_ATTRIBUTE}}, + {[](ShaderParameters& p) + { + p.meshDefinition.mTangentType = Property::VECTOR4; + }, + {ShaderOption::Type::VEC4_TANGENT}}, + }; + + PermutationSet permutationSets[]{ + // default + {{&permutations[0]}}, + + // alpha + {{&permutations[0], &permutations[1]}}, + + // three-texture setups + {{&permutations[0], &permutations[2]}}, + {{&permutations[0], &permutations[3]}}, + {{&permutations[0], &permutations[4]}}, + {{&permutations[0], &permutations[2], &permutations[3]}}, + {{&permutations[0], &permutations[3], &permutations[4]}}, + {{&permutations[0], &permutations[4], &permutations[2]}}, + {{&permutations[0], &permutations[2], &permutations[3], &permutations[4]}}, + + // subsurface scattering + {{&permutations[0], &permutations[5]}}, + + // alpha test + {{&permutations[0], &permutations[6]}}, + {{&permutations[0], &permutations[7]}}, + + // glTF channels + {{&permutations[0], &permutations[8]}}, + + // skinning + {{&permutations[0], &permutations[9]}}, + + // flip uvs + {{&permutations[0], &permutations[10]}}, + + // morphing + {{&permutations[0], &permutations[11], &permutations[12]}}, + {{&permutations[0], &permutations[11], &permutations[13]}}, + {{&permutations[0], &permutations[11], &permutations[14]}}, + {{&permutations[0], &permutations[11], &permutations[12], &permutations[13]}}, + {{&permutations[0], &permutations[11], &permutations[13], &permutations[14]}}, + {{&permutations[0], &permutations[11], &permutations[14], &permutations[12]}}, + {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14]}}, + + {{&permutations[0], &permutations[11], &permutations[12], &permutations[15]}}, + {{&permutations[0], &permutations[11], &permutations[13], &permutations[15]}}, + {{&permutations[0], &permutations[11], &permutations[14], &permutations[15]}}, + {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[15]}}, + {{&permutations[0], &permutations[11], &permutations[13], &permutations[14], &permutations[15]}}, + {{&permutations[0], &permutations[11], &permutations[14], &permutations[12], &permutations[15]}}, + {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14], &permutations[15]}}, + + // etc. + {{&permutations[0], &permutations[1], &permutations[2]}}, + {{&permutations[0], &permutations[1], &permutations[3]}}, + {{&permutations[0], &permutations[1], &permutations[2], &permutations[3]}}, + + // occlusion + {{&permutations[0], &permutations[16]}}, + }; + + TestApplication app; + ShaderManager shaderManager; + for(auto& permutationSet : permutationSets) + { + static int tc = 0; + tet_printf("Test %d's tc\n", ++tc); + auto modelRenderable = new ModelRenderable(); + modelRenderable->mMeshIdx = 0; + modelRenderable->mMaterialIdx = 0; + + NodeDefinition nodeDefinition; + std::unique_ptr renderable; + renderable.reset(modelRenderable); + nodeDefinition.mRenderables.push_back(std::move(renderable)); + + MeshDefinition meshDefinition; + MaterialDefinition materialDefinition; + ShaderParameters shaderParameter{meshDefinition, materialDefinition, nodeDefinition}; + + std::set defines; + ShaderOption option; + RendererState::Type rendererState = 0; + for(auto permutation : permutationSet.permutations) + { + permutation->configureFn(shaderParameter); + if(materialDefinition.mFlags & MaterialDefinition::TRANSPARENCY) + { + option.SetTransparency(); + } + for(auto&& optionType : permutation->options) + { + option.AddOption(optionType); + } + rendererState = (rendererState | permutation->rendererStateSet) & ~permutation->rendererStateClear; + } + option.AddOption(ShaderOption::Type::THREE_TEXTURE); + + Shader shaderFromMeshAndMaterial = shaderManager.ProduceShader(materialDefinition, meshDefinition); + Shader shaderFromOption = shaderManager.ProduceShader(option); + DALI_TEST_EQUAL(shaderFromMeshAndMaterial, shaderFromOption); + + RendererState::Type rendererStateFromMaterialDefinition = shaderManager.GetRendererState(materialDefinition); + DALI_TEST_EQUAL(rendererStateFromMaterialDefinition, rendererState); + } + + END_TEST; +} \ No newline at end of file diff --git a/automated-tests/src/dali-scene3d/utc-Dali-ShaderOption.cpp b/automated-tests/src/dali-scene3d/utc-Dali-ShaderOption.cpp new file mode 100644 index 0000000..71514fd --- /dev/null +++ b/automated-tests/src/dali-scene3d/utc-Dali-ShaderOption.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include "dali-scene3d/public-api/loader/shader-option.h" + +using namespace Dali; +using namespace Dali::Toolkit; + +void shader_definition_option_startup(void) +{ + test_return_value = TET_UNDEF; +} + +void shader_definition_option_cleanup(void) +{ + test_return_value = TET_PASS; +} + +int UtcDaliShaderOptionInit(void) +{ + Scene3D::Loader::ShaderOption option; + DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION); + END_TEST; +} + +int UtcDaliShaderOptionSetTransparency(void) +{ + Scene3D::Loader::ShaderOption option; + DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION); + + option.SetTransparency(); + DALI_TEST_NOT_EQUALS(option.GetOptionHash(), static_cast(0u), 0.1f, TEST_LOCATION); + + END_TEST; +} + +int UtcDaliShaderOptionAddOption(void) +{ + Scene3D::Loader::ShaderOption option; + DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION); + + Scene3D::Loader::ShaderOption::Type types[19] = { + Scene3D::Loader::ShaderOption::Type::GLTF_CHANNELS, + Scene3D::Loader::ShaderOption::Type::THREE_TEXTURE, + Scene3D::Loader::ShaderOption::Type::BASE_COLOR_TEXTURE, + Scene3D::Loader::ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE, + Scene3D::Loader::ShaderOption::Type::NORMAL_TEXTURE, + Scene3D::Loader::ShaderOption::Type::OCCLUSION, + Scene3D::Loader::ShaderOption::Type::EMISSIVE, + Scene3D::Loader::ShaderOption::Type::ALPHA_TEST, + Scene3D::Loader::ShaderOption::Type::SUBSURFACE, + Scene3D::Loader::ShaderOption::Type::SPECULAR, + Scene3D::Loader::ShaderOption::Type::SPECULAR_COLOR, + Scene3D::Loader::ShaderOption::Type::SKINNING, + Scene3D::Loader::ShaderOption::Type::FLIP_UVS_VERTICAL, + Scene3D::Loader::ShaderOption::Type::COLOR_ATTRIBUTE, + Scene3D::Loader::ShaderOption::Type::VEC4_TANGENT, + Scene3D::Loader::ShaderOption::Type::MORPH_POSITION, + Scene3D::Loader::ShaderOption::Type::MORPH_NORMAL, + Scene3D::Loader::ShaderOption::Type::MORPH_TANGENT, + Scene3D::Loader::ShaderOption::Type::MORPH_VERSION_2_0}; + + uint64_t hash = 0u; + for(uint32_t i = 0; i < 19; ++i) + { + hash |= (1 << static_cast(types[i])); + option.AddOption(types[i]); + DALI_TEST_EQUALS(option.GetOptionHash(), hash, TEST_LOCATION); + } + + END_TEST; +} + +int UtcDaliShaderOptionGetDefines(void) +{ + Scene3D::Loader::ShaderOption option; + DALI_TEST_EQUALS(option.GetOptionHash(), 0u, TEST_LOCATION); + + Scene3D::Loader::ShaderOption::Type types[19] = { + Scene3D::Loader::ShaderOption::Type::GLTF_CHANNELS, + Scene3D::Loader::ShaderOption::Type::THREE_TEXTURE, + Scene3D::Loader::ShaderOption::Type::BASE_COLOR_TEXTURE, + Scene3D::Loader::ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE, + Scene3D::Loader::ShaderOption::Type::NORMAL_TEXTURE, + Scene3D::Loader::ShaderOption::Type::OCCLUSION, + Scene3D::Loader::ShaderOption::Type::EMISSIVE, + Scene3D::Loader::ShaderOption::Type::ALPHA_TEST, + Scene3D::Loader::ShaderOption::Type::SUBSURFACE, + Scene3D::Loader::ShaderOption::Type::SPECULAR, + Scene3D::Loader::ShaderOption::Type::SPECULAR_COLOR, + Scene3D::Loader::ShaderOption::Type::SKINNING, + Scene3D::Loader::ShaderOption::Type::FLIP_UVS_VERTICAL, + Scene3D::Loader::ShaderOption::Type::COLOR_ATTRIBUTE, + Scene3D::Loader::ShaderOption::Type::VEC4_TANGENT, + Scene3D::Loader::ShaderOption::Type::MORPH_POSITION, + Scene3D::Loader::ShaderOption::Type::MORPH_NORMAL, + Scene3D::Loader::ShaderOption::Type::MORPH_TANGENT, + Scene3D::Loader::ShaderOption::Type::MORPH_VERSION_2_0}; + + uint64_t hash = 0u; + for(uint32_t i = 0; i < 19; ++i) + { + hash |= (1 << static_cast(types[i])); + option.AddOption(types[i]); + DALI_TEST_EQUALS(option.GetOptionHash(), hash, TEST_LOCATION); + + std::vector defines; + option.GetDefines(defines); + DALI_TEST_EQUALS(defines.size(), i + 1, TEST_LOCATION); + for(uint32_t j = 0; j < defines.size(); ++j) + { + DALI_TEST_EQUALS(defines[j], option.GetDefineKeyword(types[j]), TEST_LOCATION); + } + } + + END_TEST; +} \ No newline at end of file diff --git a/dali-scene3d/dali-scene3d.h b/dali-scene3d/dali-scene3d.h index eb7c60a..df626ad 100644 --- a/dali-scene3d/dali-scene3d.h +++ b/dali-scene3d/dali-scene3d.h @@ -59,8 +59,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/dali-scene3d/internal/controls/model/model-impl.cpp b/dali-scene3d/internal/controls/model/model-impl.cpp index 7c82d4b..7a6662d 100644 --- a/dali-scene3d/internal/controls/model/model-impl.cpp +++ b/dali-scene3d/internal/controls/model/model-impl.cpp @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include using namespace Dali; @@ -232,6 +232,26 @@ void UpdateBlendShapeNodeMapRecursively(Model::BlendShapeModelNodeMap& resultMap } } +void UpdateShaderRecursively(Scene3D::ModelNode node, Scene3D::Loader::ShaderManagerPtr shaderManager) +{ + if(!node) + { + return; + } + + GetImplementation(node).UpdateShader(shaderManager); + + uint32_t childrenCount = node.GetChildCount(); + for(uint32_t i = 0; i < childrenCount; ++i) + { + Scene3D::ModelNode childNode = Scene3D::ModelNode::DownCast(node.GetChildAt(i)); + if(childNode) + { + UpdateShaderRecursively(childNode, shaderManager); + } + } +} + } // anonymous namespace Model::Model(const std::string& modelUrl, const std::string& resourceDirectoryUrl) @@ -239,6 +259,7 @@ Model::Model(const std::string& modelUrl, const std::string& resourceDirectoryUr mModelUrl(modelUrl), mResourceDirectoryUrl(resourceDirectoryUrl), mModelRoot(), + mShaderManager(new Scene3D::Loader::ShaderManager()), mNaturalSize(Vector3::ZERO), mModelPivot(AnchorPoint::CENTER), mSceneIblScaleFactor(1.0f), @@ -296,6 +317,8 @@ void Model::AddModelNode(Scene3D::ModelNode modelNode) mModelResourceReady = true; } + UpdateShaderRecursively(modelNode, mShaderManager); + if(mIblDiffuseResourceReady && mIblSpecularResourceReady) { UpdateImageBasedLightTexture(); @@ -321,6 +344,8 @@ void Model::RemoveModelNode(Scene3D::ModelNode modelNode) { if(mModelRoot) { + UpdateShaderRecursively(modelNode, nullptr); + uint32_t maxLightCount = Scene3D::Internal::Light::GetMaximumEnabledLightCount(); for(uint32_t i = 0; i < maxLightCount; ++i) { @@ -774,6 +799,36 @@ void Model::OnInitialize() void Model::OnSceneConnection(int depth) { + Actor parent = Self().GetParent(); + while(parent) + { + // If this Model has parent SceneView and the its ShaderManager is same with privious ShaderManager, + // this Model don't need to update shader. + Scene3D::SceneView sceneView = Scene3D::SceneView::DownCast(parent); + if(sceneView) + { + mParentSceneView = sceneView; + GetImpl(sceneView).RegisterSceneItem(this); + Scene3D::Loader::ShaderManagerPtr shaderManager = GetImpl(sceneView).GetShaderManager(); + if(mShaderManager != shaderManager) + { + mShaderManager = shaderManager; + UpdateShaderRecursively(mModelRoot, mShaderManager); + } + break; + } + parent = parent.GetParent(); + } + + // Model can be added on Dali::Scene directly without SceneView. + // So, Model's mShaderManager and shaders of child ModelNodes are needed to be reset when this Model has not parent SceneView. + Scene3D::SceneView parentSceneView = mParentSceneView.GetHandle(); + if(!parentSceneView) + { + mShaderManager = new Dali::Scene3D::Loader::ShaderManager(); + UpdateShaderRecursively(mModelRoot, mShaderManager); + } + if(!mModelLoadTask && !mModelResourceReady && !mModelUrl.empty()) { // Request model load only if we setup url. @@ -791,19 +846,6 @@ void Model::OnSceneConnection(int depth) SetImageBasedLightSource(mDiffuseIblUrl, mSpecularIblUrl, mIblScaleFactor); } - Actor parent = Self().GetParent(); - while(parent) - { - Scene3D::SceneView sceneView = Scene3D::SceneView::DownCast(parent); - if(sceneView) - { - GetImpl(sceneView).RegisterSceneItem(this); - mParentSceneView = sceneView; - break; - } - parent = parent.GetParent(); - } - NotifyResourceReady(); mSizeNotification = Self().AddPropertyNotification(Actor::Property::SIZE, StepCondition(SIZE_STEP_CONDITION)); @@ -813,8 +855,11 @@ void Model::OnSceneConnection(int depth) void Model::OnSceneDisconnection() { + // If mParentSceneView is still onScene, that means this model + // is disconnected from mParentSceneView's sub tree. + // So, Unregister this Model from SceneView. Scene3D::SceneView sceneView = mParentSceneView.GetHandle(); - if(sceneView) + if(sceneView && sceneView.GetProperty(Dali::Actor::Property::CONNECTED_TO_SCENE)) { GetImpl(sceneView).UnregisterSceneItem(this); mParentSceneView.Reset(); @@ -1174,12 +1219,13 @@ void Model::NotifyResourceReady() void Model::CreateModel() { - BoundingVolume AABB; - auto& resources = mModelLoadTask->GetResources(); - auto& scene = mModelLoadTask->GetScene(); - auto& resourceChoices = mModelLoadTask->GetResourceChoices(); - Dali::Scene3D::Loader::Transforms xforms{Dali::Scene3D::Loader::MatrixStack{}, Dali::Scene3D::Loader::ViewProjection{}}; - Dali::Scene3D::Loader::NodeDefinition::CreateParams nodeParams{resources, xforms, {}, {}, {}}; + BoundingVolume AABB; + auto& resources = mModelLoadTask->GetResources(); + auto& scene = mModelLoadTask->GetScene(); + auto& resourceChoices = mModelLoadTask->GetResourceChoices(); + Dali::Scene3D::Loader::Transforms xforms{Dali::Scene3D::Loader::MatrixStack{}, Dali::Scene3D::Loader::ViewProjection{}}; + + Dali::Scene3D::Loader::NodeDefinition::CreateParams nodeParams{resources, xforms, mShaderManager, {}, {}, {}}; // Generate Dali handles from resource bundle. Note that we generate all scene's resouce immediatly. resources.GenerateResources(); diff --git a/dali-scene3d/internal/controls/model/model-impl.h b/dali-scene3d/internal/controls/model/model-impl.h index f383aff..cb64cac 100644 --- a/dali-scene3d/internal/controls/model/model-impl.h +++ b/dali-scene3d/internal/controls/model/model-impl.h @@ -361,6 +361,8 @@ private: WeakHandle mParentSceneView; Dali::PropertyNotification mSizeNotification; + Dali::Scene3D::Loader::ShaderManagerPtr mShaderManager; + // Light std::vector mLights; diff --git a/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp b/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp index 5746b93..8b18809 100644 --- a/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp +++ b/dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp @@ -62,7 +62,7 @@ DALI_TYPE_REGISTRATION_END() Property::Index RENDERING_BUFFER = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1; constexpr int32_t DEFAULT_ORIENTATION = 0; -constexpr int32_t INVALID_INDEX = -1; +constexpr int32_t INVALID_INDEX = -1; static constexpr std::string_view SKYBOX_INTENSITY_STRING = "uIntensity"; @@ -153,7 +153,8 @@ SceneView::SceneView() mWindowOrientation(DEFAULT_ORIENTATION), mSkybox(), mSkyboxOrientation(Quaternion()), - mSkyboxIntensity(1.0f) + mSkyboxIntensity(1.0f), + mShaderManager(new Scene3D::Loader::ShaderManager()) { } @@ -469,7 +470,7 @@ void SceneView::RemoveLight(Scene3D::Light light) uint32_t removedIndex = RemoveLightInternal(light); if(mActivatedLightCount < maxNumberOfLight && mLights.size() >= maxNumberOfLight) { - for(auto && lightItem : mLights) + for(auto&& lightItem : mLights) { if(lightItem.second == false) { @@ -585,6 +586,11 @@ Quaternion SceneView::GetSkyboxOrientation() const return mSkyboxOrientation; } +Dali::Scene3D::Loader::ShaderManagerPtr SceneView::GetShaderManager() const +{ + return mShaderManager; +} + /////////////////////////////////////////////////////////// // // Private methods @@ -838,9 +844,9 @@ void SceneView::UpdateSkybox(const std::string& skyboxUrl, Scene3D::EnvironmentM if(mSkybox) { - mSkybox.Unparent(); - mSkybox.Reset(); - mSkyboxTexture.Reset(); + mSkybox.Unparent(); + mSkybox.Reset(); + mSkyboxTexture.Reset(); } mSkyboxDirty = false; @@ -990,7 +996,7 @@ bool SceneView::AddLightInternal(Scene3D::Light light) int32_t SceneView::RemoveLightInternal(Scene3D::Light light) { - int32_t removedIndex = INVALID_INDEX; + int32_t removedIndex = INVALID_INDEX; uint32_t maxNumberOfLight = Scene3D::Internal::Light::GetMaximumEnabledLightCount(); for(uint32_t i = 0; i < maxNumberOfLight; ++i) { diff --git a/dali-scene3d/internal/controls/scene-view/scene-view-impl.h b/dali-scene3d/internal/controls/scene-view/scene-view-impl.h index cf117f9..3ed2b2b 100644 --- a/dali-scene3d/internal/controls/scene-view/scene-view-impl.h +++ b/dali-scene3d/internal/controls/scene-view/scene-view-impl.h @@ -35,6 +35,7 @@ #include #include #include +#include namespace Dali { @@ -203,6 +204,12 @@ public: */ Quaternion GetSkyboxOrientation() const; + /** + * @brief Retrieves ShaderManager of this SceneView. + * @return ShaderManager of this SceneView. + */ + Dali::Scene3D::Loader::ShaderManagerPtr GetShaderManager() const; + protected: /** * @brief Constructs a new SceneView. @@ -352,6 +359,9 @@ private: float mSkyboxIntensity{1.0f}; uint8_t mFrameBufferMultiSamplingLevel{0u}; + // Shader Factory + Dali::Scene3D::Loader::ShaderManagerPtr mShaderManager; + // Light std::vector> mLights; // Pair of Light object and flag that denotes the light is currently activated or not. std::vector mActivatedLights; @@ -378,8 +388,6 @@ private: bool mSkyboxDirty{false}; bool mIblDiffuseDirty{false}; bool mIblSpecularDirty{false}; - - // TODO : Light Source }; } // namespace Internal diff --git a/dali-scene3d/internal/loader/gltf2-util.cpp b/dali-scene3d/internal/loader/gltf2-util.cpp index 90deac9..5e6942f 100644 --- a/dali-scene3d/internal/loader/gltf2-util.cpp +++ b/dali-scene3d/internal/loader/gltf2-util.cpp @@ -594,6 +594,8 @@ void ConvertMaterial(const gltf2::Material& material, const std::unordered_mapmShaderIdx = 0; // TODO: further thought - auto materialIdx = primitive.mMaterial.GetIndex(); if(INVALID_INDEX == materialIdx) { @@ -1353,22 +1353,6 @@ void ProcessSkins(const gltf2::Document& document, ConversionContext& context) } } -void ProduceShaders(ShaderDefinitionFactory& shaderFactory, Dali::Scene3D::Loader::SceneDefinition& scene) -{ - uint32_t nodeCount = scene.GetNodeCount(); - for(uint32_t i = 0; i < nodeCount; ++i) - { - auto nodeDefinition = scene.GetNode(i); - for(auto& renderable : nodeDefinition->mRenderables) - { - if(shaderFactory.ProduceShader(*renderable) == INVALID_INDEX) - { - DALI_LOG_ERROR("Fail to produce shader\n"); - } - } - } -} - void SetObjectReaders() { json::SetObjectReader(GetBufferReader()); @@ -1470,17 +1454,12 @@ bool GenerateDocument(json::unique_ptr& root, gt::Document& document, bool& isMR void ConvertGltfToContext(gt::Document& document, Gltf2Util::ConversionContext& context, bool isMRendererModel) { - Dali::Scene3D::Loader::ShaderDefinitionFactory shaderFactory; - shaderFactory.SetResources(context.mOutput.mResources); - Gltf2Util::ConvertBuffers(document, context); Gltf2Util::ConvertMaterials(document, context); Gltf2Util::ConvertMeshes(document, context); Gltf2Util::ConvertNodes(document, context, isMRendererModel); Gltf2Util::ConvertAnimations(document, context); Gltf2Util::ProcessSkins(document, context); - Gltf2Util::ProduceShaders(shaderFactory, context.mOutput.mScene); - context.mOutput.mScene.EnsureUniqueSkinningShaderInstances(context.mOutput.mResources); // Set Default Environment map Gltf2Util::SetDefaultEnvironmentMap(document, context); diff --git a/dali-scene3d/internal/loader/gltf2-util.h b/dali-scene3d/internal/loader/gltf2-util.h index 457140e..d12addd 100644 --- a/dali-scene3d/internal/loader/gltf2-util.h +++ b/dali-scene3d/internal/loader/gltf2-util.h @@ -25,7 +25,6 @@ #include #include #include -#include namespace gt = gltf2; namespace js = json; @@ -48,8 +47,8 @@ struct NodeMapping class NodeIndexMapper { public: - NodeIndexMapper() = default; - NodeIndexMapper(const NodeIndexMapper&) = delete; + NodeIndexMapper() = default; + NodeIndexMapper(const NodeIndexMapper&) = delete; NodeIndexMapper& operator=(const NodeIndexMapper&) = delete; ///@brief Registers a mapping of the @a gltfIndex of a node to its @a runtimeIndex . @@ -101,8 +100,6 @@ void ConvertAnimations(const gt::Document& document, ConversionContext& context) void ProcessSkins(const gt::Document& document, ConversionContext& context); -void ProduceShaders(ShaderDefinitionFactory& shaderFactory, SceneDefinition& scene); - void SetDefaultEnvironmentMap(const gt::Document& document, ConversionContext& context); const std::string_view GetRendererModelIdentification(); diff --git a/dali-scene3d/internal/model-components/material-impl.cpp b/dali-scene3d/internal/model-components/material-impl.cpp index 4ce7d57..386fdd6 100644 --- a/dali-scene3d/internal/model-components/material-impl.cpp +++ b/dali-scene3d/internal/model-components/material-impl.cpp @@ -30,8 +30,8 @@ #include #include #include +#include #include -#include namespace Dali { @@ -101,13 +101,13 @@ Material::Material() mTextureInformations[SPECULAR].mSemantic = Scene3D::Loader::MaterialDefinition::SPECULAR; mTextureInformations[SPECULAR_COLOR].mSemantic = Scene3D::Loader::MaterialDefinition::SPECULAR_COLOR; - mTextureInformations[BASE_COLOR].mDefineKeyword = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::BASE_COLOR_TEXTURE).data(); - mTextureInformations[METALLIC_ROUGHNESS].mDefineKeyword = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::METALLIC_ROUGHNESS_TEXTURE).data(); - mTextureInformations[NORMAL].mDefineKeyword = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::NORMAL_TEXTURE).data(); - mTextureInformations[OCCLUSION].mDefineKeyword = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::OCCLUSION).data(); - mTextureInformations[EMISSIVE].mDefineKeyword = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::EMISSIVE).data(); - mTextureInformations[SPECULAR].mDefineKeyword = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::SPECULAR).data(); - mTextureInformations[SPECULAR_COLOR].mDefineKeyword = Scene3D::Loader::ShaderDefinitionOption::GetDefineKeyword(Loader::ShaderDefinitionOption::Type::SPECULAR_COLOR).data(); + mTextureInformations[BASE_COLOR].mShaderOptionType = Loader::ShaderOption::Type::BASE_COLOR_TEXTURE; + mTextureInformations[METALLIC_ROUGHNESS].mShaderOptionType = Loader::ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE; + mTextureInformations[NORMAL].mShaderOptionType = Loader::ShaderOption::Type::NORMAL_TEXTURE; + mTextureInformations[OCCLUSION].mShaderOptionType = Loader::ShaderOption::Type::OCCLUSION; + mTextureInformations[EMISSIVE].mShaderOptionType = Loader::ShaderOption::Type::EMISSIVE; + mTextureInformations[SPECULAR].mShaderOptionType = Loader::ShaderOption::Type::SPECULAR; + mTextureInformations[SPECULAR_COLOR].mShaderOptionType = Loader::ShaderOption::Type::SPECULAR_COLOR; mTextureInformations[TextureIndex::EMISSIVE].mFactor = Vector4::ZERO; } @@ -517,14 +517,9 @@ Dali::Sampler Material::GetSampler(Scene3D::Material::TextureType index) return Dali::Sampler(); } -std::string Material::GetVertexShader() +Scene3D::Loader::ShaderOption Material::GetShaderOption() const { - return mShaderData.mVertexShaderSource; -} - -std::string Material::GetFragmentShader() -{ - return mShaderData.mFragmentShaderSource; + return mShaderOption; } void Material::Apply() @@ -614,34 +609,31 @@ void Material::UpdateMaterialData() materialFlag |= textureInformation.mSemantic; } - if(mMaterialFlag != materialFlag || mShaderData.mVertexShaderSource.empty() || mShaderData.mFragmentShaderSource.empty()) + if(mMaterialFlag != materialFlag) { mModifyFlag |= MaterialModifyObserver::ModifyFlag::SHADER; - mMaterialFlag = materialFlag; - mShaderData.mVertexShaderSource = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_VERT.data(); - mShaderData.mFragmentShaderSource = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_FRAG.data(); + mMaterialFlag = materialFlag; - std::vector defines; - defines.push_back(THREE_TEX_KEYWORD.data()); + mShaderOption = Loader::ShaderOption(); for(auto&& textureInformation : mTextureInformations) { if(!textureInformation.mTexture) { continue; } - defines.push_back(textureInformation.mDefineKeyword); + mShaderOption.AddOption(textureInformation.mShaderOptionType); } - defines.push_back(GLTF_CHANNELS_KEYWORD.data()); - - for(const auto& define : defines) + mShaderOption.AddOption(Loader::ShaderOption::Type::THREE_TEXTURE); + mShaderOption.AddOption(Loader::ShaderOption::Type::GLTF_CHANNELS); + if(materialFlag & Scene3D::Loader::MaterialDefinition::TRANSPARENCY) { - Scene3D::Loader::ShaderDefinition::ApplyDefine(mShaderData.mFragmentShaderSource, define); + mShaderOption.SetTransparency(); } } // Finish to make all the material flag according to the gltf2-util. - // Then make defines as fallowing shader-definition-factory. + // Then make defines as fallowing shader-manager. // The renderer State below can be used in primitive to set renderer properties. @@ -769,7 +761,9 @@ void Material::NotifyObserver() mObserverNotifying = false; // Resolve observer queue during notify - mObservers.erase(std::remove_if(mObservers.begin(), mObservers.end(), [](auto& e) { return !e.second; }), mObservers.end()); + mObservers.erase(std::remove_if(mObservers.begin(), mObservers.end(), [](auto& e) + { return !e.second; }), + mObservers.end()); } } diff --git a/dali-scene3d/internal/model-components/material-impl.h b/dali-scene3d/internal/model-components/material-impl.h index 563bf82..3b0c985 100644 --- a/dali-scene3d/internal/model-components/material-impl.h +++ b/dali-scene3d/internal/model-components/material-impl.h @@ -34,6 +34,7 @@ #include #include #include +#include #include namespace Dali @@ -65,13 +66,13 @@ public: return mLoadingTaskId == 0u; } - std::string mUrl; - Dali::Texture mTexture; - Vector4 mFactor{Vector4::ONE}; - Dali::Sampler mSampler; - uint32_t mLoadingTaskId{0u}; - uint32_t mSemantic; - std::string mDefineKeyword; + std::string mUrl; + Dali::Texture mTexture; + Vector4 mFactor{Vector4::ONE}; + Dali::Sampler mSampler; + uint32_t mLoadingTaskId{0u}; + uint32_t mSemantic; + Scene3D::Loader::ShaderOption::Type mShaderOptionType; }; using TextureInformationContainer = std::vector; @@ -112,7 +113,7 @@ public: Dali::Property::Value GetProperty(Dali::Property::Index index) const; /** - * @brief Set a texture information for the material. + * @brief Sets a texture information for the material. * * @param[in] index The index of the texture to set. * @param[in] textureInformation The texture information to set. @@ -122,7 +123,7 @@ public: void SetTextureInformation(Scene3D::Material::TextureType index, TextureInformation&& textureInformation); /** - * @brief Set a texture for the material. + * @brief Sets a texture for the material. * * @param[in] index The index of the texture to set. * @param[in] texture The texture to set. @@ -130,7 +131,7 @@ public: void SetTexture(Scene3D::Material::TextureType index, Dali::Texture texture); /** - * @brief Get texture for the material. + * @brief Retrieves texture for the material. * * @param[in] index The index of the texture to get. * @@ -139,14 +140,14 @@ public: Dali::Texture GetTexture(Scene3D::Material::TextureType index); /** - * @brief Get the texture set for this material. + * @brief Retrieves the texture set for this material. * * @return The texture set for this material. */ TextureSet GetTextureSet(); /** - * @brief Set a sampler for the material. + * @brief Sets a sampler for the material. * * @param[in] index The index of the sampler to set. * @param[in] sampler The sampler to set. @@ -154,104 +155,96 @@ public: void SetSampler(Scene3D::Material::TextureType index, Dali::Sampler sampler); /** - * @brief Get a sampler for the material. - - * @param[in] index The index of the sampler to get. + * @brief Retrieves a sampler for the material. * + * @param[in] index The index of the sampler to get. * @return The sampler at the given index. */ Dali::Sampler GetSampler(Scene3D::Material::TextureType index); /** - * @brief Get vertex shader code for this material. - * - * @return Vertex shader code for this material. - */ - std::string GetVertexShader(); - - /** - * @brief Get fragment shader code for this material. + * @brief Retrieves Shader Option of this Material. * - * @return Fragment shader code for this material. + * @return Shader Option of this Material. */ - std::string GetFragmentShader(); + Scene3D::Loader::ShaderOption GetShaderOption() const; public: /** - * @brief Add observer to this material. + * @brief Adds observer to this material. * * @param[in] observer Pointer of observer. */ void AddObserver(MaterialModifyObserver* observer); /** - * @brief Remove observer from this material. + * @brief Removes observer from this material. * * @param[in] observer Pointer of observer. */ void RemoveObserver(MaterialModifyObserver* observer); /** - * @brief Update material data. + * @brief Updates material data. */ void UpdateMaterialData(); /** - * @brief Set uniform value to the Renderer. + * @brief Sets uniform value to the Renderer. * * @param[in] renderer Renderer object. */ void SetRendererUniform(Dali::Renderer renderer); /** - * @brief Get specular image based light texture offset. + * @brief Retrieves specular image based light texture offset. * * @return Specular image based light texture offset. */ uint32_t GetSpecularImageBasedLightTextureOffset(); /** - * @brief Get diffuse image based light texture offset. + * @brief Retrieves diffuse image based light texture offset. * * @return Diffuse image based light texture offset. */ uint32_t GetDiffuseImageBasedLightTextureOffset(); /** - * @brief Get image based light scale factor name. + * @brief Retrieves image based light scale factor name. * * @return Image based light scale factor name. */ std::string_view GetImageBasedLightScaleFactorName(); /** - * @brief Get image based light max lod uniform name. + * @brief Retrieves image based light max lod uniform name. * * @return Image based light max lod uniform name. */ std::string_view GetImageBasedLightMaxLodUniformName(); /** - * @brief Check if resource is ready. + * @brief Checks if resource is ready. * * @return True if resource is ready, false otherwise. */ bool IsResourceReady(); /** - * @brief Reset dirty flag of this material. + * @brief Resets dirty flag of this material. */ void ResetFlag(); private: /** - * @brief Check modify flag and send observers the material changeness. + * @brief Checks modify flag and send observers the material changeness. * It will clean up modify flag */ void NotifyObserver(); /** - * @brief Request loading an image from a URL and store it in TextureInformation. + * @brief Requests loading an image from a URL and store it in TextureInformation. * * @param[in] textureInformation TextureInformation object to store loaded texture information. * @param[in] url URL of the image to load. @@ -272,16 +265,16 @@ private: void ResourcesLoadComplete(); /** - * @brief Update the material using each attribute of this material and send a notification to the ModelPrimitive class. + * @brief Updates the material using each attribute of this material and send a notification to the ModelPrimitive class. */ void Apply(); private: // Delete copy & move operator - Material(const Material&) = delete; - Material(Material&&) = delete; + Material(const Material&) = delete; + Material(Material&&) = delete; Material& operator=(const Material& rhs) = delete; - Material& operator=(Material&& rhs) = delete; + Material& operator=(Material&& rhs) = delete; private: ObserverContainer mObservers{}; ///< List of observers who need to be notified after some properties are changed. @@ -296,9 +289,8 @@ private: float mIor = -1.0f; ///< Index of refraction (TODO: Magic number) MaterialModifyObserver::ModifyFlag mModifyFlag = MaterialModifyObserver::ModifyFlag::NONE; ///< Modified dirty flags - Scene3D::Loader::ShaderDefinition::RawData mShaderData; - - uint32_t mMaterialFlag = 0u; + Scene3D::Loader::ShaderOption mShaderOption; + uint32_t mMaterialFlag = std::numeric_limits::max(); Scene3D::Loader::RendererState::Type mRendererState = Scene3D::Loader::RendererState::NONE; bool mIsOpaque = true; diff --git a/dali-scene3d/internal/model-components/model-node-impl.cpp b/dali-scene3d/internal/model-components/model-node-impl.cpp index a37d4a8..7d3d5e1 100644 --- a/dali-scene3d/internal/model-components/model-node-impl.cpp +++ b/dali-scene3d/internal/model-components/model-node-impl.cpp @@ -202,6 +202,8 @@ void ModelNode::AddModelPrimitive(Dali::Scene3D::ModelPrimitive modelPrimitive) } } + GetImplementation(modelPrimitive).UpdateShader(mShaderManager); + Dali::Renderer renderer = GetImplementation(modelPrimitive).GetRenderer(); if(renderer) { @@ -244,6 +246,8 @@ void ModelNode::RemoveModelPrimitive(uint32_t index) return; } + GetImplementation(mModelPrimitiveContainer[index]).UpdateShader(nullptr); + uint32_t maxLightCount = Scene3D::Internal::Light::GetMaximumEnabledLightCount(); for(uint32_t i = 0; i < maxLightCount; ++i) { @@ -338,6 +342,18 @@ void ModelNode::RemoveLight(uint32_t lightIndex) mLights[lightIndex].Reset(); } +void ModelNode::UpdateShader(Scene3D::Loader::ShaderManagerPtr shaderManager) +{ + if(mShaderManager != shaderManager) + { + mShaderManager = shaderManager; + for(auto&& primitive : mModelPrimitiveContainer) + { + GetImplementation(primitive).UpdateShader(mShaderManager); + } + } +} + void ModelNode::SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data, Scene3D::ModelPrimitive primitive) { // Update mBlendShapeIndexMap diff --git a/dali-scene3d/internal/model-components/model-node-impl.h b/dali-scene3d/internal/model-components/model-node-impl.h index 8a06116..1a56d60 100644 --- a/dali-scene3d/internal/model-components/model-node-impl.h +++ b/dali-scene3d/internal/model-components/model-node-impl.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -246,10 +247,29 @@ public: // Public Method */ void SetImageBasedLightScaleFactor(float iblScaleFactor); + /** + * @brief Adds new Light. + * + * @param[in] light Newly added light. + * @param[in] lightIndex index of this light. + */ void AddLight(Scene3D::Light light, uint32_t lightIndex); + + /** + * @brief Removes new Light. + * + * @param[in] lightIndex index of light that will be removed. + */ void RemoveLight(uint32_t lightIndex); /** + * @brief Updates shaders by using current material + * + * @param[in] shaderManager Shader manager to create shader. + */ + void UpdateShader(Scene3D::Loader::ShaderManagerPtr shaderManager); + + /** * @brief Sets the blend shape data for a ModelPrimitive. * * @param[in] data The blend shape data. @@ -291,13 +311,14 @@ private: DALI_INTERNAL ModelNode& operator=(ModelNode&&) = delete; ///< Deleted move assignment operator. private: - ModelPrimitiveContainer mModelPrimitiveContainer; ///< List of model primitives - BoneDataContainer mBoneDataContainer; - BlendShapeIndexMap mBlendShapeIndexMap; ///< Index of blend shape by name - Dali::Texture mSpecularTexture; - Dali::Texture mDiffuseTexture; - float mIblScaleFactor{1.0f}; - uint32_t mSpecularMipmapLevels{1u}; + Scene3D::Loader::ShaderManagerPtr mShaderManager; + ModelPrimitiveContainer mModelPrimitiveContainer; ///< List of model primitives + BoneDataContainer mBoneDataContainer; + BlendShapeIndexMap mBlendShapeIndexMap; ///< Index of blend shape by name + Dali::Texture mSpecularTexture; + Dali::Texture mDiffuseTexture; + float mIblScaleFactor{1.0f}; + uint32_t mSpecularMipmapLevels{1u}; // Light std::vector mLights; diff --git a/dali-scene3d/internal/model-components/model-primitive-impl.cpp b/dali-scene3d/internal/model-components/model-primitive-impl.cpp index df71d6d..870f956 100644 --- a/dali-scene3d/internal/model-components/model-primitive-impl.cpp +++ b/dali-scene3d/internal/model-components/model-primitive-impl.cpp @@ -29,6 +29,8 @@ #include #include +#include + namespace Dali { namespace Scene3D @@ -49,11 +51,6 @@ BaseHandle Create() DALI_TYPE_REGISTRATION_BEGIN(Scene3D::ModelPrimitive, Dali::BaseHandle, Create); DALI_TYPE_REGISTRATION_END() -constexpr std::string_view MORPH_POSITION_KEYWORD = "MORPH_POSITION"; -constexpr std::string_view MORPH_NORMAL_KEYWORD = "MORPH_NORMAL"; -constexpr std::string_view MORPH_TANGENT_KEYWORD = "MORPH_TANGENT"; -constexpr std::string_view MORPH_VERSION_2_0_KEYWORD = "MORPH_VERSION_2_0"; - static constexpr uint32_t INDEX_FOR_LIGHT_CONSTRAINT_TAG = 10; } // unnamed namespace @@ -67,6 +64,7 @@ ModelPrimitivePtr ModelPrimitive::New() } ModelPrimitive::ModelPrimitive() +: mShaderManager(new Scene3D::Loader::ShaderManager()) { } @@ -225,6 +223,18 @@ void ModelPrimitive::RemoveLight(uint32_t lightIndex) mLights[lightIndex].Reset(); } +void ModelPrimitive::UpdateShader(Scene3D::Loader::ShaderManagerPtr shaderManager) +{ + if(mShaderManager != shaderManager) + { + mShaderManager = (shaderManager) ? shaderManager : new Scene3D::Loader::ShaderManager(); + if(mMaterial && GetImplementation(mMaterial).IsResourceReady()) + { + ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag::SHADER); + } + } +} + void ModelPrimitive::SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data) { mBlendShapeData = std::move(data); @@ -236,11 +246,12 @@ void ModelPrimitive::SetBlendShapeGeometry(Dali::Texture blendShapeGeometry) mBlendShapeGeometry = blendShapeGeometry; } -void ModelPrimitive::SetBlendShapeOptions(bool hasPositions, bool hasNormals, bool hasTangents) +void ModelPrimitive::SetBlendShapeOptions(bool hasPositions, bool hasNormals, bool hasTangents, Scene3D::Loader::BlendShapes::Version version) { - mHasPositions = hasPositions; - mHasNormals = hasNormals; - mHasTangents = hasTangents; + mHasPositions = hasPositions; + mHasNormals = hasNormals; + mHasTangents = hasTangents; + mBlendShapeVersion = version; } void ModelPrimitive::SetSkinned(bool isSkinned) @@ -257,44 +268,43 @@ void ModelPrimitive::OnMaterialModified(Dali::Scene3D::Material material, Materi void ModelPrimitive::ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag flag) { + if(!mMaterial) + { + return; + } + uint32_t shaderFlag = (flag & static_cast(MaterialModifyObserver::ModifyFlag::SHADER)); if(mIsMaterialChanged || shaderFlag == static_cast(MaterialModifyObserver::ModifyFlag::SHADER)) { - std::string vertexShader = GetImplementation(mMaterial).GetVertexShader(); - std::string fragmentShader = GetImplementation(mMaterial).GetFragmentShader(); + Scene3D::Loader::ShaderOption shaderOption = GetImplementation(mMaterial).GetShaderOption(); - std::vector defines; - defines.push_back("VEC4_TANGENT"); + shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::VEC4_TANGENT); if(mHasSkinning) { - defines.push_back("SKINNING"); + shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::SKINNING); } if(mHasPositions || mHasNormals || mHasTangents) { if(mHasPositions) { - defines.push_back(MORPH_POSITION_KEYWORD.data()); + shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::MORPH_POSITION); } if(mHasNormals) { - defines.push_back(MORPH_NORMAL_KEYWORD.data()); + shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::MORPH_NORMAL); } if(mHasTangents) { - defines.push_back(MORPH_TANGENT_KEYWORD.data()); + shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::MORPH_TANGENT); } - if(mBlendShapeData.version == Scene3D::Loader::BlendShapes::Version::VERSION_2_0) + if(mBlendShapeVersion == Scene3D::Loader::BlendShapes::Version::VERSION_2_0) { - defines.push_back(MORPH_VERSION_2_0_KEYWORD.data()); + shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::MORPH_VERSION_2_0); } } - for(const auto& define : defines) - { - Scene3D::Loader::ShaderDefinition::ApplyDefine(vertexShader, define); - } mShader.Reset(); - mShader = Shader::New(vertexShader, fragmentShader); + mShader = mShaderManager->ProduceShader(shaderOption); if(!mRenderer) { @@ -445,9 +455,12 @@ void ModelPrimitive::UpdateImageBasedLightTexture() void ModelPrimitive::UpdateRendererUniform() { - mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightScaleFactorName().data(), mIblScaleFactor); - mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightMaxLodUniformName().data(), static_cast(mSpecularMipmapLevels)); - GetImplementation(mMaterial).SetRendererUniform(mRenderer); + if(mMaterial) + { + mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightScaleFactorName().data(), mIblScaleFactor); + mRenderer.RegisterProperty(GetImplementation(mMaterial).GetImageBasedLightMaxLodUniformName().data(), static_cast(mSpecularMipmapLevels)); + GetImplementation(mMaterial).SetRendererUniform(mRenderer); + } } } // namespace Internal diff --git a/dali-scene3d/internal/model-components/model-primitive-impl.h b/dali-scene3d/internal/model-components/model-primitive-impl.h index 027ecac..f37eba6 100644 --- a/dali-scene3d/internal/model-components/model-primitive-impl.h +++ b/dali-scene3d/internal/model-components/model-primitive-impl.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -155,6 +156,13 @@ public: void RemoveLight(uint32_t lightIndex); /** + * @brief Updates shaders by using current material + * + * @param[in] shaderManager Shader manager to create shader. + */ + void UpdateShader(Scene3D::Loader::ShaderManagerPtr shaderManager); + + /** * @brief Sets the blend shape data for this model primitive. * * @param[in] data The blend shape data to set. @@ -174,8 +182,9 @@ public: * @param[in] hasPositions Whether or not this model primitive has positions for blend shapes. * @param[in] hasNormals Whether or not this model primitive has normals for blend shapes. * @param[in] hasTangents Whether or not this model primitive has tangents for blend shapes. + * @param[in] version blendShape version. */ - void SetBlendShapeOptions(bool hasPositions, bool hasNormals, bool hasTangents); + void SetBlendShapeOptions(bool hasPositions, bool hasNormals, bool hasTangents, Scene3D::Loader::BlendShapes::Version version); /** * @brief Sets whether or not this model primitive is skinned. @@ -228,6 +237,8 @@ private: Dali::TextureSet mTextureSet; Dali::Scene3D::Material mMaterial; + Scene3D::Loader::ShaderManagerPtr mShaderManager; + // Light std::vector mLights; int32_t mLightCount{0}; @@ -241,10 +252,11 @@ private: // For blend shape Scene3D::Loader::BlendShapes::BlendShapeData mBlendShapeData; Dali::Texture mBlendShapeGeometry; - bool mHasSkinning = false; - bool mHasPositions = false; - bool mHasNormals = false; - bool mHasTangents = false; + bool mHasSkinning = false; + bool mHasPositions = false; + bool mHasNormals = false; + bool mHasTangents = false; + Scene3D::Loader::BlendShapes::Version mBlendShapeVersion = Scene3D::Loader::BlendShapes::Version::INVALID; bool mIsMaterialChanged = false; bool mNeedToSetRendererUniform = false; diff --git a/dali-scene3d/public-api/file.list b/dali-scene3d/public-api/file.list index 70c1f6c..0c394df 100644 --- a/dali-scene3d/public-api/file.list +++ b/dali-scene3d/public-api/file.list @@ -32,8 +32,8 @@ set(scene3d_src_files ${scene3d_src_files} ${scene3d_public_api_dir}/loader/resource-bundle.cpp ${scene3d_public_api_dir}/loader/scene-definition.cpp ${scene3d_public_api_dir}/loader/shader-definition.cpp - ${scene3d_public_api_dir}/loader/shader-definition-factory.cpp - ${scene3d_public_api_dir}/loader/shader-definition-option.cpp + ${scene3d_public_api_dir}/loader/shader-manager.cpp + ${scene3d_public_api_dir}/loader/shader-option.cpp ${scene3d_public_api_dir}/loader/skinning-details.cpp ${scene3d_public_api_dir}/loader/string-callback.cpp ${scene3d_public_api_dir}/loader/utils.cpp diff --git a/dali-scene3d/public-api/loader/node-definition.cpp b/dali-scene3d/public-api/loader/node-definition.cpp index 16d0189..d3e8c36 100644 --- a/dali-scene3d/public-api/loader/node-definition.cpp +++ b/dali-scene3d/public-api/loader/node-definition.cpp @@ -22,11 +22,12 @@ #include // INTERNAL INCLUDES +#include #include +#include #include #include #include -#include namespace Dali { @@ -255,7 +256,20 @@ void ModelRenderable::ReflectResources(IResourceReflector& reflector) void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinition::CreateParams& params, ModelNode& node) const { DALI_ASSERT_DEBUG(mMeshIdx != INVALID_INDEX); - Renderable::OnCreate(nodeDefinition, params, node); + if(mShaderIdx == INVALID_INDEX) + { + Shader shader = params.mShaderManager->ProduceShader(params.mResources.mMaterials[mMaterialIdx].first, params.mResources.mMeshes[mMeshIdx].first); + static Geometry defaultGeometry = Geometry::New(); + Renderer renderer = Renderer::New(defaultGeometry, shader); + + RendererState::Apply(params.mShaderManager->GetRendererState(params.mResources.mMaterials[mMaterialIdx].first), renderer); + Internal::GetImplementation(node).UpdateShader(params.mShaderManager); + node.AddRenderer(renderer); + } + else + { + Renderable::OnCreate(nodeDefinition, params, node); + } auto& resources = params.mResources; auto& mesh = resources.mMeshes[mMeshIdx]; @@ -299,7 +313,7 @@ void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinit bool hasNormals = false; bool hasTangents = false; mesh.first.RetrieveBlendShapeComponents(hasPositions, hasNormals, hasTangents); - GetImplementation(primitive).SetBlendShapeOptions(hasPositions, hasNormals, hasTangents); + GetImplementation(primitive).SetBlendShapeOptions(hasPositions, hasNormals, hasTangents, mesh.first.mBlendShapeVersion); GetImplementation(primitive).SetBlendShapeGeometry(mesh.second.blendShapeGeometry); GetImplementation(primitive).SetSkinned(mesh.first.IsSkinned()); } @@ -360,6 +374,8 @@ void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinit node.SetProperty(Actor::Property::COLOR, mColor); + // If user uses customshader, the properties of the shader could not be changed by Material. + if(mShaderIdx == INVALID_INDEX) { matDef.mMaterial = Material::New(); auto material = matDef.mMaterial; diff --git a/dali-scene3d/public-api/loader/node-definition.h b/dali-scene3d/public-api/loader/node-definition.h index 02d056f..f3aa578 100644 --- a/dali-scene3d/public-api/loader/node-definition.h +++ b/dali-scene3d/public-api/loader/node-definition.h @@ -30,6 +30,7 @@ #include #include #include +#include #include namespace Dali @@ -150,8 +151,9 @@ public: // TYPES struct CreateParams { public: // input - ResourceBundle& mResources; - Transforms& mXforms; + ResourceBundle& mResources; + Transforms& mXforms; + Dali::Scene3D::Loader::ShaderManagerPtr mShaderManager; public: // output std::vector mConstrainables; diff --git a/dali-scene3d/public-api/loader/scene-definition.cpp b/dali-scene3d/public-api/loader/scene-definition.cpp index cf5aa61..370e926 100644 --- a/dali-scene3d/public-api/loader/scene-definition.cpp +++ b/dali-scene3d/public-api/loader/scene-definition.cpp @@ -48,39 +48,50 @@ const std::map& GetCons { static const std::map sConstraintFactory = { {Property::Type::BOOLEAN, - [](Actor& a, Property::Index i) { - return Constraint::New(a, i, [](bool& current, const PropertyInputContainer& inputs) { current = inputs[0]->GetBoolean(); }); + [](Actor& a, Property::Index i) + { + return Constraint::New(a, i, [](bool& current, const PropertyInputContainer& inputs) + { current = inputs[0]->GetBoolean(); }); }}, {Property::Type::INTEGER, - [](Actor& a, Property::Index i) { - return Constraint::New(a, i, [](int& current, const PropertyInputContainer& inputs) { current = inputs[0]->GetInteger(); }); + [](Actor& a, Property::Index i) + { + return Constraint::New(a, i, [](int& current, const PropertyInputContainer& inputs) + { current = inputs[0]->GetInteger(); }); }}, {Property::Type::FLOAT, - [](Actor& a, Property::Index i) { + [](Actor& a, Property::Index i) + { return Constraint::New(a, i, EqualToConstraint()); }}, {Property::Type::VECTOR2, - [](Actor& a, Property::Index i) { + [](Actor& a, Property::Index i) + { return Constraint::New(a, i, EqualToConstraint()); }}, {Property::Type::VECTOR3, - [](Actor& a, Property::Index i) { + [](Actor& a, Property::Index i) + { return Constraint::New(a, i, EqualToConstraint()); }}, {Property::Type::VECTOR4, - [](Actor& a, Property::Index i) { + [](Actor& a, Property::Index i) + { return Constraint::New(a, i, EqualToConstraint()); }}, {Property::Type::MATRIX, - [](Actor& a, Property::Index i) { + [](Actor& a, Property::Index i) + { return Constraint::New(a, i, EqualToConstraint()); }}, {Property::Type::MATRIX3, - [](Actor& a, Property::Index i) { + [](Actor& a, Property::Index i) + { return Constraint::New(a, i, EqualToConstraint()); }}, {Property::Type::ROTATION, - [](Actor& a, Property::Index i) { + [](Actor& a, Property::Index i) + { return Constraint::New(a, i, EqualToConstraint()); }}, }; @@ -159,7 +170,7 @@ void AddJointDebugVisual(Actor aJoint) aJoint.SetVisible(true); } -#endif //DEBUG_JOINTS +#endif // DEBUG_JOINTS class ActorCreatorVisitor : public NodeDefinition::IVisitor { @@ -234,7 +245,8 @@ void SortAndDeduplicateRequests(std::vector& requests) ++iter; } while(true); - requests.erase(std::remove_if(requests.begin(), requests.end(), [](const RequestType& sscr) { return !sscr.mShader; }), + requests.erase(std::remove_if(requests.begin(), requests.end(), [](const RequestType& sscr) + { return !sscr.mShader; }), requests.end()); } @@ -371,7 +383,10 @@ void SceneDefinition::CountResourceRefs(Index iNode, const Customization::Choice void Register(ResourceType::Value type, Index id) { - ++(*refCounts)[type][id]; + if((!(*refCounts)[type].Empty()) && (id >= 0) && ((*refCounts)[type].Size() > id)) + { + ++(*refCounts)[type][id]; + } } }; @@ -479,15 +494,15 @@ bool SceneDefinition::ReparentNode(const std::string& name, const std::string& n auto& node = *nodePtr; auto iNode = std::distance(mNodes.data(), nodePtr); - DEBUG_ONLY(auto dumpNode = [](NodeDefinition const& n) { + DEBUG_ONLY(auto dumpNode = [](NodeDefinition const& n) + { std::ostringstream stream; stream << n.mName << " (" << n.mParentIdx << "):"; for(auto i : n.mChildren) { stream << i << ", "; } - LOGD(("%s", stream.str().c_str())); - };) + LOGD(("%s", stream.str().c_str())); };) // Remove node from children of previous parent (if any). if(node->mParentIdx != INVALID_INDEX) @@ -533,15 +548,16 @@ bool SceneDefinition::RemoveNode(const std::string& name) auto& thisNodes = mNodes; unsigned int numReset = 0; std::function&)> resetFn = - [&thisNodes, &resetFn, &numReset](std::unique_ptr& nd) { - LOGD(("resetting %d", &nd - thisNodes.data())); - for(auto i : nd->mChildren) - { - resetFn(thisNodes[i]); - } - nd.reset(); - ++numReset; - }; + [&thisNodes, &resetFn, &numReset](std::unique_ptr& nd) + { + LOGD(("resetting %d", &nd - thisNodes.data())); + for(auto i : nd->mChildren) + { + resetFn(thisNodes[i]); + } + nd.reset(); + ++numReset; + }; resetFn(*node); @@ -564,7 +580,8 @@ bool SceneDefinition::RemoveNode(const std::string& name) { INDEX_FOR_REMOVAL = INVALID_INDEX }; - auto offsetter = [&offsets](Index& i) { + auto offsetter = [&offsets](Index& i) + { auto iFind = std::lower_bound(offsets.begin(), offsets.end(), i); if(iFind != offsets.end() && *iFind == i) { @@ -604,7 +621,8 @@ bool SceneDefinition::RemoveNode(const std::string& name) void SceneDefinition::GetNodeModelStack(Index index, MatrixStack& model) const { auto& thisNodes = mNodes; - std::function buildStack = [&model, &thisNodes, &buildStack](int i) { + std::function buildStack = [&model, &thisNodes, &buildStack](int i) + { auto node = thisNodes[i].get(); if(node->mParentIdx != INVALID_INDEX) { @@ -619,7 +637,8 @@ NodeDefinition* SceneDefinition::FindNode(const std::string& name, Index* outInd { auto iBegin = mNodes.begin(); auto iEnd = mNodes.end(); - auto iFind = std::find_if(iBegin, iEnd, [&name](const std::unique_ptr& nd) { return nd->mName == name; }); + auto iFind = std::find_if(iBegin, iEnd, [&name](const std::unique_ptr& nd) + { return nd->mName == name; }); auto result = iFind != iEnd ? iFind->get() : nullptr; if(result && outIndex) @@ -633,7 +652,8 @@ const NodeDefinition* SceneDefinition::FindNode(const std::string& name, Index* { auto iBegin = mNodes.begin(); auto iEnd = mNodes.end(); - auto iFind = std::find_if(iBegin, iEnd, [&name](const std::unique_ptr& nd) { return nd->mName == name; }); + auto iFind = std::find_if(iBegin, iEnd, [&name](const std::unique_ptr& nd) + { return nd->mName == name; }); auto result = iFind != iEnd ? iFind->get() : nullptr; if(result && outIndex) @@ -647,7 +667,8 @@ Index SceneDefinition::FindNodeIndex(const NodeDefinition& node) const { auto iBegin = mNodes.begin(); auto iEnd = mNodes.end(); - auto iFind = std::find_if(iBegin, iEnd, [&node](const std::unique_ptr& n) { return n.get() == &node; }); + auto iFind = std::find_if(iBegin, iEnd, [&node](const std::unique_ptr& n) + { return n.get() == &node; }); return iFind != iEnd ? std::distance(iBegin, iFind) : INVALID_INDEX; } @@ -938,7 +959,8 @@ bool SceneDefinition::FindNode(const std::string& name, std::unique_ptr& nd) { return nd->mName == name; }) + auto iFind = std::find_if(mNodes.rbegin(), mNodes.rend(), [&name](const std::unique_ptr& nd) + { return nd->mName == name; }) .base(); const bool success = iFind != mNodes.begin(); diff --git a/dali-scene3d/public-api/loader/shader-definition-factory.cpp b/dali-scene3d/public-api/loader/shader-definition-factory.cpp deleted file mode 100644 index 5eadd67..0000000 --- a/dali-scene3d/public-api/loader/shader-definition-factory.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// CLASS HEADER -#include - -// EXTERNAL INCLUDES -#include -#include - -// INTERNAL INCLUDES -#include -#include -#include -#include - -namespace Dali::Scene3D::Loader -{ -namespace -{ -struct ResourceReceiver : IResourceReceiver -{ - const ResourceBundle& mResources; - const MeshDefinition* mMeshDef = nullptr; - const MaterialDefinition* mMaterialDef = nullptr; - - ResourceReceiver(const ResourceBundle& resources) - : mResources(resources) - { - } - - void Register(ResourceType::Value type, Index id) override - { - switch(type) - { - case ResourceType::Mesh: - mMeshDef = &mResources.mMeshes[id].first; - break; - - case ResourceType::Material: - mMaterialDef = &mResources.mMaterials[id].first; - break; - - default: - break; - } - } -}; - -ShaderDefinitionOption MakeOption(const MaterialDefinition& materialDef, const MeshDefinition& meshDef) -{ - ShaderDefinitionOption option; - - const bool hasTransparency = MaskMatch(materialDef.mFlags, MaterialDefinition::TRANSPARENCY); - if(hasTransparency) - { - option.SetTransparency(); - } - - if(hasTransparency || - !materialDef.CheckTextures(MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC) || - !materialDef.CheckTextures(MaterialDefinition::NORMAL | MaterialDefinition::ROUGHNESS)) - { - option.AddOption(ShaderDefinitionOption::Type::THREE_TEXTURE); - - // For the glTF, each of basecolor, metallic_roughness, normal texture is not essential. - if(MaskMatch(materialDef.mFlags, MaterialDefinition::ALBEDO)) - { - option.AddOption(ShaderDefinitionOption::Type::BASE_COLOR_TEXTURE); - } - - if(materialDef.CheckTextures(MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS)) - { - option.AddOption(ShaderDefinitionOption::Type::METALLIC_ROUGHNESS_TEXTURE); - } - - if(MaskMatch(materialDef.mFlags, MaterialDefinition::NORMAL)) - { - option.AddOption(ShaderDefinitionOption::Type::NORMAL_TEXTURE); - } - } - - if(materialDef.GetAlphaCutoff() > 0.f) - { - option.AddOption(ShaderDefinitionOption::Type::ALPHA_TEST); - } - - if(MaskMatch(materialDef.mFlags, MaterialDefinition::SUBSURFACE)) - { - option.AddOption(ShaderDefinitionOption::Type::SUBSURFACE); - } - - if(MaskMatch(materialDef.mFlags, MaterialDefinition::OCCLUSION)) - { - option.AddOption(ShaderDefinitionOption::Type::OCCLUSION); - } - - if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE)) - { - option.AddOption(ShaderDefinitionOption::Type::EMISSIVE); - } - - if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR)) - { - option.AddOption(ShaderDefinitionOption::Type::SPECULAR); - } - - if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR_COLOR)) - { - option.AddOption(ShaderDefinitionOption::Type::SPECULAR_COLOR); - } - - if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS)) - { - option.AddOption(ShaderDefinitionOption::Type::GLTF_CHANNELS); - } - - if(meshDef.IsSkinned()) - { - option.AddOption(ShaderDefinitionOption::Type::SKINNING); - } - - if(MaskMatch(meshDef.mFlags, MeshDefinition::FLIP_UVS_VERTICAL)) - { - option.AddOption(ShaderDefinitionOption::Type::FLIP_UVS_VERTICAL); - } - - if(meshDef.mColors.IsDefined()) - { - option.AddOption(ShaderDefinitionOption::Type::COLOR_ATTRIBUTE); - } - - if(meshDef.mTangentType == Property::VECTOR4) - { - option.AddOption(ShaderDefinitionOption::Type::VEC4_TANGENT); - } - - if(meshDef.HasBlendShapes()) - { - bool hasPositions = false; - bool hasNormals = false; - bool hasTangents = false; - meshDef.RetrieveBlendShapeComponents(hasPositions, hasNormals, hasTangents); - if(hasPositions) - { - option.AddOption(ShaderDefinitionOption::Type::MORPH_POSITION); - } - - if(hasNormals) - { - option.AddOption(ShaderDefinitionOption::Type::MORPH_NORMAL); - } - - if(hasTangents) - { - option.AddOption(ShaderDefinitionOption::Type::MORPH_TANGENT); - } - - if(hasPositions || hasNormals || hasTangents) - { - if(BlendShapes::Version::VERSION_2_0 == meshDef.mBlendShapeVersion) - { - option.AddOption(ShaderDefinitionOption::Type::MORPH_VERSION_2_0); - } - } - } - - return option; -} -} // namespace - -struct ShaderDefinitionFactory::Impl -{ - ResourceBundle* mResources; // no ownership - std::map mShaderMap; -}; - -ShaderDefinitionFactory::ShaderDefinitionFactory() -: mImpl{new Impl()} -{ -} - -ShaderDefinitionFactory::~ShaderDefinitionFactory() = default; - -void ShaderDefinitionFactory::SetResources(ResourceBundle& resources) -{ - mImpl->mResources = &resources; - mImpl->mShaderMap.clear(); -} - -Index ShaderDefinitionFactory::ProduceShader(NodeDefinition::Renderable& renderable) -{ - auto& resources = *mImpl->mResources; - - ResourceReceiver receiver{resources}; - renderable.RegisterResources(receiver); - - if(!(receiver.mMeshDef && receiver.mMaterialDef)) - { - renderable.mShaderIdx = INVALID_INDEX; - return INVALID_INDEX; - } - - auto& shaderMap = mImpl->mShaderMap; - ShaderDefinitionOption option = MakeOption(*receiver.mMaterialDef, *receiver.mMeshDef); - uint64_t hash = option.GetOptionHash(); - auto iFind = shaderMap.find(hash); - if(iFind != shaderMap.end()) - { - renderable.mShaderIdx = iFind->second; - } - else - { - ShaderDefinition shaderDef; - shaderDef.mUseBuiltInShader = true; - shaderDef.mRendererState = RendererState::DEPTH_TEST; - - auto& materialDef = *receiver.mMaterialDef; - if(!materialDef.mDoubleSided) - { - shaderDef.mRendererState |= RendererState::CULL_BACK; - } - - const bool hasTransparency = MaskMatch(materialDef.mFlags, MaterialDefinition::TRANSPARENCY); - if(hasTransparency) - { - // TODO: this requires more granularity - shaderDef.mRendererState = (shaderDef.mRendererState | RendererState::ALPHA_BLEND); - } - - option.GetDefines(shaderDef.mDefines); - shaderDef.mUniforms["uCubeMatrix"] = Matrix::IDENTITY; - - Index result = resources.mShaders.size(); - shaderMap[hash] = result; - - resources.mShaders.emplace_back(std::move(shaderDef), Shader()); - - renderable.mShaderIdx = result; - } - - return renderable.mShaderIdx; -} - -} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/shader-definition-factory.h b/dali-scene3d/public-api/loader/shader-definition-factory.h deleted file mode 100644 index 273ac8f..0000000 --- a/dali-scene3d/public-api/loader/shader-definition-factory.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef DALI_SCENE3D_LOADER_SHADER_DEFINITION_FACTORY_H_ -#define DALI_SCENE3D_LOADER_SHADER_DEFINITION_FACTORY_H_ -/* - * Copyright (c) 2023 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// EXTERNAL INCLUDER -#include - -// INTERNAL INCLUDES -#include -#include -#include - -namespace Dali::Scene3D::Loader -{ -struct NodeDefinition; -class ResourceBundle; - -class DALI_SCENE3D_API ShaderDefinitionFactory -{ -public: - ShaderDefinitionFactory(); - ~ShaderDefinitionFactory(); - - /* - * @brief Input for meshes and materials, output for shaders. - */ - void SetResources(ResourceBundle& resources); - - /* - * @brief Produces the index of a shader, which should be used to index into the shaders - * vector of the ResourceBundle which was provided for the factory. This shader will be - * created if one with the given settings hasn't been created by the factory yet (shaders - * already existing in the ResourceBundle are ignored), otherwise the index of the previously - * created shader will be returned. - */ - Index ProduceShader(NodeDefinition::Renderable& renderable); - -private: - struct Impl; - const std::unique_ptr mImpl; -}; - -} // namespace Dali::Scene3D::Loader - -#endif //DALI_SCENE3D_LOADER_SHADER_DEFINITION_FACTORY_H_ diff --git a/dali-scene3d/public-api/loader/shader-definition.h b/dali-scene3d/public-api/loader/shader-definition.h index 27bb051..61f4a7c 100644 --- a/dali-scene3d/public-api/loader/shader-definition.h +++ b/dali-scene3d/public-api/loader/shader-definition.h @@ -52,7 +52,7 @@ struct DALI_SCENE3D_API ShaderDefinition ShaderDefinition(const ShaderDefinition& other); ShaderDefinition& operator=(const ShaderDefinition& other); - ShaderDefinition(ShaderDefinition&&) = default; + ShaderDefinition(ShaderDefinition&&) = default; ShaderDefinition& operator=(ShaderDefinition&&) = default; /* diff --git a/dali-scene3d/public-api/loader/shader-manager.cpp b/dali-scene3d/public-api/loader/shader-manager.cpp new file mode 100644 index 0000000..0978f20 --- /dev/null +++ b/dali-scene3d/public-api/loader/shader-manager.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// CLASS HEADER +#include + +// EXTERNAL INCLUDES +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include + +namespace Dali::Scene3D::Loader +{ +namespace +{ + +ShaderOption MakeOption(const MaterialDefinition& materialDef, const MeshDefinition& meshDef) +{ + ShaderOption option; + + const bool hasTransparency = MaskMatch(materialDef.mFlags, MaterialDefinition::TRANSPARENCY); + if(hasTransparency) + { + option.SetTransparency(); + } + + if(hasTransparency || + !materialDef.CheckTextures(MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC) || + !materialDef.CheckTextures(MaterialDefinition::NORMAL | MaterialDefinition::ROUGHNESS)) + { + option.AddOption(ShaderOption::Type::THREE_TEXTURE); + + // For the glTF, each of basecolor, metallic_roughness, normal texture is not essential. + if(MaskMatch(materialDef.mFlags, MaterialDefinition::ALBEDO)) + { + option.AddOption(ShaderOption::Type::BASE_COLOR_TEXTURE); + } + + if(materialDef.CheckTextures(MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS)) + { + option.AddOption(ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE); + } + + if(MaskMatch(materialDef.mFlags, MaterialDefinition::NORMAL)) + { + option.AddOption(ShaderOption::Type::NORMAL_TEXTURE); + } + } + + if(materialDef.GetAlphaCutoff() > 0.f) + { + option.AddOption(ShaderOption::Type::ALPHA_TEST); + } + + if(MaskMatch(materialDef.mFlags, MaterialDefinition::SUBSURFACE)) + { + option.AddOption(ShaderOption::Type::SUBSURFACE); + } + + if(MaskMatch(materialDef.mFlags, MaterialDefinition::OCCLUSION)) + { + option.AddOption(ShaderOption::Type::OCCLUSION); + } + + if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE)) + { + option.AddOption(ShaderOption::Type::EMISSIVE); + } + + if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR)) + { + option.AddOption(ShaderOption::Type::SPECULAR); + } + + if(MaskMatch(materialDef.mFlags, MaterialDefinition::SPECULAR_COLOR)) + { + option.AddOption(ShaderOption::Type::SPECULAR_COLOR); + } + + if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS)) + { + option.AddOption(ShaderOption::Type::GLTF_CHANNELS); + } + + if(meshDef.IsSkinned()) + { + option.AddOption(ShaderOption::Type::SKINNING); + } + + if(MaskMatch(meshDef.mFlags, MeshDefinition::FLIP_UVS_VERTICAL)) + { + option.AddOption(ShaderOption::Type::FLIP_UVS_VERTICAL); + } + + if(meshDef.mColors.IsDefined()) + { + option.AddOption(ShaderOption::Type::COLOR_ATTRIBUTE); + } + + if(meshDef.mTangentType == Property::VECTOR4) + { + option.AddOption(ShaderOption::Type::VEC4_TANGENT); + } + + if(meshDef.HasBlendShapes()) + { + bool hasPositions = false; + bool hasNormals = false; + bool hasTangents = false; + meshDef.RetrieveBlendShapeComponents(hasPositions, hasNormals, hasTangents); + if(hasPositions) + { + option.AddOption(ShaderOption::Type::MORPH_POSITION); + } + + if(hasNormals) + { + option.AddOption(ShaderOption::Type::MORPH_NORMAL); + } + + if(hasTangents) + { + option.AddOption(ShaderOption::Type::MORPH_TANGENT); + } + + if(hasPositions || hasNormals || hasTangents) + { + if(BlendShapes::Version::VERSION_2_0 == meshDef.mBlendShapeVersion) + { + option.AddOption(ShaderOption::Type::MORPH_VERSION_2_0); + } + } + } + + return option; +} +} // namespace + +struct ShaderManager::Impl +{ + std::map mShaderMap; + std::vector mShaders; +}; + +ShaderManager::ShaderManager() +: mImpl{new Impl()} +{ +} + +ShaderManager::~ShaderManager() = default; + +Dali::Shader ShaderManager::ProduceShader(const MaterialDefinition& materialDefinition, const MeshDefinition& meshDefinition) +{ + ShaderOption option = MakeOption(materialDefinition, meshDefinition); + return ProduceShader(option); +} + +Dali::Shader ShaderManager::ProduceShader(const ShaderOption& shaderOption) +{ + Dali::Shader result; + + auto& shaderMap = mImpl->mShaderMap; + uint64_t hash = shaderOption.GetOptionHash(); + auto iFind = shaderMap.find(hash); + if(iFind != shaderMap.end()) + { + result = mImpl->mShaders[iFind->second]; + } + else + { + ShaderDefinition shaderDef; + shaderDef.mUseBuiltInShader = true; + + shaderOption.GetDefines(shaderDef.mDefines); + shaderDef.mUniforms["uCubeMatrix"] = Matrix::IDENTITY; + + shaderMap[hash] = mImpl->mShaders.size(); + + auto raw = shaderDef.LoadRaw(""); + mImpl->mShaders.emplace_back(shaderDef.Load(std::move(raw))); + result = mImpl->mShaders.back(); + } + + return result; +} + +RendererState::Type ShaderManager::GetRendererState(const MaterialDefinition& materialDefinition) +{ + RendererState::Type rendererState = RendererState::DEPTH_TEST; + + if(!materialDefinition.mDoubleSided) + { + rendererState |= RendererState::CULL_BACK; + } + + const bool hasTransparency = MaskMatch(materialDefinition.mFlags, MaterialDefinition::TRANSPARENCY); + if(hasTransparency) + { + // TODO: this requires more granularity + rendererState = (rendererState | RendererState::ALPHA_BLEND); + } + return rendererState; +} + +} // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/shader-manager.h b/dali-scene3d/public-api/loader/shader-manager.h new file mode 100644 index 0000000..4c8988a --- /dev/null +++ b/dali-scene3d/public-api/loader/shader-manager.h @@ -0,0 +1,83 @@ +#ifndef DALI_SCENE3D_LOADER_SHADER_MANAGER_H_ +#define DALI_SCENE3D_LOADER_SHADER_MANAGER_H_ +/* + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDER +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include +#include +#include + +namespace Dali::Scene3D::Loader +{ +struct NodeDefinition; +class ResourceBundle; +class ShaderManager; +typedef IntrusivePtr ShaderManagerPtr; + +/** + * @brief This class is to manage Shaders. + * This class could be used as factory class to create Dali::Shader. + * And once created Dali::Shader is kept in this manager and will be returned when the same Dali::Shader is requested to be created. + */ +class DALI_SCENE3D_API ShaderManager : public RefObject +{ +public: + ShaderManager(); + ~ShaderManager(); + + /** + * @brief Produces a Dali::Shader for the input materialDefinition and meshDefinition. + * Returns a cached Dali::Shader if the requested Dali::Shader has already been created once. + * (Although the input materialDefinition and meshDefinition are not identical to those used to create the cached Dali::Shader, they share the cached one.) + * @param[in] materialDefinition MaterialDefinition that includes information of material to create Shader. + * @param[in] meshDefinition meshDefinition that includes information of mesh to create Shader. + * @return Dali::Shader for the materialDefinition and meshDefinition. + */ + Dali::Shader ProduceShader(const MaterialDefinition& materialDefinition, const MeshDefinition& meshDefinition); + + /** + * @brief Produces a Dali::Shader for the input ShaderOption + * Returns a cached Dali::Shader if the requested Dali::Shader has already been created once. + * @param[in] shaderOption shader option to create Shader. + * @return Dali::Shader of the shader option + */ + Dali::Shader ProduceShader(const ShaderOption& shaderOption); + + /** + * @brief Returns RendererState of the input materialDefinition. + * @param[in] materialDefinition MaterialDefinition to get RendererState + * @return RendererState of the materialDefinition. + */ + RendererState::Type GetRendererState(const MaterialDefinition& materialDefinition); + +private: + struct Impl; + const std::unique_ptr mImpl; +}; + +} // namespace Dali::Scene3D::Loader + +#endif // DALI_SCENE3D_LOADER_SHADER_MANAGER_H_ diff --git a/dali-scene3d/public-api/loader/shader-definition-option.cpp b/dali-scene3d/public-api/loader/shader-option.cpp similarity index 73% rename from dali-scene3d/public-api/loader/shader-definition-option.cpp rename to dali-scene3d/public-api/loader/shader-option.cpp index 18360de..85489ab 100644 --- a/dali-scene3d/public-api/loader/shader-definition-option.cpp +++ b/dali-scene3d/public-api/loader/shader-option.cpp @@ -16,7 +16,7 @@ */ // CLASS HEADER -#include +#include // EXTERNAL INCLUDES #include @@ -50,22 +50,22 @@ static constexpr std::string_view OPTION_KEYWORD[] = static constexpr uint32_t NUMBER_OF_OPTIONS = sizeof(OPTION_KEYWORD) / sizeof(OPTION_KEYWORD[0]); } // namespace -void ShaderDefinitionOption::SetTransparency() +void ShaderOption::SetTransparency() { mOptionHash |= (1 << NUMBER_OF_OPTIONS); } -void ShaderDefinitionOption::AddOption(Type shaderDefinitionOptionType) +void ShaderOption::AddOption(Type shaderOptionType) { - mOptionHash |= (1 << static_cast(shaderDefinitionOptionType)); + mOptionHash |= (1 << static_cast(shaderOptionType)); } -uint64_t ShaderDefinitionOption::GetOptionHash() const +uint64_t ShaderOption::GetOptionHash() const { return mOptionHash; } -void ShaderDefinitionOption::GetDefines(std::vector& defines) const +void ShaderOption::GetDefines(std::vector& defines) const { defines.clear(); for(uint32_t i = 0; i < NUMBER_OF_OPTIONS; ++i) @@ -77,9 +77,9 @@ void ShaderDefinitionOption::GetDefines(std::vector& defines) const } } -std::string_view ShaderDefinitionOption::GetDefineKeyword(Type shaderDefinitionOptionType) +std::string_view ShaderOption::GetDefineKeyword(Type shaderOptionType) { - return OPTION_KEYWORD[static_cast(shaderDefinitionOptionType)]; + return OPTION_KEYWORD[static_cast(shaderOptionType)]; } } // namespace Dali::Scene3D::Loader diff --git a/dali-scene3d/public-api/loader/shader-definition-option.h b/dali-scene3d/public-api/loader/shader-option.h similarity index 80% rename from dali-scene3d/public-api/loader/shader-definition-option.h rename to dali-scene3d/public-api/loader/shader-option.h index 3dc56be..e9d95c2 100644 --- a/dali-scene3d/public-api/loader/shader-definition-option.h +++ b/dali-scene3d/public-api/loader/shader-option.h @@ -1,5 +1,5 @@ -#ifndef DALI_SCENE3D_LOADER_SHADER_DEFINITION_OPTION_H_ -#define DALI_SCENE3D_LOADER_SHADER_DEFINITION_OPTION_H_ +#ifndef DALI_SCENE3D_LOADER_SHADER_OPTION_H_ +#define DALI_SCENE3D_LOADER_SHADER_OPTION_H_ /* * Copyright (c) 2023 Samsung Electronics Co., Ltd. * @@ -28,7 +28,7 @@ namespace Dali::Scene3D::Loader { -class DALI_SCENE3D_API ShaderDefinitionOption +class DALI_SCENE3D_API ShaderOption { public: enum class Type @@ -64,9 +64,9 @@ public: * @brief Adds new shader definition option. * If the option is already added, nothin is changed. * - * @param[in] shaderDefinitionOptionType Option to be added, + * @param[in] shaderOptionType Option to be added, */ - void AddOption(Type shaderDefinitionOptionType); + void AddOption(Type shaderOptionType); /** * @brief Retrieves current shader option hash @@ -85,10 +85,10 @@ public: /** * @brief Retrieves a single shader define keyword of input type. * - * @param[in] shaderDefinitionOptionType Shader definition option type to know its keyword. + * @param[in] shaderOptionType Shader definition option type to know its keyword. * @return string keyword of shader define. */ - static std::string_view GetDefineKeyword(Type shaderDefinitionOptionType); + static std::string_view GetDefineKeyword(Type shaderOptionType); private: uint64_t mOptionHash{0u}; @@ -96,4 +96,4 @@ private: } // namespace Dali::Scene3D::Loader -#endif // DALI_SCENE3D_LOADER_SHADER_DEFINITION_OPTION_H_ +#endif // DALI_SCENE3D_LOADER_SHADER_OPTION_H_ -- 2.7.4