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

View File

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

View File

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

View File

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

View File

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