Texture size reduction on the fly for 3D model using metadata
[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) 2022 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 // INTERNAL INCLUDES
21 #include "dali-scene3d/public-api/api.h"
22 #include "dali-scene3d/public-api/loader/environment-definition.h"
23 #include "dali-scene3d/public-api/loader/index.h"
24 #include "dali-scene3d/public-api/loader/utils.h"
25
26 // EXTERNAL INCLUDES
27 #include <dali/public-api/images/image-operations.h>
28 #include <cmath>
29 #include "dali/public-api/common/vector-wrapper.h"
30 #include "dali/public-api/math/vector4.h"
31
32 namespace Dali
33 {
34 namespace Scene3D
35 {
36 namespace Loader
37 {
38 /**
39  * @brief Helper enum for encoding and decoding sampler states.
40  */
41 struct DALI_SCENE3D_API SamplerFlags
42 {
43   using Type = uint8_t;
44
45   enum Values : Type
46   {
47     // Filter - 3 bits
48     FILTER_NEAREST        = 0,
49     FILTER_LINEAR         = NthBit(0),
50     FILTER_MIPMAP_NEAREST = NthBit(1),
51     FILTER_MIPMAP_LINEAR  = NthBit(2),
52
53     // Wrap - 2 bits
54     WRAP_REPEAT = 0,
55     WRAP_CLAMP  = NthBit(0),
56     WRAP_MIRROR = NthBit(1),
57
58     // Layout - apply shift, then mask
59     FILTER_MIN_BITS = 3,
60     FILTER_MIN_MASK = NthBit(FILTER_MIN_BITS) - 1,
61
62     FILTER_MAG_BITS  = 1,
63     FILTER_MAG_SHIFT = FILTER_MIN_BITS,
64     FILTER_MAG_MASK  = NthBit(FILTER_MAG_BITS) - 1,
65
66     WRAP_S_BITS  = 2,
67     WRAP_S_SHIFT = FILTER_MAG_SHIFT + FILTER_MAG_BITS,
68     WRAP_S_MASK  = NthBit(WRAP_S_BITS) - 1,
69
70     WRAP_T_BITS  = 2,
71     WRAP_T_SHIFT = WRAP_S_SHIFT + WRAP_S_BITS,
72     WRAP_T_MASK  = NthBit(WRAP_T_BITS) - 1,
73
74     // Diagnostics
75     MIPMAP_MASK = FILTER_MIPMAP_LINEAR | FILTER_MIPMAP_NEAREST,
76
77     // Default
78     DEFAULT = FILTER_LINEAR | (FILTER_LINEAR << FILTER_MAG_SHIFT) | (WRAP_REPEAT << WRAP_S_SHIFT) | (WRAP_REPEAT << WRAP_T_SHIFT), // LINEAR filters, REPEAT wraps
79   };
80
81   /**
82    * @return SamplerFlags bit pattern calculated from the given Dali Sampler settings.
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    */
89   static FilterMode::Type GetMinFilter(Type flags);
90
91   /**
92    * @brief Decodes the magnification filter patter of @a flags into the corresponding FilterMode.
93    */
94   static FilterMode::Type GetMagFilter(Type flags);
95
96   /**
97    * @brief Decodes the horizontal wrap pattern of @a flags into the corresponding WrapMode.
98    */
99   static WrapMode::Type GetWrapS(Type flags);
100
101   /**
102    * @brief Decodes the vertical wrap pattern of @a flags into the corresponding WrapMode.
103    */
104   static WrapMode::Type GetWrapT(Type flags);
105
106   /**
107    * @brief Creates a Sampler with the settings encoded in @a flags.
108    */
109   static Sampler MakeSampler(Type flags);
110 };
111
112 /**
113  * @brief Defines a texture from a combination of an image URI and its sampler definition.
114  */
115 struct DALI_SCENE3D_API TextureDefinition
116 {
117   std::string        mImageUri;
118   SamplerFlags::Type mSamplerFlags;
119   ImageDimensions    mMinImageDimensions;
120   SamplingMode::Type mSamplingMode;
121
122   TextureDefinition(const std::string& imageUri = "", SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT, ImageDimensions minImageDimensions = ImageDimensions(), SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR);
123 };
124
125 /**
126  * @brief Defines a material with a number of texture stages, whether mipmappping
127  *  is enabled, and an index of an environment (usually of all environments in a
128  *  scene). Textures from the environment are added last when the DALi TextureSet
129  *  is being created.
130  */
131 struct DALI_SCENE3D_API MaterialDefinition
132 {
133   enum Flags : uint32_t
134   {
135     // Texture semantics
136     ALBEDO         = NthBit(0),
137     METALLIC       = NthBit(1),
138     ROUGHNESS      = NthBit(2),
139     NORMAL         = NthBit(3),
140     EMISSIVE       = NthBit(4),
141     OCCLUSION      = NthBit(5),
142     SPECULAR       = NthBit(6),
143     SPECULAR_COLOR = NthBit(7),
144     SUBSURFACE     = NthBit(8), // Note: dli-only
145
146     // Other binary options
147     TRANSPARENCY  = NthBit(20),
148     GLTF_CHANNELS = NthBit(21), // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#pbrmetallicroughnessmetallicroughnesstexture
149
150     // Alpha cutoff - reserved from the 24th bit
151     ALPHA_CUTOFF_BITS  = 8,
152     ALPHA_CUTOFF_SHIFT = sizeof(uint32_t) * 8 - ALPHA_CUTOFF_BITS,
153     ALPHA_CUTOFF_MASK  = (1 << ALPHA_CUTOFF_BITS) - 1,
154   };
155
156   /**
157    * @brief A(n image based) texture that's used in a material.
158    */
159   struct TextureStage
160   {
161     uint32_t          mSemantic;
162     TextureDefinition mTexture;
163   };
164
165   using Vector = std::vector<std::pair<MaterialDefinition, TextureSet>>;
166
167   struct RawData
168   {
169     struct TextureData
170     {
171       PixelData          mPixels;
172       SamplerFlags::Type mSamplerFlags;
173     };
174
175     std::vector<TextureData> mTextures;
176   };
177
178   MaterialDefinition() = default;
179
180   MaterialDefinition(const MaterialDefinition&) = delete;
181   MaterialDefinition& operator=(const MaterialDefinition&) = delete;
182
183   MaterialDefinition(MaterialDefinition&&) = default;
184   MaterialDefinition& operator=(MaterialDefinition&&) = default;
185
186   /**
187    * @brief Loads (or, in the case of solid color materials, creates) raw pixel data,
188    *  which is then returned.
189    * @note This may be called from any thread.
190    */
191   RawData LoadRaw(const std::string& imagesPath) const;
192
193   /**
194    * @brief Creates Textures from the pixel data in @a raw, gets the
195    *  the cube maps from the iEnvironment'th element of @a environments,
196    *  then creates a DALi TextureSet and returns it.
197    * @note This must be called from the event thread.
198    * @note The textures are added in the following order: 2D, cube maps.
199    */
200   TextureSet Load(const EnvironmentDefinition::Vector& environments, RawData&& raw) const;
201
202   /**
203    * @brief Checks if the given mask matches any of the textures defined.
204    */
205   bool CheckTextures(uint32_t flags) const;
206
207   /**
208    * @return The alpha test reference value.
209    * @note A value of 0.f means no alpha testing.
210    */
211   float GetAlphaCutoff() const
212   {
213     return ((mFlags >> ALPHA_CUTOFF_SHIFT) & ALPHA_CUTOFF_MASK) / 255.f;
214   }
215
216   /**
217    * @brief Encodes the alpha test reference @a value in flags.
218    * @note A value of 0.f means no alpha testing.
219    */
220   void SetAlphaCutoff(float value)
221   {
222     DALI_ASSERT_DEBUG(value >= 0.f && value <= 1.f);
223     mFlags |= static_cast<uint8_t>(std::round(value * 255.f)) << ALPHA_CUTOFF_SHIFT;
224   }
225
226 public: // DATA
227   uint32_t mFlags = 0x0;
228
229   Index   mEnvironmentIdx      = 0;
230   Vector4 mColor               = Color::WHITE;
231   float   mMetallic            = 1.f;
232   float   mRoughness           = 1.f;
233   Vector4 mBaseColorFactor     = Vector4::ONE;
234   float   mNormalScale         = 1.f;
235   float   mOcclusionStrength   = 1.f;
236   Vector3 mEmissiveFactor      = Vector3::ZERO;
237   float   mDielectricSpecular  = 0.04f;
238   float   mSpecularFactor      = 1.0f;
239   Vector3 mSpecularColorFactor = Vector3::ONE;
240
241   // For the glTF, each of albedo, metallicRoughness, normal textures are not essential.
242   bool mNeedAlbedoTexture            = true;
243   bool mNeedMetallicRoughnessTexture = true;
244   bool mNeedNormalTexture            = true;
245   bool mDoubleSided                  = false;
246
247   std::vector<TextureStage> mTextureStages;
248 };
249
250 } // namespace Loader
251 } // namespace Scene3D
252 } // namespace Dali
253
254 #endif //DALI_SCENE3D_LOADER_MATERIAL_DEFINITION_H