fix: prevent selection outline crash on first selection
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
@@ -31,7 +32,12 @@ struct ObjectIdOutlineStyle {
|
|||||||
|
|
||||||
class BuiltinObjectIdOutlinePass {
|
class BuiltinObjectIdOutlinePass {
|
||||||
public:
|
public:
|
||||||
|
BuiltinObjectIdOutlinePass();
|
||||||
~BuiltinObjectIdOutlinePass() = default;
|
~BuiltinObjectIdOutlinePass() = default;
|
||||||
|
BuiltinObjectIdOutlinePass(const BuiltinObjectIdOutlinePass&) = delete;
|
||||||
|
BuiltinObjectIdOutlinePass& operator=(const BuiltinObjectIdOutlinePass&) = delete;
|
||||||
|
BuiltinObjectIdOutlinePass(BuiltinObjectIdOutlinePass&&) = delete;
|
||||||
|
BuiltinObjectIdOutlinePass& operator=(BuiltinObjectIdOutlinePass&&) = delete;
|
||||||
|
|
||||||
static constexpr uint32_t kMaxSelectedObjectCount = 256u;
|
static constexpr uint32_t kMaxSelectedObjectCount = 256u;
|
||||||
|
|
||||||
@@ -55,6 +61,8 @@ private:
|
|||||||
bool EnsureInitialized(const RenderContext& renderContext);
|
bool EnsureInitialized(const RenderContext& renderContext);
|
||||||
bool CreateResources(const RenderContext& renderContext);
|
bool CreateResources(const RenderContext& renderContext);
|
||||||
void DestroyResources();
|
void DestroyResources();
|
||||||
|
bool HasCreatedResources() const;
|
||||||
|
void ResetState();
|
||||||
|
|
||||||
RHI::RHIDevice* m_device = nullptr;
|
RHI::RHIDevice* m_device = nullptr;
|
||||||
RHI::RHIType m_backendType = RHI::RHIType::D3D12;
|
RHI::RHIType m_backendType = RHI::RHIType::D3D12;
|
||||||
@@ -64,7 +72,7 @@ private:
|
|||||||
RHI::RHIDescriptorSet* m_constantSet = nullptr;
|
RHI::RHIDescriptorSet* m_constantSet = nullptr;
|
||||||
RHI::RHIDescriptorPool* m_texturePool = nullptr;
|
RHI::RHIDescriptorPool* m_texturePool = nullptr;
|
||||||
RHI::RHIDescriptorSet* m_textureSet = nullptr;
|
RHI::RHIDescriptorSet* m_textureSet = nullptr;
|
||||||
Resources::ResourceHandle<Resources::Shader> m_builtinObjectIdOutlineShader;
|
std::optional<Resources::ResourceHandle<Resources::Shader>> m_builtinObjectIdOutlineShader;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Passes
|
} // namespace Passes
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "Resources/BuiltinResources.h"
|
#include "Resources/BuiltinResources.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
namespace Rendering {
|
namespace Rendering {
|
||||||
@@ -85,6 +86,10 @@ RHI::GraphicsPipelineDesc CreatePipelineDesc(
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
BuiltinObjectIdOutlinePass::BuiltinObjectIdOutlinePass() {
|
||||||
|
ResetState();
|
||||||
|
}
|
||||||
|
|
||||||
void BuiltinObjectIdOutlinePass::Shutdown() {
|
void BuiltinObjectIdOutlinePass::Shutdown() {
|
||||||
DestroyResources();
|
DestroyResources();
|
||||||
}
|
}
|
||||||
@@ -181,7 +186,9 @@ bool BuiltinObjectIdOutlinePass::EnsureInitialized(const RenderContext& renderCo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DestroyResources();
|
if (HasCreatedResources()) {
|
||||||
|
DestroyResources();
|
||||||
|
}
|
||||||
return CreateResources(renderContext);
|
return CreateResources(renderContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,21 +197,23 @@ bool BuiltinObjectIdOutlinePass::CreateResources(const RenderContext& renderCont
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_device = renderContext.device;
|
Resources::ResourceHandle<Resources::Shader> shader = Resources::ResourceManager::Get().Load<Resources::Shader>(
|
||||||
m_backendType = renderContext.backendType;
|
|
||||||
m_builtinObjectIdOutlineShader = Resources::ResourceManager::Get().Load<Resources::Shader>(
|
|
||||||
Resources::GetBuiltinObjectIdOutlineShaderPath());
|
Resources::GetBuiltinObjectIdOutlineShaderPath());
|
||||||
if (!m_builtinObjectIdOutlineShader.IsValid()) {
|
if (!shader.IsValid()) {
|
||||||
Debug::Logger::Get().Error(
|
Debug::Logger::Get().Error(
|
||||||
Debug::LogCategory::Rendering,
|
Debug::LogCategory::Rendering,
|
||||||
"BuiltinObjectIdOutlinePass failed to load builtin object-id-outline shader resource");
|
"BuiltinObjectIdOutlinePass failed to load builtin object-id-outline shader resource");
|
||||||
DestroyResources();
|
ResetState();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_device = renderContext.device;
|
||||||
|
m_backendType = renderContext.backendType;
|
||||||
|
m_builtinObjectIdOutlineShader.emplace(std::move(shader));
|
||||||
|
|
||||||
const Resources::ShaderBackend backend = ::XCEngine::Rendering::Detail::ToShaderBackend(m_backendType);
|
const Resources::ShaderBackend backend = ::XCEngine::Rendering::Detail::ToShaderBackend(m_backendType);
|
||||||
const Resources::ShaderPass* outlinePass =
|
const Resources::ShaderPass* outlinePass =
|
||||||
FindObjectIdOutlineCompatiblePass(*m_builtinObjectIdOutlineShader.Get(), backend);
|
FindObjectIdOutlineCompatiblePass(*m_builtinObjectIdOutlineShader->Get(), backend);
|
||||||
if (outlinePass == nullptr) {
|
if (outlinePass == nullptr) {
|
||||||
Debug::Logger::Get().Error(
|
Debug::Logger::Get().Error(
|
||||||
Debug::LogCategory::Rendering,
|
Debug::LogCategory::Rendering,
|
||||||
@@ -276,10 +285,10 @@ bool BuiltinObjectIdOutlinePass::CreateResources(const RenderContext& renderCont
|
|||||||
|
|
||||||
m_pipelineState = m_device->CreatePipelineState(
|
m_pipelineState = m_device->CreatePipelineState(
|
||||||
CreatePipelineDesc(
|
CreatePipelineDesc(
|
||||||
m_backendType,
|
m_backendType,
|
||||||
m_pipelineLayout,
|
m_pipelineLayout,
|
||||||
*m_builtinObjectIdOutlineShader.Get(),
|
*m_builtinObjectIdOutlineShader->Get(),
|
||||||
outlinePass->name));
|
outlinePass->name));
|
||||||
if (m_pipelineState == nullptr || !m_pipelineState->IsValid()) {
|
if (m_pipelineState == nullptr || !m_pipelineState->IsValid()) {
|
||||||
DestroyResources();
|
DestroyResources();
|
||||||
return false;
|
return false;
|
||||||
@@ -288,6 +297,17 @@ bool BuiltinObjectIdOutlinePass::CreateResources(const RenderContext& renderCont
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BuiltinObjectIdOutlinePass::HasCreatedResources() const {
|
||||||
|
return m_device != nullptr ||
|
||||||
|
m_pipelineLayout != nullptr ||
|
||||||
|
m_pipelineState != nullptr ||
|
||||||
|
m_constantPool != nullptr ||
|
||||||
|
m_constantSet != nullptr ||
|
||||||
|
m_texturePool != nullptr ||
|
||||||
|
m_textureSet != nullptr ||
|
||||||
|
m_builtinObjectIdOutlineShader.has_value();
|
||||||
|
}
|
||||||
|
|
||||||
void BuiltinObjectIdOutlinePass::DestroyResources() {
|
void BuiltinObjectIdOutlinePass::DestroyResources() {
|
||||||
if (m_pipelineState != nullptr) {
|
if (m_pipelineState != nullptr) {
|
||||||
m_pipelineState->Shutdown();
|
m_pipelineState->Shutdown();
|
||||||
@@ -325,9 +345,23 @@ void BuiltinObjectIdOutlinePass::DestroyResources() {
|
|||||||
m_pipelineLayout = nullptr;
|
m_pipelineLayout = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_builtinObjectIdOutlineShader.has_value()) {
|
||||||
|
m_builtinObjectIdOutlineShader.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BuiltinObjectIdOutlinePass::ResetState() {
|
||||||
m_device = nullptr;
|
m_device = nullptr;
|
||||||
m_backendType = RHI::RHIType::D3D12;
|
m_backendType = RHI::RHIType::D3D12;
|
||||||
m_builtinObjectIdOutlineShader.Reset();
|
m_pipelineLayout = nullptr;
|
||||||
|
m_pipelineState = nullptr;
|
||||||
|
m_constantPool = nullptr;
|
||||||
|
m_constantSet = nullptr;
|
||||||
|
m_texturePool = nullptr;
|
||||||
|
m_textureSet = nullptr;
|
||||||
|
m_builtinObjectIdOutlineShader.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Passes
|
} // namespace Passes
|
||||||
|
|||||||
Reference in New Issue
Block a user