Fixed deletion crash caused by Renderables

This commit is contained in:
Kah Wei 2022-10-25 14:31:28 +08:00
parent 23b8b66297
commit c2e51dc603
5 changed files with 67 additions and 41 deletions

View File

@ -59,7 +59,7 @@ namespace SHADE
} }
// Add renderable in // Add renderable in
subBatch->Renderables.insert(renderable); subBatch->Renderables.insert(renderable->GetEID());
// Also add material instance in // Also add material instance in
referencedMatInstances.insert(renderable->GetMaterial()); referencedMatInstances.insert(renderable->GetMaterial());
@ -80,27 +80,34 @@ namespace SHADE
if (subBatch == subBatches.end()) if (subBatch == subBatches.end())
return; return;
subBatch->Renderables.erase(renderable); subBatch->Renderables.erase(renderable->GetEID());
// Check if other renderables in subBatches contain the same material instance // Check if other renderables in subBatches contain the same material instance
bool matUnused = true; bool matUnused = true;
for (const auto& sb : subBatches) for (const auto& sb : subBatches)
for (const auto& rend : sb.Renderables) for (const auto& rendId : sb.Renderables)
{ {
if (rend->GetMaterial() == renderable->GetMaterial()) auto rend = SHComponentManager::GetComponent<SHRenderable>(rendId);
if (rend)
{ {
matUnused = false; if (rend->GetMaterial() == renderable->GetMaterial())
break; {
matUnused = false;
break;
}
}
else
{
SHLOG_WARNING("[SHBatch] Entity with a missing SHRenderable found!");
} }
} }
// Material is no longer in this library, so we remove it // Material is no longer in this library, so we remove it
if (matUnused) if (matUnused)
referencedMatInstances.erase(renderable->GetMaterial()); referencedMatInstances.erase(renderable->WasMaterialChanged() ? renderable->GetPrevMaterial() : renderable->GetMaterial());
// Mark all as dirty // Mark all as dirty
for (bool& dirt : isDirty) setAllDirtyFlags();
dirt = true;
} }
void SHBatch::Clear() void SHBatch::Clear()
@ -162,9 +169,17 @@ namespace SHADE
// Build CPU Buffer // Build CPU Buffer
char* propsCurrPtr = matPropsData.get(); char* propsCurrPtr = matPropsData.get();
for (auto& subBatch : subBatches) for (auto& subBatch : subBatches)
for (const SHRenderable* renderable : subBatch.Renderables) for (auto rendId : subBatch.Renderables)
{ {
renderable->GetMaterial()->ExportProperties(propsCurrPtr); const SHRenderable* renderable = SHComponentManager::GetComponent<SHRenderable>(rendId);
if (renderable)
{
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
}
else
{
SHLOG_WARNING("[SHBatch] Entity with a missing SHRenderable found!");
}
propsCurrPtr += singleMatPropAlignedSize; propsCurrPtr += singleMatPropAlignedSize;
} }
@ -188,18 +203,18 @@ namespace SHADE
// Populate on the CPU // Populate on the CPU
for (auto& subBatch : subBatches) for (auto& subBatch : subBatches)
for (const SHRenderable* renderable : subBatch.Renderables) for (auto rendId : subBatch.Renderables)
{ {
// Transform // Transform
auto transform = SHComponentManager::GetComponent<SHTransformComponent>(renderable->GetEID()); auto transform = SHComponentManager::GetComponent<SHTransformComponent>(rendId);
if (!transform) if (transform)
{ {
SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); transformData.emplace_back(transform->GetTRS());
transformData.emplace_back();
} }
else else
{ {
transformData.emplace_back(transform->GetTRS()); SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!");
transformData.emplace_back();
} }
} }
@ -221,10 +236,10 @@ namespace SHADE
// Populate on the CPU // Populate on the CPU
for (auto& subBatch : subBatches) for (auto& subBatch : subBatches)
for (const SHRenderable* renderable : subBatch.Renderables) for (auto rendId : subBatch.Renderables)
{ {
eidData.emplace_back(renderable->GetEID()); eidData.emplace_back(rendId);
} }
// Transfer to GPU // Transfer to GPU
if (eidBuffer[frameIndex]) if (eidBuffer[frameIndex])
@ -305,11 +320,10 @@ namespace SHADE
}); });
// Fill in buffers (CPU) // Fill in buffers (CPU)
for (const SHRenderable* renderable : subBatch.Renderables) for (auto rendId : subBatch.Renderables)
{ {
// Transform // Transform
EntityID eid = renderable->GetEID(); auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(rendId);
auto transform = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
if (!transform) if (!transform)
{ {
SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!"); SHLOG_WARNING("[SHBatch] Entity contianing a SHRenderable with no SHTransformComponent found!");
@ -320,12 +334,20 @@ namespace SHADE
transformData.emplace_back(transform->GetTRS()); transformData.emplace_back(transform->GetTRS());
} }
eidData.emplace_back(eid); eidData.emplace_back(rendId);
// Material Properties // Material Properties
if (!EMPTY_MAT_PROPS) if (!EMPTY_MAT_PROPS)
{ {
renderable->GetMaterial()->ExportProperties(propsCurrPtr); const SHRenderable* renderable = SHComponentManager::GetComponent<SHRenderable>(rendId);
if (renderable)
{
renderable->GetMaterial()->ExportProperties(propsCurrPtr);
}
else
{
SHLOG_WARNING("[SHBatch] Entity with a missing SHRenderable found!");
}
propsCurrPtr += singleMatPropAlignedSize; propsCurrPtr += singleMatPropAlignedSize;
} }
} }

