summaryrefslogtreecommitdiffstats
path: root/AssetLoader
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2021-03-31 13:53:23 +0000
committers-ol <s+removethis@s-ol.nu>2021-03-31 15:49:39 +0000
commit85909b2a9fc470d0f425fed5962bb8fc5a5fde57 (patch)
tree1f99551d1cace6afe739d0b2f1644ad95cabcd5c /AssetLoader
parentC API for GLTFLoader (diff)
downloadDiligentTools-85909b2a9fc470d0f425fed5962bb8fc5a5fde57.tar.gz
DiligentTools-85909b2a9fc470d0f425fed5962bb8fc5a5fde57.zip
implement loading GLTF files from memory
Diffstat (limited to 'AssetLoader')
-rw-r--r--AssetLoader/include/GLTFLoader.hpp11
-rw-r--r--AssetLoader/interface/GLTFLoader.h27
-rw-r--r--AssetLoader/src/GLTFLoader.cpp90
3 files changed, 119 insertions, 9 deletions
diff --git a/AssetLoader/include/GLTFLoader.hpp b/AssetLoader/include/GLTFLoader.hpp
index 83b9a4d..2b9afaf 100644
--- a/AssetLoader/include/GLTFLoader.hpp
+++ b/AssetLoader/include/GLTFLoader.hpp
@@ -391,6 +391,17 @@ private:
IDeviceContext* pContext,
const IGLTFModelCreateInfo& CI);
+ void LoadFromMemory(IRenderDevice* pDevice,
+ IDeviceContext* pContext,
+ const IGLTFModelCreateInfo& CI);
+
+ void LoadScene(IRenderDevice* pDevice,
+ const tinygltf::Model& gltf_model,
+ const std::string& BaseDir,
+ GLTF_TextureCacheType* pTextureCache,
+ ResourceManager* pResourceMgr,
+ const IGLTFModelCreateInfo& CI);
+
void LoadNode(Node* parent,
const tinygltf::Node& gltf_node,
uint32_t nodeIndex,
diff --git a/AssetLoader/interface/GLTFLoader.h b/AssetLoader/interface/GLTFLoader.h
index 810a7c4..402559e 100644
--- a/AssetLoader/interface/GLTFLoader.h
+++ b/AssetLoader/interface/GLTFLoader.h
@@ -100,12 +100,39 @@ typedef enum GLTF_BUFFER_ID GLTF_BUFFER_ID;
struct GLTF_TextureCacheType;
typedef struct GLTF_TextureCacheType GLTF_TextureCacheType;
+enum GLTF_FILE_TYPE
+{
+ GLTF_FILE_TYPE_UNKNOWN = 0,
+ GLTF_FILE_TYPE_ASCII,
+ GLTF_FILE_TYPE_BINARY,
+};
+typedef enum GLTF_FILE_TYPE GLTF_FILE_TYPE;
+
/// Model create information
struct IGLTFModelCreateInfo
{
/// File name
+
+ /// If FileName is provided, Data member must be null
const char* FileName DEFAULT_INITIALIZER(nullptr);
+ /// In-memory GLTF Data
+
+ /// If Data is provided, FileName member must be null
+ const void* Data DEFAULT_INITIALIZER(nullptr);
+
+ /// In-memory GLTF Data length
+
+ /// Data size (in bytes) must be provided if Data is not null
+ size_t DataSize DEFAULT_INITIALIZER(0);
+
+ /// File type
+
+ /// If GLTF_FILE_TYPE_UNKNOWN and File name is provided, this
+ /// is detected based on the file extension (.gltf / .glb).
+ /// If Data is provided, this must not be GLTF_FILE_TYPE_UNKNOWN.
+ GLTF_FILE_TYPE FileType DEFAULT_INITIALIZER(GLTF_FILE_TYPE_UNKNOWN);
+
/// Optional texture cache to use when loading the model.
/// The loader will try to find all the textures in the cache
/// and add all new textures to the cache.
diff --git a/AssetLoader/src/GLTFLoader.cpp b/AssetLoader/src/GLTFLoader.cpp
index 1c546f7..9fabac2 100644
--- a/AssetLoader/src/GLTFLoader.cpp
+++ b/AssetLoader/src/GLTFLoader.cpp
@@ -250,7 +250,13 @@ Model::Model(IRenderDevice* pDevice,
IDeviceContext* pContext,
const IGLTFModelCreateInfo& CI)
{
- LoadFromFile(pDevice, pContext, CI);
+ if (CI.FileName) {
+ LoadFromFile(pDevice, pContext, CI);
+ } else if (CI.Data) {
+ LoadFromMemory(pDevice, pContext, CI);
+ } else {
+ LOG_ERROR_AND_THROW("Either File Name or Data must be set");
+ }
}
Model::~Model()
@@ -1753,14 +1759,85 @@ void Model::LoadFromFile(IRenderDevice* pDevice,
LOG_WARNING_MESSAGE("Loaded gltf file ", filename, " with the following warning:", warning);
}
- LoadTextureSamplers(pDevice, gltf_model);
- LoadTextures(pDevice, gltf_model, LoaderData.BaseDir, pTextureCache, pResourceMgr);
- LoadMaterials(gltf_model);
+ LoadScene(pDevice, gltf_model, LoaderData.BaseDir, pTextureCache, pResourceMgr, CI);
+
+ if (pContext != nullptr)
+ {
+ PrepareGPUResources(pDevice, pContext);
+ }
+}
+
+void Model::LoadFromMemory(IRenderDevice* pDevice,
+ IDeviceContext* pContext,
+ const IGLTFModelCreateInfo& CI)
+{
+ if (CI.Data == nullptr || CI.DataSize == 0)
+ LOG_ERROR_AND_THROW("Data must not be empty");
+ auto* const pTextureCache = CI.pTextureCache;
+ auto* const pResourceMgr = CI.pCacheInfo != nullptr ? CI.pCacheInfo->pResourceMgr : nullptr;
+ if (CI.pTextureCache != nullptr && pResourceMgr != nullptr)
+ LOG_WARNING_MESSAGE("Texture cache is ignored when resource manager is used");
+
+ Callbacks::ImageLoaderData LoaderData{pTextureCache, pResourceMgr};
+ LoaderData.BaseDir = "";
+
+ tinygltf::TinyGLTF gltf_context;
+ gltf_context.SetImageLoader(Callbacks::LoadImageData, &LoaderData);
+
+ bool binary;
+ switch (CI.FileType) {
+ case GLTF_FILE_TYPE_UNKNOWN:
+ LOG_ERROR_AND_THROW("FileType must not be UNKNOWN when loading from memory");
+ case GLTF_FILE_TYPE_ASCII:
+ binary = false;
+ break;
+ case GLTF_FILE_TYPE_BINARY:
+ binary = true;
+ break;
+ }
+
+ std::string error;
+ std::string warning;
+ tinygltf::Model gltf_model;
+
+ bool modelLoaded = false;
+ if (binary)
+ modelLoaded = gltf_context.LoadBinaryFromMemory(&gltf_model, &error, &warning, (const unsigned char*)CI.Data, CI.DataSize);
+ else
+ modelLoaded = gltf_context.LoadASCIIFromString(&gltf_model, &error, &warning, (const char*)CI.Data, CI.DataSize, "");
+ if (!modelLoaded)
+ {
+ LOG_ERROR_AND_THROW("Failed to load gltf file from memory: ", error);
+ }
+ if (!warning.empty())
+ {
+ LOG_WARNING_MESSAGE("Loaded gltf file from memory with the following warning:", warning);
+ }
+
+ LoadScene(pDevice, gltf_model, "", pTextureCache, pResourceMgr, CI);
+
+ if (pContext != nullptr)
+ {
+ PrepareGPUResources(pDevice, pContext);
+ }
+}
+
+void Model::LoadScene(IRenderDevice* pDevice,
+ const tinygltf::Model& gltf_model,
+ const std::string& BaseDir,
+ GLTF_TextureCacheType* pTextureCache,
+ ResourceManager* pResourceMgr,
+ const IGLTFModelCreateInfo& CI)
+{
std::vector<Uint32> IndexData;
std::vector<VertexBasicAttribs> VertexBasicData;
std::vector<VertexSkinAttribs> VertexSkinData;
+ LoadTextureSamplers(pDevice, gltf_model);
+ LoadTextures(pDevice, gltf_model, BaseDir, pTextureCache, pResourceMgr);
+ LoadMaterials(gltf_model);
+
// TODO: scene handling with no default scene
const tinygltf::Scene& scene = gltf_model.scenes[gltf_model.defaultScene > -1 ? gltf_model.defaultScene : 0];
for (size_t i = 0; i < scene.nodes.size(); i++)
@@ -1854,11 +1931,6 @@ void Model::LoadFromFile(IRenderDevice* pDevice,
CreateBuffer(GLTF_BUFFER_ID_INDEX, IndexData.data(), IndexData.size() * sizeof(IndexData[0]),
BIND_INDEX_BUFFER, "GLTF index buffer");
}
-
- if (pContext != nullptr)
- {
- PrepareGPUResources(pDevice, pContext);
- }
}
void Model::CalculateBoundingBox(Node* node, const Node* parent)