Graphics: Fix WorldInstance removal while being in use
This commit is contained in:
@@ -41,8 +41,10 @@ namespace Nz
|
||||
m_invalidatedWorldInstances.insert(worldInstance);
|
||||
}
|
||||
|
||||
void ForwardFramePipeline::RegisterInstancedDrawable(WorldInstance* worldInstance, const InstancedRenderable* instancedRenderable)
|
||||
void ForwardFramePipeline::RegisterInstancedDrawable(WorldInstancePtr worldInstance, const InstancedRenderable* instancedRenderable)
|
||||
{
|
||||
m_removedWorldInstances.erase(worldInstance);
|
||||
|
||||
auto& renderableMap = m_renderables[worldInstance];
|
||||
if (auto it = renderableMap.find(instancedRenderable); it == renderableMap.end())
|
||||
{
|
||||
@@ -99,6 +101,9 @@ namespace Nz
|
||||
{
|
||||
Graphics* graphics = Graphics::Instance();
|
||||
|
||||
renderFrame.PushForRelease(std::move(m_removedWorldInstances));
|
||||
m_removedWorldInstances.clear();
|
||||
|
||||
if (m_rebuildFrameGraph)
|
||||
{
|
||||
renderFrame.PushForRelease(std::move(m_bakedFrameGraph));
|
||||
@@ -252,7 +257,7 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
void ForwardFramePipeline::UnregisterInstancedDrawable(WorldInstance* worldInstance, const InstancedRenderable* instancedRenderable)
|
||||
void ForwardFramePipeline::UnregisterInstancedDrawable(const WorldInstancePtr& worldInstance, const InstancedRenderable* instancedRenderable)
|
||||
{
|
||||
auto instanceIt = m_renderables.find(worldInstance);
|
||||
if (instanceIt == m_renderables.end())
|
||||
@@ -267,7 +272,10 @@ namespace Nz
|
||||
if (instancedRenderables.size() > 1)
|
||||
instancedRenderables.erase(renderableIt);
|
||||
else
|
||||
m_renderables.erase(worldInstance);
|
||||
{
|
||||
m_removedWorldInstances.insert(worldInstance);
|
||||
m_renderables.erase(instanceIt);;
|
||||
}
|
||||
|
||||
std::size_t matCount = instancedRenderable->GetMaterialCount();
|
||||
for (std::size_t i = 0; i < matCount; ++i)
|
||||
|
||||
@@ -60,9 +60,9 @@ namespace Nz
|
||||
GraphicsComponent& entityGfx = registry.get<GraphicsComponent>(entity);
|
||||
NodeComponent& entityNode = registry.get<NodeComponent>(entity);
|
||||
|
||||
WorldInstance& worldInstance = entityGfx.GetWorldInstance();
|
||||
const WorldInstancePtr& worldInstance = entityGfx.GetWorldInstance();
|
||||
for (const auto& renderable : entityGfx.GetRenderables())
|
||||
m_pipeline->RegisterInstancedDrawable(&worldInstance, renderable.get());
|
||||
m_pipeline->RegisterInstancedDrawable(worldInstance, renderable.get());
|
||||
|
||||
m_invalidatedWorldNode.insert(entity);
|
||||
|
||||
@@ -75,14 +75,14 @@ namespace Nz
|
||||
|
||||
graphicsEntity.onRenderableAttached.Connect(entityGfx.OnRenderableAttached, [this](GraphicsComponent* gfx, const std::shared_ptr<InstancedRenderable>& renderable)
|
||||
{
|
||||
WorldInstance& worldInstance = gfx->GetWorldInstance();
|
||||
m_pipeline->RegisterInstancedDrawable(&worldInstance, renderable.get());
|
||||
const WorldInstancePtr& worldInstance = gfx->GetWorldInstance();
|
||||
m_pipeline->RegisterInstancedDrawable(worldInstance, renderable.get());
|
||||
});
|
||||
|
||||
graphicsEntity.onRenderableDetach.Connect(entityGfx.OnRenderableDetach, [this](GraphicsComponent* gfx, const std::shared_ptr<InstancedRenderable>& renderable)
|
||||
{
|
||||
WorldInstance& worldInstance = gfx->GetWorldInstance();
|
||||
m_pipeline->UnregisterInstancedDrawable(&worldInstance, renderable.get());
|
||||
const WorldInstancePtr& worldInstance = gfx->GetWorldInstance();
|
||||
m_pipeline->UnregisterInstancedDrawable(worldInstance, renderable.get());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -106,9 +106,9 @@ namespace Nz
|
||||
m_invalidatedWorldNode.erase(entity);
|
||||
|
||||
GraphicsComponent& entityGfx = registry.get<GraphicsComponent>(entity);
|
||||
WorldInstance& worldInstance = entityGfx.GetWorldInstance();
|
||||
const WorldInstancePtr& worldInstance = entityGfx.GetWorldInstance();
|
||||
for (const auto& renderable : entityGfx.GetRenderables())
|
||||
m_pipeline->UnregisterInstancedDrawable(&worldInstance, renderable.get());
|
||||
m_pipeline->UnregisterInstancedDrawable(worldInstance, renderable.get());
|
||||
}
|
||||
|
||||
void RenderSystem::OnNodeDestroy(entt::registry& registry, entt::entity entity)
|
||||
@@ -139,10 +139,10 @@ namespace Nz
|
||||
const NodeComponent& entityNode = registry.get<const NodeComponent>(entity);
|
||||
GraphicsComponent& entityGraphics = registry.get<GraphicsComponent>(entity);
|
||||
|
||||
WorldInstance& worldInstance = entityGraphics.GetWorldInstance();
|
||||
worldInstance.UpdateWorldMatrix(entityNode.GetTransformMatrix());
|
||||
const WorldInstancePtr& worldInstance = entityGraphics.GetWorldInstance();
|
||||
worldInstance->UpdateWorldMatrix(entityNode.GetTransformMatrix());
|
||||
|
||||
m_pipeline->InvalidateWorldInstance(&worldInstance);
|
||||
m_pipeline->InvalidateWorldInstance(worldInstance.get());
|
||||
}
|
||||
m_invalidatedWorldNode.clear();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Nz
|
||||
m_worldMatrix(Nz::Matrix4f::Identity()),
|
||||
m_dataInvalided(true)
|
||||
{
|
||||
Nz::PredefinedInstanceData instanceUboOffsets = Nz::PredefinedInstanceData::GetOffsets();
|
||||
PredefinedInstanceData instanceUboOffsets = PredefinedInstanceData::GetOffsets();
|
||||
|
||||
m_instanceDataBuffer = Graphics::Instance()->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform);
|
||||
if (!m_instanceDataBuffer->Initialize(instanceUboOffsets.totalSize, Nz::BufferUsage::DeviceLocal | Nz::BufferUsage::Dynamic))
|
||||
@@ -39,11 +39,11 @@ namespace Nz
|
||||
{
|
||||
if (m_dataInvalided)
|
||||
{
|
||||
Nz::PredefinedInstanceData instanceUboOffsets = Nz::PredefinedInstanceData::GetOffsets();
|
||||
PredefinedInstanceData instanceUboOffsets = PredefinedInstanceData::GetOffsets();
|
||||
|
||||
auto& allocation = uploadPool.Allocate(m_instanceDataBuffer->GetSize());
|
||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, instanceUboOffsets.worldMatrixOffset) = m_worldMatrix;
|
||||
Nz::AccessByOffset<Nz::Matrix4f&>(allocation.mappedPtr, instanceUboOffsets.invWorldMatrixOffset) = m_invWorldMatrix;
|
||||
AccessByOffset<Matrix4f&>(allocation.mappedPtr, instanceUboOffsets.worldMatrixOffset) = m_worldMatrix;
|
||||
AccessByOffset<Matrix4f&>(allocation.mappedPtr, instanceUboOffsets.invWorldMatrixOffset) = m_invWorldMatrix;
|
||||
|
||||
builder.CopyBuffer(allocation, m_instanceDataBuffer.get());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user