View File

@ -55,7 +55,7 @@ namespace SHADE
/* Data Members */ /* Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
Handle<SHMesh> Mesh; Handle<SHMesh> Mesh;
std::unordered_set<const SHRenderable*> Renderables; std::unordered_set<EntityID> Renderables;
}; };
/***********************************************************************************/ /***********************************************************************************/
/*! /*!

View File

@ -677,10 +677,10 @@ namespace SHADE
continue; continue;
// Remove from old material's SuperBatch // Remove from old material's SuperBatch
Handle<SHMaterial> prevMaterial = renderable.GetPrevMaterial(); Handle<SHMaterialInstance> prevMaterial = renderable.GetPrevMaterial();
if (prevMaterial) if (prevMaterial)
{ {
Handle<SHSuperBatch> oldSuperBatch = prevMaterial->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); Handle<SHSuperBatch> oldSuperBatch = prevMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
oldSuperBatch->Remove(&renderable); oldSuperBatch->Remove(&renderable);
} }

View File

@ -31,15 +31,16 @@ namespace SHADE
void SHRenderable::OnDestroy() void SHRenderable::OnDestroy()
{ {
// Remove from SuperBatch
Handle<SHSuperBatch> superBatch = sharedMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
superBatch->Remove(this);
// Free resources
if (material) if (material)
{ {
material.Free(); material.Free();
material = {}; material = {};
} }
// Remove from SuperBatch
Handle<SHSuperBatch> superBatch = sharedMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch();
superBatch->Remove(this);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -51,17 +52,20 @@ namespace SHADE
if (!material && sharedMaterial == materialInstance) if (!material && sharedMaterial == materialInstance)
return; return;
// Flag that material was changed
materialChanged = true;
// Free copies of materials if any // Free copies of materials if any
if (material) if (material)
{ {
oldMaterial = material;
material.Free(); material.Free();
material = {}; material = {};
} }
else if (sharedMaterial)
// Flag that material was changed {
materialChanged = true; oldMaterial = sharedMaterial;
if (sharedMaterial) }
oldMaterial = sharedMaterial->GetBaseMaterial();
// Update the material // Update the material
sharedMaterial = materialInstance; sharedMaterial = materialInstance;

View File

@ -55,7 +55,7 @@ namespace SHADE
/* Getter Functions */ /* Getter Functions */
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
bool WasMaterialChanged() const noexcept { return materialChanged; } bool WasMaterialChanged() const noexcept { return materialChanged; }
Handle<SHMaterial> GetPrevMaterial() const noexcept { return oldMaterial; } Handle<SHMaterialInstance> GetPrevMaterial() const noexcept { return oldMaterial; }
/*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/
/* Batcher Dispatcher Functions */ /* Batcher Dispatcher Functions */
@ -74,7 +74,7 @@ namespace SHADE
Handle<SHMaterialInstance> sharedMaterial; Handle<SHMaterialInstance> sharedMaterial;
Handle<SHMaterialInstance> material; Handle<SHMaterialInstance> material;
bool materialChanged = true; bool materialChanged = true;
Handle<SHMaterial> oldMaterial; Handle<SHMaterialInstance> oldMaterial;
}; };
} }