From 58e6a3c4c25be27365c28636e1c12ad45f5d3e07 Mon Sep 17 00:00:00 2001 From: Kah Wei Date: Sat, 19 Nov 2022 17:30:48 +0800 Subject: [PATCH] Re-aded ability to change shaders Bugged, replacing shaders results in object being rendered in the old position --- .../MaterialInspector/SHMaterialInspector.cpp | 2 -- .../src/Graphics/MiddleEnd/Batching/SHBatch.cpp | 6 +++++- .../src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp | 9 +++++---- .../MiddleEnd/Interface/SHGraphicsSystem.cpp | 12 +++++++++++- .../src/Graphics/MiddleEnd/Interface/SHMaterial.cpp | 10 +++++++--- .../src/Graphics/MiddleEnd/Interface/SHMaterial.h | 8 +++++--- 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp index 88de7b73..3ffed8e3 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MaterialInspector/SHMaterialInspector.cpp @@ -174,7 +174,6 @@ namespace SHADE bool shaderChanged = false; const auto* SHADER_INFO = SHAssetManager::GetData(currentMatSpec->fragShader); const std::string SHADER_NAME = SHADER_INFO ? SHADER_INFO->name : "Unknown Shader"; - ImGui::BeginDisabled(); isDirty |= SHEditorWidgets::DragDropReadOnlyField ( "Fragment Shader", SHADER_NAME.data(), @@ -182,7 +181,6 @@ namespace SHADE [this](const AssetID& id) { currentMatSpec->fragShader = id; }, SHDragDrop::DRAG_RESOURCE ); - ImGui::EndDisabled(); // Load the shader to access it's data auto fragShader = SHResourceManager::LoadOrGet(currentMatSpec->fragShader); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp index 5b3bfac2..ddd1f51b 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHBatch.cpp @@ -507,9 +507,13 @@ namespace SHADE return; } + // Nothing to draw + if (subBatches.empty()) + return; + // Bind all required objects before drawing static std::array dynamicOffset{ 0 }; - cmdBuffer->BeginLabeledSegment("SHBatch"); + cmdBuffer->BeginLabeledSegment("SHBatch for Pipeline #" + std::to_string(pipeline.GetId().Data.Index)); cmdBuffer->BindPipeline(pipeline); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::TRANSFORM, transformDataBuffer[frameIndex], 0); cmdBuffer->BindVertexBuffer(SHGraphicsConstants::VertexBufferBindings::INTEGER_DATA, instancedIntegerBuffer[frameIndex], 0); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp index 6760d937..91728d71 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Batching/SHSuperBatch.cpp @@ -55,13 +55,14 @@ namespace SHADE void SHSuperBatch::Remove(const SHRenderable* renderable) noexcept { - const Handle PIPELINE = renderable->GetMaterial()->GetBaseMaterial()->GetPipeline(); + Handle baseMat = renderable->GetMaterial()->GetBaseMaterial(); + const Handle PIPELINE = baseMat->HasPipelineChanged() ? baseMat->GetPrevPipeline() : baseMat->GetPipeline(); // Check if we have a Batch with the same pipeline yet auto batch = std::find_if(batches.begin(), batches.end(), [&](const SHBatch& batch) - { - return batch.GetPipeline() == PIPELINE; - }); + { + return batch.GetPipeline() == PIPELINE; + }); // Attempt to remove if it exists if (batch == batches.end()) diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp index ff265c49..5b40a745 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp @@ -890,7 +890,9 @@ namespace SHADE Handle prevMaterial = renderable.HasMaterialChanged() ? renderable.GetPrevMaterial() : renderable.GetMaterial(); if (prevMaterial) { - Handle oldSuperBatch = prevMaterial->GetBaseMaterial()->GetPipeline()->GetPipelineState().GetSubpass()->GetSuperBatch(); + Handle baseMat = prevMaterial->GetBaseMaterial(); + Handle prevPipeline = baseMat->HasPipelineChanged() ? baseMat->GetPrevPipeline() : baseMat->GetPipeline(); + Handle oldSuperBatch = prevPipeline->GetPipelineState().GetSubpass()->GetSuperBatch(); oldSuperBatch->Remove(&renderable); } @@ -905,6 +907,14 @@ namespace SHADE // Unset change flag renderable.ResetChangedFlag(); } + + // Unset all material old pipeline since we would have finished processing + auto gfxSystem = reinterpret_cast(system); + auto [matBegin, matEnd] = gfxSystem->resourceManager.GetDenseAccess(); + for (auto iter = matBegin; iter != matEnd; ++iter) + { + iter->ForgetOldPipeline(); + } } #pragma endregion ROUTINES diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp index 7ca7c394..1a007b95 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.cpp @@ -21,6 +21,8 @@ namespace SHADE if (_pipeline == pipeline) return; + // Mark old pipeline and set new pipeline + oldPipeline = pipeline; pipeline = _pipeline; // Set up properties based on the pipeline @@ -41,9 +43,6 @@ namespace SHADE // Reset since pipeline changed ResetProperties(); - - // Mark changed so that we know to update dependent material instances - propertiesChanged = true; } Handle SHMaterial::GetPipeline() const @@ -111,4 +110,9 @@ namespace SHADE { propertiesChanged = false; } + + void SHMaterial::ForgetOldPipeline() noexcept + { + oldPipeline = {}; + } } diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h index c75692f2..7913d912 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMaterial.h @@ -44,6 +44,7 @@ namespace SHADE /*-----------------------------------------------------------------------------*/ void SetPipeline(Handle _pipeline); Handle GetPipeline() const; + Handle GetPrevPipeline() const { return oldPipeline; }; /*-----------------------------------------------------------------------------*/ /* Property Functions */ @@ -68,10 +69,11 @@ namespace SHADE /* Query Functions */ /*-----------------------------------------------------------------------------*/ Handle GetShaderBlockInterface() const noexcept; - bool HasPipelineChanged() const noexcept { return pipelineChanged; } + bool HasPipelineChanged() const noexcept { return oldPipeline; } bool HasPropertiesChanged() const noexcept { return propertiesChanged; } - bool HasChanged() const noexcept { return pipelineChanged || propertiesChanged; } + bool HasChanged() const noexcept { return oldPipeline || propertiesChanged; } void ClearChangeFlag() noexcept; + void ForgetOldPipeline() noexcept; private: /*-----------------------------------------------------------------------------*/ @@ -81,7 +83,7 @@ namespace SHADE std::unique_ptr propMemory; Byte propMemorySize = 0; bool propertiesChanged = true; - bool pipelineChanged = true; + Handle oldPipeline; /*-----------------------------------------------------------------------------*/ /* Helper Functions */