Files
XCEngine/engine/src/Rendering/Passes/BuiltinObjectIdPass.cpp

170 lines
5.3 KiB
C++

#include "Rendering/Passes/BuiltinObjectIdPass.h"
#include "Core/Asset/ResourceManager.h"
#include "RHI/RHICommandList.h"
#include <XCEngine/Rendering/RenderPassGraphContract.h>
#include "Rendering/FrameData/RendererListUtils.h"
#include "Rendering/Internal/RenderSurfacePipelineUtils.h"
#include "Rendering/Extraction/RenderSceneExtractor.h"
#include "Rendering/RenderSurface.h"
#include "Resources/Mesh/Mesh.h"
#include <cstddef>
#include <vector>
namespace XCEngine {
namespace Rendering {
namespace Passes {
BuiltinObjectIdPass::~BuiltinObjectIdPass() {
Shutdown();
}
const char* BuiltinObjectIdPass::GetName() const {
return "BuiltinObjectIdPass";
}
RHI::InputLayoutDesc BuiltinObjectIdPass::BuildInputLayout() {
RHI::InputLayoutDesc inputLayout = {};
RHI::InputElementDesc position = {};
position.semanticName = "POSITION";
position.semanticIndex = 0;
position.format = static_cast<uint32_t>(RHI::Format::R32G32B32_Float);
position.inputSlot = 0;
position.alignedByteOffset = static_cast<uint32_t>(offsetof(Resources::StaticMeshVertex, position));
inputLayout.elements.push_back(position);
RHI::InputElementDesc normal = {};
normal.semanticName = "NORMAL";
normal.semanticIndex = 0;
normal.format = static_cast<uint32_t>(RHI::Format::R32G32B32_Float);
normal.inputSlot = 0;
normal.alignedByteOffset = static_cast<uint32_t>(offsetof(Resources::StaticMeshVertex, normal));
inputLayout.elements.push_back(normal);
RHI::InputElementDesc texcoord = {};
texcoord.semanticName = "TEXCOORD";
texcoord.semanticIndex = 0;
texcoord.format = static_cast<uint32_t>(RHI::Format::R32G32_Float);
texcoord.inputSlot = 0;
texcoord.alignedByteOffset = static_cast<uint32_t>(offsetof(Resources::StaticMeshVertex, uv0));
inputLayout.elements.push_back(texcoord);
return inputLayout;
}
bool BuiltinObjectIdPass::Initialize(const RenderContext& context) {
return context.IsValid();
}
bool BuiltinObjectIdPass::SupportsRenderGraph() const {
return true;
}
bool BuiltinObjectIdPass::RecordRenderGraph(
const RenderPassRenderGraphContext& context) {
return RecordRasterRenderPass(
*this,
context,
{
false,
true,
true
});
}
bool BuiltinObjectIdPass::Execute(const RenderPassContext& context) {
if (!context.renderContext.IsValid()) {
return false;
}
const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
if (!::XCEngine::Rendering::Internal::HasSingleColorAttachment(context.surface) ||
colorAttachments.empty() ||
colorAttachments[0] == nullptr ||
context.surface.GetDepthAttachment() == nullptr) {
return false;
}
const Math::RectInt renderArea = context.surface.GetRenderArea();
if (renderArea.width <= 0 || renderArea.height <= 0) {
return false;
}
if (!EnsureInitialized(context.renderContext, context.surface)) {
return false;
}
RHI::RHICommandList* commandList = context.renderContext.commandList;
RHI::RHIResourceView* renderTarget = colorAttachments[0];
RHI::RHIResourceView* depthAttachment = context.surface.GetDepthAttachment();
if (context.surface.IsAutoTransitionEnabled()) {
commandList->TransitionBarrier(
renderTarget,
context.surface.GetColorStateBefore(),
RHI::ResourceStates::RenderTarget);
commandList->TransitionBarrier(
depthAttachment,
context.surface.GetDepthStateBefore(),
RHI::ResourceStates::DepthWrite);
}
commandList->SetRenderTargets(1, &renderTarget, depthAttachment);
const RHI::Viewport viewport = {
static_cast<float>(renderArea.x),
static_cast<float>(renderArea.y),
static_cast<float>(renderArea.width),
static_cast<float>(renderArea.height),
0.0f,
1.0f
};
const RHI::Rect scissorRect = {
renderArea.x,
renderArea.y,
renderArea.x + renderArea.width,
renderArea.y + renderArea.height
};
const float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
const RHI::Rect clearRects[] = { scissorRect };
commandList->SetViewport(viewport);
commandList->SetScissorRect(scissorRect);
commandList->ClearRenderTarget(renderTarget, clearColor, 1, clearRects);
commandList->ClearDepthStencil(depthAttachment, 1.0f, 0, 1, clearRects);
commandList->SetPrimitiveTopology(RHI::PrimitiveTopology::TriangleList);
commandList->SetPipelineState(m_pipelineState);
VisitRendererListVisibleItems(
context.sceneData,
RendererListType::ObjectId,
[&](const VisibleRenderItem& visibleItem) {
DrawVisibleItem(context.renderContext, context.sceneData, visibleItem);
});
commandList->EndRenderPass();
if (context.surface.IsAutoTransitionEnabled()) {
commandList->TransitionBarrier(
renderTarget,
RHI::ResourceStates::RenderTarget,
context.surface.GetColorStateAfter());
commandList->TransitionBarrier(
depthAttachment,
RHI::ResourceStates::DepthWrite,
context.surface.GetDepthStateAfter());
}
return true;
}
void BuiltinObjectIdPass::Shutdown() {
DestroyResources();
}
} // namespace Passes
} // namespace Rendering
} // namespace XCEngine