Makes Models use common shader manager
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / internal / model-components / model-primitive-impl.h
1 #ifndef DALI_SCENE3D_MODEL_COMPONENTS_MODEL_PRIMITIVE_IMPL_H
2 #define DALI_SCENE3D_MODEL_COMPONENTS_MODEL_PRIMITIVE_IMPL_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/common/dali-common.h>
23 #include <dali/public-api/common/intrusive-ptr.h>
24 #include <dali/public-api/object/base-object.h>
25 #include <dali/public-api/object/property-value.h>
26 #include <dali/public-api/object/property.h>
27 #include <set>
28
29 // INTERNAL INCLUDES
30 #include <dali-scene3d/internal/model-components/material-modify-observer.h>
31 #include <dali-scene3d/internal/model-components/model-primitive-modify-observer.h>
32 #include <dali-scene3d/public-api/light/light.h>
33 #include <dali-scene3d/public-api/loader/blend-shape-details.h>
34 #include <dali-scene3d/public-api/loader/mesh-definition.h>
35 #include <dali-scene3d/public-api/loader/shader-manager.h>
36 #include <dali-scene3d/public-api/model-components/material.h>
37 #include <dali-scene3d/public-api/model-components/model-primitive.h>
38
39 namespace Dali
40 {
41 namespace Scene3D
42 {
43 namespace Internal
44 {
45 using ModelPrimitivePtr = IntrusivePtr<ModelPrimitive>;
46
47 /**
48  * @brief TODO : Explain me.
49  * Use Vector4 Tangent data
50  * Same ModelPrimitive all shares IBL
51  */
52 class ModelPrimitive : public BaseObject, public MaterialModifyObserver
53 {
54 private:
55   using ModelPrimitiveModifyObserverContainer = std::set<ModelPrimitiveModifyObserver*>;
56
57 public:
58   // Creation & Destruction
59   /**
60    * @brief Create a new ModelPrimitive object.
61    * @return A smart-pointer to the newly allocated ModelPrimitive.
62    */
63   static ModelPrimitivePtr New();
64
65 protected:
66   /**
67    * @brief Construct a new ModelPrimitive.
68    */
69   ModelPrimitive();
70
71   /**
72    * @brief Second-phase constructor.
73    */
74   void Initialize();
75
76   /**
77    * @brief Virtual destructor.
78    */
79   virtual ~ModelPrimitive();
80
81 public:
82   /**
83    * @brief Set Renderer that is created by Scene3D::Loader internally.
84    */
85   void SetRenderer(Dali::Renderer renderer);
86
87   /**
88    * @copydoc Dali::Scene3D::ModelPrimitive::GetRenderer()
89    */
90   Dali::Renderer GetRenderer() const;
91
92   /**
93    * @copydoc Dali::Scene3D::ModelPrimitive::SetGeometry()
94    */
95   void SetGeometry(Dali::Geometry geometry);
96
97   /**
98    * @copydoc Dali::Scene3D::ModelPrimitive::GetGeometry()
99    */
100   Dali::Geometry GetGeometry() const;
101
102   /**
103    * @copydoc Dali::Scene3D::ModelPrimitive::SetMaterial()
104    */
105   void SetMaterial(Dali::Scene3D::Material material, bool updateRenderer = true);
106
107   /**
108    * @copydoc Dali::Scene3D::ModelPrimitive::GetMaterial()
109    */
110   Dali::Scene3D::Material GetMaterial() const;
111
112   /**
113    * @brief Adds a primitive observer to this model primitive.
114    *
115    * @param[in] observer The observer to add.
116    */
117   void AddPrimitiveObserver(ModelPrimitiveModifyObserver* observer);
118
119   /**
120    * @brief Removes a primitive observer from this model primitive.
121    *
122    * @param[in] observer The observer to remove.
123    */
124   void RemovePrimitiveObserver(ModelPrimitiveModifyObserver* observer);
125
126   /**
127    * @brief Sets the image-based lighting texture for this model primitive.
128    *
129    * @param[in] diffuseTexture The diffuse texture.
130    * @param[in] specularTexture The specular texture.
131    * @param[in] iblScaleFactor The scale factor to set for image-based lighting.
132    * @param[in] specularMipmapLevels The number of mipmap levels of specular texture.
133    */
134   void SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float iblScaleFactor, uint32_t specularMipmapLevels);
135
136   /**
137    * @brief Sets the scale factor for image-based lighting for this model primitive.
138    *
139    * @param[in] iblScaleFactor The scale factor to set for image-based lighting.
140    */
141   void SetImageBasedLightScaleFactor(float iblScaleFactor);
142
143   /**
144    * @brief Adds a Light on this medel primitive
145    *
146    * @param[in] light Added light.
147    * @param[in] lightIndex Index of added light.
148    */
149   void AddLight(Scene3D::Light light, uint32_t lightIndex);
150
151   /**
152    * @brief Removes a light at the lightIndex of this model primitive
153    *
154    * @param[in] lightIndex Index of added light.
155    */
156   void RemoveLight(uint32_t lightIndex);
157
158   /**
159    * @brief Updates shaders by using current material
160    *
161    * @param[in] shaderManager Shader manager to create shader.
162    */
163   void UpdateShader(Scene3D::Loader::ShaderManagerPtr shaderManager);
164
165   /**
166    * @brief Sets the blend shape data for this model primitive.
167    *
168    * @param[in] data The blend shape data to set.
169    */
170   void SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data);
171
172   /**
173    * @brief Sets the blend shape geometry for this model primitive.
174    *
175    * @param[in] blendShapeGeometry The blend shape geometry to set.
176    */
177   void SetBlendShapeGeometry(Dali::Texture blendShapeGeometry);
178
179   /**
180    * @brief Sets the blend shape options for this model primitive.
181    *
182    * @param[in] hasPositions Whether or not this model primitive has positions for blend shapes.
183    * @param[in] hasNormals Whether or not this model primitive has normals for blend shapes.
184    * @param[in] hasTangents Whether or not this model primitive has tangents for blend shapes.
185    * @param[in] version blendShape version.
186    */
187   void SetBlendShapeOptions(bool hasPositions, bool hasNormals, bool hasTangents, Scene3D::Loader::BlendShapes::Version version);
188
189   /**
190    * @brief Sets whether or not this model primitive is skinned.
191    *
192    * @param[in] isSkinned Whether or not this model primitive is skinned.
193    */
194   void SetSkinned(bool isSkinned);
195
196 private: // From MaterialModifyObserver
197   /**
198    * @copydoc Dali::Scene3D::Internal::Material::MaterialModifyObserver::OnMaterialModified()
199    */
200   void OnMaterialModified(Dali::Scene3D::Material material, MaterialModifyObserver::ModifyFlag flag) override;
201
202 private:
203   /**
204    * @brief Apply materials data into renderer.
205    */
206   void ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag flag = MaterialModifyObserver::ModifyFlag::NONE);
207
208   /**
209    * @brief Updates the uniform of renderer.
210    */
211   void UpdateRendererUniform();
212
213   /**
214    * @brief Creates a renderer.
215    */
216   void CreateRenderer();
217
218   /**
219    * @brief Updates the image-based lighting texture.
220    */
221   void UpdateImageBasedLightTexture();
222
223 private:
224   // Delete copy & move operator
225   ModelPrimitive(const ModelPrimitive&)                    = delete;
226   ModelPrimitive(ModelPrimitive&&)                         = delete;
227   ModelPrimitive& operator=(const ModelPrimitive& rhs)     = delete;
228   ModelPrimitive& operator=(ModelPrimitive&& rhs) noexcept = delete;
229
230 private:
231   ModelPrimitiveModifyObserverContainer mObservers{};
232
233   // For Renderer
234   Dali::Renderer          mRenderer;
235   Dali::Geometry          mGeometry;
236   Dali::Shader            mShader;
237   Dali::TextureSet        mTextureSet;
238   Dali::Scene3D::Material mMaterial;
239
240   Scene3D::Loader::ShaderManagerPtr mShaderManager;
241
242   // Light
243   std::vector<Scene3D::Light> mLights;
244   int32_t                     mLightCount{0};
245
246   // For IBL
247   Dali::Texture mSpecularTexture;
248   Dali::Texture mDiffuseTexture;
249   float         mIblScaleFactor{1.0f};
250   uint32_t      mSpecularMipmapLevels{1u};
251
252   // For blend shape
253   Scene3D::Loader::BlendShapes::BlendShapeData mBlendShapeData;
254   Dali::Texture                                mBlendShapeGeometry;
255   bool                                         mHasSkinning       = false;
256   bool                                         mHasPositions      = false;
257   bool                                         mHasNormals        = false;
258   bool                                         mHasTangents       = false;
259   Scene3D::Loader::BlendShapes::Version        mBlendShapeVersion = Scene3D::Loader::BlendShapes::Version::INVALID;
260
261   bool mIsMaterialChanged        = false;
262   bool mNeedToSetRendererUniform = false;
263 };
264
265 } // namespace Internal
266
267 // Helpers for public-api forwarding methods
268
269 inline Internal::ModelPrimitive& GetImplementation(Dali::Scene3D::ModelPrimitive& modelPrimitive)
270 {
271   DALI_ASSERT_ALWAYS(modelPrimitive && "ModelPrimitive handle is empty");
272
273   BaseObject& handle = modelPrimitive.GetBaseObject();
274
275   return static_cast<Internal::ModelPrimitive&>(handle);
276 }
277
278 inline const Internal::ModelPrimitive& GetImplementation(const Dali::Scene3D::ModelPrimitive& modelPrimitive)
279 {
280   DALI_ASSERT_ALWAYS(modelPrimitive && "ModelPrimitive handle is empty");
281
282   const BaseObject& handle = modelPrimitive.GetBaseObject();
283
284   return static_cast<const Internal::ModelPrimitive&>(handle);
285 }
286
287 } // namespace Scene3D
288
289 } // namespace Dali
290
291 #endif // DALI_SCENE3D_MODEL_COMPONENTS_MODEL_PRIMITIVE_IMPL_H