· 4 years ago · Mar 30, 2021, 03:22 PM
1From 949df6bdb9d838934b0f14316bb6fc715962200d Mon Sep 17 00:00:00 2001
2From: s-ol <s+removethis@s-ol.nu>
3Date: Sat, 27 Mar 2021 09:58:07 +0100
4Subject: [PATCH 1/3] DILIGENT_BEGIN_INTERFACE1 helper
5
6---
7 DiligentCore/Primitives/interface/CommonDefinitions.h | 9 +++++++++
8 1 file changed, 9 insertions(+)
9
10diff --git a/DiligentCore/Primitives/interface/CommonDefinitions.h b/DiligentCore/Primitives/interface/CommonDefinitions.h
11index 483ae86f..8a290076 100644
12--- a/DiligentCore/Primitives/interface/CommonDefinitions.h
13+++ b/DiligentCore/Primitives/interface/CommonDefinitions.h
14@@ -69,6 +69,13 @@
15         } Iface;                                  \
16         struct Iface##Methods
17 
18+#    define DILIGENT_BEGIN_INTERFACE1(Iface)      \
19+        typedef struct Iface                      \
20+        {                                         \
21+            struct Iface##Vtbl* pVtbl;            \
22+        } Iface;                                  \
23+        struct Iface##Methods
24+
25 #    define DEFAULT_VALUE(x)
26 
27 #    define CALL_IFACE_METHOD(Iface, Method, This, ...) (This)->pVtbl->Iface.Method((I##Iface*)(This), ##__VA_ARGS__)
28@@ -96,6 +103,8 @@
29 
30 #    define DILIGENT_BEGIN_INTERFACE(Name, Base) struct Name : public Base
31 
32+#    define DILIGENT_BEGIN_INTERFACE1(Name) struct Name
33+
34 #    define DEFAULT_VALUE(x) = x
35 
36 #endif
37-- 
382.31.0
39
40From 1b66dcfa8bd1f2deddb3e406653a3553c5549bf5 Mon Sep 17 00:00:00 2001
41From: s-ol <s+removethis@s-ol.nu>
42Date: Sat, 27 Mar 2021 10:12:40 +0100
43Subject: [PATCH 2/3] C API for GLTFLoader
44
45---
46 DiligentTools/AssetLoader/CMakeLists.txt                    |   4 +-
47 .../{interface => include}/GLTFLoader.hpp                   | 139 ++++----------
48 .../GLTFResourceManager.hpp                                 |   0
49 DiligentTools/AssetLoader/interface/GLTFLoader.h            | 178 ++++++++++++++++++
50 DiligentTools/AssetLoader/src/GLTFLoader.cpp                |  75 +++++---
51 5 files changed, 263 insertions(+), 133 deletions(-)
52 rename DiligentTools/AssetLoader/{interface => include}/GLTFLoader.hpp (74%)
53 rename DiligentTools/AssetLoader/{interface => include}/GLTFResourceManager.hpp (100%)
54 create mode 100644 DiligentTools/AssetLoader/interface/GLTFLoader.h
55
56diff --git a/DiligentTools/AssetLoader/CMakeLists.txt b/DiligentTools/AssetLoader/CMakeLists.txt
57index 52b8694..fd4bf7b 100644
58--- a/DiligentTools/AssetLoader/CMakeLists.txt
59+++ b/DiligentTools/AssetLoader/CMakeLists.txt
60@@ -4,12 +4,12 @@ project(Diligent-AssetLoader CXX)
61 
62 set(INCLUDE 
63     #include/GLTFLoader.hpp
64+    #include/GLTFResourceManager.hpp
65 )
66 
67 set(INTERFACE
68-    interface/GLTFLoader.hpp
69+    interface/GLTFLoader.h
70     interface/DXSDKMeshLoader.hpp
71-    interface/GLTFResourceManager.hpp
72 )
73 
74 set(SOURCE 
75diff --git a/DiligentTools/AssetLoader/interface/GLTFLoader.hpp b/DiligentTools/AssetLoader/include/GLTFLoader.hpp
76similarity index 74%
77rename from DiligentTools/AssetLoader/interface/GLTFLoader.hpp
78rename to DiligentTools/AssetLoader/include/GLTFLoader.hpp
79index 3547775..83b9a4d 100644
80--- a/DiligentTools/AssetLoader/interface/GLTFLoader.hpp
81+++ b/DiligentTools/AssetLoader/include/GLTFLoader.hpp
82@@ -39,6 +39,7 @@
83 #include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
84 #include "../../../DiligentCore/Common/interface/RefCntAutoPtr.hpp"
85 #include "../../../DiligentCore/Common/interface/AdvancedMath.hpp"
86+#include "GLTFLoader.h"
87 #include "GLTFResourceManager.hpp"
88 
89 namespace tinygltf
90@@ -55,33 +56,6 @@ namespace Diligent
91 namespace GLTF
92 {
93 
94-struct ResourceCacheUseInfo
95-{
96-    ResourceManager* pResourceMgr = nullptr;
97-
98-    Uint8 IndexBufferIdx   = 0;
99-    Uint8 VertexBuffer0Idx = 0;
100-    Uint8 VertexBuffer1Idx = 0;
101-
102-    /// Base color texture format.
103-    TEXTURE_FORMAT BaseColorFormat = TEX_FORMAT_RGBA8_UNORM;
104-
105-    /// Base color texture format for alpha-cut and alpha-blend materials.
106-    TEXTURE_FORMAT BaseColorAlphaFormat = TEX_FORMAT_RGBA8_UNORM;
107-
108-    /// Physical descriptor texture format.
109-    TEXTURE_FORMAT PhysicalDescFormat = TEX_FORMAT_RGBA8_UNORM;
110-
111-    /// Normal map format.
112-    TEXTURE_FORMAT NormalFormat = TEX_FORMAT_RGBA8_UNORM;
113-
114-    /// Occlusion texture format.
115-    TEXTURE_FORMAT OcclusionFormat = TEX_FORMAT_RGBA8_UNORM;
116-
117-    /// Emissive texture format.
118-    TEXTURE_FORMAT EmissiveFormat = TEX_FORMAT_RGBA8_UNORM;
119-};
120-
121 struct Material
122 {
123     Material() noexcept
124@@ -95,14 +69,6 @@ struct Material
125         PBR_WORKFLOW_SPEC_GLOSS
126     };
127 
128-    enum ALPHA_MODE
129-    {
130-        ALPHA_MODE_OPAQUE = 0,
131-        ALPHA_MODE_MASK,
132-        ALPHA_MODE_BLEND,
133-        ALPHA_MODE_NUM_MODES
134-    };
135-
136     // Material attributes packed in a shader-friendly format
137     struct ShaderAttribs
138     {
139@@ -126,7 +92,7 @@ struct Material
140         float MetallicFactor = 1;
141 
142         float RoughnessFactor = 1;
143-        int   AlphaMode       = ALPHA_MODE_OPAQUE;
144+        int   AlphaMode       = GLTF_MAT_ALPHA_MODE_OPAQUE;
145         float AlphaCutoff     = 0.5f;
146         float Dummy0;
147 
148@@ -327,9 +293,16 @@ struct Animation
149     float End   = std::numeric_limits<float>::min();
150 };
151 
152+struct GLTF_TextureCacheType
153+{
154+    std::mutex TexturesMtx;
155 
156-struct Model
157+    std::unordered_map<std::string, RefCntWeakPtr<ITexture>> Textures;
158+};
159+
160+class Model : public IGLTFModel
161 {
162+public:
163     struct VertexBasicAttribs
164     {
165         float3 pos;
166@@ -344,14 +317,6 @@ struct Model
167         float4 weight0;
168     };
169 
170-    enum BUFFER_ID
171-    {
172-        BUFFER_ID_VERTEX_BASIC_ATTRIBS = 0,
173-        BUFFER_ID_VERTEX_SKIN_ATTRIBS,
174-        BUFFER_ID_INDEX,
175-        BUFFER_ID_NUM_BUFFERS
176-    };
177-
178     Uint32 IndexCount = 0;
179 
180     /// Transformation matrix that transforms unit cube [0,1]x[0,1]x[0,1] into
181@@ -374,76 +339,36 @@ struct Model
182         float3 max = float3{-FLT_MAX, -FLT_MAX, -FLT_MAX};
183     } dimensions;
184 
185-    struct TextureCacheType
186-    {
187-        std::mutex TexturesMtx;
188-
189-        std::unordered_map<std::string, RefCntWeakPtr<ITexture>> Textures;
190-    };
191-
192-    /// Model create information
193-    struct CreateInfo
194-    {
195-        /// File name
196-        const char* FileName = nullptr;
197-
198-        /// Optional texture cache to use when loading the model.
199-        /// The loader will try to find all the textures in the cache
200-        /// and add all new textures to the cache.
201-        TextureCacheType* pTextureCache = nullptr;
202-
203-        /// Optional resource cache usage info.
204-        ResourceCacheUseInfo* pCacheInfo = nullptr;
205-
206-        /// Whether to load animation and initialize skin attributes
207-        /// buffer.
208-        bool LoadAnimationAndSkin = true;
209-
210-        CreateInfo() = default;
211-
212-        explicit CreateInfo(const char*           _FileName,
213-                            TextureCacheType*     _pTextureCache        = nullptr,
214-                            ResourceCacheUseInfo* _pCacheInfo           = nullptr,
215-                            bool                  _LoadAnimationAndSkin = true) :
216-            // clang-format off
217-            FileName            {_FileName},
218-            pTextureCache       {_pTextureCache},
219-            pCacheInfo          {_pCacheInfo},
220-            LoadAnimationAndSkin{_LoadAnimationAndSkin}
221-        // clang-format on
222-        {
223-        }
224-    };
225-    Model(IRenderDevice*    pDevice,
226-          IDeviceContext*   pContext,
227-          const CreateInfo& CI);
228+    Model(IRenderDevice*              pDevice,
229+          IDeviceContext*             pContext,
230+          const IGLTFModelCreateInfo& CI);
231 
232     ~Model();
233 
234-    void UpdateAnimation(Uint32 index, float time);
235+    virtual void UpdateAnimation(Uint32 index, float time) override final;
236 
237-    void PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx);
238+    virtual void PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx) override final;
239 
240-    bool IsGPUDataInitialized() const
241+    virtual bool IsGPUDataInitialized() const override final
242     {
243         return GPUDataInitialized.load();
244     }
245 
246-    void Transform(const float4x4& Matrix);
247+    virtual void Transform(const float* Matrix) override final;
248 
249-    IBuffer* GetBuffer(BUFFER_ID BuffId)
250+    virtual IBuffer* GetBuffer(GLTF_BUFFER_ID BuffId) override final
251     {
252         return Buffers[BuffId].pBuffer;
253     }
254 
255-    ITexture* GetTexture(Uint32 Index)
256+    virtual ITexture* GetTexture(Uint32 Index) override final
257     {
258         return Textures[Index].pTexture;
259     }
260 
261-    Uint32 GetFirstIndexLocation() const
262+    virtual Uint32 GetFirstIndexLocation() const override final
263     {
264-        auto& IndBuff = Buffers[BUFFER_ID_INDEX];
265+        auto& IndBuff = Buffers[GLTF_BUFFER_ID_INDEX];
266         VERIFY(!IndBuff.pSuballocation || IndBuff.pSuballocation->GetOffset() % sizeof(Uint32) == 0,
267                "Allocation offset is not multiple of sizeof(Uint32)");
268         return IndBuff.pSuballocation ?
269@@ -451,9 +376,9 @@ struct Model
270             0;
271     }
272 
273-    Uint32 GetBaseVertex() const
274+    virtual Uint32 GetBaseVertex() const override final
275     {
276-        auto& VertBuff = Buffers[BUFFER_ID_VERTEX_BASIC_ATTRIBS];
277+        auto& VertBuff = Buffers[GLTF_BUFFER_ID_VERTEX_BASIC_ATTRIBS];
278         VERIFY(!VertBuff.pSuballocation || VertBuff.pSuballocation->GetOffset() % sizeof(VertexBasicAttribs) == 0,
279                "Allocation offset is not multiple of sizeof(VertexAttribs0)");
280         return VertBuff.pSuballocation ?
281@@ -462,9 +387,9 @@ struct Model
282     }
283 
284 private:
285-    void LoadFromFile(IRenderDevice*    pDevice,
286-                      IDeviceContext*   pContext,
287-                      const CreateInfo& CI);
288+    void LoadFromFile(IRenderDevice*              pDevice,
289+                      IDeviceContext*             pContext,
290+                      const IGLTFModelCreateInfo& CI);
291 
292     void LoadNode(Node*                            parent,
293                   const tinygltf::Node&            gltf_node,
294@@ -476,11 +401,11 @@ private:
295 
296     void LoadSkins(const tinygltf::Model& gltf_model);
297 
298-    void LoadTextures(IRenderDevice*         pDevice,
299-                      const tinygltf::Model& gltf_model,
300-                      const std::string&     BaseDir,
301-                      TextureCacheType*      pTextureCache,
302-                      ResourceManager*       pResourceMgr);
303+    void LoadTextures(IRenderDevice*              pDevice,
304+                      const tinygltf::Model&      gltf_model,
305+                      const std::string&          BaseDir,
306+                      GLTF_TextureCacheType*      pTextureCache,
307+                      ResourceManager*            pResourceMgr);
308 
309     void  LoadTextureSamplers(IRenderDevice* pDevice, const tinygltf::Model& gltf_model);
310     void  LoadMaterials(const tinygltf::Model& gltf_model);
311@@ -497,7 +422,7 @@ private:
312         RefCntAutoPtr<IBuffer>              pBuffer;
313         RefCntAutoPtr<IBufferSuballocation> pSuballocation;
314     };
315-    std::array<BufferInfo, BUFFER_ID_NUM_BUFFERS> Buffers;
316+    std::array<BufferInfo, GLTF_BUFFER_ID_NUM_BUFFERS> Buffers;
317 
318     struct TextureInfo
319     {
320diff --git a/DiligentTools/AssetLoader/interface/GLTFResourceManager.hpp b/DiligentTools/AssetLoader/include/GLTFResourceManager.hpp
321similarity index 100%
322rename from DiligentTools/AssetLoader/interface/GLTFResourceManager.hpp
323rename to DiligentTools/AssetLoader/include/GLTFResourceManager.hpp
324diff --git a/DiligentTools/AssetLoader/interface/GLTFLoader.h b/DiligentTools/AssetLoader/interface/GLTFLoader.h
325new file mode 100644
326index 0000000..810a7c4
327--- /dev/null
328+++ b/DiligentTools/AssetLoader/interface/GLTFLoader.h
329@@ -0,0 +1,178 @@
330+/*
331+ *  Copyright 2019-2021 Diligent Graphics LLC
332+ *  Copyright 2015-2019 Egor Yusov
333+ *  
334+ *  Licensed under the Apache License, Version 2.0 (the "License");
335+ *  you may not use this file except in compliance with the License.
336+ *  You may obtain a copy of the License at
337+ *  
338+ *      http://www.apache.org/licenses/LICENSE-2.0
339+ *  
340+ *  Unless required by applicable law or agreed to in writing, software
341+ *  distributed under the License is distributed on an "AS IS" BASIS,
342+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
343+ *  See the License for the specific language governing permissions and
344+ *  limitations under the License.
345+ *
346+ *  In no event and under no legal theory, whether in tort (including negligence), 
347+ *  contract, or otherwise, unless required by applicable law (such as deliberate 
348+ *  and grossly negligent acts) or agreed to in writing, shall any Contributor be
349+ *  liable for any damages, including any direct, indirect, special, incidental, 
350+ *  or consequential damages of any character arising as a result of this License or 
351+ *  out of the use or inability to use the software (including but not limited to damages 
352+ *  for loss of goodwill, work stoppage, computer failure or malfunction, or any and 
353+ *  all other commercial damages or losses), even if such Contributor has been advised 
354+ *  of the possibility of such damages.
355+ */
356+
357+#pragma once
358+
359+#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
360+#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
361+
362+#if PLATFORM_ANDROID || PLATFORM_LINUX || PLATFORM_MACOS || PLATFORM_IOS || (PLATFORM_WIN32 && !defined(_MSC_VER))
363+// https://gcc.gnu.org/wiki/Visibility
364+#    define API_QUALIFIER __attribute__((visibility("default")))
365+#elif PLATFORM_WIN32
366+#    define API_QUALIFIER
367+#else
368+#    error Unsupported platform
369+#endif
370+
371+
372+DILIGENT_BEGIN_NAMESPACE(Diligent)
373+
374+DILIGENT_BEGIN_NAMESPACE(GLTF)
375+
376+#if DILIGENT_CPP_INTERFACE
377+    class ResourceManager;
378+#else
379+    struct ResourceManager;
380+    typedef struct ResourceManager ResourceManager;
381+#endif
382+
383+struct GLTF_ResourceCacheUseInfo
384+{
385+    ResourceManager* pResourceMgr DEFAULT_INITIALIZER(nullptr);
386+
387+    Uint8 IndexBufferIdx   DEFAULT_INITIALIZER(0);
388+    Uint8 VertexBuffer0Idx DEFAULT_INITIALIZER(0);
389+    Uint8 VertexBuffer1Idx DEFAULT_INITIALIZER(0);
390+
391+    /// Base color texture format.
392+    TEXTURE_FORMAT BaseColorFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
393+
394+    /// Base color texture format for alpha-cut and alpha-blend materials.
395+    TEXTURE_FORMAT BaseColorAlphaFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
396+
397+    /// Physical descriptor texture format.
398+    TEXTURE_FORMAT PhysicalDescFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
399+
400+    /// Normal map format.
401+    TEXTURE_FORMAT NormalFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
402+
403+    /// Occlusion texture format.
404+    TEXTURE_FORMAT OcclusionFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
405+
406+    /// Emissive texture format.
407+    TEXTURE_FORMAT EmissiveFormat DEFAULT_INITIALIZER(TEX_FORMAT_RGBA8_UNORM);
408+};
409+typedef struct GLTF_ResourceCacheUseInfo GLTF_ResourceCacheUseInfo;
410+
411+enum GLTF_MAT_ALPHA_MODE
412+{
413+    GLTF_MAT_ALPHA_MODE_OPAQUE = 0,
414+    GLTF_MAT_ALPHA_MODE_MASK,
415+    GLTF_MAT_ALPHA_MODE_BLEND,
416+    GLTF_MAT_ALPHA_MODE_NUM_MODES
417+};
418+typedef enum GLTF_MAT_ALPHA_MODE GLTF_MAT_ALPHA_MODE;
419+
420+enum GLTF_BUFFER_ID
421+{
422+    GLTF_BUFFER_ID_VERTEX_BASIC_ATTRIBS = 0,
423+    GLTF_BUFFER_ID_VERTEX_SKIN_ATTRIBS,
424+    GLTF_BUFFER_ID_INDEX,
425+    GLTF_BUFFER_ID_NUM_BUFFERS
426+};
427+typedef enum GLTF_BUFFER_ID GLTF_BUFFER_ID;
428+
429+struct GLTF_TextureCacheType;
430+typedef struct GLTF_TextureCacheType GLTF_TextureCacheType;
431+
432+/// Model create information
433+struct IGLTFModelCreateInfo
434+{
435+    /// File name
436+    const char* FileName DEFAULT_INITIALIZER(nullptr);
437+
438+    /// Optional texture cache to use when loading the model.
439+    /// The loader will try to find all the textures in the cache
440+    /// and add all new textures to the cache.
441+    GLTF_TextureCacheType* pTextureCache DEFAULT_INITIALIZER(nullptr);
442+
443+    /// Optional resource cache usage info.
444+    GLTF_ResourceCacheUseInfo* pCacheInfo DEFAULT_INITIALIZER(nullptr);
445+
446+    /// Whether to load animation and initialize skin attributes
447+    /// buffer.
448+    bool LoadAnimationAndSkin DEFAULT_INITIALIZER(true);
449+};
450+typedef struct IGLTFModelCreateInfo IGLTFModelCreateInfo;
451+
452+#define DILIGENT_INTERFACE_NAME IGLTFModel
453+#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h"
454+
455+#define IGLTFModelInclusiveMethods \
456+    IGLTFModelMethods GLTF_Model
457+
458+// clang-format off
459+
460+DILIGENT_BEGIN_INTERFACE1(IGLTFModel)
461+{
462+    VIRTUAL void METHOD(UpdateAnimation)(THIS_ Uint32 index, float time) PURE;
463+
464+    VIRTUAL void METHOD(PrepareGPUResources)(THIS_ IRenderDevice* pDevice, IDeviceContext* pCtx) PURE;
465+
466+    VIRTUAL bool METHOD(IsGPUDataInitialized)(THIS) CONST PURE;
467+
468+    VIRTUAL void METHOD(Transform)(THIS_ const float* Matrix) PURE;
469+
470+    VIRTUAL IBuffer* METHOD(GetBuffer)(THIS_ GLTF_BUFFER_ID BuffId) PURE;
471+
472+    VIRTUAL ITexture* METHOD(GetTexture)(THIS_ Uint32 Index) PURE;
473+
474+    VIRTUAL Uint32 METHOD(GetFirstIndexLocation)(THIS) CONST PURE;
475+
476+    VIRTUAL Uint32 METHOD(GetBaseVertex)(THIS) CONST PURE;
477+};
478+DILIGENT_END_INTERFACE
479+
480+#include "../../../Primitives/interface/UndefInterfaceHelperMacros.h"
481+
482+#if DILIGENT_C_INTERFACE
483+
484+#    define IGLTFModel_UpdateAnimation(This, ...)     CALL_IFACE_METHOD(GLTF_Model, UpdateAnimation,       This, __VA_ARGS__)
485+#    define IGLTFModel_PrepareGPUResources(This, ...) CALL_IFACE_METHOD(GLTF_Model, PrepareGPUResources,   This, __VA_ARGS__)
486+#    define IGLTFModel_IsGPUDataInitialized(This)     CALL_IFACE_METHOD(GLTF_Model, IsGPUDataInitialized,  This)
487+#    define IGLTFModel_Transform(This, ...)           CALL_IFACE_METHOD(GLTF_Model, Transform,             This, __VA_ARGS__)
488+#    define IGLTFModel_GetBuffer(This, ...)           CALL_IFACE_METHOD(GLTF_Model, GetBuffer,             This, __VA_ARGS__)
489+#    define IGLTFModel_GetTexture(This, ...)          CALL_IFACE_METHOD(GLTF_Model, GetTexture,            This, __VA_ARGS__)
490+#    define IGLTFModel_GetFirstIndexLocation(This)    CALL_IFACE_METHOD(GLTF_Model, GetFirstIndexLocation, This)
491+#    define IGLTFModel_GetBaseVertex(This)            CALL_IFACE_METHOD(GLTF_Model, GetBaseVertex,         This)
492+
493+// clang-format on
494+
495+/// Initializes the renderer
496+API_QUALIFIER
497+struct IGLTFModel* DILIGENT_GLOBAL_FUNCTION(IGLTFModel_Create)(IRenderDevice*              pDevice,
498+                                                               IDeviceContext*             pCtx,
499+                                                               const IGLTFModelCreateInfo* CI);
500+
501+API_QUALIFIER
502+void DILIGENT_GLOBAL_FUNCTION(IGLTFModel_Destroy)(struct IGLTFModel* model);
503+#endif
504+
505+DILIGENT_END_NAMESPACE // namespace GLTF
506+
507+DILIGENT_END_NAMESPACE // namespace Diligent
508diff --git a/DiligentTools/AssetLoader/src/GLTFLoader.cpp b/DiligentTools/AssetLoader/src/GLTFLoader.cpp
509index b000caa..1c546f7 100644
510--- a/DiligentTools/AssetLoader/src/GLTFLoader.cpp
511+++ b/DiligentTools/AssetLoader/src/GLTFLoader.cpp
512@@ -246,9 +246,9 @@ void Node::UpdateTransforms()
513 
514 
515 
516-Model::Model(IRenderDevice*    pDevice,
517-             IDeviceContext*   pContext,
518-             const CreateInfo& CI)
519+Model::Model(IRenderDevice*              pDevice,
520+             IDeviceContext*             pContext,
521+             const IGLTFModelCreateInfo& CI)
522 {
523     LoadFromFile(pDevice, pContext, CI);
524 }
525@@ -710,7 +710,7 @@ static float GetTextureAlphaCutoffValue(const tinygltf::Model& gltf_model, int T
526 void Model::LoadTextures(IRenderDevice*         pDevice,
527                          const tinygltf::Model& gltf_model,
528                          const std::string&     BaseDir,
529-                         TextureCacheType*      pTextureCache,
530+                         GLTF_TextureCacheType* pTextureCache,
531                          ResourceManager*       pResourceMgr)
532 {
533     for (const tinygltf::Texture& gltf_tex : gltf_model.textures)
534@@ -1021,7 +1021,7 @@ void Model::PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx)
535         }
536     }
537 
538-    auto UpdateBuffer = [&](BUFFER_ID BuffId) //
539+    auto UpdateBuffer = [&](GLTF_BUFFER_ID BuffId) //
540     {
541         auto&    BuffInfo = Buffers[BuffId];
542         IBuffer* pBuffer  = nullptr;
543@@ -1052,14 +1052,14 @@ void Model::PrepareGPUResources(IRenderDevice* pDevice, IDeviceContext* pCtx)
544             if (Buffers[BuffId].pBuffer != nullptr)
545             {
546                 VERIFY_EXPR(Buffers[BuffId].pBuffer == pBuffer);
547-                Barriers.emplace_back(StateTransitionDesc{pBuffer, RESOURCE_STATE_UNKNOWN, BuffId == BUFFER_ID_INDEX ? RESOURCE_STATE_INDEX_BUFFER : RESOURCE_STATE_VERTEX_BUFFER, true});
548+                Barriers.emplace_back(StateTransitionDesc{pBuffer, RESOURCE_STATE_UNKNOWN, BuffId == GLTF_BUFFER_ID_INDEX ? RESOURCE_STATE_INDEX_BUFFER : RESOURCE_STATE_VERTEX_BUFFER, true});
549             }
550         }
551     };
552 
553-    UpdateBuffer(BUFFER_ID_VERTEX_BASIC_ATTRIBS);
554-    UpdateBuffer(BUFFER_ID_VERTEX_SKIN_ATTRIBS);
555-    UpdateBuffer(BUFFER_ID_INDEX);
556+    UpdateBuffer(GLTF_BUFFER_ID_VERTEX_BASIC_ATTRIBS);
557+    UpdateBuffer(GLTF_BUFFER_ID_VERTEX_SKIN_ATTRIBS);
558+    UpdateBuffer(GLTF_BUFFER_ID_INDEX);
559 
560     if (!Barriers.empty())
561         pCtx->TransitionResourceStates(static_cast<Uint32>(Barriers.size()), Barriers.data());
562@@ -1195,11 +1195,11 @@ void Model::LoadMaterials(const tinygltf::Model& gltf_model)
563                 const tinygltf::Parameter& param = alpha_mode_it->second;
564                 if (param.string_value == "BLEND")
565                 {
566-                    Mat.Attribs.AlphaMode = Material::ALPHA_MODE_BLEND;
567+                    Mat.Attribs.AlphaMode = GLTF_MAT_ALPHA_MODE_BLEND;
568                 }
569                 if (param.string_value == "MASK")
570                 {
571-                    Mat.Attribs.AlphaMode   = Material::ALPHA_MODE_MASK;
572+                    Mat.Attribs.AlphaMode   = GLTF_MAT_ALPHA_MODE_MASK;
573                     Mat.Attribs.AlphaCutoff = 0.5f;
574                 }
575             }
576@@ -1434,8 +1434,8 @@ namespace
577 
578 struct ImageLoaderData
579 {
580-    Model::TextureCacheType* const pTextureCache;
581-    ResourceManager* const         pResourceMgr;
582+    GLTF_TextureCacheType* const pTextureCache;
583+    ResourceManager* const       pResourceMgr;
584 
585     std::vector<RefCntAutoPtr<IObject>> TexturesHold;
586 
587@@ -1699,9 +1699,9 @@ bool ReadWholeFile(std::vector<unsigned char>* out,
588 
589 } // namespace Callbacks
590 
591-void Model::LoadFromFile(IRenderDevice*    pDevice,
592-                         IDeviceContext*   pContext,
593-                         const CreateInfo& CI)
594+void Model::LoadFromFile(IRenderDevice*              pDevice,
595+                         IDeviceContext*             pContext,
596+                         const IGLTFModelCreateInfo& CI)
597 {
598     if (CI.FileName == nullptr || *CI.FileName == 0)
599         LOG_ERROR_AND_THROW("File path must not be empty");
600@@ -1799,7 +1799,7 @@ void Model::LoadFromFile(IRenderDevice*    pDevice,
601 
602     Extensions = gltf_model.extensionsUsed;
603 
604-    auto CreateBuffer = [&](BUFFER_ID BuffId, const void* pData, size_t Size, BIND_FLAGS BindFlags, const char* Name) //
605+    auto CreateBuffer = [&](GLTF_BUFFER_ID BuffId, const void* pData, size_t Size, BIND_FLAGS BindFlags, const char* Name) //
606     {
607         VERIFY_EXPR(Size > 0);
608 
609@@ -1809,13 +1809,13 @@ void Model::LoadFromFile(IRenderDevice*    pDevice,
610             Uint32 CacheBufferIndex = 0;
611             switch (BuffId)
612             {
613-                case BUFFER_ID_INDEX:
614+                case GLTF_BUFFER_ID_INDEX:
615                     CacheBufferIndex = CI.pCacheInfo->IndexBufferIdx;
616                     break;
617-                case BUFFER_ID_VERTEX_BASIC_ATTRIBS:
618+                case GLTF_BUFFER_ID_VERTEX_BASIC_ATTRIBS:
619                     CacheBufferIndex = CI.pCacheInfo->VertexBuffer0Idx;
620                     break;
621-                case BUFFER_ID_VERTEX_SKIN_ATTRIBS:
622+                case GLTF_BUFFER_ID_VERTEX_SKIN_ATTRIBS:
623                     CacheBufferIndex = CI.pCacheInfo->VertexBuffer1Idx;
624                     break;
625                 default:
626@@ -1840,18 +1840,18 @@ void Model::LoadFromFile(IRenderDevice*    pDevice,
627         }
628     };
629 
630-    CreateBuffer(BUFFER_ID_VERTEX_BASIC_ATTRIBS, VertexBasicData.data(), VertexBasicData.size() * sizeof(VertexBasicData[0]),
631+    CreateBuffer(GLTF_BUFFER_ID_VERTEX_BASIC_ATTRIBS, VertexBasicData.data(), VertexBasicData.size() * sizeof(VertexBasicData[0]),
632                  BIND_VERTEX_BUFFER, "GLTF vertex attribs 0 buffer");
633 
634     if (!VertexSkinData.empty())
635     {
636-        CreateBuffer(BUFFER_ID_VERTEX_SKIN_ATTRIBS, VertexSkinData.data(), VertexSkinData.size() * sizeof(VertexSkinData[0]),
637+        CreateBuffer(GLTF_BUFFER_ID_VERTEX_SKIN_ATTRIBS, VertexSkinData.data(), VertexSkinData.size() * sizeof(VertexSkinData[0]),
638                      BIND_VERTEX_BUFFER, "GLTF vertex attribs 1 buffer");
639     }
640 
641     if (!IndexData.empty())
642     {
643-        CreateBuffer(BUFFER_ID_INDEX, IndexData.data(), IndexData.size() * sizeof(IndexData[0]),
644+        CreateBuffer(GLTF_BUFFER_ID_INDEX, IndexData.data(), IndexData.size() * sizeof(IndexData[0]),
645                      BIND_INDEX_BUFFER, "GLTF index buffer");
646     }
647 
648@@ -1989,8 +1989,9 @@ void Model::UpdateAnimation(Uint32 index, float time)
649     }
650 }
651 
652-void Model::Transform(const float4x4& Matrix)
653+void Model::Transform(const float* _Matrix)
654 {
655+    auto Matrix = float4x4::MakeMatrix(_Matrix);
656     for (auto& root_node : Nodes)
657     {
658         root_node->Matrix *= Matrix;
659@@ -2033,7 +2034,33 @@ Node* Model::NodeFromIndex(uint32_t index)
660     return nodeFound;
661 }
662 
663+API_QUALIFIER
664+IGLTFModel* IGLTFModel_Create(IRenderDevice*              pDevice,
665+                              IDeviceContext*             pCtx,
666+                              const IGLTFModelCreateInfo* CI) {
667+    return new Model(pDevice, pCtx, *CI);
668+}
669+
670+API_QUALIFIER
671+void IGLTFModel_Destroy(IGLTFModel* model) {
672+    delete model;
673+}
674 
675 } // namespace GLTF
676 
677 } // namespace Diligent
678+
679+extern "C"
680+{
681+    API_QUALIFIER
682+    Diligent::GLTF::IGLTFModel* Diligent_IGLTFModel_Create(Diligent::IRenderDevice*                    pDevice,
683+                                                           Diligent::IDeviceContext*                   pCtx,
684+                                                           const Diligent::GLTF::IGLTFModelCreateInfo* CI) {
685+        return Diligent::GLTF::IGLTFModel_Create(pDevice, pCtx, CI);
686+    }
687+
688+    API_QUALIFIER
689+    void Diligent_IGLTFModel_Destroy(Diligent::GLTF::IGLTFModel* model) {
690+        Diligent::GLTF::IGLTFModel_Destroy(model);
691+    }
692+}
693-- 
6942.31.0
695
696From 9c62b6faaeb4236440258200f7235e1224a774ff Mon Sep 17 00:00:00 2001
697From: s-ol <s+removethis@s-ol.nu>
698Date: Sat, 27 Mar 2021 10:12:58 +0100
699Subject: [PATCH 3/3] C API for GLTF_PBR_Renderer
700
701---
702 DiligentFX/GLTF_PBR_Renderer/CMakeLists.txt              |  12 +-
703 .../include/GLTF_PBR_Renderer.hpp                        | 266 ++++++++++++
704 .../interface/GLTF_PBR_Renderer.h                        | 328 +++++++++++++++
705 .../interface/GLTF_PBR_Renderer.hpp                      | 379 ------------------
706 DiligentFX/GLTF_PBR_Renderer/src/GLTF_PBR_Renderer.cpp   |  96 +++--
707 5 files changed, 664 insertions(+), 417 deletions(-)
708 create mode 100644 DiligentFX/GLTF_PBR_Renderer/include/GLTF_PBR_Renderer.hpp
709 create mode 100644 DiligentFX/GLTF_PBR_Renderer/interface/GLTF_PBR_Renderer.h
710 delete mode 100644 DiligentFX/GLTF_PBR_Renderer/interface/GLTF_PBR_Renderer.hpp
711
712diff --git a/DiligentFX/GLTF_PBR_Renderer/CMakeLists.txt b/DiligentFX/GLTF_PBR_Renderer/CMakeLists.txt
713index c5b4d1e..77c1118 100644
714--- a/DiligentFX/GLTF_PBR_Renderer/CMakeLists.txt
715+++ b/DiligentFX/GLTF_PBR_Renderer/CMakeLists.txt
716@@ -2,15 +2,21 @@ cmake_minimum_required (VERSION 3.6)
717 
718 set(SOURCE
719     "${CMAKE_CURRENT_SOURCE_DIR}/src/GLTF_PBR_Renderer.cpp"
720+)  
721+
722+set(INTERFACE
723+    "${CMAKE_CURRENT_SOURCE_DIR}/interface/GLTF_PBR_Renderer.h"
724 )
725 
726 set(INCLUDE
727-    "${CMAKE_CURRENT_SOURCE_DIR}/interface/GLTF_PBR_Renderer.hpp"
728+    "${CMAKE_CURRENT_SOURCE_DIR}/include/GLTF_PBR_Renderer.hpp"
729 )
730 
731-target_sources(DiligentFX PRIVATE ${SOURCE} ${INCLUDE})
732+target_sources(DiligentFX PRIVATE ${SOURCE} ${INCLUDE} ${INTERFACE})
733 
734 target_include_directories(DiligentFX
735 PUBLIC
736-    "${CMAKE_CURRENT_SOURCE_DIR}/interface"
737+    interface
738+PRIVATE
739+    include
740 )
741diff --git a/DiligentFX/GLTF_PBR_Renderer/include/GLTF_PBR_Renderer.hpp b/DiligentFX/GLTF_PBR_Renderer/include/GLTF_PBR_Renderer.hpp
742new file mode 100644
743index 0000000..bb764d3
744--- /dev/null
745+++ b/DiligentFX/GLTF_PBR_Renderer/include/GLTF_PBR_Renderer.hpp
746@@ -0,0 +1,266 @@
747+/*
748+ *  Copyright 2019-2021 Diligent Graphics LLC
749+ *  Copyright 2015-2019 Egor Yusov
750+ *  
751+ *  Licensed under the Apache License, Version 2.0 (the "License");
752+ *  you may not use this file except in compliance with the License.
753+ *  You may obtain a copy of the License at
754+ *  
755+ *      http://www.apache.org/licenses/LICENSE-2.0
756+ *  
757+ *  Unless required by applicable law or agreed to in writing, software
758+ *  distributed under the License is distributed on an "AS IS" BASIS,
759+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
760+ *  See the License for the specific language governing permissions and
761+ *  limitations under the License.
762+ *
763+ *  In no event and under no legal theory, whether in tort (including negligence), 
764+ *  contract, or otherwise, unless required by applicable law (such as deliberate 
765+ *  and grossly negligent acts) or agreed to in writing, shall any Contributor be
766+ *  liable for any damages, including any direct, indirect, special, incidental, 
767+ *  or consequential damages of any character arising as a result of this License or 
768+ *  out of the use or inability to use the software (including but not limited to damages 
769+ *  for loss of goodwill, work stoppage, computer failure or malfunction, or any and 
770+ *  all other commercial damages or losses), even if such Contributor has been advised 
771+ *  of the possibility of such damages.
772+ */
773+
774+#pragma once
775+
776+#include <unordered_map>
777+#include <functional>
778+#include <mutex>
779+#include <vector>
780+
781+#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
782+#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
783+#include "../../../DiligentCore/Common/interface/HashUtils.hpp"
784+#include "../../../DiligentTools/AssetLoader/include/GLTFLoader.hpp"
785+#include "../interface/GLTF_PBR_Renderer.h"
786+
787+namespace Diligent
788+{
789+
790+/// GLTF Model shader resource binding information
791+struct GLTF_ModelResourceBindings
792+{
793+    void Clear()
794+    {
795+        MaterialSRB.clear();
796+    }
797+
798+    GLTF_ModelResourceBindings() : MaterialSRB{} {}
799+    GLTF_ModelResourceBindings(const GLTF_ModelResourceBindings& o) : MaterialSRB{o.MaterialSRB} {};
800+    ~GLTF_ModelResourceBindings() { MaterialSRB.~vector(); }
801+
802+    union {
803+      /// Shader resource binding for every material
804+      std::vector<RefCntAutoPtr<IShaderResourceBinding>> MaterialSRB;
805+
806+      Uint32 _spacer[8];
807+    };
808+};
809+
810+/// GLTF resource cache shader resource binding information
811+struct GLTF_ResourceCacheBindings
812+{
813+    /// Resource version
814+    Uint32 Version = 0;
815+
816+    RefCntAutoPtr<IShaderResourceBinding> pSRB;
817+};
818+
819+#include "Shaders/GLTF_PBR/public/GLTF_PBR_Structures.fxh"
820+
821+/// Implementation of a GLTF PBR renderer
822+class GLTF_PBR_Renderer : public IGLTF_PBR_Renderer
823+{
824+public:
825+
826+    /// Initializes the renderer
827+    GLTF_PBR_Renderer(IRenderDevice*                 pDevice,
828+                      IDeviceContext*                pCtx,
829+                      const GLTF_RendererCreateInfo& CI);
830+
831+    /// Rendering information
832+
833+
834+    /// Renders a GLTF model.
835+
836+    /// \param [in] pCtx           - Device context to record rendering commands to.
837+    /// \param [in] GLTFModel      - GLTF model to render.
838+    /// \param [in] RenderParams   - Render parameters.
839+    /// \param [in] pModelBindings - The model's shader resource binding information.
840+    /// \param [in] pCacheBindings - Shader resource cache binding information, if the
841+    ///                              model has been created using the cache.
842+    virtual void Render(IDeviceContext*             pCtx,
843+                        IGLTFModel*                 GLTFModel,
844+                        const GLTF_RenderInfo&      RenderParams,
845+                        GLTF_ModelResourceBindings* pModelBindings,
846+                        GLTF_ResourceCacheBindings* pCacheBindings = nullptr) override final;
847+
848+    /// Creates resource bindings for a given GLTF model
849+    virtual GLTF_ModelResourceBindings CreateResourceBindings(IGLTFModel*  GLTFModel,
850+                                                              IBuffer*     pCameraAttribs,
851+                                                              IBuffer*     pLightAttribs) override final;
852+
853+    /// Precompute cubemaps used by IBL.
854+    virtual void PrecomputeCubemaps(IRenderDevice*  pDevice,
855+                                    IDeviceContext* pCtx,
856+                                    ITextureView*   pEnvironmentMap) override final;
857+
858+    // clang-format off
859+    virtual ITextureView* GetIrradianceCubeSRV()    override final { return m_pIrradianceCubeSRV; }
860+    virtual ITextureView* GetPrefilteredEnvMapSRV() override final { return m_pPrefilteredEnvMapSRV; }
861+    virtual ITextureView* GetWhiteTexSRV()          override final { return m_pWhiteTexSRV; }
862+    virtual ITextureView* GetBlackTexSRV()          override final { return m_pBlackTexSRV; }
863+    virtual ITextureView* GetDefaultNormalMapSRV()  override final { return m_pDefaultNormalMapSRV; }
864+    // clang-format on
865+
866+    /// Creates a shader resource binding for the given material.
867+
868+    /// \param [in] Model          - GLTF model that keeps material textures.
869+    /// \param [in] Material       - GLTF material to create SRB for.
870+    /// \param [in] pCameraAttribs - Camera attributes constant buffer to set in the SRB.
871+    /// \param [in] pLightAttribs  - Light attributes constant buffer to set in the SRB.
872+    /// \param [in] pPSO           - Optional PSO object to use to create the SRB instead of the
873+    ///                              default PSO. Can be null
874+    /// \param [out] ppMaterialSRB - Pointer to memory location where the pointer to the SRB object
875+    ///                              will be written.
876+    virtual void CreateMaterialSRB(IGLTFModel*              Model,
877+                                   GLTF::Material&          Material,
878+                                   IBuffer*                 pCameraAttribs,
879+                                   IBuffer*                 pLightAttribs,
880+                                   IPipelineState*          pPSO,
881+                                   IShaderResourceBinding** ppMaterialSRB); // override final;
882+
883+
884+    /// Creates a shader resource binding for a GTLF resource cache.
885+
886+    /// \param [in] pDevice        - Render device that may be needed by the resource cache to create
887+    ///                              internal objects.
888+    /// \param [in] pCtx           - Device context that may be needed by the resource cache to initialize
889+    ///                              internal objects.
890+    /// \param [in] CacheUseInfo   - GLTF resource cache usage information.
891+    /// \param [in] pCameraAttribs - Camera attributes constant buffer to set in the SRB.
892+    /// \param [in] pLightAttribs  - Light attributes constant buffer to set in the SRB.
893+    /// \param [in] pPSO           - Optional PSO object to use to create the SRB instead of the
894+    ///                              default PSO. Can be null
895+    /// \param [out] ppCacheSRB    - Pointer to memory location where the pointer to the SRB object
896+    ///                              will be written.
897+    virtual void CreateResourceCacheSRB(IRenderDevice*              pDevice,
898+                                        IDeviceContext*             pCtx,
899+                                        GLTF_ResourceCacheUseInfo&  CacheUseInfo,
900+                                        IBuffer*                    pCameraAttribs,
901+                                        IBuffer*                    pLightAttribs,
902+                                        IPipelineState*             pPSO,
903+                                        IShaderResourceBinding**    ppCacheSRB) override final;
904+
905+    /// Prepares the renderer for rendering objects.
906+    /// This method must be called at least once per frame.
907+    virtual void Begin(IDeviceContext* pCtx) override final;
908+
909+
910+    /// Prepares the renderer for rendering objects from the resource cache.
911+    /// This method must be called at least once per frame before the first object
912+    /// from the cache is rendered.
913+    virtual void BeginPSO(IRenderDevice*              pDevice,
914+                          IDeviceContext*             pCtx,
915+                          GLTF_ResourceCacheUseInfo&  CacheUseInfo,
916+                          GLTF_ResourceCacheBindings& Bindings,
917+                          IBuffer*                    pCameraAttribs,
918+                          IBuffer*                    pLightAttribs,
919+                          IPipelineState*             pPSO = nullptr) override final;
920+
921+private:
922+    void PrecomputeBRDF(IRenderDevice*  pDevice,
923+                        IDeviceContext* pCtx);
924+
925+    void CreatePSO(IRenderDevice* pDevice);
926+
927+    void InitCommonSRBVars(IShaderResourceBinding* pSRB,
928+                           IBuffer*                pCameraAttribs,
929+                           IBuffer*                pLightAttribs);
930+
931+    struct PSOKey
932+    {
933+        PSOKey() noexcept {};
934+        PSOKey(GLTF_MAT_ALPHA_MODE _AlphaMode, bool _DoubleSided) :
935+                 AlphaMode{_AlphaMode},
936+                 DoubleSided{_DoubleSided}
937+        {}
938+
939+        bool operator==(const PSOKey& rhs) const
940+        {
941+            return AlphaMode == rhs.AlphaMode && DoubleSided == rhs.DoubleSided;
942+        }
943+        bool operator!=(const PSOKey& rhs) const
944+        {
945+            return AlphaMode != rhs.AlphaMode || DoubleSided != rhs.DoubleSided;
946+        }
947+
948+        GLTF_MAT_ALPHA_MODE AlphaMode = GLTF_MAT_ALPHA_MODE_OPAQUE;
949+        bool DoubleSided = false;
950+    };
951+
952+    static size_t GetPSOIdx(const PSOKey& Key)
953+    {
954+        size_t PSOIdx;
955+
956+        PSOIdx = Key.AlphaMode == GLTF_MAT_ALPHA_MODE_BLEND ? 1 : 0;
957+             PSOIdx = PSOIdx * 2 + (Key.DoubleSided ? 1 : 0);
958+             return PSOIdx;
959+    }
960+
961+    void AddPSO(const PSOKey& Key, RefCntAutoPtr<IPipelineState> pPSO)
962+    {
963+        auto Idx = GetPSOIdx(Key);
964+        if (Idx >= m_PSOCache.size())
965+            m_PSOCache.resize(Idx + 1);
966+        VERIFY_EXPR(!m_PSOCache[Idx]);
967+        m_PSOCache[Idx] = std::move(pPSO);
968+    }
969+
970+    IPipelineState* GetPSO(const PSOKey& Key)
971+    {
972+        auto Idx = GetPSOIdx(Key);
973+        VERIFY_EXPR(Idx < m_PSOCache.size());
974+        return Idx < m_PSOCache.size() ? m_PSOCache[Idx].RawPtr() : nullptr;
975+    }
976+
977+    const GLTF_RendererCreateInfo m_Settings;
978+
979+    static constexpr Uint32     BRDF_LUT_Dim = 512;
980+    RefCntAutoPtr<ITextureView> m_pBRDF_LUT_SRV;
981+
982+    std::vector<RefCntAutoPtr<IPipelineState>> m_PSOCache;
983+
984+    RefCntAutoPtr<ITextureView> m_pWhiteTexSRV;
985+    RefCntAutoPtr<ITextureView> m_pBlackTexSRV;
986+    RefCntAutoPtr<ITextureView> m_pDefaultNormalMapSRV;
987+    RefCntAutoPtr<ITextureView> m_pDefaultPhysDescSRV;
988+
989+
990+    static constexpr TEXTURE_FORMAT IrradianceCubeFmt    = TEX_FORMAT_RGBA32_FLOAT;
991+    static constexpr TEXTURE_FORMAT PrefilteredEnvMapFmt = TEX_FORMAT_RGBA16_FLOAT;
992+    static constexpr Uint32         IrradianceCubeDim    = 64;
993+    static constexpr Uint32         PrefilteredEnvMapDim = 256;
994+
995+    RefCntAutoPtr<ITextureView>           m_pIrradianceCubeSRV;
996+    RefCntAutoPtr<ITextureView>           m_pPrefilteredEnvMapSRV;
997+    RefCntAutoPtr<IPipelineState>         m_pPrecomputeIrradianceCubePSO;
998+    RefCntAutoPtr<IPipelineState>         m_pPrefilterEnvMapPSO;
999+    RefCntAutoPtr<IShaderResourceBinding> m_pPrecomputeIrradianceCubeSRB;
1000+    RefCntAutoPtr<IShaderResourceBinding> m_pPrefilterEnvMapSRB;
1001+
1002+    GLTF_RenderInfo m_RenderParams;
1003+
1004+    RefCntAutoPtr<IBuffer> m_TransformsCB;
1005+    RefCntAutoPtr<IBuffer> m_GLTFAttribsCB;
1006+    RefCntAutoPtr<IBuffer> m_PrecomputeEnvMapAttribsCB;
1007+    RefCntAutoPtr<IBuffer> m_JointsBuffer;
1008+};
1009+
1010+DEFINE_FLAG_ENUM_OPERATORS(ALPHA_MODE_FLAGS)
1011+
1012+} // namespace Diligent
1013diff --git a/DiligentFX/GLTF_PBR_Renderer/interface/GLTF_PBR_Renderer.h b/DiligentFX/GLTF_PBR_Renderer/interface/GLTF_PBR_Renderer.h
1014new file mode 100644
1015index 0000000..4db08c6
1016--- /dev/null
1017+++ b/DiligentFX/GLTF_PBR_Renderer/interface/GLTF_PBR_Renderer.h
1018@@ -0,0 +1,328 @@
1019+/*
1020+ *  Copyright 2019-2021 Diligent Graphics LLC
1021+ *  Copyright 2015-2019 Egor Yusov
1022+ *  
1023+ *  Licensed under the Apache License, Version 2.0 (the "License");
1024+ *  you may not use this file except in compliance with the License.
1025+ *  You may obtain a copy of the License at
1026+ *  
1027+ *      http://www.apache.org/licenses/LICENSE-2.0
1028+ *  
1029+ *  Unless required by applicable law or agreed to in writing, software
1030+ *  distributed under the License is distributed on an "AS IS" BASIS,
1031+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1032+ *  See the License for the specific language governing permissions and
1033+ *  limitations under the License.
1034+ *
1035+ *  In no event and under no legal theory, whether in tort (including negligence), 
1036+ *  contract, or otherwise, unless required by applicable law (such as deliberate 
1037+ *  and grossly negligent acts) or agreed to in writing, shall any Contributor be
1038+ *  liable for any damages, including any direct, indirect, special, incidental, 
1039+ *  or consequential damages of any character arising as a result of this License or 
1040+ *  out of the use or inability to use the software (including but not limited to damages 
1041+ *  for loss of goodwill, work stoppage, computer failure or malfunction, or any and 
1042+ *  all other commercial damages or losses), even if such Contributor has been advised 
1043+ *  of the possibility of such damages.
1044+ */
1045+
1046+#pragma once
1047+
1048+#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
1049+#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
1050+#include "../../../DiligentTools/AssetLoader/interface/GLTFLoader.h"
1051+
1052+DILIGENT_BEGIN_NAMESPACE(Diligent)
1053+
1054+#if DILIGENT_CPP_INTERFACE
1055+	using namespace Diligent::GLTF;
1056+#endif
1057+
1058+/// Renderer create info
1059+struct GLTF_RendererCreateInfo
1060+{
1061+    /// Render target format.
1062+    TEXTURE_FORMAT RTVFmt DEFAULT_INITIALIZER(TEX_FORMAT_UNKNOWN);
1063+
1064+    /// Depth-buffer format.
1065+
1066+    /// \note   If both RTV and DSV formats are TEX_FORMAT_UNKNOWN,
1067+    ///         the renderer will not initialize PSO, uniform buffers and other
1068+    ///         resources. It is expected that an application will use custom
1069+    ///         render callback function.
1070+    TEXTURE_FORMAT DSVFmt DEFAULT_INITIALIZER(TEX_FORMAT_UNKNOWN);
1071+
1072+    /// Indicates if front face is CCW.
1073+    bool FrontCCW DEFAULT_INITIALIZER(false);
1074+
1075+    /// Indicates if the renderer should allow debug views.
1076+    /// Rendering with debug views disabled is more efficient.
1077+    bool AllowDebugView DEFAULT_INITIALIZER(false);
1078+
1079+    /// Indicates whether to use IBL.
1080+    bool UseIBL DEFAULT_INITIALIZER(false);
1081+
1082+    /// Whether to use ambient occlusion texture.
1083+    bool UseAO DEFAULT_INITIALIZER(true);
1084+
1085+    /// Whether to use emissive texture.
1086+    bool UseEmissive DEFAULT_INITIALIZER(true);
1087+
1088+    /// When set to true, pipeline state will be compiled with immutable samplers.
1089+    /// When set to false, samplers from the texture views will be used.
1090+    bool UseImmutableSamplers DEFAULT_INITIALIZER(true);
1091+
1092+    /// Whether to use texture atlas (e.g. apply UV transforms when sampling textures).
1093+    bool UseTextureAtals DEFAULT_INITIALIZER(false);
1094+
1095+#if DILIGENT_CPP_INTERFACE
1096+    static const SamplerDesc DefaultSampler;
1097+#endif
1098+
1099+    /// Immutable sampler for color map texture.
1100+    SamplerDesc ColorMapImmutableSampler DEFAULT_INITIALIZER(DefaultSampler);
1101+
1102+    /// Immutable sampler for physical description map texture.
1103+    SamplerDesc PhysDescMapImmutableSampler DEFAULT_INITIALIZER(DefaultSampler);
1104+
1105+    /// Immutable sampler for normal map texture.
1106+    SamplerDesc NormalMapImmutableSampler DEFAULT_INITIALIZER(DefaultSampler);
1107+
1108+    /// Immutable sampler for AO texture.
1109+    SamplerDesc AOMapImmutableSampler DEFAULT_INITIALIZER(DefaultSampler);
1110+
1111+    /// Immutable sampler for emissive map texture.
1112+    SamplerDesc EmissiveMapImmutableSampler DEFAULT_INITIALIZER(DefaultSampler);
1113+
1114+    /// Maximum number of joints
1115+    Uint32 MaxJointCount DEFAULT_INITIALIZER(64);
1116+
1117+		// Geometry Shader
1118+    IShader* pGS DEFAULT_INITIALIZER(nullptr);
1119+};
1120+typedef struct GLTF_RendererCreateInfo GLTF_RendererCreateInfo;
1121+
1122+/// Alpha mode flags
1123+DILIGENT_TYPED_ENUM(ALPHA_MODE_FLAGS, Uint32)
1124+{
1125+    /// Render nothing
1126+    ALPHA_MODE_FLAG_NONE = 0,
1127+
1128+    /// Render opaque matetrials
1129+    ALPHA_MODE_FLAG_OPAQUE = 1 << GLTF_MAT_ALPHA_MODE_OPAQUE,
1130+
1131+    /// Render alpha-masked matetrials
1132+    ALPHA_MODE_FLAG_MASK = 1 << GLTF_MAT_ALPHA_MODE_MASK,
1133+
1134+    /// Render alpha-blended matetrials
1135+    ALPHA_MODE_FLAG_BLEND = 1 << GLTF_MAT_ALPHA_MODE_BLEND,
1136+
1137+    /// Render all materials
1138+    ALPHA_MODE_FLAG_ALL = ALPHA_MODE_FLAG_OPAQUE | ALPHA_MODE_FLAG_MASK | ALPHA_MODE_FLAG_BLEND
1139+};
1140+
1141+/// Debug view type
1142+DILIGENT_TYPED_ENUM(DEBUG_VIEW_TYPE, int)
1143+{
1144+    DEBUG_VIEW_TYPE_NONE             = 0,
1145+    DEBUG_VIEW_TYPE_BASE_COLOR       = 1,
1146+    DEBUG_VIEW_TYPE_TRANSPARENCY     = 2,
1147+    DEBUG_VIEW_TYPE_NORMAL_MAP       = 3,
1148+    DEBUG_VIEW_TYPE_OCCLUSION        = 4,
1149+    DEBUG_VIEW_TYPE_EMISSIVE         = 5,
1150+    DEBUG_VIEW_TYPE_METALLIC         = 6,
1151+    DEBUG_VIEW_TYPE_ROUGHNESS        = 7,
1152+    DEBUG_VIEW_TYPE_DIFFUSE_COLOR    = 8,
1153+    DEBUG_VIEW_TYPE_SPECULAR_COLOR   = 9,
1154+    DEBUG_VIEW_TYPE_REFLECTANCE_90   = 10,
1155+    DEBUG_VIEW_TYPE_MESH_NORMAL      = 11,
1156+    DEBUG_VIEW_TYPE_PERTURBED_NORMAL = 12,
1157+    DEBUG_VIEW_TYPE_N_DOT_V          = 13,
1158+    DEBUG_VIEW_TYPE_DIFFUSE_IBL      = 14,
1159+    DEBUG_VIEW_TYPE_SPECULAR_IBL     = 15,
1160+    DEBUG_VIEW_TYPE_NUM,
1161+};
1162+
1163+/// Rendering information
1164+struct GLTF_RenderInfo
1165+{
1166+    /// Model transform matrix
1167+    float ModelTransform[16]
1168+#if DILIGENT_CPP_INTERFACE
1169+    		= { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }
1170+#endif
1171+    		;
1172+
1173+    /// Flag indicating which alpha modes to render
1174+    ALPHA_MODE_FLAGS AlphaModes DEFAULT_INITIALIZER(ALPHA_MODE_FLAG_ALL);
1175+
1176+    DEBUG_VIEW_TYPE DebugView DEFAULT_INITIALIZER(DEBUG_VIEW_TYPE_NONE);
1177+
1178+    /// Ambient occlusion strength
1179+    float OcclusionStrength DEFAULT_INITIALIZER(1);
1180+
1181+    /// Emission scale
1182+    float EmissionScale DEFAULT_INITIALIZER(1);
1183+
1184+    /// IBL scale
1185+    float IBLScale DEFAULT_INITIALIZER(1);
1186+
1187+    /// Average log luminance used by tone mapping
1188+    float AverageLogLum DEFAULT_INITIALIZER(0.3f);
1189+
1190+    /// Middle gray value used by tone mapping
1191+    float MiddleGray DEFAULT_INITIALIZER(0.18f);
1192+
1193+    /// White point value used by tone mapping
1194+    float WhitePoint DEFAULT_INITIALIZER(3.f);
1195+};
1196+typedef struct GLTF_RenderInfo GLTF_RenderInfo;
1197+
1198+struct GLTF_ModelResourceBindings;
1199+typedef struct GLTF_ModelResourceBindings GLTF_ModelResourceBindings;
1200+
1201+#if DILIGENT_C_INTERFACE
1202+struct GLTF_ModelResourceBindings {
1203+  	Uint32 _spacer[8];
1204+};
1205+#endif
1206+
1207+struct GLTF_ResourceCacheBindings;
1208+typedef struct GLTF_ResourceCacheBindings GLTF_ResourceCacheBindings;
1209+
1210+#define DILIGENT_INTERFACE_NAME IGLTF_PBR_Renderer
1211+#include "../../../Primitives/interface/DefineInterfaceHelperMacros.h"
1212+
1213+#define IGLTF_PBR_RendererInclusiveMethods \
1214+    IGLTF_PBR_RendererMethods GLTF_PBR_Renderer
1215+
1216+// clang-format off
1217+
1218+/// Implementation of a GLTF PBR renderer
1219+DILIGENT_BEGIN_INTERFACE1(IGLTF_PBR_Renderer)
1220+{
1221+    /// Renders a GLTF model.
1222+
1223+    /// \param [in] pCtx           - Device context to record rendering commands to.
1224+    /// \param [in] GLTFModel      - GLTF model to render.
1225+    /// \param [in] RenderParams   - Render parameters.
1226+    /// \param [in] pModelBindings - The model's shader resource binding information.
1227+    /// \param [in] pCacheBindings - Shader resource cache binding information, if the
1228+    ///                              model has been created using the cache.
1229+    VIRTUAL void METHOD(Render)(THIS_
1230+                                IDeviceContext*             pCtx,
1231+                                IGLTFModel*                 GLTFModel,
1232+                                const GLTF_RenderInfo REF   RenderParams,
1233+                                GLTF_ModelResourceBindings* pModelBindings,
1234+                                GLTF_ResourceCacheBindings* pCacheBindings) PURE;
1235+
1236+    /// Creates resource bindings for a given GLTF model
1237+    VIRTUAL GLTF_ModelResourceBindings METHOD(CreateResourceBindings)(THIS_
1238+                                                                      IGLTFModel*    GLTFModel,
1239+                                                                      IBuffer*       pCameraAttribs,
1240+                                                                      IBuffer*       pLightAttribs) PURE;
1241+
1242+    /// Precompute cubemaps used by IBL.
1243+    VIRTUAL void METHOD(PrecomputeCubemaps)(THIS_
1244+                                            IRenderDevice*  pDevice,
1245+                                            IDeviceContext* pCtx,
1246+                                            ITextureView*   pEnvironmentMap) PURE;
1247+
1248+    // clang-format off
1249+    VIRTUAL ITextureView* METHOD(GetIrradianceCubeSRV)(THIS)    PURE;
1250+    VIRTUAL ITextureView* METHOD(GetPrefilteredEnvMapSRV)(THIS) PURE;
1251+    VIRTUAL ITextureView* METHOD(GetWhiteTexSRV)(THIS)          PURE;
1252+    VIRTUAL ITextureView* METHOD(GetBlackTexSRV)(THIS)          PURE;
1253+    VIRTUAL ITextureView* METHOD(GetDefaultNormalMapSRV)(THIS)  PURE;
1254+    // clang-format on
1255+
1256+		/*
1257+    /// Creates a shader resource binding for the given material.
1258+
1259+    /// \param [in] Model          - GLTF model that keeps material textures.
1260+    /// \param [in] Material       - GLTF material to create SRB for.
1261+    /// \param [in] pCameraAttribs - Camera attributes constant buffer to set in the SRB.
1262+    /// \param [in] pLightAttribs  - Light attributes constant buffer to set in the SRB.
1263+    /// \param [in] pPSO           - Optional PSO object to use to create the SRB instead of the
1264+    ///                              default PSO. Can be null
1265+    /// \param [out] ppMaterialSRB - Pointer to memory location where the pointer to the SRB object
1266+    ///                              will be written.
1267+    VIRTUAL void METHOD(CreateMaterialSRB)(THIS_
1268+                                           IGLTFModel*              Model,
1269+                                           GLTF_Material REF        Material,
1270+                                           IBuffer*                 pCameraAttribs,
1271+                                           IBuffer*                 pLightAttribs,
1272+                                           IPipelineState*          pPSO,
1273+                                           IShaderResourceBinding** ppMaterialSRB) PURE;
1274+   	*/
1275+
1276+
1277+    /// Creates a shader resource binding for a GTLF resource cache.
1278+
1279+    /// \param [in] pDevice        - Render device that may be needed by the resource cache to create
1280+    ///                              internal objects.
1281+    /// \param [in] pCtx           - Device context that may be needed by the resource cache to initialize
1282+    ///                              internal objects.
1283+    /// \param [in] CacheUseInfo   - GLTF resource cache usage information.
1284+    /// \param [in] pCameraAttribs - Camera attributes constant buffer to set in the SRB.
1285+    /// \param [in] pLightAttribs  - Light attributes constant buffer to set in the SRB.
1286+    /// \param [in] pPSO           - Optional PSO object to use to create the SRB instead of the
1287+    ///                              default PSO. Can be null
1288+    /// \param [out] ppCacheSRB    - Pointer to memory location where the pointer to the SRB object
1289+    ///                              will be written.
1290+    VIRTUAL void METHOD(CreateResourceCacheSRB)(THIS_
1291+                                                IRenderDevice*                pDevice,
1292+                                                IDeviceContext*               pCtx,
1293+                                                GLTF_ResourceCacheUseInfo REF CacheUseInfo,
1294+                                                IBuffer*                      pCameraAttribs,
1295+                                                IBuffer*                      pLightAttribs,
1296+                                                IPipelineState*               pPSO,
1297+                                                IShaderResourceBinding**      ppCacheSRB) PURE;
1298+
1299+    /// Prepares the renderer for rendering objects.
1300+    /// This method must be called at least once per frame.
1301+    VIRTUAL void METHOD(Begin)(THIS_
1302+                               IDeviceContext* pCtx) PURE;
1303+
1304+
1305+    /// Prepares the renderer for rendering objects from the resource cache.
1306+    /// This method must be called at least once per frame before the first object
1307+    /// from the cache is rendered.
1308+    VIRTUAL void METHOD(BeginPSO)(THIS_
1309+                                  IRenderDevice*                 pDevice,
1310+                                  IDeviceContext*                pCtx,
1311+                                  GLTF_ResourceCacheUseInfo REF  CacheUseInfo,
1312+                                  GLTF_ResourceCacheBindings REF Bindings,
1313+                                  IBuffer*                       pCameraAttribs,
1314+                                  IBuffer*                       pLightAttribs,
1315+                                  IPipelineState*                pPSO) PURE;
1316+};
1317+DILIGENT_END_INTERFACE
1318+
1319+#include "../../../Primitives/interface/UndefInterfaceHelperMacros.h"
1320+
1321+#if DILIGENT_C_INTERFACE
1322+
1323+#    define IGLTF_PBR_Renderer_Render(This, ...)                 CALL_IFACE_METHOD(GLTF_PBR_Renderer, Render,                  This, __VA_ARGS__)
1324+#    define IGLTF_PBR_Renderer_CreateResourceBindings(This, ...) CALL_IFACE_METHOD(GLTF_PBR_Renderer, CreateResourceBindings,  This, __VA_ARGS__)
1325+#    define IGLTF_PBR_Renderer_PrecomputeCubemaps(This, ...)     CALL_IFACE_METHOD(GLTF_PBR_Renderer, PrecomputeCubemaps,      This, __VA_ARGS__)
1326+#    define IGLTF_PBR_Renderer_GetIrradianceCubeSRV(This)        CALL_IFACE_METHOD(GLTF_PBR_Renderer, GetIrradianceCubeSRV,    This)
1327+#    define IGLTF_PBR_Renderer_GetPrefilteredEnvMapSRV(This)     CALL_IFACE_METHOD(GLTF_PBR_Renderer, GetPrefilteredEnvMapSRV, This)
1328+#    define IGLTF_PBR_Renderer_GetWhiteTexSRV(This)              CALL_IFACE_METHOD(GLTF_PBR_Renderer, GetWhiteTexSRV,          This)
1329+#    define IGLTF_PBR_Renderer_GetBlackTexSRV(This)              CALL_IFACE_METHOD(GLTF_PBR_Renderer, GetBlackTexSRV,          This)
1330+#    define IGLTF_PBR_Renderer_GetDefaultNormalMapSRV(This)      CALL_IFACE_METHOD(GLTF_PBR_Renderer, GetDefaultNormalMapSRV,  This)
1331+#    define IGLTF_PBR_Renderer_CreateMaterialSRB(This, ...)      CALL_IFACE_METHOD(GLTF_PBR_Renderer, CreateMaterialSRB,       This, __VA_ARGS__)
1332+#    define IGLTF_PBR_Renderer_CreateResourceCacheSRB(This, ...) CALL_IFACE_METHOD(GLTF_PBR_Renderer, CreateResourceCacheSRB,  This, __VA_ARGS__)
1333+#    define IGLTF_PBR_Renderer_Begin(This, ...)                  CALL_IFACE_METHOD(GLTF_PBR_Renderer, Begin,                   This, __VA_ARGS__)
1334+#    define IGLTF_PBR_Renderer_BeginPSO(This, ...)               CALL_IFACE_METHOD(GLTF_PBR_Renderer, BeginPSO,                This, __VA_ARGS__)
1335+
1336+#endif
1337+
1338+// clang-format on
1339+
1340+/// Initializes the renderer
1341+API_QUALIFIER
1342+struct IGLTF_PBR_Renderer* DILIGENT_GLOBAL_FUNCTION(IGLTF_PBR_Renderer_Create)(IRenderDevice*                 pDevice,
1343+                                                                               IDeviceContext*                pCtx,
1344+                                                                               const GLTF_RendererCreateInfo* CI);
1345+
1346+DILIGENT_END_NAMESPACE // namespace Diligent
1347diff --git a/DiligentFX/GLTF_PBR_Renderer/interface/GLTF_PBR_Renderer.hpp b/DiligentFX/GLTF_PBR_Renderer/interface/GLTF_PBR_Renderer.hpp
1348deleted file mode 100644
1349index 4c6deab..0000000
1350--- a/DiligentFX/GLTF_PBR_Renderer/interface/GLTF_PBR_Renderer.hpp
1351+++ /dev/null
1352@@ -1,379 +0,0 @@
1353-/*
1354- *  Copyright 2019-2021 Diligent Graphics LLC
1355- *  Copyright 2015-2019 Egor Yusov
1356- *  
1357- *  Licensed under the Apache License, Version 2.0 (the "License");
1358- *  you may not use this file except in compliance with the License.
1359- *  You may obtain a copy of the License at
1360- *  
1361- *      http://www.apache.org/licenses/LICENSE-2.0
1362- *  
1363- *  Unless required by applicable law or agreed to in writing, software
1364- *  distributed under the License is distributed on an "AS IS" BASIS,
1365- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1366- *  See the License for the specific language governing permissions and
1367- *  limitations under the License.
1368- *
1369- *  In no event and under no legal theory, whether in tort (including negligence), 
1370- *  contract, or otherwise, unless required by applicable law (such as deliberate 
1371- *  and grossly negligent acts) or agreed to in writing, shall any Contributor be
1372- *  liable for any damages, including any direct, indirect, special, incidental, 
1373- *  or consequential damages of any character arising as a result of this License or 
1374- *  out of the use or inability to use the software (including but not limited to damages 
1375- *  for loss of goodwill, work stoppage, computer failure or malfunction, or any and 
1376- *  all other commercial damages or losses), even if such Contributor has been advised 
1377- *  of the possibility of such damages.
1378- */
1379-
1380-#pragma once
1381-
1382-#include <unordered_map>
1383-#include <functional>
1384-#include <mutex>
1385-#include <vector>
1386-
1387-#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/DeviceContext.h"
1388-#include "../../../DiligentCore/Graphics/GraphicsEngine/interface/RenderDevice.h"
1389-#include "../../../DiligentCore/Common/interface/HashUtils.hpp"
1390-#include "../../../DiligentTools/AssetLoader/interface/GLTFLoader.hpp"
1391-
1392-namespace Diligent
1393-{
1394-
1395-#include "Shaders/GLTF_PBR/public/GLTF_PBR_Structures.fxh"
1396-
1397-/// Implementation of a GLTF PBR renderer
1398-class GLTF_PBR_Renderer
1399-{
1400-public:
1401-    /// Renderer create info
1402-    struct CreateInfo
1403-    {
1404-        /// Render target format.
1405-        TEXTURE_FORMAT RTVFmt = TEX_FORMAT_UNKNOWN;
1406-
1407-        /// Depth-buffer format.
1408-
1409-        /// \note   If both RTV and DSV formats are TEX_FORMAT_UNKNOWN,
1410-        ///         the renderer will not initialize PSO, uniform buffers and other
1411-        ///         resources. It is expected that an application will use custom
1412-        ///         render callback function.
1413-        TEXTURE_FORMAT DSVFmt = TEX_FORMAT_UNKNOWN;
1414-
1415-        /// Indicates if front face is CCW.
1416-        bool FrontCCW = false;
1417-
1418-        /// Indicates if the renderer should allow debug views.
1419-        /// Rendering with debug views disabled is more efficient.
1420-        bool AllowDebugView = false;
1421-
1422-        /// Indicates whether to use IBL.
1423-        bool UseIBL = false;
1424-
1425-        /// Whether to use ambient occlusion texture.
1426-        bool UseAO = true;
1427-
1428-        /// Whether to use emissive texture.
1429-        bool UseEmissive = true;
1430-
1431-        /// When set to true, pipeline state will be compiled with immutable samplers.
1432-        /// When set to false, samplers from the texture views will be used.
1433-        bool UseImmutableSamplers = true;
1434-
1435-        /// Whether to use texture atlas (e.g. apply UV transforms when sampling textures).
1436-        bool UseTextureAtals = false;
1437-
1438-        static const SamplerDesc DefaultSampler;
1439-
1440-        /// Immutable sampler for color map texture.
1441-        SamplerDesc ColorMapImmutableSampler = DefaultSampler;
1442-
1443-        /// Immutable sampler for physical description map texture.
1444-        SamplerDesc PhysDescMapImmutableSampler = DefaultSampler;
1445-
1446-        /// Immutable sampler for normal map texture.
1447-        SamplerDesc NormalMapImmutableSampler = DefaultSampler;
1448-
1449-        /// Immutable sampler for AO texture.
1450-        SamplerDesc AOMapImmutableSampler = DefaultSampler;
1451-
1452-        /// Immutable sampler for emissive map texture.
1453-        SamplerDesc EmissiveMapImmutableSampler = DefaultSampler;
1454-
1455-        /// Maximum number of joints
1456-        Uint32 MaxJointCount = 64;
1457-    };
1458-
1459-    /// Initializes the renderer
1460-    GLTF_PBR_Renderer(IRenderDevice*    pDevice,
1461-                      IDeviceContext*   pCtx,
1462-                      const CreateInfo& CI);
1463-
1464-    /// Rendering information
1465-    struct RenderInfo
1466-    {
1467-        /// Model transform matrix
1468-        float4x4 ModelTransform = float4x4::Identity();
1469-
1470-        /// Alpha mode flags
1471-        enum ALPHA_MODE_FLAGS : Uint32
1472-        {
1473-            /// Render nothing
1474-            ALPHA_MODE_FLAG_NONE = 0,
1475-
1476-            /// Render opaque matetrials
1477-            ALPHA_MODE_FLAG_OPAQUE = 1 << GLTF::Material::ALPHA_MODE_OPAQUE,
1478-
1479-            /// Render alpha-masked matetrials
1480-            ALPHA_MODE_FLAG_MASK = 1 << GLTF::Material::ALPHA_MODE_MASK,
1481-
1482-            /// Render alpha-blended matetrials
1483-            ALPHA_MODE_FLAG_BLEND = 1 << GLTF::Material::ALPHA_MODE_BLEND,
1484-
1485-            /// Render all materials
1486-            ALPHA_MODE_FLAG_ALL = ALPHA_MODE_FLAG_OPAQUE | ALPHA_MODE_FLAG_MASK | ALPHA_MODE_FLAG_BLEND
1487-        };
1488-        /// Flag indicating which alpha modes to render
1489-        ALPHA_MODE_FLAGS AlphaModes = ALPHA_MODE_FLAG_ALL;
1490-
1491-        /// Debug view type
1492-        enum class DebugViewType : int
1493-        {
1494-            None            = 0,
1495-            BaseColor       = 1,
1496-            Transparency    = 2,
1497-            NormalMap       = 3,
1498-            Occlusion       = 4,
1499-            Emissive        = 5,
1500-            Metallic        = 6,
1501-            Roughness       = 7,
1502-            DiffuseColor    = 8,
1503-            SpecularColor   = 9,
1504-            Reflectance90   = 10,
1505-            MeshNormal      = 11,
1506-            PerturbedNormal = 12,
1507-            NdotV           = 13,
1508-            DiffuseIBL      = 14,
1509-            SpecularIBL     = 15,
1510-            NumDebugViews
1511-        };
1512-        DebugViewType DebugView = DebugViewType::None;
1513-
1514-        /// Ambient occlusion strength
1515-        float OcclusionStrength = 1;
1516-
1517-        /// Emission scale
1518-        float EmissionScale = 1;
1519-
1520-        /// IBL scale
1521-        float IBLScale = 1;
1522-
1523-        /// Average log luminance used by tone mapping
1524-        float AverageLogLum = 0.3f;
1525-
1526-        /// Middle gray value used by tone mapping
1527-        float MiddleGray = 0.18f;
1528-
1529-        /// White point value used by tone mapping
1530-        float WhitePoint = 3.f;
1531-    };
1532-
1533-    /// GLTF Model shader resource binding information
1534-    struct ModelResourceBindings
1535-    {
1536-        void Clear()
1537-        {
1538-            MaterialSRB.clear();
1539-        }
1540-        /// Shader resource binding for every material
1541-        std::vector<RefCntAutoPtr<IShaderResourceBinding>> MaterialSRB;
1542-    };
1543-
1544-    /// GLTF resource cache shader resource binding information
1545-    struct ResourceCacheBindings
1546-    {
1547-        /// Resource version
1548-        Uint32 Version = 0;
1549-
1550-        RefCntAutoPtr<IShaderResourceBinding> pSRB;
1551-    };
1552-
1553-    /// Renders a GLTF model.
1554-
1555-    /// \param [in] pCtx           - Device context to record rendering commands to.
1556-    /// \param [in] GLTFModel      - GLTF model to render.
1557-    /// \param [in] RenderParams   - Render parameters.
1558-    /// \param [in] pModelBindings - The model's shader resource binding information.
1559-    /// \param [in] pCacheBindings - Shader resource cache binding information, if the
1560-    ///                              model has been created using the cache.
1561-    void Render(IDeviceContext*        pCtx,
1562-                GLTF::Model&           GLTFModel,
1563-                const RenderInfo&      RenderParams,
1564-                ModelResourceBindings* pModelBindings,
1565-                ResourceCacheBindings* pCacheBindings = nullptr);
1566-
1567-    /// Creates resource bindings for a given GLTF model
1568-    ModelResourceBindings CreateResourceBindings(GLTF::Model& GLTFModel,
1569-                                                 IBuffer*     pCameraAttribs,
1570-                                                 IBuffer*     pLightAttribs);
1571-
1572-    /// Precompute cubemaps used by IBL.
1573-    void PrecomputeCubemaps(IRenderDevice*  pDevice,
1574-                            IDeviceContext* pCtx,
1575-                            ITextureView*   pEnvironmentMap);
1576-
1577-    // clang-format off
1578-    ITextureView* GetIrradianceCubeSRV()    { return m_pIrradianceCubeSRV; }
1579-    ITextureView* GetPrefilteredEnvMapSRV() { return m_pPrefilteredEnvMapSRV; }
1580-    ITextureView* GetWhiteTexSRV()          { return m_pWhiteTexSRV; }
1581-    ITextureView* GetBlackTexSRV()          { return m_pBlackTexSRV; }
1582-    ITextureView* GetDefaultNormalMapSRV()  { return m_pDefaultNormalMapSRV; }
1583-    // clang-format on
1584-
1585-    /// Creates a shader resource binding for the given material.
1586-
1587-    /// \param [in] Model          - GLTF model that keeps material textures.
1588-    /// \param [in] Material       - GLTF material to create SRB for.
1589-    /// \param [in] pCameraAttribs - Camera attributes constant buffer to set in the SRB.
1590-    /// \param [in] pLightAttribs  - Light attributes constant buffer to set in the SRB.
1591-    /// \param [in] pPSO           - Optional PSO object to use to create the SRB instead of the
1592-    ///                              default PSO. Can be null
1593-    /// \param [out] ppMaterialSRB - Pointer to memory location where the pointer to the SRB object
1594-    ///                              will be written.
1595-    void CreateMaterialSRB(GLTF::Model&             Model,
1596-                           GLTF::Material&          Material,
1597-                           IBuffer*                 pCameraAttribs,
1598-                           IBuffer*                 pLightAttribs,
1599-                           IPipelineState*          pPSO,
1600-                           IShaderResourceBinding** ppMaterialSRB);
1601-
1602-
1603-    /// Creates a shader resource binding for a GTLF resource cache.
1604-
1605-    /// \param [in] pDevice        - Render device that may be needed by the resource cache to create
1606-    ///                              internal objects.
1607-    /// \param [in] pCtx           - Device context that may be needed by the resource cache to initialize
1608-    ///                              internal objects.
1609-    /// \param [in] CacheUseInfo   - GLTF resource cache usage information.
1610-    /// \param [in] pCameraAttribs - Camera attributes constant buffer to set in the SRB.
1611-    /// \param [in] pLightAttribs  - Light attributes constant buffer to set in the SRB.
1612-    /// \param [in] pPSO           - Optional PSO object to use to create the SRB instead of the
1613-    ///                              default PSO. Can be null
1614-    /// \param [out] ppCacheSRB    - Pointer to memory location where the pointer to the SRB object
1615-    ///                              will be written.
1616-    void CreateResourceCacheSRB(IRenderDevice*              pDevice,
1617-                                IDeviceContext*             pCtx,
1618-                                GLTF::ResourceCacheUseInfo& CacheUseInfo,
1619-                                IBuffer*                    pCameraAttribs,
1620-                                IBuffer*                    pLightAttribs,
1621-                                IPipelineState*             pPSO,
1622-                                IShaderResourceBinding**    ppCacheSRB);
1623-
1624-    /// Prepares the renderer for rendering objects.
1625-    /// This method must be called at least once per frame.
1626-    void Begin(IDeviceContext* pCtx);
1627-
1628-
1629-    /// Prepares the renderer for rendering objects from the resource cache.
1630-    /// This method must be called at least once per frame before the first object
1631-    /// from the cache is rendered.
1632-    void Begin(IRenderDevice*              pDevice,
1633-               IDeviceContext*             pCtx,
1634-               GLTF::ResourceCacheUseInfo& CacheUseInfo,
1635-               ResourceCacheBindings&      Bindings,
1636-               IBuffer*                    pCameraAttribs,
1637-               IBuffer*                    pLightAttribs,
1638-               IPipelineState*             pPSO = nullptr);
1639-
1640-private:
1641-    void PrecomputeBRDF(IRenderDevice*  pDevice,
1642-                        IDeviceContext* pCtx);
1643-
1644-    void CreatePSO(IRenderDevice* pDevice);
1645-
1646-    void InitCommonSRBVars(IShaderResourceBinding* pSRB,
1647-                           IBuffer*                pCameraAttribs,
1648-                           IBuffer*                pLightAttribs);
1649-
1650-    struct PSOKey
1651-    {
1652-        PSOKey() noexcept {};
1653-        PSOKey(GLTF::Material::ALPHA_MODE _AlphaMode, bool _DoubleSided) :
1654-            AlphaMode{_AlphaMode},
1655-            DoubleSided{_DoubleSided}
1656-        {}
1657-
1658-        bool operator==(const PSOKey& rhs) const
1659-        {
1660-            return AlphaMode == rhs.AlphaMode && DoubleSided == rhs.DoubleSided;
1661-        }
1662-        bool operator!=(const PSOKey& rhs) const
1663-        {
1664-            return AlphaMode != rhs.AlphaMode || DoubleSided != rhs.DoubleSided;
1665-        }
1666-
1667-        GLTF::Material::ALPHA_MODE AlphaMode   = GLTF::Material::ALPHA_MODE_OPAQUE;
1668-        bool                       DoubleSided = false;
1669-    };
1670-
1671-    static size_t GetPSOIdx(const PSOKey& Key)
1672-    {
1673-        size_t PSOIdx;
1674-
1675-        PSOIdx = Key.AlphaMode == GLTF::Material::ALPHA_MODE_BLEND ? 1 : 0;
1676-        PSOIdx = PSOIdx * 2 + (Key.DoubleSided ? 1 : 0);
1677-        return PSOIdx;
1678-    }
1679-
1680-    void AddPSO(const PSOKey& Key, RefCntAutoPtr<IPipelineState> pPSO)
1681-    {
1682-        auto Idx = GetPSOIdx(Key);
1683-        if (Idx >= m_PSOCache.size())
1684-            m_PSOCache.resize(Idx + 1);
1685-        VERIFY_EXPR(!m_PSOCache[Idx]);
1686-        m_PSOCache[Idx] = std::move(pPSO);
1687-    }
1688-
1689-    IPipelineState* GetPSO(const PSOKey& Key)
1690-    {
1691-        auto Idx = GetPSOIdx(Key);
1692-        VERIFY_EXPR(Idx < m_PSOCache.size());
1693-        return Idx < m_PSOCache.size() ? m_PSOCache[Idx].RawPtr() : nullptr;
1694-    }
1695-
1696-    const CreateInfo m_Settings;
1697-
1698-    static constexpr Uint32     BRDF_LUT_Dim = 512;
1699-    RefCntAutoPtr<ITextureView> m_pBRDF_LUT_SRV;
1700-
1701-    std::vector<RefCntAutoPtr<IPipelineState>> m_PSOCache;
1702-
1703-    RefCntAutoPtr<ITextureView> m_pWhiteTexSRV;
1704-    RefCntAutoPtr<ITextureView> m_pBlackTexSRV;
1705-    RefCntAutoPtr<ITextureView> m_pDefaultNormalMapSRV;
1706-    RefCntAutoPtr<ITextureView> m_pDefaultPhysDescSRV;
1707-
1708-
1709-    static constexpr TEXTURE_FORMAT IrradianceCubeFmt    = TEX_FORMAT_RGBA32_FLOAT;
1710-    static constexpr TEXTURE_FORMAT PrefilteredEnvMapFmt = TEX_FORMAT_RGBA16_FLOAT;
1711-    static constexpr Uint32         IrradianceCubeDim    = 64;
1712-    static constexpr Uint32         PrefilteredEnvMapDim = 256;
1713-
1714-    RefCntAutoPtr<ITextureView>           m_pIrradianceCubeSRV;
1715-    RefCntAutoPtr<ITextureView>           m_pPrefilteredEnvMapSRV;
1716-    RefCntAutoPtr<IPipelineState>         m_pPrecomputeIrradianceCubePSO;
1717-    RefCntAutoPtr<IPipelineState>         m_pPrefilterEnvMapPSO;
1718-    RefCntAutoPtr<IShaderResourceBinding> m_pPrecomputeIrradianceCubeSRB;
1719-    RefCntAutoPtr<IShaderResourceBinding> m_pPrefilterEnvMapSRB;
1720-
1721-    RenderInfo m_RenderParams;
1722-
1723-    RefCntAutoPtr<IBuffer> m_TransformsCB;
1724-    RefCntAutoPtr<IBuffer> m_GLTFAttribsCB;
1725-    RefCntAutoPtr<IBuffer> m_PrecomputeEnvMapAttribsCB;
1726-    RefCntAutoPtr<IBuffer> m_JointsBuffer;
1727-};
1728-
1729-DEFINE_FLAG_ENUM_OPERATORS(GLTF_PBR_Renderer::RenderInfo::ALPHA_MODE_FLAGS)
1730-
1731-} // namespace Diligent
1732diff --git a/DiligentFX/GLTF_PBR_Renderer/src/GLTF_PBR_Renderer.cpp b/DiligentFX/GLTF_PBR_Renderer/src/GLTF_PBR_Renderer.cpp
1733index a07371b..bbfbd4c 100644
1734--- a/DiligentFX/GLTF_PBR_Renderer/src/GLTF_PBR_Renderer.cpp
1735+++ b/DiligentFX/GLTF_PBR_Renderer/src/GLTF_PBR_Renderer.cpp
1736@@ -41,11 +41,11 @@
1737 namespace Diligent
1738 {
1739 
1740-const SamplerDesc GLTF_PBR_Renderer::CreateInfo::DefaultSampler = Sam_LinearWrap;
1741+const SamplerDesc GLTF_RendererCreateInfo::DefaultSampler = Sam_LinearWrap;
1742 
1743 GLTF_PBR_Renderer::GLTF_PBR_Renderer(IRenderDevice*    pDevice,
1744                                      IDeviceContext*   pCtx,
1745-                                     const CreateInfo& CI) :
1746+                                     const GLTF_RendererCreateInfo& CI) :
1747     m_Settings{CI}
1748 {
1749     if (m_Settings.UseIBL)
1750@@ -208,6 +208,7 @@ void GLTF_PBR_Renderer::PrecomputeBRDF(IRenderDevice*  pDevice,
1751         // Finally, create the pipeline state
1752         PSOCreateInfo.pVS = pVS;
1753         PSOCreateInfo.pPS = pPS;
1754+
1755         pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &PrecomputeBRDF_PSO);
1756     }
1757     pCtx->SetPipelineState(PrecomputeBRDF_PSO);
1758@@ -257,9 +258,9 @@ void GLTF_PBR_Renderer::CreatePSO(IRenderDevice* pDevice)
1759     Macros.AddShaderMacro("USE_TEXTURE_ATLAS", m_Settings.UseTextureAtals);
1760     Macros.AddShaderMacro("PBR_WORKFLOW_METALLIC_ROUGHNESS", GLTF::Material::PBR_WORKFLOW_METALL_ROUGH);
1761     Macros.AddShaderMacro("PBR_WORKFLOW_SPECULAR_GLOSINESS", GLTF::Material::PBR_WORKFLOW_SPEC_GLOSS);
1762-    Macros.AddShaderMacro("GLTF_ALPHA_MODE_OPAQUE", GLTF::Material::ALPHA_MODE_OPAQUE);
1763-    Macros.AddShaderMacro("GLTF_ALPHA_MODE_MASK", GLTF::Material::ALPHA_MODE_MASK);
1764-    Macros.AddShaderMacro("GLTF_ALPHA_MODE_BLEND", GLTF::Material::ALPHA_MODE_BLEND);
1765+    Macros.AddShaderMacro("GLTF_ALPHA_MODE_OPAQUE", GLTF_MAT_ALPHA_MODE_OPAQUE);
1766+    Macros.AddShaderMacro("GLTF_ALPHA_MODE_MASK", GLTF_MAT_ALPHA_MODE_MASK);
1767+    Macros.AddShaderMacro("GLTF_ALPHA_MODE_BLEND", GLTF_MAT_ALPHA_MODE_BLEND);
1768     ShaderCI.Macros = Macros;
1769     RefCntAutoPtr<IShader> pVS;
1770     {
1771@@ -343,8 +344,11 @@ void GLTF_PBR_Renderer::CreatePSO(IRenderDevice* pDevice)
1772     PSOCreateInfo.pVS = pVS;
1773     PSOCreateInfo.pPS = pPS;
1774 
1775+    if (m_Settings.pGS)
1776+        PSOCreateInfo.pGS = m_Settings.pGS;
1777+
1778     {
1779-        PSOKey Key{GLTF::Material::ALPHA_MODE_OPAQUE, false};
1780+        PSOKey Key{GLTF_MAT_ALPHA_MODE_OPAQUE, false};
1781 
1782         RefCntAutoPtr<IPipelineState> pSingleSidedOpaquePSO;
1783         pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &pSingleSidedOpaquePSO);
1784@@ -371,7 +375,7 @@ void GLTF_PBR_Renderer::CreatePSO(IRenderDevice* pDevice)
1785     RT0.BlendOpAlpha   = BLEND_OPERATION_ADD;
1786 
1787     {
1788-        PSOKey Key{GLTF::Material::ALPHA_MODE_BLEND, false};
1789+        PSOKey Key{GLTF_MAT_ALPHA_MODE_BLEND, false};
1790 
1791         RefCntAutoPtr<IPipelineState> pSingleSidedBlendPSO;
1792         pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &pSingleSidedBlendPSO);
1793@@ -432,13 +436,15 @@ void GLTF_PBR_Renderer::InitCommonSRBVars(IShaderResourceBinding* pSRB,
1794 }
1795 
1796 
1797-void GLTF_PBR_Renderer::CreateMaterialSRB(GLTF::Model&             Model,
1798+void GLTF_PBR_Renderer::CreateMaterialSRB(IGLTFModel*              _Model,
1799                                           GLTF::Material&          Material,
1800                                           IBuffer*                 pCameraAttribs,
1801                                           IBuffer*                 pLightAttribs,
1802                                           IPipelineState*          pPSO,
1803                                           IShaderResourceBinding** ppMaterialSRB)
1804 {
1805+    auto& Model = *static_cast<GLTF::Model*>(_Model);
1806+
1807     if (pPSO == nullptr)
1808         pPSO = GetPSO(PSOKey{});
1809 
1810@@ -495,7 +501,7 @@ void GLTF_PBR_Renderer::CreateMaterialSRB(GLTF::Model&             Model,
1811 
1812 void GLTF_PBR_Renderer::CreateResourceCacheSRB(IRenderDevice*              pDevice,
1813                                                IDeviceContext*             pCtx,
1814-                                               GLTF::ResourceCacheUseInfo& CacheUseInfo,
1815+                                               GLTF_ResourceCacheUseInfo&  CacheUseInfo,
1816                                                IBuffer*                    pCameraAttribs,
1817                                                IBuffer*                    pLightAttribs,
1818                                                IPipelineState*             pPSO,
1819@@ -705,7 +711,7 @@ void GLTF_PBR_Renderer::PrecomputeCubemaps(IRenderDevice*  pDevice,
1820 
1821 
1822     // clang-format off
1823-	const std::array<float4x4, 6> Matrices =
1824+  const std::array<float4x4, 6> Matrices =
1825     {
1826 /* +X */ float4x4::RotationY(+PI_F / 2.f),
1827 /* -X */ float4x4::RotationY(-PI_F / 2.f),
1828@@ -713,7 +719,7 @@ void GLTF_PBR_Renderer::PrecomputeCubemaps(IRenderDevice*  pDevice,
1829 /* -Y */ float4x4::RotationX(+PI_F / 2.f),
1830 /* +Z */ float4x4::Identity(),
1831 /* -Z */ float4x4::RotationY(PI_F)
1832-	};
1833+  };
1834     // clang-format on
1835 
1836     pCtx->SetPipelineState(m_pPrecomputeIrradianceCubePSO);
1837@@ -786,16 +792,17 @@ void GLTF_PBR_Renderer::PrecomputeCubemaps(IRenderDevice*  pDevice,
1838 }
1839 
1840 
1841-GLTF_PBR_Renderer::ModelResourceBindings GLTF_PBR_Renderer::CreateResourceBindings(
1842-    GLTF::Model& GLTFModel,
1843+GLTF_ModelResourceBindings GLTF_PBR_Renderer::CreateResourceBindings(
1844+    IGLTFModel*  _GLTFModel,
1845     IBuffer*     pCameraAttribs,
1846     IBuffer*     pLightAttribs)
1847 {
1848-    ModelResourceBindings ResourceBindings;
1849+    auto& GLTFModel = *static_cast<GLTF::Model*>(_GLTFModel);
1850+    GLTF_ModelResourceBindings ResourceBindings;
1851     ResourceBindings.MaterialSRB.resize(GLTFModel.Materials.size());
1852     for (size_t mat = 0; mat < GLTFModel.Materials.size(); ++mat)
1853     {
1854-        CreateMaterialSRB(GLTFModel, GLTFModel.Materials[mat], pCameraAttribs, pLightAttribs, nullptr, &ResourceBindings.MaterialSRB[mat]);
1855+        CreateMaterialSRB(_GLTFModel, GLTFModel.Materials[mat], pCameraAttribs, pLightAttribs, nullptr, &ResourceBindings.MaterialSRB[mat]);
1856     }
1857     return ResourceBindings;
1858 }
1859@@ -809,13 +816,13 @@ void GLTF_PBR_Renderer::Begin(IDeviceContext* pCtx)
1860     }
1861 }
1862 
1863-void GLTF_PBR_Renderer::Begin(IRenderDevice*              pDevice,
1864-                              IDeviceContext*             pCtx,
1865-                              GLTF::ResourceCacheUseInfo& CacheUseInfo,
1866-                              ResourceCacheBindings&      Bindings,
1867-                              IBuffer*                    pCameraAttribs,
1868-                              IBuffer*                    pLightAttribs,
1869-                              IPipelineState*             pPSO)
1870+void GLTF_PBR_Renderer::BeginPSO(IRenderDevice*                   pDevice,
1871+                                 IDeviceContext*                  pCtx,
1872+                                 GLTF_ResourceCacheUseInfo&       CacheUseInfo,
1873+                                 GLTF_ResourceCacheBindings&      Bindings,
1874+                                 IBuffer*                         pCameraAttribs,
1875+                                 IBuffer*                         pLightAttribs,
1876+                                 IPipelineState*                  pPSO)
1877 {
1878     VERIFY_EXPR(CacheUseInfo.pResourceMgr != nullptr);
1879 
1880@@ -851,12 +858,14 @@ void GLTF_PBR_Renderer::Begin(IRenderDevice*              pDevice,
1881     pCtx->SetIndexBuffer(pIndexBuffer, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
1882 }
1883 
1884-void GLTF_PBR_Renderer::Render(IDeviceContext*        pCtx,
1885-                               GLTF::Model&           GLTFModel,
1886-                               const RenderInfo&      RenderParams,
1887-                               ModelResourceBindings* pModelBindings,
1888-                               ResourceCacheBindings* pCacheBindings)
1889+void GLTF_PBR_Renderer::Render(IDeviceContext*             pCtx,
1890+                               IGLTFModel*                 _GLTFModel,
1891+                               const GLTF_RenderInfo&      RenderParams,
1892+                               GLTF_ModelResourceBindings* pModelBindings,
1893+                               GLTF_ResourceCacheBindings* pCacheBindings)
1894 {
1895+    auto& GLTFModel = *static_cast<GLTF::Model*>(_GLTFModel);
1896+
1897     DEV_CHECK_ERR((pModelBindings != nullptr) ^ (pCacheBindings != nullptr), "Either model bindings or cache bindings must not be null");
1898     DEV_CHECK_ERR(pModelBindings == nullptr || pModelBindings->MaterialSRB.size() == GLTFModel.Materials.size(),
1899                   "The number of material shader resource bindings is not consistent with the number of materials");
1900@@ -868,12 +877,12 @@ void GLTF_PBR_Renderer::Render(IDeviceContext*        pCtx,
1901         std::array<Uint32, 2>   Offsets = {};
1902         std::array<IBuffer*, 2> pVBs =
1903             {
1904-                GLTFModel.GetBuffer(GLTF::Model::BUFFER_ID_VERTEX_BASIC_ATTRIBS),
1905-                GLTFModel.GetBuffer(GLTF::Model::BUFFER_ID_VERTEX_SKIN_ATTRIBS) //
1906+                GLTFModel.GetBuffer(GLTF_BUFFER_ID_VERTEX_BASIC_ATTRIBS),
1907+                GLTFModel.GetBuffer(GLTF_BUFFER_ID_VERTEX_SKIN_ATTRIBS) //
1908             };
1909         pCtx->SetVertexBuffers(0, static_cast<Uint32>(pVBs.size()), pVBs.data(), Offsets.data(), RESOURCE_STATE_TRANSITION_MODE_TRANSITION, SET_VERTEX_BUFFERS_FLAG_RESET);
1910 
1911-        if (auto* pIndexBuffer = GLTFModel.GetBuffer(GLTF::Model::BUFFER_ID_INDEX))
1912+        if (auto* pIndexBuffer = GLTFModel.GetBuffer(GLTF_BUFFER_ID_INDEX))
1913         {
1914             pCtx->SetIndexBuffer(pIndexBuffer, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
1915         }
1916@@ -882,11 +891,11 @@ void GLTF_PBR_Renderer::Render(IDeviceContext*        pCtx,
1917     const auto FirstIndexLocation = GLTFModel.GetFirstIndexLocation();
1918     const auto BaseVertex         = GLTFModel.GetBaseVertex();
1919 
1920-    const std::array<GLTF::Material::ALPHA_MODE, 3> AlphaModes //
1921+    const std::array<GLTF_MAT_ALPHA_MODE, 3> AlphaModes //
1922         {
1923-            GLTF::Material::ALPHA_MODE_OPAQUE, // Opaque primitives - first
1924-            GLTF::Material::ALPHA_MODE_MASK,   // Alpha-masked primitives - second
1925-            GLTF::Material::ALPHA_MODE_BLEND,  // Transparent primitives - last (TODO: depth sorting)
1926+            GLTF_MAT_ALPHA_MODE_OPAQUE, // Opaque primitives - first
1927+            GLTF_MAT_ALPHA_MODE_MASK,   // Alpha-masked primitives - second
1928+            GLTF_MAT_ALPHA_MODE_BLEND,  // Transparent primitives - last (TODO: depth sorting)
1929         };
1930 
1931     const GLTF::Mesh*       pLastAnimatedMesh = nullptr;
1932@@ -961,7 +970,7 @@ void GLTF_PBR_Renderer::Render(IDeviceContext*        pCtx,
1933 
1934                 {
1935                     MapHelper<GLTFNodeShaderTransforms> pTransforms{pCtx, m_TransformsCB, MAP_WRITE, MAP_FLAG_DISCARD};
1936-                    pTransforms->NodeMatrix = Mesh.Transforms.matrix * RenderParams.ModelTransform;
1937+                    pTransforms->NodeMatrix = Mesh.Transforms.matrix * float4x4::MakeMatrix(RenderParams.ModelTransform);
1938                     pTransforms->JointCount = static_cast<int>(JointCount);
1939                 }
1940 
1941@@ -1017,4 +1026,21 @@ void GLTF_PBR_Renderer::Render(IDeviceContext*        pCtx,
1942     }
1943 }
1944 
1945+API_QUALIFIER
1946+IGLTF_PBR_Renderer* IGLTF_PBR_Renderer_Create(IRenderDevice*                 pDevice,
1947+                                              IDeviceContext*                pCtx,
1948+                                              const GLTF_RendererCreateInfo* CI) {
1949+    return new GLTF_PBR_Renderer(pDevice, pCtx, *CI);
1950+}
1951+
1952 } // namespace Diligent
1953+
1954+extern "C"
1955+{
1956+    API_QUALIFIER
1957+    Diligent::IGLTF_PBR_Renderer* Diligent_IGLTF_PBR_Renderer_Create(Diligent::IRenderDevice*                 pDevice,
1958+                                                                     Diligent::IDeviceContext*                pCtx,
1959+                                                                     const Diligent::GLTF_RendererCreateInfo* CI) {
1960+        return Diligent::IGLTF_PBR_Renderer_Create(pDevice, pCtx, CI);
1961+    }
1962+}
1963-- 
19642.31.0
1965