Fixed SVACE and related issues in dali-scene-loader.
[platform/core/uifw/dali-toolkit.git] / dali-scene-loader / public-api / material-definition.h
1 #ifndef DALI_SCENE_LOADER_MATERIAL_DEFINITION_H
2 #define DALI_SCENE_LOADER_MATERIAL_DEFINITION_H
3 /*
4  * Copyright (c) 2020 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-scene-loader/public-api/api.h"
22 #include "dali-scene-loader/public-api/environment-definition.h"
23 #include "dali-scene-loader/public-api/index.h"
24 #include "dali-scene-loader/public-api/utils.h"
25
26 // EXTERNAL INCLUDES
27 #include "dali/public-api/math/vector4.h"
28 #include "dali/public-api/common/vector-wrapper.h"
29 #include <cmath>
30
31 namespace Dali
32 {
33 namespace SceneLoader
34 {
35
36 /**
37  * @brief Helper enum for encoding and decoding sampler states.
38  */
39 struct DALI_SCENE_LOADER_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    * @return SamplerFlags bit pattern calculated from the given Dali Sampler settings.
81    */
82   static Type Encode(FilterMode::Type minFilter, FilterMode::Type magFilter,
83     WrapMode::Type wrapS, WrapMode::Type wrapT);
84
85   /**
86    * @brief Decodes the minification filter patter of @a flags into the corresponding FilterMode.
87    */
88   static FilterMode::Type  GetMinFilter(Type flags);
89
90   /**
91    * @brief Decodes the magnification filter patter of @a flags into the corresponding FilterMode.
92    */
93   static FilterMode::Type  GetMagFilter(Type flags);
94
95   /**
96    * @brief Decodes the horizontal wrap pattern of @a flags into the corresponding WrapMode.
97    */
98   static WrapMode::Type GetWrapS(Type flags);
99
100   /**
101    * @brief Decodes the vertical wrap pattern of @a flags into the corresponding WrapMode.
102    */
103   static WrapMode::Type GetWrapT(Type flags);
104
105   /**
106    * @brief Creates a Sampler with the settings encoded in @a flags.
107    */
108   static Sampler MakeSampler(Type flags);
109 };
110
111 /**
112  * @brief Defines a texture from a combination of an image URI and its sampler definition.
113  */
114 struct DALI_SCENE_LOADER_API TextureDefinition
115 {
116   std::string mImageUri;
117   SamplerFlags::Type mSamplerFlags;
118
119   TextureDefinition(const std::string& imageUri = "", SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT)
120   :  mImageUri(imageUri),
121     mSamplerFlags(samplerFlags)
122   {}
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_SCENE_LOADER_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),  // TODO: support
141     OCCLUSION = NthBit(5),  // TODO: support
142     SUBSURFACE = NthBit(6),  // Note: dli-only
143
144     // Other binary options
145     TRANSPARENCY = NthBit(20),
146     GLTF_CHANNELS = NthBit(21),  // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#pbrmetallicroughnessmetallicroughnesstexture
147
148     // Alpha cutoff - reserved from the 24th bit
149     ALPHA_CUTOFF_BITS = 8,
150     ALPHA_CUTOFF_SHIFT = sizeof(uint32_t) * 8 - ALPHA_CUTOFF_BITS,
151     ALPHA_CUTOFF_MASK = (1 << ALPHA_CUTOFF_BITS) - 1,
152   };
153
154   /**
155    * @brief A(n image based) texture that's used in a material.
156    */
157   struct TextureStage
158   {
159     uint32_t mSemantic;
160     TextureDefinition mTexture;
161   };
162
163   using Vector = std::vector<std::pair<MaterialDefinition, TextureSet>>;
164
165   struct RawData
166   {
167     struct TextureData
168     {
169       PixelData mPixels;
170       SamplerFlags::Type mSamplerFlags;
171     };
172
173     std::vector<TextureData> mTextures;
174   };
175
176   MaterialDefinition() = default;
177
178   MaterialDefinition(const MaterialDefinition&) = delete;
179   MaterialDefinition& operator=(const MaterialDefinition&) = delete;
180
181   MaterialDefinition(MaterialDefinition&&) = default;
182   MaterialDefinition& operator=(MaterialDefinition&&) = default;
183
184   /**
185    * @brief Loads (or, in the case of solid color materials, creates) raw pixel data,
186    *  which is then returned.
187    * @note This may be called from any thread.
188    */
189   RawData LoadRaw(const std::string& imagesPath) const;
190
191   /**
192    * @brief Creates Textures from the pixel data in @a raw, gets the
193    *  the cube maps from the iEnvironment'th element of @a environments,
194    *  then creates a DALi TextureSet and returns it.
195    * @note This must be called from the event thread.
196    * @note The textures are added in the following order: 2D, cube maps.
197    */
198   TextureSet Load(const EnvironmentDefinition::Vector& environments, RawData&& raw) const;
199
200   /**
201    * @brief Checks if the given mask matches any of the textures defined.
202    */
203   bool CheckTextures(uint32_t flags) const;
204
205   /**
206    * @return The alpha test reference value.
207    * @note A value of 0.f means no alpha testing.
208    */
209   float GetAlphaCutoff() const
210   {
211     return ((mFlags >> ALPHA_CUTOFF_SHIFT) & ALPHA_CUTOFF_MASK) / 255.f;
212   }
213
214   /**
215    * @brief Encodes the alpha test reference @a value in flags.
216    * @note A value of 0.f means no alpha testing.
217    */
218   void SetAlphaCutoff(float value)
219   {
220     DALI_ASSERT_DEBUG(value >= 0.f && value <= 1.f);
221     mFlags |= static_cast<uint8_t>(std::round(value * 255.f)) << ALPHA_CUTOFF_SHIFT;
222   }
223
224 public: // DATA
225   uint32_t mFlags = 0x0;
226
227   Index mEnvironmentIdx = 0;
228   Vector4 mColor = Color::WHITE;
229   float mMetallic = 1.f;
230   float mRoughness = 1.f;
231   std::vector<TextureStage> mTextureStages;
232 };
233
234 }
235 }
236
237 #endif //DALI_SCENE_LOADER_MATERIAL_DEFINITION_H