Graphics/RenderSystem: Handle visibility immediatly
This fixes an issue when rendermask/scissor box is updated right after making an entity visible (e.g. widgets)
This commit is contained in:
parent
fff4029047
commit
4f3542356d
|
|
@ -52,6 +52,9 @@ namespace Nz
|
|||
RenderSystem& operator=(RenderSystem&&) = delete;
|
||||
|
||||
private:
|
||||
struct GraphicsEntity;
|
||||
struct LightEntity;
|
||||
|
||||
void OnCameraDestroy(entt::registry& registry, entt::entity entity);
|
||||
void OnDisabledConstructed(entt::registry& registry, entt::entity entity);
|
||||
void OnGraphicsDestroy(entt::registry& registry, entt::entity entity);
|
||||
|
|
@ -59,9 +62,10 @@ namespace Nz
|
|||
void OnNodeDestroy(entt::registry& registry, entt::entity entity);
|
||||
void OnSharedSkeletonDestroy(entt::registry& registry, entt::entity entity);
|
||||
void OnSkeletonDestroy(entt::registry& registry, entt::entity entity);
|
||||
void UpdateGraphicsVisibility(GraphicsEntity* gfxData, GraphicsComponent& gfxComponent, bool isVisible);
|
||||
void UpdateLightVisibility(LightEntity* gfxData, LightComponent& lightComponent, bool isVisible);
|
||||
void UpdateInstances();
|
||||
void UpdateObservers();
|
||||
void UpdateVisibility();
|
||||
|
||||
static constexpr std::size_t NoInstance = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
|
|
@ -132,10 +136,6 @@ namespace Nz
|
|||
std::unordered_map<entt::entity, GraphicsEntity*> m_graphicsEntities;
|
||||
std::unordered_map<entt::entity, LightEntity*> m_lightEntities;
|
||||
std::unordered_map<Skeleton*, SharedSkeleton> m_sharedSkeletonInstances;
|
||||
std::unordered_set<GraphicsEntity*> m_newlyHiddenGfxEntities;
|
||||
std::unordered_set<GraphicsEntity*> m_newlyVisibleGfxEntities;
|
||||
std::unordered_set<LightEntity*> m_newlyHiddenLightEntities;
|
||||
std::unordered_set<LightEntity*> m_newlyVisibleLightEntities;
|
||||
std::vector<std::unique_ptr<WindowSwapchain>> m_windowSwapchains;
|
||||
ElementRendererRegistry m_elementRegistry;
|
||||
MemoryPool<CameraEntity> m_cameraEntityPool;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ namespace Nz
|
|||
void RenderSystem::Update(Time /*elapsedTime*/)
|
||||
{
|
||||
UpdateObservers();
|
||||
UpdateVisibility();
|
||||
UpdateInstances();
|
||||
|
||||
for (auto& windowPtr : m_windowSwapchains)
|
||||
|
|
@ -109,8 +108,6 @@ namespace Nz
|
|||
|
||||
m_graphicsEntities.erase(entity);
|
||||
m_invalidatedGfxWorldNode.erase(graphicsEntity);
|
||||
m_newlyHiddenGfxEntities.erase(graphicsEntity);
|
||||
m_newlyVisibleGfxEntities.erase(graphicsEntity);
|
||||
|
||||
GraphicsComponent& entityGfx = m_registry.get<GraphicsComponent>(entity);
|
||||
if (entityGfx.IsVisible())
|
||||
|
|
@ -142,8 +139,6 @@ namespace Nz
|
|||
|
||||
m_lightEntities.erase(entity);
|
||||
m_invalidatedLightWorldNode.erase(lightEntity);
|
||||
m_newlyHiddenLightEntities.erase(lightEntity);
|
||||
m_newlyVisibleLightEntities.erase(lightEntity);
|
||||
|
||||
LightComponent& entityLight = m_registry.get<LightComponent>(entity);
|
||||
if (entityLight.IsVisible())
|
||||
|
|
@ -221,6 +216,58 @@ namespace Nz
|
|||
graphicsEntity->skeletonInstanceIndex = NoInstance;
|
||||
}
|
||||
|
||||
void RenderSystem::UpdateGraphicsVisibility(GraphicsEntity* gfxData, GraphicsComponent& gfxComponent, bool isVisible)
|
||||
{
|
||||
if (isVisible)
|
||||
{
|
||||
for (std::size_t renderableIndex = 0; renderableIndex < GraphicsComponent::MaxRenderableCount; ++renderableIndex)
|
||||
{
|
||||
const auto& renderableEntry = gfxComponent.GetRenderableEntry(renderableIndex);
|
||||
if (!renderableEntry.renderable)
|
||||
continue;
|
||||
|
||||
gfxData->renderableIndices[renderableIndex] = m_pipeline->RegisterRenderable(gfxData->worldInstanceIndex, gfxData->skeletonInstanceIndex, renderableEntry.renderable.get(), renderableEntry.renderMask, gfxComponent.GetScissorBox());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::size_t renderableIndex = 0; renderableIndex < GraphicsComponent::MaxRenderableCount; ++renderableIndex)
|
||||
{
|
||||
const auto& renderableEntry = gfxComponent.GetRenderableEntry(renderableIndex);
|
||||
if (!renderableEntry.renderable)
|
||||
continue;
|
||||
|
||||
m_pipeline->UnregisterRenderable(gfxData->renderableIndices[renderableIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderSystem::UpdateLightVisibility(LightEntity* gfxData, LightComponent& lightComponent, bool isVisible)
|
||||
{
|
||||
if (isVisible)
|
||||
{
|
||||
for (std::size_t renderableIndex = 0; renderableIndex < LightComponent::MaxLightCount; ++renderableIndex)
|
||||
{
|
||||
const auto& lightEntry = lightComponent.GetLightEntry(renderableIndex);
|
||||
if (!lightEntry.light)
|
||||
continue;
|
||||
|
||||
gfxData->lightIndices[renderableIndex] = m_pipeline->RegisterLight(lightEntry.light.get(), lightEntry.renderMask);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (std::size_t lightIndex = 0; lightIndex < LightComponent::MaxLightCount; ++lightIndex)
|
||||
{
|
||||
const auto& lightEntry = lightComponent.GetLightEntry(lightIndex);
|
||||
if (!lightEntry.light)
|
||||
continue;
|
||||
|
||||
m_pipeline->UnregisterLight(gfxData->lightIndices[lightIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderSystem::UpdateInstances()
|
||||
{
|
||||
for (CameraEntity* cameraEntity : m_invalidatedCameraNode)
|
||||
|
|
@ -344,23 +391,14 @@ namespace Nz
|
|||
}
|
||||
});
|
||||
|
||||
graphicsEntity->onVisibilityUpdate.Connect(entityGfx.OnVisibilityUpdate, [this, graphicsEntity](GraphicsComponent* /*gfx*/, bool isVisible)
|
||||
graphicsEntity->onVisibilityUpdate.Connect(entityGfx.OnVisibilityUpdate, [this, graphicsEntity](GraphicsComponent* gfx, bool isVisible)
|
||||
{
|
||||
if (isVisible)
|
||||
{
|
||||
m_newlyHiddenGfxEntities.erase(graphicsEntity);
|
||||
m_newlyVisibleGfxEntities.insert(graphicsEntity);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_newlyHiddenGfxEntities.insert(graphicsEntity);
|
||||
m_newlyVisibleGfxEntities.erase(graphicsEntity);
|
||||
}
|
||||
UpdateGraphicsVisibility(graphicsEntity, *gfx, isVisible);
|
||||
});
|
||||
m_invalidatedGfxWorldNode.insert(graphicsEntity);
|
||||
|
||||
if (entityGfx.IsVisible())
|
||||
m_newlyVisibleGfxEntities.insert(graphicsEntity);
|
||||
UpdateGraphicsVisibility(graphicsEntity, m_registry.get<GraphicsComponent>(entity), true);
|
||||
|
||||
assert(m_graphicsEntities.find(entity) == m_graphicsEntities.end());
|
||||
m_graphicsEntities.emplace(entity, graphicsEntity);
|
||||
|
|
@ -402,33 +440,15 @@ namespace Nz
|
|||
m_pipeline->UnregisterLight(lightEntity->lightIndices[lightIndex]);
|
||||
});
|
||||
|
||||
lightEntity->onVisibilityUpdate.Connect(entityLight.OnVisibilityUpdate, [this, lightEntity](LightComponent* /*light*/, bool isVisible)
|
||||
lightEntity->onVisibilityUpdate.Connect(entityLight.OnVisibilityUpdate, [this, lightEntity](LightComponent* light, bool isVisible)
|
||||
{
|
||||
if (isVisible)
|
||||
{
|
||||
m_newlyHiddenLightEntities.erase(lightEntity);
|
||||
m_newlyVisibleLightEntities.insert(lightEntity);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_newlyHiddenLightEntities.insert(lightEntity);
|
||||
m_newlyVisibleLightEntities.erase(lightEntity);
|
||||
}
|
||||
UpdateLightVisibility(lightEntity, *light, isVisible);
|
||||
});
|
||||
|
||||
m_invalidatedLightWorldNode.insert(lightEntity);
|
||||
|
||||
if (entityLight.IsVisible())
|
||||
{
|
||||
for (std::size_t lightIndex = 0; lightIndex < LightComponent::MaxLightCount; ++lightIndex)
|
||||
{
|
||||
const auto& lightEntry = entityLight.GetLightEntry(lightIndex);
|
||||
if (!lightEntry.light)
|
||||
continue;
|
||||
|
||||
lightEntity->lightIndices[lightIndex] = m_pipeline->RegisterLight(lightEntry.light.get(), lightEntry.renderMask);
|
||||
}
|
||||
}
|
||||
UpdateLightVisibility(lightEntity, m_registry.get<LightComponent>(entity), true);
|
||||
|
||||
assert(m_lightEntities.find(entity) == m_lightEntities.end());
|
||||
m_lightEntities.emplace(entity, lightEntity);
|
||||
|
|
@ -466,73 +486,4 @@ namespace Nz
|
|||
graphicsEntity->skeletonInstanceIndex = m_pipeline->RegisterSkeleton(std::make_shared<SkeletonInstance>(skeleton));
|
||||
});
|
||||
}
|
||||
|
||||
void RenderSystem::UpdateVisibility()
|
||||
{
|
||||
// Unregister drawable for hidden entities
|
||||
for (GraphicsEntity* graphicsEntity : m_newlyHiddenGfxEntities)
|
||||
{
|
||||
GraphicsComponent& entityGfx = m_registry.get<GraphicsComponent>(graphicsEntity->entity);
|
||||
|
||||
for (std::size_t renderableIndex = 0; renderableIndex < GraphicsComponent::MaxRenderableCount; ++renderableIndex)
|
||||
{
|
||||
const auto& renderableEntry = entityGfx.GetRenderableEntry(renderableIndex);
|
||||
if (!renderableEntry.renderable)
|
||||
continue;
|
||||
|
||||
m_pipeline->UnregisterRenderable(graphicsEntity->renderableIndices[renderableIndex]);
|
||||
}
|
||||
}
|
||||
m_newlyHiddenGfxEntities.clear();
|
||||
|
||||
// Register drawable for newly visible entities
|
||||
for (GraphicsEntity* graphicsEntity : m_newlyVisibleGfxEntities)
|
||||
{
|
||||
GraphicsComponent& entityGfx = m_registry.get<GraphicsComponent>(graphicsEntity->entity);
|
||||
|
||||
for (std::size_t renderableIndex = 0; renderableIndex < GraphicsComponent::MaxRenderableCount; ++renderableIndex)
|
||||
{
|
||||
const auto& renderableEntry = entityGfx.GetRenderableEntry(renderableIndex);
|
||||
if (!renderableEntry.renderable)
|
||||
continue;
|
||||
|
||||
graphicsEntity->renderableIndices[renderableIndex] = m_pipeline->RegisterRenderable(graphicsEntity->worldInstanceIndex, graphicsEntity->skeletonInstanceIndex, renderableEntry.renderable.get(), renderableEntry.renderMask, entityGfx.GetScissorBox());
|
||||
}
|
||||
}
|
||||
m_newlyVisibleGfxEntities.clear();
|
||||
|
||||
// Unregister lights for hidden entities
|
||||
for (LightEntity* lightEntity : m_newlyHiddenLightEntities)
|
||||
{
|
||||
LightComponent& entityLights = m_registry.get<LightComponent>(lightEntity->entity);
|
||||
|
||||
for (std::size_t lightIndex = 0; lightIndex < LightComponent::MaxLightCount; ++lightIndex)
|
||||
{
|
||||
const auto& lightEntry = entityLights.GetLightEntry(lightIndex);
|
||||
if (!lightEntry.light)
|
||||
continue;
|
||||
|
||||
m_pipeline->UnregisterLight(lightEntity->lightIndices[lightIndex]);
|
||||
}
|
||||
}
|
||||
m_newlyHiddenLightEntities.clear();
|
||||
|
||||
// Register lights for newly visible entities
|
||||
for (LightEntity* lightEntity : m_newlyVisibleLightEntities)
|
||||
{
|
||||
LightComponent& entityLights = m_registry.get<LightComponent>(lightEntity->entity);
|
||||
|
||||
for (std::size_t renderableIndex = 0; renderableIndex < LightComponent::MaxLightCount; ++renderableIndex)
|
||||
{
|
||||
const auto& lightEntry = entityLights.GetLightEntry(renderableIndex);
|
||||
if (!lightEntry.light)
|
||||
continue;
|
||||
|
||||
lightEntity->lightIndices[renderableIndex] = m_pipeline->RegisterLight(lightEntry.light.get(), lightEntry.renderMask);
|
||||
}
|
||||
}
|
||||
m_newlyVisibleLightEntities.clear();
|
||||
|
||||
//FIXME: Handle light visibility
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue