From bba5eb041ddecae942c5a123fc470152485a2d12 Mon Sep 17 00:00:00 2001 From: seungho baek Date: Tue, 5 Dec 2023 17:37:37 +0900 Subject: [PATCH] Use DepthIndex for 3D rendering order Change-Id: Id722744a3db4aa1504ae45894b6edcc4039994d7 Signed-off-by: seungho baek --- .../utc-Dali-ModelPrimitiveImpl.cpp | 29 +++++++++++ .../src/dali-scene3d/utc-Dali-Material.cpp | 6 ++- .../src/dali-scene3d/utc-Dali-ModelPrimitive.cpp | 2 +- .../internal/model-components/material-impl.cpp | 20 ++++++++ .../internal/model-components/material-impl.h | 10 ++++ .../model-components/material-modify-observer.h | 9 ++-- .../model-components/model-primitive-impl.cpp | 22 ++++++-- .../model-components/model-primitive-impl.h | 6 ++- .../public-api/common/scene-depth-index-ranges.h | 58 ++++++++++++++++++++++ .../public-api/model-components/material.h | 36 +++++++++++--- 10 files changed, 181 insertions(+), 17 deletions(-) create mode 100644 dali-scene3d/public-api/common/scene-depth-index-ranges.h diff --git a/automated-tests/src/dali-scene3d-internal/utc-Dali-ModelPrimitiveImpl.cpp b/automated-tests/src/dali-scene3d-internal/utc-Dali-ModelPrimitiveImpl.cpp index 00dba92..57ba4c2 100644 --- a/automated-tests/src/dali-scene3d-internal/utc-Dali-ModelPrimitiveImpl.cpp +++ b/automated-tests/src/dali-scene3d-internal/utc-Dali-ModelPrimitiveImpl.cpp @@ -21,6 +21,7 @@ #include #include +#include using namespace Dali; using namespace Dali::Toolkit; @@ -62,4 +63,32 @@ int UtcDaliModelPrimitiveImplSetData(void) DALI_TEST_CHECK(GetImplementation(modelPrimitive).GetRenderer()); END_TEST; +} + +int UtcDaliModelPrimitiveMaterialDepthIndex(void) +{ + ToolkitTestApplication application; + + Scene3D::ModelPrimitive modelPrimitive = Scene3D::ModelPrimitive::New(); + + tet_printf("Check primitive don't have material initial time\n"); + + DALI_TEST_CHECK(!modelPrimitive.GetMaterial()); + + Dali::Geometry geometry = Dali::Geometry::New(); + Dali::Scene3D::Material material = Dali::Scene3D::Material::New(); + + modelPrimitive.SetGeometry(geometry); + modelPrimitive.SetMaterial(material); + DALI_TEST_CHECK(material == modelPrimitive.GetMaterial()); + + DALI_TEST_CHECK(GetImplementation(modelPrimitive).GetRenderer()); + + Dali::Renderer renderer = GetImplementation(modelPrimitive).GetRenderer(); + DALI_TEST_CHECK(renderer.GetProperty(Dali::Renderer::Property::DEPTH_INDEX) == Scene3D::DepthIndex::Ranges::SCENE); + + material.SetProperty(Scene3D::Material::Property::DEPTH_INDEX, 50); + DALI_TEST_CHECK(renderer.GetProperty(Dali::Renderer::Property::DEPTH_INDEX) == 50); + + END_TEST; } \ No newline at end of file diff --git a/automated-tests/src/dali-scene3d/utc-Dali-Material.cpp b/automated-tests/src/dali-scene3d/utc-Dali-Material.cpp index c3fcdd0..36f6a22 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-Material.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-Material.cpp @@ -224,6 +224,10 @@ int UtcDaliMaterialSetGetProperty(void) material.SetProperty(Scene3D::Material::Property::SPECULAR_COLOR_FACTOR, specularColorFactor); DALI_TEST_EQUALS(specularColorFactor, material.GetProperty(Scene3D::Material::Property::SPECULAR_COLOR_FACTOR), TEST_LOCATION); + int32_t depthIndex = 50; + material.SetProperty(Scene3D::Material::Property::DEPTH_INDEX, depthIndex); + DALI_TEST_EQUALS(depthIndex, material.GetProperty(Scene3D::Material::Property::DEPTH_INDEX), TEST_LOCATION); + END_TEST; } @@ -307,4 +311,4 @@ int UtcDaliMaterialSetGetSampler(void) DALI_TEST_CHECK(!material.GetSampler((Scene3D::Material::TextureType)100)); END_TEST; -} \ No newline at end of file +} diff --git a/automated-tests/src/dali-scene3d/utc-Dali-ModelPrimitive.cpp b/automated-tests/src/dali-scene3d/utc-Dali-ModelPrimitive.cpp index 3719861..0733aab 100644 --- a/automated-tests/src/dali-scene3d/utc-Dali-ModelPrimitive.cpp +++ b/automated-tests/src/dali-scene3d/utc-Dali-ModelPrimitive.cpp @@ -184,4 +184,4 @@ int UtcDaliModelPrimitiveSetGetMaterial(void) DALI_TEST_CHECK(material2 == modelPrimitive.GetMaterial()); END_TEST; -} \ No newline at end of file +} diff --git a/dali-scene3d/internal/model-components/material-impl.cpp b/dali-scene3d/internal/model-components/material-impl.cpp index 0e58ce5..0eb6213 100644 --- a/dali-scene3d/internal/model-components/material-impl.cpp +++ b/dali-scene3d/internal/model-components/material-impl.cpp @@ -324,6 +324,16 @@ void Material::SetProperty(Dali::Property::Index index, Dali::Property::Value pr } break; } + case Dali::Scene3D::Material::Property::DEPTH_INDEX: + { + int32_t depthIndex = 0; + if(propertyValue.Get(depthIndex) && mDepthIndex != depthIndex) + { + mDepthIndex = depthIndex; + mModifyFlag |= MaterialModifyObserver::ModifyFlag::PROPERTY; + } + break; + } } if(needToApply) @@ -437,6 +447,11 @@ Dali::Property::Value Material::GetProperty(Dali::Property::Index index) const value = Vector3(mTextureInformations[TextureIndex::SPECULAR_COLOR].mFactor); break; } + case Dali::Scene3D::Material::Property::DEPTH_INDEX: + { + value = mDepthIndex; + break; + } } return value; } @@ -702,6 +717,11 @@ void Material::SetRendererUniform(Dali::Renderer renderer) Scene3D::Loader::RendererState::Apply(mRendererState, renderer); } +void Material::SetRendererProperty(Dali::Renderer renderer) +{ + renderer.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, mDepthIndex); +} + uint32_t Material::GetShadowMapTextureOffset() { return OFFSET_FOR_SHADOW_MAP_TEXTURE; diff --git a/dali-scene3d/internal/model-components/material-impl.h b/dali-scene3d/internal/model-components/material-impl.h index a41b8b5..a4c605f 100644 --- a/dali-scene3d/internal/model-components/material-impl.h +++ b/dali-scene3d/internal/model-components/material-impl.h @@ -36,6 +36,7 @@ #include #include #include +#include namespace Dali { @@ -198,6 +199,13 @@ public: void SetRendererUniform(Dali::Renderer renderer); /** + * @brief Sets property value to the Renderer. + * + * @param[in] renderer Renderer object. + */ + void SetRendererProperty(Dali::Renderer renderer); + + /** * @brief Retrieves shadow map texture offset. * * @return shadow map texture offset. @@ -301,6 +309,8 @@ private: uint32_t mMaterialFlag = std::numeric_limits::max(); Scene3D::Loader::RendererState::Type mRendererState = Scene3D::Loader::RendererState::NONE; + int32_t mDepthIndex{Scene3D::DepthIndex::Ranges::SCENE}; + bool mIsOpaque = true; bool mIsMask = false; bool mObserverNotifying; ///< True if observe is notify now. If then, we should not change the mObservers. diff --git a/dali-scene3d/internal/model-components/material-modify-observer.h b/dali-scene3d/internal/model-components/material-modify-observer.h index 4b0c93d..e5e3bbb 100644 --- a/dali-scene3d/internal/model-components/material-modify-observer.h +++ b/dali-scene3d/internal/model-components/material-modify-observer.h @@ -41,10 +41,11 @@ public: */ enum ModifyFlag { - NONE = 0, - TEXTURE = 1 << 0, - SHADER = 1 << 1, - UNIFORM = 1 << 2, + NONE = 0, + TEXTURE = 1 << 0, + SHADER = 1 << 1, + UNIFORM = 1 << 2, + PROPERTY = 1 << 3, }; /** diff --git a/dali-scene3d/internal/model-components/model-primitive-impl.cpp b/dali-scene3d/internal/model-components/model-primitive-impl.cpp index 48519f7..27c8170 100644 --- a/dali-scene3d/internal/model-components/model-primitive-impl.cpp +++ b/dali-scene3d/internal/model-components/model-primitive-impl.cpp @@ -436,13 +436,18 @@ void ModelPrimitive::ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag uint32_t uniformFlag = (flag & static_cast(MaterialModifyObserver::ModifyFlag::UNIFORM)); if(mIsMaterialChanged || uniformFlag == static_cast(MaterialModifyObserver::ModifyFlag::UNIFORM)) { - if(!mRenderer) + if(mRenderer) { - mNeedToSetRendererUniform = true; + UpdateRendererUniform(); } - else + } + + uint32_t propertyFlag = (flag & static_cast(MaterialModifyObserver::ModifyFlag::PROPERTY)); + if(mIsMaterialChanged || propertyFlag == static_cast(MaterialModifyObserver::ModifyFlag::PROPERTY)) + { + if(mRenderer) { - UpdateRendererUniform(); + UpdateRendererProperty(); } } mIsMaterialChanged = false; @@ -458,6 +463,7 @@ void ModelPrimitive::CreateRenderer() mRenderer = Renderer::New(mGeometry, mShader); mRenderer.SetTextures(mTextureSet); UpdateRendererUniform(); + UpdateRendererProperty(); for(auto* observer : mObservers) { @@ -549,6 +555,14 @@ void ModelPrimitive::UpdateRendererUniform() } } +void ModelPrimitive::UpdateRendererProperty() +{ + if(mMaterial) + { + GetImplementation(mMaterial).SetRendererProperty(mRenderer); + } +} + } // namespace Internal } // namespace Scene3D diff --git a/dali-scene3d/internal/model-components/model-primitive-impl.h b/dali-scene3d/internal/model-components/model-primitive-impl.h index 5913424..6725e1a 100644 --- a/dali-scene3d/internal/model-components/model-primitive-impl.h +++ b/dali-scene3d/internal/model-components/model-primitive-impl.h @@ -213,6 +213,11 @@ private: void UpdateRendererUniform(); /** + * @brief Updates the property of renderer. + */ + void UpdateRendererProperty(); + + /** * @brief Creates a renderer. */ void CreateRenderer(); @@ -266,7 +271,6 @@ private: Scene3D::Loader::BlendShapes::Version mBlendShapeVersion = Scene3D::Loader::BlendShapes::Version::INVALID; bool mIsMaterialChanged = false; - bool mNeedToSetRendererUniform = false; }; } // namespace Internal diff --git a/dali-scene3d/public-api/common/scene-depth-index-ranges.h b/dali-scene3d/public-api/common/scene-depth-index-ranges.h new file mode 100644 index 0000000..5b3a0c9 --- /dev/null +++ b/dali-scene3d/public-api/common/scene-depth-index-ranges.h @@ -0,0 +1,58 @@ +#ifndef DALI_SCENE3D_SCENE_DEPTH_INDEX_RANGES_H +#define DALI_SCENE3D_SCENE_DEPTH_INDEX_RANGES_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. + * + */ + +namespace Dali +{ +namespace Scene3D +{ +namespace DepthIndex +{ + +/** + * @brief Depth index ranges to define rendering order. + * @SINCE_2_3.3 + */ +enum Ranges +{ + /** + * @brief Depth index range for 3D scene content. + * @details The range of the scene content is between [SCENE, SCENE + 999] + * @SINCE_2_3.3 + */ + SCENE = -2000, + + /** + * @brief Depth index range for UI scene content. + * @details The range of the UI content is between [UI, UI + 999]. + * Some of internally created Renderer of Toolkit::Control already has + * default depth index value. + * Developer can fix the default values for their design. + * @SINCE_2_3.3 + */ + UI = 0 +}; + +} // namespace DepthIndex + +} // namespace Scene3D + +} // namespace Dali + +#endif // DALI_SCENE3D_SCENE_DEPTH_INDEX_RANGES_H diff --git a/dali-scene3d/public-api/model-components/material.h b/dali-scene3d/public-api/model-components/material.h index 6e2c73b..7687307 100644 --- a/dali-scene3d/public-api/model-components/material.h +++ b/dali-scene3d/public-api/model-components/material.h @@ -193,8 +193,8 @@ public: DOUBLE_SIDED, /** - *@brief Index of refraction (IOR) of the material surface - *@details type Property::FLOAT + * @brief Index of refraction (IOR) of the material surface + * @details type Property::FLOAT * @SINCE_2_2.22 */ IOR, @@ -207,8 +207,8 @@ public: SPECULAR_URL, /** - *@brief Property for the specular factor of the material surface. - *@details Type Property::FLOAT. + * @brief Property for the specular factor of the material surface. + * @details Type Property::FLOAT. * @SINCE_2_2.22 */ SPECULAR_FACTOR, @@ -221,11 +221,35 @@ public: SPECULAR_COLOR_URL, /** - *@brief Property for the specular color factor of the material surface. - *@details Type Property::VECTOR3. + * @brief Property for the specular color factor of the material surface. + * @details Type Property::VECTOR3. * @SINCE_2_2.22 */ SPECULAR_COLOR_FACTOR, + + /** + * @brief Property to define rendering order. + * @details Depth index is used to define rendering order. This property + * is compatible with Dali::Renderer::Property::DepthIndex. Basically, + * a Renderer that has smaller depth index is rendered earlier. + * In the ordinary DALI UI components has 0 as depth index by default. + * (For the case of Toolkit::Control, its renderer has depth index + * value between [-20, 20] as fallowing the renderer's purpose) + * + * In the Scene3D cases, the rendering order of each Renderer may need + * to be manually defined to match scene developer's intent. + * Scene3D::DepthIndex::Ranges could be used to adjust rendering order + * between 3D Scene content. + * Or it also could be used to manage UI component in 3D Scene independently. + * + * Changing the depth index only affects the rendering order, and does not + * mean that objects drawn later will be drawn on top. To compute final + * rendering order, whether the object is opaque or non-opaque takes precedence + * over the depth index. Changing the rendering order among translucent objects + * has a significant impact on the rendering results. + * @SINCE_2_3.3 + */ + DEPTH_INDEX, }; }; -- 2.7.4