git.s-ol.nu forks/DiligentTools / 1b66dcf
C API for GLTFLoader s-ol 2 years ago
7 changed file(s) with 835 addition(s) and 705 deletion(s). Raw diff Collapse all Expand all
33
44 set(INCLUDE
55 #include/GLTFLoader.hpp
6 #include/GLTFResourceManager.hpp
67 )
78
89 set(INTERFACE
9 interface/GLTFLoader.hpp
10 interface/GLTFLoader.h
1011 interface/DXSDKMeshLoader.hpp
11 interface/GLTFResourceManager.hpp
1212 )
1313
1414 set(SOURCE
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 #include <vector>
30 #include <array>
31 #include <memory>
32 #include <cfloat>
33 #include <unordered_map>
34 #include <mutex>
35 #include <atomic>
36
37 #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
38 #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
39 #include "../../../DiligentCore/Common/interface/RefCntAutoPtr.hpp"
40 #include "../../../DiligentCore/Common/interface/AdvancedMath.hpp"
41 #include "GLTFLoader.h"
42 #include "GLTFResourceManager.hpp"
43
44 namespace tinygltf
45 {
46
47 class Node;
48 class Model;
49
50 } // namespace tinygltf
51
52 namespace Diligent
53 {
54
55 namespace GLTF
56 {
57
58 struct Material
59 {
60 Material() noexcept
61 {
62 TextureIds.fill(-1);
63 }
64
65 enum PBR_WORKFLOW
66 {
67 PBR_WORKFLOW_METALL_ROUGH = 0,
68 PBR_WORKFLOW_SPEC_GLOSS
69 };
70
71 // Material attributes packed in a shader-friendly format
72 struct ShaderAttribs
73 {
74 float4 BaseColorFactor = float4{1, 1, 1, 1};
75 float4 EmissiveFactor = float4{1, 1, 1, 1};
76 float4 SpecularFactor = float4{1, 1, 1, 1};
77
78 int Workflow = PBR_WORKFLOW_METALL_ROUGH;
79 float BaseColorUVSelector = -1;
80 float PhysicalDescriptorUVSelector = -1;
81 float NormalUVSelector = -1;
82
83 float OcclusionUVSelector = -1;
84 float EmissiveUVSelector = -1;
85 float BaseColorSlice = 0;
86 float PhysicalDescriptorSlice = 0;
87
88 float NormalSlice = 0;
89 float OcclusionSlice = 0;
90 float EmissiveSlice = 0;
91 float MetallicFactor = 1;
92
93 float RoughnessFactor = 1;
94 int AlphaMode = GLTF_MAT_ALPHA_MODE_OPAQUE;
95 float AlphaCutoff = 0.5f;
96 float Dummy0;
97
98 // When texture atlas is used, UV scale and bias applied to
99 // each texture coordinate set
100 float4 BaseColorUVScaleBias = float4{1, 1, 0, 0};
101 float4 PhysicalDescriptorUVScaleBias = float4{1, 1, 0, 0};
102 float4 NormalUVScaleBias = float4{1, 1, 0, 0};
103 float4 OcclusionUVScaleBias = float4{1, 1, 0, 0};
104 float4 EmissiveUVScaleBias = float4{1, 1, 0, 0};
105 };
106 static_assert(sizeof(ShaderAttribs) % 16 == 0, "ShaderAttribs struct must be 16-byte aligned");
107 ShaderAttribs Attribs;
108
109 bool DoubleSided = false;
110
111 enum TEXTURE_ID
112 {
113 // Base color for metallic-roughness workflow or
114 // diffuse color for specular-glossinees workflow
115 TEXTURE_ID_BASE_COLOR = 0,
116
117 // Metallic-roughness or specular-glossinees map
118 TEXTURE_ID_PHYSICAL_DESC,
119
120 TEXTURE_ID_NORMAL_MAP,
121 TEXTURE_ID_OCCLUSION,
122 TEXTURE_ID_EMISSIVE,
123 TEXTURE_ID_NUM_TEXTURES
124 };
125 // Texture indices in Model.Textures array
126 std::array<int, TEXTURE_ID_NUM_TEXTURES> TextureIds = {};
127 };
128
129
130 struct Primitive
131 {
132 const Uint32 FirstIndex;
133 const Uint32 IndexCount;
134 const Uint32 VertexCount;
135 const Uint32 MaterialId;
136
137 const BoundBox BB;
138
139 Primitive(Uint32 _FirstIndex,
140 Uint32 _IndexCount,
141 Uint32 _VertexCount,
142 Uint32 _MaterialId,
143 const float3& BBMin,
144 const float3& BBMax) :
145 FirstIndex{_FirstIndex},
146 IndexCount{_IndexCount},
147 VertexCount{_VertexCount},
148 MaterialId{_MaterialId},
149 BB{BBMin, BBMax}
150 {
151 }
152
153 Primitive(Primitive&&) = default;
154
155 bool HasIndices() const
156 {
157 return IndexCount > 0;
158 }
159 };
160
161
162
163 struct Mesh
164 {
165 std::vector<Primitive> Primitives;
166
167 BoundBox BB;
168
169 // There may be no primitives in the mesh, in which
170 // case the bounding box will be invalid.
171 bool IsValidBB() const
172 {
173 return !Primitives.empty();
174 }
175
176 struct TransformData
177 {
178 float4x4 matrix;
179 std::vector<float4x4> jointMatrices;
180 };
181
182 TransformData Transforms;
183
184 Mesh(const float4x4& matrix);
185 };
186
187
188 struct Node;
189 struct Skin
190 {
191 std::string Name;
192 Node* pSkeletonRoot = nullptr;
193 std::vector<float4x4> InverseBindMatrices;
194 std::vector<Node*> Joints;
195 };
196
197 struct Camera
198 {
199 enum class Projection
200 {
201 Unknown,
202 Perspective,
203 Orthographic
204 } Type = Projection::Unknown;
205
206 std::string Name;
207
208 struct PerspectiveAttribs
209 {
210 float AspectRatio;
211 float YFov;
212 float ZNear;
213 float ZFar;
214 };
215 struct OrthographicAttribs
216 {
217 float XMag;
218 float YMag;
219 float ZNear;
220 float ZFar;
221 };
222 union
223 {
224 PerspectiveAttribs Perspective = {};
225 OrthographicAttribs Orthographic;
226 };
227
228 float4x4 matrix;
229 };
230
231 struct Node
232 {
233 std::string Name;
234 Node* Parent = nullptr;
235 Uint32 Index;
236
237 std::vector<std::unique_ptr<Node>> Children;
238
239 float4x4 Matrix;
240 std::unique_ptr<Mesh> pMesh;
241 std::unique_ptr<Camera> pCamera;
242 Skin* pSkin = nullptr;
243 Int32 SkinIndex = -1;
244 float3 Translation;
245 float3 Scale = float3{1, 1, 1};
246 Quaternion Rotation;
247 BoundBox BVH;
248 BoundBox AABB;
249
250 bool IsValidBVH = false;
251
252 float4x4 LocalMatrix() const;
253 float4x4 GetMatrix() const;
254 void UpdateTransforms();
255 };
256
257
258 struct AnimationChannel
259 {
260 enum PATH_TYPE
261 {
262 TRANSLATION,
263 ROTATION,
264 SCALE
265 };
266 PATH_TYPE PathType;
267 Node* pNode = nullptr;
268 Uint32 SamplerIndex = static_cast<Uint32>(-1);
269 };
270
271
272 struct AnimationSampler
273 {
274 enum INTERPOLATION_TYPE
275 {
276 LINEAR,
277 STEP,
278 CUBICSPLINE
279 };
280 INTERPOLATION_TYPE Interpolation;
281 std::vector<float> Inputs;
282 std::vector<float4> OutputsVec4;
283 };
284
285 struct Animation
286 {
287 std::string Name;
288 std::vector<AnimationSampler> Samplers;
289 std::vector<AnimationChannel> Channels;
290
291 float Start = std::numeric_limits<float>::max();
292 float End = std::numeric_limits<float>::min();
293 };
294
295 struct GLTF_TextureCacheType
296 {
297 std::mutex TexturesMtx;
298
299 std::unordered_map<std::string, RefCntWeakPtr<ITexture>> Textures;
300 };
301
302 class Model : public IGLTFModel
303 {
304 public:
305 struct VertexBasicAttribs
306 {
307 float3 pos;
308 float3 normal;
309 float2 uv0;
310 float2 uv1;
311 };
312
313 struct VertexSkinAttribs
314 {
315 float4 joint0;
316 float4 weight0;
317 };
318
319 Uint32 IndexCount = 0;
320
321 /// Transformation matrix that transforms unit cube [0,1]x[0,1]x[0,1] into
322 /// axis-aligned bounding box in model space.
323 float4x4 AABBTransform;
324
325 std::vector<std::unique_ptr<Node>> Nodes;
326 std::vector<Node*> LinearNodes;
327
328 std::vector<std::unique_ptr<Skin>> Skins;
329
330 std::vector<RefCntAutoPtr<ISampler>> TextureSamplers;
331 std::vector<Material> Materials;
332 std::vector<Animation> Animations;
333 std::vector<std::string> Extensions;
334
335 struct Dimensions
336 {
337 float3 min = float3{+FLT_MAX, +FLT_MAX, +FLT_MAX};
338 float3 max = float3{-FLT_MAX, -FLT_MAX, -FLT_MAX};
339 } dimensions;
340
341 Model(IRenderDevice* pDevice,
342 IDeviceContext* pContext,
343 const IGLTFModelCreateInfo& CI);
344
345 ~Model();
346
347 virtual void UpdateAnimation(Uint32 index, float time) override final;
348
349 virtual void PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx) override final;
350
351 virtual bool IsGPUDataInitialized() const override final
352 {
353 return GPUDataInitialized.load();
354 }
355
356 virtual void Transform(const float* Matrix) override final;
357
358 virtual IBuffer* GetBuffer(GLTF_BUFFER_ID BuffId) override final
359 {
360 return Buffers[BuffId].pBuffer;
361 }
362
363 virtual ITexture* GetTexture(Uint32 Index) override final
364 {
365 return Textures[Index].pTexture;
366 }
367
368 virtual Uint32 GetFirstIndexLocation() const override final
369 {
370 auto& IndBuff = Buffers[GLTF_BUFFER_ID_INDEX];
371 VERIFY(!IndBuff.pSuballocation || IndBuff.pSuballocation->GetOffset() % sizeof(Uint32) == 0,
372 "Allocation offset is not multiple of sizeof(Uint32)");
373 return IndBuff.pSuballocation ?
374 static_cast<Uint32>(IndBuff.pSuballocation->GetOffset() / sizeof(Uint32)) :
375 0;
376 }
377
378 virtual Uint32 GetBaseVertex() const override final
379 {
380 auto& VertBuff = Buffers[GLTF_BUFFER_ID_VERTEX_BASIC_ATTRIBS];
381 VERIFY(!VertBuff.pSuballocation || VertBuff.pSuballocation->GetOffset() % sizeof(VertexBasicAttribs) == 0,
382 "Allocation offset is not multiple of sizeof(VertexAttribs0)");
383 return VertBuff.pSuballocation ?
384 static_cast<Uint32>(VertBuff.pSuballocation->GetOffset() / sizeof(VertexBasicAttribs)) :
385 0;
386 }
387
388 private:
389 void LoadFromFile(IRenderDevice* pDevice,
390 IDeviceContext* pContext,
391 const IGLTFModelCreateInfo& CI);
392
393 void LoadNode(Node* parent,
394 const tinygltf::Node& gltf_node,
395 uint32_t nodeIndex,
396 const tinygltf::Model& gltf_model,
397 std::vector<Uint32>& IndexData,
398 std::vector<VertexBasicAttribs>& VertexBasicData,
399 std::vector<VertexSkinAttribs>* pVertexSkinData);
400
401 void LoadSkins(const tinygltf::Model& gltf_model);
402
403 void LoadTextures(IRenderDevice* pDevice,
404 const tinygltf::Model& gltf_model,
405 const std::string& BaseDir,
406 GLTF_TextureCacheType* pTextureCache,
407 ResourceManager* pResourceMgr);
408
409 void LoadTextureSamplers(IRenderDevice* pDevice, const tinygltf::Model& gltf_model);
410 void LoadMaterials(const tinygltf::Model& gltf_model);
411 void LoadAnimations(const tinygltf::Model& gltf_model);
412 void CalculateBoundingBox(Node* node, const Node* parent);
413 void CalculateSceneDimensions();
414 Node* FindNode(Node* parent, Uint32 index);
415 Node* NodeFromIndex(uint32_t index);
416
417 std::atomic_bool GPUDataInitialized{false};
418
419 struct BufferInfo
420 {
421 RefCntAutoPtr<IBuffer> pBuffer;
422 RefCntAutoPtr<IBufferSuballocation> pSuballocation;
423 };
424 std::array<BufferInfo, GLTF_BUFFER_ID_NUM_BUFFERS> Buffers;
425
426 struct TextureInfo
427 {
428 RefCntAutoPtr<ITexture> pTexture;
429 RefCntAutoPtr<ITextureAtlasSuballocation> pAtlasSuballocation;
430
431 bool IsValid() const
432 {
433 return pTexture || pAtlasSuballocation;
434 }
435 };
436 std::vector<TextureInfo> Textures;
437 };
438
439 } // namespace GLTF
440
441 } // namespace Diligent
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 #include <mutex>
30 #include <vector>
31 #include <unordered_map>
32 #include <atomic>
33
34 #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
35 #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
36 #include "../../../DiligentCore/Common/interface/RefCntAutoPtr.hpp"
37 #include "../../../DiligentCore/Common/interface/ObjectBase.hpp"
38 #include "../../../DiligentCore/Graphics/GraphicsTools/interface/BufferSuballocator.h"
39 #include "../../../DiligentCore/Graphics/GraphicsTools/interface/DynamicTextureAtlas.h"
40
41
42 namespace Diligent
43 {
44
45 namespace GLTF
46 {
47
48 /// GLTF resource manager
49 class ResourceManager final : public ObjectBase<IObject>
50 {
51 public:
52 using TBase = ObjectBase<IObject>;
53
54 struct CreateInfo
55 {
56 const BufferSuballocatorCreateInfo* BuffSuballocators = nullptr; // [NumBuffSuballocators]
57 const DynamicTextureAtlasCreateInfo* TexAtlases = nullptr; // [NumTexAtlases]
58
59 Uint32 NumBuffSuballocators = 0;
60 Uint32 NumTexAtlases = 0;
61
62 DynamicTextureAtlasCreateInfo DefaultAtlasDesc;
63 };
64
65 static RefCntAutoPtr<ResourceManager> Create(IRenderDevice* pDevice,
66 const CreateInfo& CI);
67
68 RefCntAutoPtr<IBufferSuballocation> AllocateBufferSpace(Uint32 BufferIndex,
69 Uint32 Size,
70 Uint32 Alignment)
71 {
72 RefCntAutoPtr<IBufferSuballocation> pSuballoc;
73 m_BufferSuballocators[BufferIndex]->Allocate(Size, Alignment, &pSuballoc);
74 return pSuballoc;
75 }
76
77 RefCntAutoPtr<ITextureAtlasSuballocation> AllocateTextureSpace(TEXTURE_FORMAT Fmt,
78 Uint32 Width,
79 Uint32 Height,
80 const char* CacheId = nullptr,
81 IObject* pUserData = nullptr);
82
83 RefCntAutoPtr<ITextureAtlasSuballocation> FindAllocation(const char* CacheId);
84
85 Uint32 GetTextureVersion()
86 {
87 Uint32 Version = 0;
88
89 std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
90 for (auto atlas_it : m_Atlases)
91 Version += atlas_it.second->GetVersion();
92
93 return Version;
94 }
95
96 Uint32 GetBufferVersion(Uint32 Index) const
97 {
98 return m_BufferSuballocators[Index]->GetVersion();
99 }
100
101 IBuffer* GetBuffer(Uint32 Index, IRenderDevice* pDevice, IDeviceContext* pContext)
102 {
103 return m_BufferSuballocators[Index]->GetBuffer(pDevice, pContext);
104 }
105
106 ITexture* GetTexture(TEXTURE_FORMAT Fmt, IRenderDevice* pDevice, IDeviceContext* pContext)
107 {
108 decltype(m_Atlases)::iterator cache_it; // NB: can't initialize it without locking the mutex
109 {
110 std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
111 cache_it = m_Atlases.find(Fmt);
112 if (cache_it == m_Atlases.end())
113 return nullptr;
114 }
115
116 return cache_it->second->GetTexture(pDevice, pContext);
117 }
118
119 // NB: can't return reference here!
120 TextureDesc GetAtlasDesc(TEXTURE_FORMAT Fmt)
121 {
122 {
123 std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
124
125 auto cache_it = m_Atlases.find(Fmt);
126 if (cache_it != m_Atlases.end())
127 return cache_it->second->GetAtlasDesc();
128 }
129
130 // Atlas is not present in the map - use default description
131 TextureDesc Desc = m_DefaultAtlasDesc.Desc;
132 Desc.Format = Fmt;
133 return Desc;
134 }
135
136 private:
137 template <typename AllocatorType, typename ObjectType>
138 friend class Diligent::MakeNewRCObj;
139
140 ResourceManager(IReferenceCounters* pRefCounters,
141 IRenderDevice* pDevice,
142 const CreateInfo& CI);
143
144 std::vector<RefCntAutoPtr<IBufferSuballocator>> m_BufferSuballocators;
145
146 DynamicTextureAtlasCreateInfo m_DefaultAtlasDesc;
147 const std::string m_DefaultAtlasName;
148
149 using AtlasesHashMapType = std::unordered_map<TEXTURE_FORMAT, RefCntAutoPtr<IDynamicTextureAtlas>, std::hash<Uint32>>;
150 std::mutex m_AtlasesMtx;
151 AtlasesHashMapType m_Atlases;
152
153 using TexAllocationsHashMapType = std::unordered_map<std::string, RefCntWeakPtr<ITextureAtlasSuballocation>>;
154 std::mutex m_TexAllocationsMtx;
155 TexAllocationsHashMapType m_TexAllocations;
156 };
157
158 } // namespace GLTF
159
160 } // namespace Diligent
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
30 #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
31
32 #if PLATFORM_ANDROID || PLATFORM_LINUX || PLATFORM_MACOS || PLATFORM_IOS || (PLATFORM_WIN32 && !defined(_MSC_VER))
33 // https://gcc.gnu.org/wiki/Visibility
34 # define API_QUALIFIER __attribute__((visibility("default")))
35 #elif PLATFORM_WIN32
36 # define API_QUALIFIER
37 #else
38 # error Unsupported platform
39 #endif
40
41
42 DILIGENT_BEGIN_NAMESPACE(Diligent)
43
44 DILIGENT_BEGIN_NAMESPACE(GLTF)
45
46 #if DILIGENT_CPP_INTERFACE
47 class ResourceManager;
48 #else
49 struct ResourceManager;
50 typedef struct ResourceManager ResourceManager;
51 #endif
52
53 struct GLTF_ResourceCacheUseInfo
54 {
55 ResourceManager* pResourceMgr DEFAULT_INITIALIZER(nullptr);
56
57 Uint8 IndexBufferIdx DEFAULT_INITIALIZER(0);
58 Uint8 VertexBuffer0Idx DEFAULT_INITIALIZER(0);
59 Uint8 VertexBuffer1Idx DEFAULT_INITIALIZER(0);
60
61 /// Base color texture format.
62 TEXTURE_FORMAT BaseColorFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
63
64 /// Base color texture format for alpha-cut and alpha-blend materials.
65 TEXTURE_FORMAT BaseColorAlphaFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
66
67 /// Physical descriptor texture format.
68 TEXTURE_FORMAT PhysicalDescFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
69
70 /// Normal map format.
71 TEXTURE_FORMAT NormalFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
72
73 /// Occlusion texture format.
74 TEXTURE_FORMAT OcclusionFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
75
76 /// Emissive texture format.
77 TEXTURE_FORMAT EmissiveFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
78 };
79 typedef struct GLTF_ResourceCacheUseInfo GLTF_ResourceCacheUseInfo;
80
81 enum GLTF_MAT_ALPHA_MODE
82 {
83 GLTF_MAT_ALPHA_MODE_OPAQUE = 0,
84 GLTF_MAT_ALPHA_MODE_MASK,
85 GLTF_MAT_ALPHA_MODE_BLEND,
86 GLTF_MAT_ALPHA_MODE_NUM_MODES
87 };
88 typedef enum GLTF_MAT_ALPHA_MODE GLTF_MAT_ALPHA_MODE;
89
90 enum GLTF_BUFFER_ID
91 {
92 GLTF_BUFFER_ID_VERTEX_BASIC_ATTRIBS = 0,
93 GLTF_BUFFER_ID_VERTEX_SKIN_ATTRIBS,
94 GLTF_BUFFER_ID_INDEX,
95 GLTF_BUFFER_ID_NUM_BUFFERS
96 };
97 typedef enum GLTF_BUFFER_ID GLTF_BUFFER_ID;
98
99 struct GLTF_TextureCacheType;
100 typedef struct GLTF_TextureCacheType GLTF_TextureCacheType;
101
102 /// Model create information
103 struct IGLTFModelCreateInfo
104 {
105 /// File name
106 const char* FileName DEFAULT_INITIALIZER(nullptr);
107
108 /// Optional texture cache to use when loading the model.
109 /// The loader will try to find all the textures in the cache
110 /// and add all new textures to the cache.
111 GLTF_TextureCacheType* pTextureCache DEFAULT_INITIALIZER(nullptr);
112
113 /// Optional resource cache usage info.
114 GLTF_ResourceCacheUseInfo* pCacheInfo DEFAULT_INITIALIZER(nullptr);
115
116 /// Whether to load animation and initialize skin attributes
117 /// buffer.
118 bool LoadAnimationAndSkin DEFAULT_INITIALIZER(true);
119 };
120 typedef struct IGLTFModelCreateInfo IGLTFModelCreateInfo;
121
122 #define DILIGENT_INTERFACE_NAME IGLTFModel
123 #include "../../../Primitives/interface/DefineInterfaceHelperMacros.h"
124
125 #define IGLTFModelInclusiveMethods \
126 IGLTFModelMethods GLTF_Model
127
128 // clang-format off
129
130 DILIGENT_BEGIN_INTERFACE1(IGLTFModel)
131 {
132 VIRTUAL void METHOD(UpdateAnimation)(THIS_ Uint32 index, float time) PURE;
133
134 VIRTUAL void METHOD(PrepareGPUResources)(THIS_ IRenderDevice* pDevice, IDeviceContext* pCtx) PURE;
135
136 VIRTUAL bool METHOD(IsGPUDataInitialized)(THIS) CONST PURE;
137
138 VIRTUAL void METHOD(Transform)(THIS_ const float* Matrix) PURE;
139
140 VIRTUAL IBuffer* METHOD(GetBuffer)(THIS_ GLTF_BUFFER_ID BuffId) PURE;
141
142 VIRTUAL ITexture* METHOD(GetTexture)(THIS_ Uint32 Index) PURE;
143
144 VIRTUAL Uint32 METHOD(GetFirstIndexLocation)(THIS) CONST PURE;
145
146 VIRTUAL Uint32 METHOD(GetBaseVertex)(THIS) CONST PURE;
147 };
148 DILIGENT_END_INTERFACE
149
150 #include "../../../Primitives/interface/UndefInterfaceHelperMacros.h"
151
152 #if DILIGENT_C_INTERFACE
153
154 # define IGLTFModel_UpdateAnimation(This, ...) CALL_IFACE_METHOD(GLTF_Model, UpdateAnimation, This, __VA_ARGS__)
155 # define IGLTFModel_PrepareGPUResources(This, ...) CALL_IFACE_METHOD(GLTF_Model, PrepareGPUResources, This, __VA_ARGS__)
156 # define IGLTFModel_IsGPUDataInitialized(This) CALL_IFACE_METHOD(GLTF_Model, IsGPUDataInitialized, This)
157 # define IGLTFModel_Transform(This, ...) CALL_IFACE_METHOD(GLTF_Model, Transform, This, __VA_ARGS__)
158 # define IGLTFModel_GetBuffer(This, ...) CALL_IFACE_METHOD(GLTF_Model, GetBuffer, This, __VA_ARGS__)
159 # define IGLTFModel_GetTexture(This, ...) CALL_IFACE_METHOD(GLTF_Model, GetTexture, This, __VA_ARGS__)
160 # define IGLTFModel_GetFirstIndexLocation(This) CALL_IFACE_METHOD(GLTF_Model, GetFirstIndexLocation, This)
161 # define IGLTFModel_GetBaseVertex(This) CALL_IFACE_METHOD(GLTF_Model, GetBaseVertex, This)
162
163 // clang-format on
164
165 /// Initializes the renderer
166 API_QUALIFIER
167 struct IGLTFModel* DILIGENT_GLOBAL_FUNCTION(IGLTFModel_Create)(IRenderDevice* pDevice,
168 IDeviceContext* pCtx,
169 const IGLTFModelCreateInfo* CI);
170
171 API_QUALIFIER
172 void DILIGENT_GLOBAL_FUNCTION(IGLTFModel_Destroy)(struct IGLTFModel* model);
173 #endif
174
175 DILIGENT_END_NAMESPACE // namespace GLTF
176
177 DILIGENT_END_NAMESPACE // namespace Diligent
+0
-517
AssetLoader/interface/GLTFLoader.hpp less more
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 #include <vector>
30 #include <array>
31 #include <memory>
32 #include <cfloat>
33 #include <unordered_map>
34 #include <mutex>
35 #include <atomic>
36
37 #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
38 #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
39 #include "../../../DiligentCore/Common/interface/RefCntAutoPtr.hpp"
40 #include "../../../DiligentCore/Common/interface/AdvancedMath.hpp"
41 #include "GLTFResourceManager.hpp"
42
43 namespace tinygltf
44 {
45
46 class Node;
47 class Model;
48
49 } // namespace tinygltf
50
51 namespace Diligent
52 {
53
54 namespace GLTF
55 {
56
57 struct ResourceCacheUseInfo
58 {
59 ResourceManager* pResourceMgr = nullptr;
60
61 Uint8 IndexBufferIdx = 0;
62 Uint8 VertexBuffer0Idx = 0;
63 Uint8 VertexBuffer1Idx = 0;
64
65 /// Base color texture format.
66 TEXTURE_FORMAT BaseColorFormat = TEX_FORMAT_RGBA8_UNORM;
67
68 /// Base color texture format for alpha-cut and alpha-blend materials.
69 TEXTURE_FORMAT BaseColorAlphaFormat = TEX_FORMAT_RGBA8_UNORM;
70
71 /// Physical descriptor texture format.
72 TEXTURE_FORMAT PhysicalDescFormat = TEX_FORMAT_RGBA8_UNORM;
73
74 /// Normal map format.
75 TEXTURE_FORMAT NormalFormat = TEX_FORMAT_RGBA8_UNORM;
76
77 /// Occlusion texture format.
78 TEXTURE_FORMAT OcclusionFormat = TEX_FORMAT_RGBA8_UNORM;
79
80 /// Emissive texture format.
81 TEXTURE_FORMAT EmissiveFormat = TEX_FORMAT_RGBA8_UNORM;
82 };
83
84 struct Material
85 {
86 Material() noexcept
87 {
88 TextureIds.fill(-1);
89 }
90
91 enum PBR_WORKFLOW
92 {
93 PBR_WORKFLOW_METALL_ROUGH = 0,
94 PBR_WORKFLOW_SPEC_GLOSS
95 };
96
97 enum ALPHA_MODE
98 {
99 ALPHA_MODE_OPAQUE = 0,
100 ALPHA_MODE_MASK,
101 ALPHA_MODE_BLEND,
102 ALPHA_MODE_NUM_MODES
103 };
104
105 // Material attributes packed in a shader-friendly format
106 struct ShaderAttribs
107 {
108 float4 BaseColorFactor = float4{1, 1, 1, 1};
109 float4 EmissiveFactor = float4{1, 1, 1, 1};
110 float4 SpecularFactor = float4{1, 1, 1, 1};
111
112 int Workflow = PBR_WORKFLOW_METALL_ROUGH;
113 float BaseColorUVSelector = -1;
114 float PhysicalDescriptorUVSelector = -1;
115 float NormalUVSelector = -1;
116
117 float OcclusionUVSelector = -1;
118 float EmissiveUVSelector = -1;
119 float BaseColorSlice = 0;
120 float PhysicalDescriptorSlice = 0;
121
122 float NormalSlice = 0;
123 float OcclusionSlice = 0;
124 float EmissiveSlice = 0;
125 float MetallicFactor = 1;
126
127 float RoughnessFactor = 1;
128 int AlphaMode = ALPHA_MODE_OPAQUE;
129 float AlphaCutoff = 0.5f;
130 float Dummy0;
131
132 // When texture atlas is used, UV scale and bias applied to
133 // each texture coordinate set
134 float4 BaseColorUVScaleBias = float4{1, 1, 0, 0};
135 float4 PhysicalDescriptorUVScaleBias = float4{1, 1, 0, 0};
136 float4 NormalUVScaleBias = float4{1, 1, 0, 0};
137 float4 OcclusionUVScaleBias = float4{1, 1, 0, 0};
138 float4 EmissiveUVScaleBias = float4{1, 1, 0, 0};
139 };
140 static_assert(sizeof(ShaderAttribs) % 16 == 0, "ShaderAttribs struct must be 16-byte aligned");
141 ShaderAttribs Attribs;
142
143 bool DoubleSided = false;
144
145 enum TEXTURE_ID
146 {
147 // Base color for metallic-roughness workflow or
148 // diffuse color for specular-glossinees workflow
149 TEXTURE_ID_BASE_COLOR = 0,
150
151 // Metallic-roughness or specular-glossinees map
152 TEXTURE_ID_PHYSICAL_DESC,
153
154 TEXTURE_ID_NORMAL_MAP,
155 TEXTURE_ID_OCCLUSION,
156 TEXTURE_ID_EMISSIVE,
157 TEXTURE_ID_NUM_TEXTURES
158 };
159 // Texture indices in Model.Textures array
160 std::array<int, TEXTURE_ID_NUM_TEXTURES> TextureIds = {};
161 };
162
163
164 struct Primitive
165 {
166 const Uint32 FirstIndex;
167 const Uint32 IndexCount;
168 const Uint32 VertexCount;
169 const Uint32 MaterialId;
170
171 const BoundBox BB;
172
173 Primitive(Uint32 _FirstIndex,
174 Uint32 _IndexCount,
175 Uint32 _VertexCount,
176 Uint32 _MaterialId,
177 const float3& BBMin,
178 const float3& BBMax) :
179 FirstIndex{_FirstIndex},
180 IndexCount{_IndexCount},
181 VertexCount{_VertexCount},
182 MaterialId{_MaterialId},
183 BB{BBMin, BBMax}
184 {
185 }
186
187 Primitive(Primitive&&) = default;
188
189 bool HasIndices() const
190 {
191 return IndexCount > 0;
192 }
193 };
194
195
196
197 struct Mesh
198 {
199 std::vector<Primitive> Primitives;
200
201 BoundBox BB;
202
203 // There may be no primitives in the mesh, in which
204 // case the bounding box will be invalid.
205 bool IsValidBB() const
206 {
207 return !Primitives.empty();
208 }
209
210 struct TransformData
211 {
212 float4x4 matrix;
213 std::vector<float4x4> jointMatrices;
214 };
215
216 TransformData Transforms;
217
218 Mesh(const float4x4& matrix);
219 };
220
221
222 struct Node;
223 struct Skin
224 {
225 std::string Name;
226 Node* pSkeletonRoot = nullptr;
227 std::vector<float4x4> InverseBindMatrices;
228 std::vector<Node*> Joints;
229 };
230
231 struct Camera
232 {
233 enum class Projection
234 {
235 Unknown,
236 Perspective,
237 Orthographic
238 } Type = Projection::Unknown;
239
240 std::string Name;
241
242 struct PerspectiveAttribs
243 {
244 float AspectRatio;
245 float YFov;
246 float ZNear;
247 float ZFar;
248 };
249 struct OrthographicAttribs
250 {
251 float XMag;
252 float YMag;
253 float ZNear;
254 float ZFar;
255 };
256 union
257 {
258 PerspectiveAttribs Perspective = {};
259 OrthographicAttribs Orthographic;
260 };
261
262 float4x4 matrix;
263 };
264
265 struct Node
266 {
267 std::string Name;
268 Node* Parent = nullptr;
269 Uint32 Index;
270
271 std::vector<std::unique_ptr<Node>> Children;
272
273 float4x4 Matrix;
274 std::unique_ptr<Mesh> pMesh;
275 std::unique_ptr<Camera> pCamera;
276 Skin* pSkin = nullptr;
277 Int32 SkinIndex = -1;
278 float3 Translation;
279 float3 Scale = float3{1, 1, 1};
280 Quaternion Rotation;
281 BoundBox BVH;
282 BoundBox AABB;
283
284 bool IsValidBVH = false;
285
286 float4x4 LocalMatrix() const;
287 float4x4 GetMatrix() const;
288 void UpdateTransforms();
289 };
290
291
292 struct AnimationChannel
293 {
294 enum PATH_TYPE
295 {
296 TRANSLATION,
297 ROTATION,
298 SCALE
299 };
300 PATH_TYPE PathType;
301 Node* pNode = nullptr;
302 Uint32 SamplerIndex = static_cast<Uint32>(-1);
303 };
304
305
306 struct AnimationSampler
307 {
308 enum INTERPOLATION_TYPE
309 {
310 LINEAR,
311 STEP,
312 CUBICSPLINE
313 };
314 INTERPOLATION_TYPE Interpolation;
315 std::vector<float> Inputs;
316 std::vector<float4> OutputsVec4;
317 };
318
319 struct Animation
320 {
321 std::string Name;
322 std::vector<AnimationSampler> Samplers;
323 std::vector<AnimationChannel> Channels;
324
325 float Start = std::numeric_limits<float>::max();
326 float End = std::numeric_limits<float>::min();
327 };
328
329
330 struct Model
331 {
332 struct VertexBasicAttribs
333 {
334 float3 pos;
335 float3 normal;
336 float2 uv0;
337 float2 uv1;
338 };
339
340 struct VertexSkinAttribs
341 {
342 float4 joint0;
343 float4 weight0;
344 };
345
346 enum BUFFER_ID
347 {
348 BUFFER_ID_VERTEX_BASIC_ATTRIBS = 0,
349 BUFFER_ID_VERTEX_SKIN_ATTRIBS,
350 BUFFER_ID_INDEX,
351 BUFFER_ID_NUM_BUFFERS
352 };
353
354 Uint32 IndexCount = 0;
355
356 /// Transformation matrix that transforms unit cube [0,1]x[0,1]x[0,1] into
357 /// axis-aligned bounding box in model space.
358 float4x4 AABBTransform;
359
360 std::vector<std::unique_ptr<Node>> Nodes;
361 std::vector<Node*> LinearNodes;
362
363 std::vector<std::unique_ptr<Skin>> Skins;
364
365 std::vector<RefCntAutoPtr<ISampler>> TextureSamplers;
366 std::vector<Material> Materials;
367 std::vector<Animation> Animations;
368 std::vector<std::string> Extensions;
369
370 struct Dimensions
371 {
372 float3 min = float3{+FLT_MAX, +FLT_MAX, +FLT_MAX};
373 float3 max = float3{-FLT_MAX, -FLT_MAX, -FLT_MAX};
374 } dimensions;
375
376 struct TextureCacheType
377 {
378 std::mutex TexturesMtx;
379
380 std::unordered_map<std::string, RefCntWeakPtr<ITexture>> Textures;
381 };
382
383 /// Model create information
384 struct CreateInfo
385 {
386 /// File name
387 const char* FileName = nullptr;
388
389 /// Optional texture cache to use when loading the model.
390 /// The loader will try to find all the textures in the cache
391 /// and add all new textures to the cache.
392 TextureCacheType* pTextureCache = nullptr;
393
394 /// Optional resource cache usage info.
395 ResourceCacheUseInfo* pCacheInfo = nullptr;
396
397 /// Whether to load animation and initialize skin attributes
398 /// buffer.
399 bool LoadAnimationAndSkin = true;
400
401 CreateInfo() = default;
402
403 explicit CreateInfo(const char* _FileName,
404 TextureCacheType* _pTextureCache = nullptr,
405 ResourceCacheUseInfo* _pCacheInfo = nullptr,
406 bool _LoadAnimationAndSkin = true) :
407 // clang-format off
408 FileName {_FileName},
409 pTextureCache {_pTextureCache},
410 pCacheInfo {_pCacheInfo},
411 LoadAnimationAndSkin{_LoadAnimationAndSkin}
412 // clang-format on
413 {
414 }
415 };
416 Model(IRenderDevice* pDevice,
417 IDeviceContext* pContext,
418 const CreateInfo& CI);
419
420 ~Model();
421
422 void UpdateAnimation(Uint32 index, float time);
423
424 void PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx);
425
426 bool IsGPUDataInitialized() const
427 {
428 return GPUDataInitialized.load();
429 }
430
431 void Transform(const float4x4& Matrix);
432
433 IBuffer* GetBuffer(BUFFER_ID BuffId)
434 {
435 return Buffers[BuffId].pBuffer;
436 }
437
438 ITexture* GetTexture(Uint32 Index)
439 {
440 return Textures[Index].pTexture;
441 }
442
443 Uint32 GetFirstIndexLocation() const
444 {
445 auto& IndBuff = Buffers[BUFFER_ID_INDEX];
446 VERIFY(!IndBuff.pSuballocation || IndBuff.pSuballocation->GetOffset() % sizeof(Uint32) == 0,
447 "Allocation offset is not multiple of sizeof(Uint32)");
448 return IndBuff.pSuballocation ?
449 static_cast<Uint32>(IndBuff.pSuballocation->GetOffset() / sizeof(Uint32)) :
450 0;
451 }
452
453 Uint32 GetBaseVertex() const
454 {
455 auto& VertBuff = Buffers[BUFFER_ID_VERTEX_BASIC_ATTRIBS];
456 VERIFY(!VertBuff.pSuballocation || VertBuff.pSuballocation->GetOffset() % sizeof(VertexBasicAttribs) == 0,
457 "Allocation offset is not multiple of sizeof(VertexAttribs0)");
458 return VertBuff.pSuballocation ?
459 static_cast<Uint32>(VertBuff.pSuballocation->GetOffset() / sizeof(VertexBasicAttribs)) :
460 0;
461 }
462
463 private:
464 void LoadFromFile(IRenderDevice* pDevice,
465 IDeviceContext* pContext,
466 const CreateInfo& CI);
467
468 void LoadNode(Node* parent,
469 const tinygltf::Node& gltf_node,
470 uint32_t nodeIndex,
471 const tinygltf::Model& gltf_model,
472 std::vector<Uint32>& IndexData,
473 std::vector<VertexBasicAttribs>& VertexBasicData,
474 std::vector<VertexSkinAttribs>* pVertexSkinData);
475
476 void LoadSkins(const tinygltf::Model& gltf_model);
477
478 void LoadTextures(IRenderDevice* pDevice,
479 const tinygltf::Model& gltf_model,
480 const std::string& BaseDir,
481 TextureCacheType* pTextureCache,
482 ResourceManager* pResourceMgr);
483
484 void LoadTextureSamplers(IRenderDevice* pDevice, const tinygltf::Model& gltf_model);
485 void LoadMaterials(const tinygltf::Model& gltf_model);
486 void LoadAnimations(const tinygltf::Model& gltf_model);
487 void CalculateBoundingBox(Node* node, const Node* parent);
488 void CalculateSceneDimensions();
489 Node* FindNode(Node* parent, Uint32 index);
490 Node* NodeFromIndex(uint32_t index);
491
492 std::atomic_bool GPUDataInitialized{false};
493
494 struct BufferInfo
495 {
496 RefCntAutoPtr<IBuffer> pBuffer;
497 RefCntAutoPtr<IBufferSuballocation> pSuballocation;
498 };
499 std::array<BufferInfo, BUFFER_ID_NUM_BUFFERS> Buffers;
500
501 struct TextureInfo
502 {
503 RefCntAutoPtr<ITexture> pTexture;
504 RefCntAutoPtr<ITextureAtlasSuballocation> pAtlasSuballocation;
505
506 bool IsValid() const
507 {
508 return pTexture || pAtlasSuballocation;
509 }
510 };
511 std::vector<TextureInfo> Textures;
512 };
513
514 } // namespace GLTF
515
516 } // namespace Diligent
+0
-161
AssetLoader/interface/GLTFResourceManager.hpp less more
0 /*
1 * Copyright 2019-2021 Diligent Graphics LLC
2 * Copyright 2015-2019 Egor Yusov
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * In no event and under no legal theory, whether in tort (including negligence),
17 * contract, or otherwise, unless required by applicable law (such as deliberate
18 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
19 * liable for any damages, including any direct, indirect, special, incidental,
20 * or consequential damages of any character arising as a result of this License or
21 * out of the use or inability to use the software (including but not limited to damages
22 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
23 * all other commercial damages or losses), even if such Contributor has been advised
24 * of the possibility of such damages.
25 */
26
27 #pragma once
28
29 #include <mutex>
30 #include <vector>
31 #include <unordered_map>
32 #include <atomic>
33
34 #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
35 #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
36 #include "../../../DiligentCore/Common/interface/RefCntAutoPtr.hpp"
37 #include "../../../DiligentCore/Common/interface/ObjectBase.hpp"
38 #include "../../../DiligentCore/Graphics/GraphicsTools/interface/BufferSuballocator.h"
39 #include "../../../DiligentCore/Graphics/GraphicsTools/interface/DynamicTextureAtlas.h"
40
41
42 namespace Diligent
43 {
44
45 namespace GLTF
46 {
47
48 /// GLTF resource manager
49 class ResourceManager final : public ObjectBase<IObject>
50 {
51 public:
52 using TBase = ObjectBase<IObject>;
53
54 struct CreateInfo
55 {
56 const BufferSuballocatorCreateInfo* BuffSuballocators = nullptr; // [NumBuffSuballocators]
57 const DynamicTextureAtlasCreateInfo* TexAtlases = nullptr; // [NumTexAtlases]
58
59 Uint32 NumBuffSuballocators = 0;
60 Uint32 NumTexAtlases = 0;
61
62 DynamicTextureAtlasCreateInfo DefaultAtlasDesc;
63 };
64
65 static RefCntAutoPtr<ResourceManager> Create(IRenderDevice* pDevice,
66 const CreateInfo& CI);
67
68 RefCntAutoPtr<IBufferSuballocation> AllocateBufferSpace(Uint32 BufferIndex,
69 Uint32 Size,
70 Uint32 Alignment)
71 {
72 RefCntAutoPtr<IBufferSuballocation> pSuballoc;
73 m_BufferSuballocators[BufferIndex]->Allocate(Size, Alignment, &pSuballoc);
74 return pSuballoc;
75 }
76
77 RefCntAutoPtr<ITextureAtlasSuballocation> AllocateTextureSpace(TEXTURE_FORMAT Fmt,
78 Uint32 Width,
79 Uint32 Height,
80 const char* CacheId = nullptr,
81 IObject* pUserData = nullptr);
82
83 RefCntAutoPtr<ITextureAtlasSuballocation> FindAllocation(const char* CacheId);
84
85 Uint32 GetTextureVersion()
86 {
87 Uint32 Version = 0;
88
89 std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
90 for (auto atlas_it : m_Atlases)
91 Version += atlas_it.second->GetVersion();
92
93 return Version;
94 }
95
96 Uint32 GetBufferVersion(Uint32 Index) const
97 {
98 return m_BufferSuballocators[Index]->GetVersion();
99 }
100
101 IBuffer* GetBuffer(Uint32 Index, IRenderDevice* pDevice, IDeviceContext* pContext)
102 {
103 return m_BufferSuballocators[Index]->GetBuffer(pDevice, pContext);
104 }
105
106 ITexture* GetTexture(TEXTURE_FORMAT Fmt, IRenderDevice* pDevice, IDeviceContext* pContext)
107 {
108 decltype(m_Atlases)::iterator cache_it; // NB: can't initialize it without locking the mutex
109 {
110 std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
111 cache_it = m_Atlases.find(Fmt);
112 if (cache_it == m_Atlases.end())
113 return nullptr;
114 }
115
116 return cache_it->second->GetTexture(pDevice, pContext);
117 }
118
119 // NB: can't return reference here!
120 TextureDesc GetAtlasDesc(TEXTURE_FORMAT Fmt)
121 {
122 {
123 std::lock_guard<std::mutex> Lock{m_AtlasesMtx};
124
125 auto cache_it = m_Atlases.find(Fmt);
126 if (cache_it != m_Atlases.end())
127 return cache_it->second->GetAtlasDesc();
128 }
129
130 // Atlas is not present in the map - use default description
131 TextureDesc Desc = m_DefaultAtlasDesc.Desc;
132 Desc.Format = Fmt;
133 return Desc;
134 }
135
136 private:
137 template <typename AllocatorType, typename ObjectType>
138 friend class Diligent::MakeNewRCObj;
139
140 ResourceManager(IReferenceCounters* pRefCounters,
141 IRenderDevice* pDevice,
142 const CreateInfo& CI);
143
144 std::vector<RefCntAutoPtr<IBufferSuballocator>> m_BufferSuballocators;
145
146 DynamicTextureAtlasCreateInfo m_DefaultAtlasDesc;
147 const std::string m_DefaultAtlasName;
148
149 using AtlasesHashMapType = std::unordered_map<TEXTURE_FORMAT, RefCntAutoPtr<IDynamicTextureAtlas>, std::hash<Uint32>>;
150 std::mutex m_AtlasesMtx;
151 AtlasesHashMapType m_Atlases;
152
153 using TexAllocationsHashMapType = std::unordered_map<std::string, RefCntWeakPtr<ITextureAtlasSuballocation>>;
154 std::mutex m_TexAllocationsMtx;
155 TexAllocationsHashMapType m_TexAllocations;
156 };
157
158 } // namespace GLTF
159
160 } // namespace Diligent
245245
246246
247247
248 Model::Model(IRenderDevice* pDevice,
249 IDeviceContext* pContext,
250 const CreateInfo& CI)
248 Model::Model(IRenderDevice* pDevice,
249 IDeviceContext* pContext,
250 const IGLTFModelCreateInfo& CI)
251251 {
252252 LoadFromFile(pDevice, pContext, CI);
253253 }
709709 void Model::LoadTextures(IRenderDevice* pDevice,
710710 const tinygltf::Model& gltf_model,
711711 const std::string& BaseDir,
712 TextureCacheType* pTextureCache,
712 GLTF_TextureCacheType* pTextureCache,
713713 ResourceManager* pResourceMgr)
714714 {
715715 for (const tinygltf::Texture& gltf_tex : gltf_model.textures)
10201020 }
10211021 }
10221022
1023 auto UpdateBuffer = [&](BUFFER_ID BuffId) //
1023 auto UpdateBuffer = [&](GLTF_BUFFER_ID BuffId) //
10241024 {
10251025 auto& BuffInfo = Buffers[BuffId];
10261026 IBuffer* pBuffer = nullptr;
10511051 if (Buffers[BuffId].pBuffer != nullptr)
10521052 {
10531053 VERIFY_EXPR(Buffers[BuffId].pBuffer == pBuffer);
1054 Barriers.emplace_back(StateTransitionDesc{pBuffer, RESOURCE_STATE_UNKNOWN, BuffId == BUFFER_ID_INDEX ? RESOURCE_STATE_INDEX_BUFFER : RESOURCE_STATE_VERTEX_BUFFER, true});
1054 Barriers.emplace_back(StateTransitionDesc{pBuffer, RESOURCE_STATE_UNKNOWN, BuffId == GLTF_BUFFER_ID_INDEX ? RESOURCE_STATE_INDEX_BUFFER : RESOURCE_STATE_VERTEX_BUFFER, true});
10551055 }
10561056 }
10571057 };
10581058
1059 UpdateBuffer(BUFFER_ID_VERTEX_BASIC_ATTRIBS);
1060 UpdateBuffer(BUFFER_ID_VERTEX_SKIN_ATTRIBS);
1061 UpdateBuffer(BUFFER_ID_INDEX);
1059 UpdateBuffer(GLTF_BUFFER_ID_VERTEX_BASIC_ATTRIBS);
1060 UpdateBuffer(GLTF_BUFFER_ID_VERTEX_SKIN_ATTRIBS);
1061 UpdateBuffer(GLTF_BUFFER_ID_INDEX);
10621062
10631063 if (!Barriers.empty())
10641064 pCtx->TransitionResourceStates(static_cast<Uint32>(Barriers.size()), Barriers.data());
11941194 const tinygltf::Parameter& param = alpha_mode_it->second;
11951195 if (param.string_value == "BLEND")
11961196 {
1197 Mat.Attribs.AlphaMode = Material::ALPHA_MODE_BLEND;
1197 Mat.Attribs.AlphaMode = GLTF_MAT_ALPHA_MODE_BLEND;
11981198 }
11991199 if (param.string_value == "MASK")
12001200 {
1201 Mat.Attribs.AlphaMode = Material::ALPHA_MODE_MASK;
1201 Mat.Attribs.AlphaMode = GLTF_MAT_ALPHA_MODE_MASK;
12021202 Mat.Attribs.AlphaCutoff = 0.5f;
12031203 }
12041204 }
14331433
14341434 struct ImageLoaderData
14351435 {
1436 Model::TextureCacheType* const pTextureCache;
1437 ResourceManager* const pResourceMgr;
1436 GLTF_TextureCacheType* const pTextureCache;
1437 ResourceManager* const pResourceMgr;
14381438
14391439 std::vector<RefCntAutoPtr<IObject>> TexturesHold;
14401440
16981698
16991699 } // namespace Callbacks
17001700
1701 void Model::LoadFromFile(IRenderDevice* pDevice,
1702 IDeviceContext* pContext,
1703 const CreateInfo& CI)
1701 void Model::LoadFromFile(IRenderDevice* pDevice,
1702 IDeviceContext* pContext,
1703 const IGLTFModelCreateInfo& CI)
17041704 {
17051705 if (CI.FileName == nullptr || *CI.FileName == 0)
17061706 LOG_ERROR_AND_THROW("File path must not be empty");
17981798
17991799 Extensions = gltf_model.extensionsUsed;
18001800
1801 auto CreateBuffer = [&](BUFFER_ID BuffId, const void* pData, size_t Size, BIND_FLAGS BindFlags, const char* Name) //
1801 auto CreateBuffer = [&](GLTF_BUFFER_ID BuffId, const void* pData, size_t Size, BIND_FLAGS BindFlags, const char* Name) //
18021802 {
18031803 VERIFY_EXPR(Size > 0);
18041804
18081808 Uint32 CacheBufferIndex = 0;
18091809 switch (BuffId)
18101810 {
1811 case BUFFER_ID_INDEX:
1811 case GLTF_BUFFER_ID_INDEX:
18121812 CacheBufferIndex = CI.pCacheInfo->IndexBufferIdx;
18131813 break;
1814 case BUFFER_ID_VERTEX_BASIC_ATTRIBS:
1814 case GLTF_BUFFER_ID_VERTEX_BASIC_ATTRIBS:
18151815 CacheBufferIndex = CI.pCacheInfo->VertexBuffer0Idx;
18161816 break;
1817 case BUFFER_ID_VERTEX_SKIN_ATTRIBS:
1817 case GLTF_BUFFER_ID_VERTEX_SKIN_ATTRIBS:
18181818 CacheBufferIndex = CI.pCacheInfo->VertexBuffer1Idx;
18191819 break;
18201820 default:
18391839 }
18401840 };
18411841
1842 CreateBuffer(BUFFER_ID_VERTEX_BASIC_ATTRIBS, VertexBasicData.data(), VertexBasicData.size() * sizeof(VertexBasicData[0]),
1842 CreateBuffer(GLTF_BUFFER_ID_VERTEX_BASIC_ATTRIBS, VertexBasicData.data(), VertexBasicData.size() * sizeof(VertexBasicData[0]),
18431843 BIND_VERTEX_BUFFER, "GLTF vertex attribs 0 buffer");
18441844
18451845 if (!VertexSkinData.empty())
18461846 {
1847 CreateBuffer(BUFFER_ID_VERTEX_SKIN_ATTRIBS, VertexSkinData.data(), VertexSkinData.size() * sizeof(VertexSkinData[0]),
1847 CreateBuffer(GLTF_BUFFER_ID_VERTEX_SKIN_ATTRIBS, VertexSkinData.data(), VertexSkinData.size() * sizeof(VertexSkinData[0]),
18481848 BIND_VERTEX_BUFFER, "GLTF vertex attribs 1 buffer");
18491849 }
18501850
18511851 if (!IndexData.empty())
18521852 {
1853 CreateBuffer(BUFFER_ID_INDEX, IndexData.data(), IndexData.size() * sizeof(IndexData[0]),
1853 CreateBuffer(GLTF_BUFFER_ID_INDEX, IndexData.data(), IndexData.size() * sizeof(IndexData[0]),
18541854 BIND_INDEX_BUFFER, "GLTF index buffer");
18551855 }
18561856
19881988 }
19891989 }
19901990
1991 void Model::Transform(const float4x4& Matrix)
1992 {
1991 void Model::Transform(const float* _Matrix)
1992 {
1993 auto Matrix = float4x4::MakeMatrix(_Matrix);
19931994 for (auto& root_node : Nodes)
19941995 {
19951996 root_node->Matrix *= Matrix;
20322033 return nodeFound;
20332034 }
20342035
2036 API_QUALIFIER
2037 IGLTFModel* IGLTFModel_Create(IRenderDevice* pDevice,
2038 IDeviceContext* pCtx,
2039 const IGLTFModelCreateInfo* CI) {
2040 return new Model(pDevice, pCtx, *CI);
2041 }
2042
2043 API_QUALIFIER
2044 void IGLTFModel_Destroy(IGLTFModel* model) {
2045 delete model;
2046 }
20352047
20362048 } // namespace GLTF
20372049
20382050 } // namespace Diligent
2051
2052 extern "C"
2053 {
2054 API_QUALIFIER
2055 Diligent::GLTF::IGLTFModel* Diligent_IGLTFModel_Create(Diligent::IRenderDevice* pDevice,
2056 Diligent::IDeviceContext* pCtx,
2057 const Diligent::GLTF::IGLTFModelCreateInfo* CI) {
2058 return Diligent::GLTF::IGLTFModel_Create(pDevice, pCtx, CI);
2059 }
2060
2061 API_QUALIFIER
2062 void Diligent_IGLTFModel_Destroy(Diligent::GLTF::IGLTFModel* model) {
2063 Diligent::GLTF::IGLTFModel_Destroy(model);
2064 }
2065 }