git.s-ol.nu ~forks/DiligentTools / 85909b2
implement loading GLTF files from memory s-ol 3 months ago
3 changed file(s) with 120 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
390390 IDeviceContext* pContext,
391391 const IGLTFModelCreateInfo& CI);
392392
393 void LoadFromMemory(IRenderDevice* pDevice,
394 IDeviceContext* pContext,
395 const IGLTFModelCreateInfo& CI);
396
397 void LoadScene(IRenderDevice* pDevice,
398 const tinygltf::Model& gltf_model,
399 const std::string& BaseDir,
400 GLTF_TextureCacheType* pTextureCache,
401 ResourceManager* pResourceMgr,
402 const IGLTFModelCreateInfo& CI);
403
393404 void LoadNode(Node* parent,
394405 const tinygltf::Node& gltf_node,
395406 uint32_t nodeIndex,
9999 struct GLTF_TextureCacheType;
100100 typedef struct GLTF_TextureCacheType GLTF_TextureCacheType;
101101
102 enum GLTF_FILE_TYPE
103 {
104 GLTF_FILE_TYPE_UNKNOWN = 0,
105 GLTF_FILE_TYPE_ASCII,
106 GLTF_FILE_TYPE_BINARY,
107 };
108 typedef enum GLTF_FILE_TYPE GLTF_FILE_TYPE;
109
102110 /// Model create information
103111 struct IGLTFModelCreateInfo
104112 {
105113 /// File name
114
115 /// If FileName is provided, Data member must be null
106116 const char* FileName DEFAULT_INITIALIZER(nullptr);
117
118 /// In-memory GLTF Data
119
120 /// If Data is provided, FileName member must be null
121 const void* Data DEFAULT_INITIALIZER(nullptr);
122
123 /// In-memory GLTF Data length
124
125 /// Data size (in bytes) must be provided if Data is not null
126 size_t DataSize DEFAULT_INITIALIZER(0);
127
128 /// File type
129
130 /// If GLTF_FILE_TYPE_UNKNOWN and File name is provided, this
131 /// is detected based on the file extension (.gltf / .glb).
132 /// If Data is provided, this must not be GLTF_FILE_TYPE_UNKNOWN.
133 GLTF_FILE_TYPE FileType DEFAULT_INITIALIZER(GLTF_FILE_TYPE_UNKNOWN);
107134
108135 /// Optional texture cache to use when loading the model.
109136 /// The loader will try to find all the textures in the cache
249249 IDeviceContext* pContext,
250250 const IGLTFModelCreateInfo& CI)
251251 {
252 LoadFromFile(pDevice, pContext, CI);
252 if (CI.FileName) {
253 LoadFromFile(pDevice, pContext, CI);
254 } else if (CI.Data) {
255 LoadFromMemory(pDevice, pContext, CI);
256 } else {
257 LOG_ERROR_AND_THROW("Either File Name or Data must be set");
258 }
253259 }
254260
255261 Model::~Model()
17521758 LOG_WARNING_MESSAGE("Loaded gltf file ", filename, " with the following warning:", warning);
17531759 }
17541760
1755 LoadTextureSamplers(pDevice, gltf_model);
1756 LoadTextures(pDevice, gltf_model, LoaderData.BaseDir, pTextureCache, pResourceMgr);
1757 LoadMaterials(gltf_model);
1758
1761 LoadScene(pDevice, gltf_model, LoaderData.BaseDir, pTextureCache, pResourceMgr, CI);
1762
1763 if (pContext != nullptr)
1764 {
1765 PrepareGPUResources(pDevice, pContext);
1766 }
1767 }
1768
1769 void Model::LoadFromMemory(IRenderDevice* pDevice,
1770 IDeviceContext* pContext,
1771 const IGLTFModelCreateInfo& CI)
1772 {
1773 if (CI.Data == nullptr || CI.DataSize == 0)
1774 LOG_ERROR_AND_THROW("Data must not be empty");
1775
1776 auto* const pTextureCache = CI.pTextureCache;
1777 auto* const pResourceMgr = CI.pCacheInfo != nullptr ? CI.pCacheInfo->pResourceMgr : nullptr;
1778 if (CI.pTextureCache != nullptr && pResourceMgr != nullptr)
1779 LOG_WARNING_MESSAGE("Texture cache is ignored when resource manager is used");
1780
1781 Callbacks::ImageLoaderData LoaderData{pTextureCache, pResourceMgr};
1782 LoaderData.BaseDir = "";
1783
1784 tinygltf::TinyGLTF gltf_context;
1785 gltf_context.SetImageLoader(Callbacks::LoadImageData, &LoaderData);
1786
1787 bool binary;
1788 switch (CI.FileType) {
1789 case GLTF_FILE_TYPE_UNKNOWN:
1790 LOG_ERROR_AND_THROW("FileType must not be UNKNOWN when loading from memory");
1791 case GLTF_FILE_TYPE_ASCII:
1792 binary = false;
1793 break;
1794 case GLTF_FILE_TYPE_BINARY:
1795 binary = true;
1796 break;
1797 }
1798
1799 std::string error;
1800 std::string warning;
1801 tinygltf::Model gltf_model;
1802
1803 bool modelLoaded = false;
1804 if (binary)
1805 modelLoaded = gltf_context.LoadBinaryFromMemory(&gltf_model, &error, &warning, (const unsigned char*)CI.Data, CI.DataSize);
1806 else
1807 modelLoaded = gltf_context.LoadASCIIFromString(&gltf_model, &error, &warning, (const char*)CI.Data, CI.DataSize, "");
1808 if (!modelLoaded)
1809 {
1810 LOG_ERROR_AND_THROW("Failed to load gltf file from memory: ", error);
1811 }
1812 if (!warning.empty())
1813 {
1814 LOG_WARNING_MESSAGE("Loaded gltf file from memory with the following warning:", warning);
1815 }
1816
1817 LoadScene(pDevice, gltf_model, "", pTextureCache, pResourceMgr, CI);
1818
1819 if (pContext != nullptr)
1820 {
1821 PrepareGPUResources(pDevice, pContext);
1822 }
1823 }
1824
1825 void Model::LoadScene(IRenderDevice* pDevice,
1826 const tinygltf::Model& gltf_model,
1827 const std::string& BaseDir,
1828 GLTF_TextureCacheType* pTextureCache,
1829 ResourceManager* pResourceMgr,
1830 const IGLTFModelCreateInfo& CI)
1831 {
17591832 std::vector<Uint32> IndexData;
17601833 std::vector<VertexBasicAttribs> VertexBasicData;
17611834 std::vector<VertexSkinAttribs> VertexSkinData;
1835
1836 LoadTextureSamplers(pDevice, gltf_model);
1837 LoadTextures(pDevice, gltf_model, BaseDir, pTextureCache, pResourceMgr);
1838 LoadMaterials(gltf_model);
17621839
17631840 // TODO: scene handling with no default scene
17641841 const tinygltf::Scene& scene = gltf_model.scenes[gltf_model.defaultScene > -1 ? gltf_model.defaultScene : 0];
18531930 CreateBuffer(GLTF_BUFFER_ID_INDEX, IndexData.data(), IndexData.size() * sizeof(IndexData[0]),
18541931 BIND_INDEX_BUFFER, "GLTF index buffer");
18551932 }
1856
1857 if (pContext != nullptr)
1858 {
1859 PrepareGPUResources(pDevice, pContext);
1860 }
18611933 }
18621934
18631935 void Model::CalculateBoundingBox(Node* node, const Node* parent)