diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp index 528472a7..7ca7c394 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp @@ -12,9 +12,9 @@ namespace SHADE { - /*---------------------------------------------------------------------------------*/ - /* Pipeline Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Pipeline Functions */ + /*-----------------------------------------------------------------------------------*/ void SHMaterial::SetPipeline(Handle _pipeline) { // Reassignment, we ignore @@ -24,40 +24,26 @@ namespace SHADE pipeline = _pipeline; // Set up properties based on the pipeline - if (!pipeline) + if (pipeline) { - // Clear memory and all that - propMemory.reset(); - return; - } - - // Allocate memory for properties - const Handle SHADER_INFO = GetShaderBlockInterface(); - propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; - if (propMemorySize <= 0) - { - propMemory.reset(); - } - else - { - propMemory.reset(new char[propMemorySize]); - } - ResetProperties(); - - // Search all material instances for instances that use this base material - // to force a reset of properties - auto gfxSystem = SHSystemManager::GetSystem(); - if (gfxSystem) - { - auto [matInstBegin, matInstEnd] = gfxSystem->GetAllMaterialInstances(); - for (auto iter = matInstBegin; iter != matInstEnd; ++iter) + // Allocate memory for properties + const Handle SHADER_INFO = GetShaderBlockInterface(); + propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; + if (propMemorySize <= 0) { - if (iter->GetBaseMaterial() == GetHandle()) - { - iter->ResetProperties(); - } + propMemory.reset(); + } + else + { + propMemory.reset(new char[propMemorySize]); } } + + // Reset since pipeline changed + ResetProperties(); + + // Mark changed so that we know to update dependent material instances + propertiesChanged = true; } Handle SHMaterial::GetPipeline() const @@ -65,9 +51,9 @@ namespace SHADE return pipeline; } - /*---------------------------------------------------------------------------------*/ - /* Property Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Property Functions */ + /*-----------------------------------------------------------------------------------*/ void SHMaterial::ResetProperties() { // Reset all the properties to default values @@ -89,6 +75,8 @@ namespace SHADE break; } } + + propertiesChanged = true; } void SHMaterial::ExportProperties(void* dest) const noexcept @@ -103,9 +91,9 @@ namespace SHADE return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; } - /*---------------------------------------------------------------------------------*/ - /* Helper Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ Handle SHMaterial::GetShaderBlockInterface() const noexcept { return pipeline->GetPipelineLayout()->GetShaderBlockInterface @@ -115,4 +103,12 @@ namespace SHADE vk::ShaderStageFlagBits::eFragment ); } + + /*-----------------------------------------------------------------------------------*/ + /* Query Functions */ + /*-----------------------------------------------------------------------------------*/ + void SHMaterial::ClearChangeFlag() noexcept + { + propertiesChanged = false; + } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h index 15764ae0..c75692f2 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h @@ -68,6 +68,10 @@ namespace SHADE /* Query Functions */ /*-----------------------------------------------------------------------------*/ Handle GetShaderBlockInterface() const noexcept; + bool HasPipelineChanged() const noexcept { return pipelineChanged; } + bool HasPropertiesChanged() const noexcept { return propertiesChanged; } + bool HasChanged() const noexcept { return pipelineChanged || propertiesChanged; } + void ClearChangeFlag() noexcept; private: /*-----------------------------------------------------------------------------*/ @@ -76,6 +80,8 @@ namespace SHADE Handle pipeline; std::unique_ptr propMemory; Byte propMemorySize = 0; + bool propertiesChanged = true; + bool pipelineChanged = true; /*-----------------------------------------------------------------------------*/ /* Helper Functions */ diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp index f81cfa5c..b74a69b0 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.hpp @@ -33,8 +33,7 @@ namespace SHADE } // Get offset and modify the memory directly - T* dataPtr = reinterpret_cast(propMemory.get() + PROP_INFO->offset); - *dataPtr = value; + setPropertyUnsafe(PROP_INFO->offset, value); } template @@ -86,5 +85,6 @@ namespace SHADE void SHMaterial::setPropertyUnsafe(uint32_t memOffset, const T& value) { (*reinterpret_cast(propMemory.get() + memOffset)) = value; + propertiesChanged = true; } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp index 44216163..7526538f 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.cpp @@ -62,12 +62,20 @@ namespace SHADE } // Data was exported so unflag - //dataWasChanged = false; + dataWasChanged = false; } - /*---------------------------------------------------------------------------------*/ - /* Helper Functions */ - /*---------------------------------------------------------------------------------*/ + /*-----------------------------------------------------------------------------------*/ + /* Query Functions */ + /*-----------------------------------------------------------------------------------*/ + bool SHMaterialInstance::HasChanged() const noexcept + { + return dataWasChanged || (baseMaterial && baseMaterial->HasChanged()); + } + + /*-----------------------------------------------------------------------------------*/ + /* Helper Functions */ + /*-----------------------------------------------------------------------------------*/ Handle SHMaterialInstance::getShaderBlockInterface() const noexcept { return baseMaterial->GetPipeline()->GetPipelineLayout()->GetShaderBlockInterface diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h index d09ed097..57e3dfce 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterialInstance.h @@ -69,7 +69,7 @@ namespace SHADE /* Getter Functions */ /*-----------------------------------------------------------------------------*/ Handle GetBaseMaterial() const noexcept { return baseMaterial; } - bool HasChanged() const noexcept { return dataWasChanged; } + bool HasChanged() const noexcept; bool IsBlank() const noexcept { return overrideData.empty(); } // No overrides private: