[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-scene3d / public-api / loader / material-definition.h
1 #ifndef DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H
2 #define DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H
3 /*
4  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 // EXTERNAL INCLUDES
21 #include <dali/public-api/common/vector-wrapper.h>
22 #include <dali/public-api/images/image-operations.h>
23 #include <dali/public-api/math/vector4.h>
24 #include <cmath>
25
26 // INTERNAL INCLUDES
27 #include <dali-scene3d/public-api/api.h>
28 #include <dali-scene3d/public-api/loader/environment-definition.h>
29 #include <dali-scene3d/public-api/loader/index.h>
30 #include <dali-scene3d/public-api/loader/utils.h>
31 #include <dali-scene3d/public-api/model-components/material.h>
32
33 namespace Dali::Scene3D::Loader
34 {
35 /**
36  * @brief Helper enum for encoding and decoding sampler states.
37  * @SINCE_2_0.7
38  */
39 struct DALI_SCENE3D_API SamplerFlags
40 {
41   using Type = uint8_t;
42
43   enum Values : Type
44   {
45     // Filter - 3 bits
46     FILTER_NEAREST        = 0,
47     FILTER_LINEAR         = NthBit(0),
48     FILTER_MIPMAP_NEAREST = NthBit(1),
49     FILTER_MIPMAP_LINEAR  = NthBit(2),
50
51     // Wrap - 2 bits
52     WRAP_REPEAT = 0,
53     WRAP_CLAMP  = NthBit(0),
54     WRAP_MIRROR = NthBit(1),
55
56     // Layout - apply shift, then mask
57     FILTER_MIN_BITS = 3,
58     FILTER_MIN_MASK = NthBit(FILTER_MIN_BITS) - 1,
59
60     FILTER_MAG_BITS  = 1,
61     FILTER_MAG_SHIFT = FILTER_MIN_BITS,
62     FILTER_MAG_MASK  = NthBit(FILTER_MAG_BITS) - 1,
63
64     WRAP_S_BITS  = 2,
65     WRAP_S_SHIFT = FILTER_MAG_SHIFT + FILTER_MAG_BITS,
66     WRAP_S_MASK  = NthBit(WRAP_S_BITS) - 1,
67
68     WRAP_T_BITS  = 2,
69     WRAP_T_SHIFT = WRAP_S_SHIFT + WRAP_S_BITS,
70     WRAP_T_MASK  = NthBit(WRAP_T_BITS) - 1,
71
72     // Diagnostics
73     MIPMAP_MASK = FILTER_MIPMAP_LINEAR | FILTER_MIPMAP_NEAREST,
74
75     // Default
76     DEFAULT = FILTER_LINEAR | (FILTER_LINEAR << FILTER_MAG_SHIFT) | (WRAP_REPEAT << WRAP_S_SHIFT) | (WRAP_REPEAT << WRAP_T_SHIFT), // LINEAR filters, REPEAT wraps
77   };
78
79   /**
80    * @brief Retrieves the bit pattern calculated from the given Dali Sampler settings.
81    * @SINCE_2_0.7
82    * @return SamplerFlags bit pattern.
83    */
84   static Type Encode(FilterMode::Type minFilter, FilterMode::Type magFilter, WrapMode::Type wrapS, WrapMode::Type wrapT);
85
86   /**
87    * @brief Decodes the minification filter patter of @a flags into the corresponding FilterMode.
88    * @SINCE_2_0.7
89    */
90   static FilterMode::Type GetMinFilter(Type flags);
91
92   /**
93    * @brief Decodes the magnification filter patter of @a flags into the corresponding FilterMode.
94    * @SINCE_2_0.7
95    */
96   static FilterMode::Type GetMagFilter(Type flags);
97
98   /**
99    * @brief Decodes the horizontal wrap pattern of @a flags into the corresponding WrapMode.
100    * @SINCE_2_0.7
101    */
102   static WrapMode::Type GetWrapS(Type flags);
103
104   /**
105    * @brief Decodes the vertical wrap pattern of @a flags into the corresponding WrapMode.
106    * @SINCE_2_0.7
107    */
108   static WrapMode::Type GetWrapT(Type flags);
109
110   /**
111    * @brief Creates a Sampler with the settings encoded in @a flags.
112    * @SINCE_2_0.7
113    */
114   static Sampler MakeSampler(Type flags);
115 };
116
117 /**
118  * @brief Defines a texture from a combination of an image URI and its sampler definition.
119  * @SINCE_2_0.7
120  */
121 struct DALI_SCENE3D_API TextureDefinition
122 {
123   static const Matrix3 DEFAULT_TRANSFORM;
124
125   std::string          mImageUri; // When the texture is loaded from embedded resources, this URI is used as a data stream.
126   std::string          mDirectoryPath;
127   SamplerFlags::Type   mSamplerFlags;
128   ImageDimensions      mMinImageDimensions;
129   SamplingMode::Type   mSamplingMode;
130   Matrix3              mTransform{DEFAULT_TRANSFORM}; // Texture transform
131   std::vector<uint8_t> mTextureBuffer;
132
133   TextureDefinition(const std::string& imageUri = "", SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR, Matrix3 transform = DEFAULT_TRANSFORM);
134   TextureDefinition(std::string&& imageUri, SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR, Matrix3 transform = DEFAULT_TRANSFORM);
135   TextureDefinition(std::vector<uint8_t>&& textureBuffer, SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR, Matrix3 transform = DEFAULT_TRANSFORM);
136 };
137
138 /**
139  * @brief Defines a material with a number of texture stages, whether mipmappping
140  *  is enabled, and an index of an environment (usually of all environments in a
141  *  scene). Textures from the environment are added last when the DALi TextureSet
142  *  is being created.
143  * @SINCE_2_0.7
144  */
145 struct DALI_SCENE3D_API MaterialDefinition
146 {
147   enum Flags : uint32_t
148   {
149     // Texture semantics
150     ALBEDO         = NthBit(0),
151     METALLIC       = NthBit(1),
152     ROUGHNESS      = NthBit(2),
153     NORMAL         = NthBit(3),
154     EMISSIVE       = NthBit(4),
155     OCCLUSION      = NthBit(5),
156     SPECULAR       = NthBit(6),
157     SPECULAR_COLOR = NthBit(7),
158     SUBSURFACE     = NthBit(8), // Note: dli-only
159
160     // Other binary options
161     TRANSPARENCY  = NthBit(20),
162     GLTF_CHANNELS = NthBit(21), // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#pbrmetallicroughnessmetallicroughnesstexture
163
164     // Alpha cutoff - reserved from the 24th bit
165     ALPHA_CUTOFF_BITS  = 8,
166     ALPHA_CUTOFF_SHIFT = sizeof(uint32_t) * 8 - ALPHA_CUTOFF_BITS,
167     ALPHA_CUTOFF_MASK  = (1 << ALPHA_CUTOFF_BITS) - 1,
168   };
169
170   /**
171    * @brief A(n image based) texture that's used in a material.
172    * @SINCE_2_0.7
173    */
174   struct TextureStage
175   {
176     uint32_t          mSemantic;
177     TextureDefinition mTexture;
178   };
179
180   using Vector = std::vector<std::pair<MaterialDefinition, TextureSet>>;
181
182   struct RawData
183   {
184     struct TextureData
185     {
186       PixelData          mPixels;
187       SamplerFlags::Type mSamplerFlags;
188     };
189
190     std::vector<TextureData> mTextures;
191   };
192
193   MaterialDefinition() = default;
194
195   MaterialDefinition(const MaterialDefinition&) = delete;
196   MaterialDefinition& operator=(const MaterialDefinition&) = delete;
197
198   MaterialDefinition(MaterialDefinition&&) = default;
199   MaterialDefinition& operator=(MaterialDefinition&&) = default;
200
201   /**
202    * @brief Loads (or, in the case of solid color materials, creates) raw pixel data,
203    *  which is then returned.
204    * @SINCE_2_0.7
205    * @note This may be called from any thread.
206    */
207   RawData LoadRaw(const std::string& imagesPath);
208
209   /**
210    * @brief Creates Textures from the pixel data in @a raw, gets the
211    *  the cube maps from the iEnvironment'th element of @a environments,
212    *  then creates a DALi TextureSet and returns it.
213    * @SINCE_2_0.7
214    * @note This must be called from the event thread.
215    * @note The textures are added in the following order: 2D, cube maps.
216    */
217   TextureSet Load(const EnvironmentDefinition::Vector& environments, RawData&& raw) const;
218
219   /**
220    * @brief Checks if the given mask matches any of the textures defined.
221    * @SINCE_2_0.7
222    */
223   bool CheckTextures(uint32_t flags) const;
224
225   /**
226    * @return The alpha test reference value.
227    * @SINCE_2_0.7
228    * @note A value of 0.f means no alpha testing.
229    */
230   float GetAlphaCutoff() const
231   {
232     return ((mFlags >> ALPHA_CUTOFF_SHIFT) & ALPHA_CUTOFF_MASK) / 255.f;
233   }
234
235   /**
236    * @brief Encodes the alpha test reference @a value in flags.
237    * @SINCE_2_0.7
238    * @note A value of 0.f means no alpha testing.
239    */
240   void SetAlphaCutoff(float value)
241   {
242     DALI_ASSERT_DEBUG(value >= 0.f && value <= 1.f);
243     mFlags |= static_cast<uint8_t>(std::round(value * 255.f)) << ALPHA_CUTOFF_SHIFT;
244   }
245
246 public: // DATA
247   std::shared_ptr<RawData> mRawData;
248   uint32_t                 mFlags = 0x0;
249
250   Index   mEnvironmentIdx      = 0;
251   Vector4 mColor               = Color::WHITE;
252   float   mMetallic            = 1.f;
253   float   mRoughness           = 1.f;
254   Vector4 mBaseColorFactor     = Vector4::ONE;
255   float   mNormalScale         = 1.f;
256   float   mOcclusionStrength   = 1.f;
257   Vector3 mEmissiveFactor      = Vector3::ZERO;
258   float   mIor                 = -1.0f;
259   float   mDielectricSpecular  = 0.04f;
260   float   mSpecularFactor      = 1.0f;
261   Vector3 mSpecularColorFactor = Vector3::ONE;
262
263   // For the glTF, each of albedo, metallicRoughness, normal textures are not essential.
264   bool mNeedAlbedoTexture            = true;
265   bool mNeedMetallicRoughnessTexture = true;
266   bool mNeedNormalTexture            = true;
267   bool mDoubleSided                  = false;
268
269   Scene3D::Material::AlphaModeType mAlphaModeType = Scene3D::Material::AlphaModeType::OPAQUE;
270   bool                             mIsOpaque      = true;
271   bool                             mIsMask        = false;
272
273   bool mShadowAvailable = false;
274
275   std::vector<TextureStage> mTextureStages;
276   Material                  mMaterial;
277 };
278
279 } // namespace Dali::Scene3D::Loader
280
281 #endif //DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H