ADD: async glTF texture preloading
This commit is contained in:
@@ -206,7 +206,7 @@ void VulkanEngine::init()
|
|||||||
|
|
||||||
// Async asset loader for background glTF + texture jobs
|
// Async asset loader for background glTF + texture jobs
|
||||||
_asyncLoader = std::make_unique<AsyncAssetLoader>();
|
_asyncLoader = std::make_unique<AsyncAssetLoader>();
|
||||||
_asyncLoader->init(this, _assetManager.get(), _textureCache.get(), 1);
|
_asyncLoader->init(this, _assetManager.get(), _textureCache.get(), 4);
|
||||||
|
|
||||||
// Optional ray tracing manager if supported and extensions enabled
|
// Optional ray tracing manager if supported and extensions enabled
|
||||||
if (_deviceManager->supportsRayQuery() && _deviceManager->supportsAccelerationStructure())
|
if (_deviceManager->supportsRayQuery() && _deviceManager->supportsAccelerationStructure())
|
||||||
@@ -342,6 +342,7 @@ void VulkanEngine::init_default_data()
|
|||||||
}
|
}
|
||||||
|
|
||||||
addGLTFInstance("mirage", "mirage2000/scene.gltf", glm::mat4(1.0f));
|
addGLTFInstance("mirage", "mirage2000/scene.gltf", glm::mat4(1.0f));
|
||||||
|
preloadInstanceTextures("mirage");
|
||||||
|
|
||||||
_mainDeletionQueue.push_function([&]() {
|
_mainDeletionQueue.push_function([&]() {
|
||||||
_resourceManager->destroy_image(_whiteImage);
|
_resourceManager->destroy_image(_whiteImage);
|
||||||
@@ -391,6 +392,36 @@ uint32_t VulkanEngine::loadGLTFAsync(const std::string &sceneName,
|
|||||||
return _asyncLoader->load_gltf_async(sceneName, modelRelativePath, transform);
|
return _asyncLoader->load_gltf_async(sceneName, modelRelativePath, transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanEngine::preloadInstanceTextures(const std::string &instanceName)
|
||||||
|
{
|
||||||
|
if (!_textureCache || !_sceneManager)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto gltfScene = _sceneManager->getGLTFInstanceScene(instanceName);
|
||||||
|
if (!gltfScene)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t frame = static_cast<uint32_t>(_frameNumber);
|
||||||
|
uint32_t count = 0;
|
||||||
|
|
||||||
|
// Mark all materials in this glTF scene as used so TextureCache will
|
||||||
|
// schedule their textures for upload before the object is visible.
|
||||||
|
for (const auto &[name, material] : gltfScene->materials)
|
||||||
|
{
|
||||||
|
if (material && material->data.materialSet)
|
||||||
|
{
|
||||||
|
_textureCache->markSetUsed(material->data.materialSet, frame);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt::println("[Engine] Preloaded {} material sets for instance '{}'", count, instanceName);
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanEngine::cleanup()
|
void VulkanEngine::cleanup()
|
||||||
{
|
{
|
||||||
if (_asyncLoader)
|
if (_asyncLoader)
|
||||||
|
|||||||
@@ -210,6 +210,10 @@ public:
|
|||||||
const std::string &modelRelativePath,
|
const std::string &modelRelativePath,
|
||||||
const glm::mat4 &transform = glm::mat4(1.f));
|
const glm::mat4 &transform = glm::mat4(1.f));
|
||||||
|
|
||||||
|
// Preload textures for an already-loaded scene instance so they are
|
||||||
|
// available before the object becomes visible (visibility-driven loading).
|
||||||
|
void preloadInstanceTextures(const std::string &instanceName);
|
||||||
|
|
||||||
bool resize_requested{false};
|
bool resize_requested{false};
|
||||||
bool freeze_rendering{false};
|
bool freeze_rendering{false};
|
||||||
|
|
||||||
|
|||||||
@@ -467,6 +467,7 @@ namespace
|
|||||||
glm::mat4 S = glm::scale(glm::mat4(1.0f), glm::vec3(gltfScale[0], gltfScale[1], gltfScale[2]));
|
glm::mat4 S = glm::scale(glm::mat4(1.0f), glm::vec3(gltfScale[0], gltfScale[1], gltfScale[2]));
|
||||||
glm::mat4 M = T * R * S;
|
glm::mat4 M = T * R * S;
|
||||||
eng->loadGLTFAsync(gltfName, gltfPath, M);
|
eng->loadGLTFAsync(gltfName, gltfPath, M);
|
||||||
|
eng->preloadInstanceTextures(gltfName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -518,6 +518,16 @@ bool SceneManager::removeGLTFInstance(const std::string &name)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<LoadedGLTF> SceneManager::getGLTFInstanceScene(const std::string &instanceName) const
|
||||||
|
{
|
||||||
|
auto it = dynamicGLTFInstances.find(instanceName);
|
||||||
|
if (it != dynamicGLTFInstances.end())
|
||||||
|
{
|
||||||
|
return it->second.scene;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool SceneManager::getGLTFInstanceTransform(const std::string &name, glm::mat4 &outTransform)
|
bool SceneManager::getGLTFInstanceTransform(const std::string &name, glm::mat4 &outTransform)
|
||||||
{
|
{
|
||||||
auto it = dynamicGLTFInstances.find(name);
|
auto it = dynamicGLTFInstances.find(name);
|
||||||
|
|||||||
@@ -177,6 +177,9 @@ public:
|
|||||||
|
|
||||||
const PickingDebug &getPickingDebug() const { return pickingDebug; }
|
const PickingDebug &getPickingDebug() const { return pickingDebug; }
|
||||||
|
|
||||||
|
// Returns the LoadedGLTF scene for a named GLTF instance, or nullptr if not found.
|
||||||
|
std::shared_ptr<LoadedGLTF> getGLTFInstanceScene(const std::string &instanceName) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EngineContext *_context = nullptr;
|
EngineContext *_context = nullptr;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user