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
|
||||
_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
|
||||
if (_deviceManager->supportsRayQuery() && _deviceManager->supportsAccelerationStructure())
|
||||
@@ -342,6 +342,7 @@ void VulkanEngine::init_default_data()
|
||||
}
|
||||
|
||||
addGLTFInstance("mirage", "mirage2000/scene.gltf", glm::mat4(1.0f));
|
||||
preloadInstanceTextures("mirage");
|
||||
|
||||
_mainDeletionQueue.push_function([&]() {
|
||||
_resourceManager->destroy_image(_whiteImage);
|
||||
@@ -391,6 +392,36 @@ uint32_t VulkanEngine::loadGLTFAsync(const std::string &sceneName,
|
||||
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()
|
||||
{
|
||||
if (_asyncLoader)
|
||||
|
||||
@@ -210,6 +210,10 @@ public:
|
||||
const std::string &modelRelativePath,
|
||||
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 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 M = T * R * S;
|
||||
eng->loadGLTFAsync(gltfName, gltfPath, M);
|
||||
eng->preloadInstanceTextures(gltfName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -518,6 +518,16 @@ bool SceneManager::removeGLTFInstance(const std::string &name)
|
||||
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)
|
||||
{
|
||||
auto it = dynamicGLTFInstances.find(name);
|
||||
|
||||
@@ -177,6 +177,9 @@ public:
|
||||
|
||||
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:
|
||||
EngineContext *_context = nullptr;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user