git.s-ol.nu ~forks/DiligentTools / 668caa7
Few minor updates to GLTF loader assiduous 10 months ago
2 changed file(s) with 41 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
203203
204204 TransformData Transforms;
205205
206 Mesh(IRenderDevice* pDevice, const float4x4& matrix);
206 Mesh(const float4x4& matrix);
207207 };
208208
209209
448448 IDeviceContext* pContext,
449449 const CreateInfo& CI);
450450
451 void LoadNode(IRenderDevice* pDevice,
452 Node* parent,
451 void LoadNode(Node* parent,
453452 const tinygltf::Node& gltf_node,
454453 uint32_t nodeIndex,
455454 const tinygltf::Model& gltf_model,
184184 }
185185
186186
187 Mesh::Mesh(IRenderDevice* pDevice, const float4x4& matrix)
187 Mesh::Mesh(const float4x4& matrix)
188188 {
189189 Transforms.matrix = matrix;
190190 }
256256 {
257257 }
258258
259 void Model::LoadNode(IRenderDevice* pDevice,
260 Node* parent,
259 void Model::LoadNode(Node* parent,
261260 const tinygltf::Node& gltf_node,
262261 uint32_t nodeIndex,
263262 const tinygltf::Model& gltf_model,
265264 std::vector<VertexBasicAttribs>& VertexBasicData,
266265 std::vector<VertexSkinAttribs>* pVertexSkinData)
267266 {
268 std::unique_ptr<Node> NewNode(new Node{});
267 std::unique_ptr<Node> NewNode{new Node{}};
269268 NewNode->Index = nodeIndex;
270269 NewNode->Parent = parent;
271270 NewNode->Name = gltf_node.name;
303302 {
304303 for (size_t i = 0; i < gltf_node.children.size(); i++)
305304 {
306 LoadNode(pDevice, NewNode.get(), gltf_model.nodes[gltf_node.children[i]], gltf_node.children[i], gltf_model,
305 LoadNode(NewNode.get(), gltf_model.nodes[gltf_node.children[i]], gltf_node.children[i], gltf_model,
307306 IndexData, VertexBasicData, pVertexSkinData);
308307 }
309308 }
312311 if (gltf_node.mesh >= 0)
313312 {
314313 const tinygltf::Mesh& gltf_mesh = gltf_model.meshes[gltf_node.mesh];
315 std::unique_ptr<Mesh> pNewMesh{new Mesh{pDevice, NewNode->Matrix}};
314 std::unique_ptr<Mesh> pNewMesh{new Mesh{NewNode->Matrix}};
316315 for (size_t j = 0; j < gltf_mesh.primitives.size(); j++)
317316 {
318317 const tinygltf::Primitive& primitive = gltf_mesh.primitives[j];
599598 {
600599 for (const auto& source : gltf_model.skins)
601600 {
602 std::unique_ptr<Skin> NewSkin(new Skin{});
601 std::unique_ptr<Skin> NewSkin{new Skin{}};
603602 NewSkin->Name = source.name;
604603
605604 // Find skeleton root node
784783 // No reference
785784 const TextureDesc AtlasDesc = pResourceMgr->GetAtlasDesc(TEX_FORMAT_RGBA8_UNORM);
786785
786 // Load all mip levels.
787787 auto pInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, AtlasDesc.MipLevels);
788788
789 // Init data will be atomically set in the allocation before any other thread may be able to
790 // get access to it.
789 // pInitData will be atomically set in the allocation before any other thread may be able to
790 // access it.
791791 // Note that it is possible that more than one thread prepares pInitData for the same allocation.
792792 // It it also possible that multiple instances of the same allocation are created before the first
793793 // is added to the cache. This is all OK though.
812812 pDevice->CreateTexture(TexDesc, nullptr, &TexInfo.pTexture);
813813 TexInfo.pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)->SetSampler(pSampler);
814814
815 // Load only the lowest mip level; other mip levels will be generated on the GPU.
815816 auto pTexInitData = PrepareGLTFTextureInitData(gltf_image, AlphaCutoff, 1);
816817 TexInfo.pTexture->SetUserData(pTexInitData);
817818 }
827828 TextureLoadInfo LoadInfo;
828829 if (pResourceMgr != nullptr)
829830 {
830 LoadInfo.Name = "Staging upload texture for compressed";
831 LoadInfo.Name = "Staging compressed upload texture";
831832 LoadInfo.Usage = USAGE_STAGING;
832833 LoadInfo.BindFlags = BIND_NONE;
833834 LoadInfo.CPUAccessFlags = CPU_ACCESS_WRITE;
834835 }
836 else
837 {
838 LoadInfo.Name = "Compressed texture for GLTF model";
839 }
835840 switch (gltf_image.pixel_type)
836841 {
837842 case IMAGE_FILE_FORMAT_DDS:
856861
857862 pTexInitData->pStagingTex = std::move(pStagingTex);
858863
859 // Init data will be atomically set in the allocation before any other thread may be able to
860 // get access to it.
861 // Note that it is possible that more than one thread prepares pInitData for the same allocation.
864 // pTexInitData will be atomically set in the allocation before any other thread may be able to
865 // access it.
866 // Note that it is possible that more than one thread prepares pTexInitData for the same allocation.
862867 // It it also possible that multiple instances of the same allocation are created before the first
863868 // is added to the cache. This is all OK though.
864869 TexInfo.pAtlasSuballocation = pResourceMgr->AllocateTextureSpace(TexDesc.Format, TexDesc.Width, TexDesc.Height, CacheId.c_str(), pTexInitData);
912917
913918 for (Uint32 i = 0; i < Textures.size(); ++i)
914919 {
915 auto& DstTexInfo = Textures[i];
916
917 ITexture* pTexture = nullptr;
918 TextureInitData* pInitData = nullptr;
920 auto& DstTexInfo = Textures[i];
921 ITexture* pTexture = nullptr;
922
923 RefCntAutoPtr<TextureInitData> pInitData;
919924 if (DstTexInfo.pAtlasSuballocation)
920925 {
921926 pTexture = DstTexInfo.pAtlasSuballocation->GetAtlas()->GetTexture(pDevice, pCtx);
922927 pInitData = ValidatedCast<TextureInitData>(DstTexInfo.pAtlasSuballocation->GetUserData());
928 // User data is only set when the allocation is created, so no other
929 // thread can call SetUserData() in parallel.
930 DstTexInfo.pAtlasSuballocation->SetUserData(nullptr);
923931 }
924932 else if (DstTexInfo.pTexture)
925933 {
926934 pTexture = DstTexInfo.pTexture;
927935 pInitData = ValidatedCast<TextureInitData>(pTexture->GetUserData());
936 // User data is only set when the texture is created, so no other
937 // thread can call SetUserData() in parallel.
938 pTexture->SetUserData(nullptr);
928939 }
929940
930941 if (!pTexture)
932943
933944 if (pInitData == nullptr)
934945 {
935 // Texture data has already been initialized by another model
946 // Shared texture has already been initialized by another model
936947 continue;
937948 }
938949
10001011 // Texture is already initialized
10011012 }
10021013
1003 if (DstTexInfo.pAtlasSuballocation)
1004 {
1005 // User data is only set when the allocation is created, so no other
1006 // threads can call SetUserData().
1007 DstTexInfo.pAtlasSuballocation->SetUserData(nullptr);
1008 }
1009 else if (DstTexInfo.pTexture)
1010 {
1014 if (DstTexInfo.pTexture)
1015 {
1016 // Note that we may need to transition a texture even if it has been fully initialized,
1017 // as is the case with KTX/DDS textures.
10111018 VERIFY_EXPR(pTexture == DstTexInfo.pTexture);
10121019 Barriers.emplace_back(StateTransitionDesc{pTexture, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_SHADER_RESOURCE, true});
1013
1014 // User data is only set when the texture is created, so no other
1015 // threads can call SetUserData().
1016 pTexture->SetUserData(nullptr);
10171020 }
10181021 }
10191022
14351438 Model::TextureCacheType* const pTextureCache;
14361439 ResourceManager* const pResourceMgr;
14371440
1438 std::vector<RefCntAutoPtr<ITexture>> TextureHold;
1439 std::vector<RefCntAutoPtr<ITextureAtlasSuballocation>> TextureAllocationsHold;
1441 std::vector<RefCntAutoPtr<IObject>> TexturesHold;
14401442
14411443 std::string BaseDir;
14421444 };
14751477 gltf_image->pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
14761478
14771479 // Keep strong reference to ensure the allocation is alive (second time, but that's fine).
1478 pLoaderData->TextureAllocationsHold.emplace_back(std::move(pAllocation));
1480 pLoaderData->TexturesHold.emplace_back(std::move(pAllocation));
14791481
14801482 return true;
14811483 }
15011503 gltf_image->pixel_type = TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE;
15021504
15031505 // Keep strong reference to ensure the texture is alive (second time, but that's fine).
1504 pLoaderData->TextureHold.emplace_back(std::move(pTexture));
1506 pLoaderData->TexturesHold.emplace_back(std::move(pTexture));
15051507
15061508 return true;
15071509 }
16431645 if (auto pAllocation = pLoaderData->pResourceMgr->FindAllocation(filepath.c_str()))
16441646 {
16451647 // Keep strong reference to ensure the allocation is alive.
1646 pLoaderData->TextureAllocationsHold.emplace_back(std::move(pAllocation));
1648 pLoaderData->TexturesHold.emplace_back(std::move(pAllocation));
16471649 // Tiny GLTF checks the size of 'out', it can't be empty
16481650 out->resize(1);
16491651 return true;
16591661 if (auto pTexture = it->second.Lock())
16601662 {
16611663 // Keep strong reference to ensure the texture is alive.
1662 pLoaderData->TextureHold.emplace_back(std::move(pTexture));
1664 pLoaderData->TexturesHold.emplace_back(std::move(pTexture));
16631665 // Tiny GLTF checks the size of 'out', it can't be empty
16641666 out->resize(1);
16651667 return true;
17651767 for (size_t i = 0; i < scene.nodes.size(); i++)
17661768 {
17671769 const tinygltf::Node node = gltf_model.nodes[scene.nodes[i]];
1768 LoadNode(pDevice, nullptr, node, scene.nodes[i], gltf_model,
1770 LoadNode(nullptr, node, scene.nodes[i], gltf_model,
17691771 IndexData, VertexBasicData,
17701772 CI.LoadAnimationAndSkin ? &VertexSkinData : nullptr);
17711773 }