2026-04-01 16:44:11 +08:00
|
|
|
#include "Rendering/Passes/BuiltinObjectIdPass.h"
|
|
|
|
|
|
2026-04-02 19:17:22 +08:00
|
|
|
#include "Core/Asset/ResourceManager.h"
|
2026-04-01 16:44:11 +08:00
|
|
|
#include "RHI/RHICommandList.h"
|
2026-04-05 21:53:35 +08:00
|
|
|
#include "Rendering/Extraction/RenderSceneExtractor.h"
|
2026-04-05 18:20:19 +08:00
|
|
|
#include "Rendering/RenderSurface.h"
|
2026-04-01 16:44:11 +08:00
|
|
|
#include "Resources/Mesh/Mesh.h"
|
|
|
|
|
|
|
|
|
|
#include <cstddef>
|
2026-04-03 17:05:38 +08:00
|
|
|
#include <vector>
|
2026-04-01 16:44:11 +08:00
|
|
|
|
|
|
|
|
namespace XCEngine {
|
|
|
|
|
namespace Rendering {
|
|
|
|
|
namespace Passes {
|
|
|
|
|
|
|
|
|
|
BuiltinObjectIdPass::~BuiltinObjectIdPass() {
|
|
|
|
|
Shutdown();
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-05 18:20:19 +08:00
|
|
|
const char* BuiltinObjectIdPass::GetName() const {
|
|
|
|
|
return "BuiltinObjectIdPass";
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 19:17:22 +08:00
|
|
|
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);
|
2026-04-04 01:59:28 +08:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
2026-04-02 19:17:22 +08:00
|
|
|
return inputLayout;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-05 18:20:19 +08:00
|
|
|
bool BuiltinObjectIdPass::Initialize(const RenderContext& context) {
|
|
|
|
|
return EnsureInitialized(context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool BuiltinObjectIdPass::Execute(const RenderPassContext& context) {
|
|
|
|
|
if (!context.renderContext.IsValid()) {
|
2026-04-01 16:44:11 +08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-05 18:20:19 +08:00
|
|
|
const std::vector<RHI::RHIResourceView*>& colorAttachments = context.surface.GetColorAttachments();
|
|
|
|
|
if (colorAttachments.empty() ||
|
|
|
|
|
colorAttachments[0] == nullptr ||
|
|
|
|
|
context.surface.GetDepthAttachment() == nullptr) {
|
2026-04-01 16:44:11 +08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-05 18:20:19 +08:00
|
|
|
const Math::RectInt renderArea = context.surface.GetRenderArea();
|
2026-04-01 16:44:11 +08:00
|
|
|
if (renderArea.width <= 0 || renderArea.height <= 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-05 18:20:19 +08:00
|
|
|
if (!EnsureInitialized(context.renderContext)) {
|
2026-04-01 16:44:11 +08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-05 18:20:19 +08:00
|
|
|
RHI::RHICommandList* commandList = context.renderContext.commandList;
|
2026-04-01 16:44:11 +08:00
|
|
|
RHI::RHIResourceView* renderTarget = colorAttachments[0];
|
|
|
|
|
|
2026-04-05 18:20:19 +08:00
|
|
|
if (context.surface.IsAutoTransitionEnabled()) {
|
2026-04-01 16:44:11 +08:00
|
|
|
commandList->TransitionBarrier(
|
|
|
|
|
renderTarget,
|
2026-04-05 18:20:19 +08:00
|
|
|
context.surface.GetColorStateBefore(),
|
2026-04-01 16:44:11 +08:00
|
|
|
RHI::ResourceStates::RenderTarget);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-05 18:20:19 +08:00
|
|
|
commandList->SetRenderTargets(1, &renderTarget, context.surface.GetDepthAttachment());
|
2026-04-01 16:44:11 +08:00
|
|
|
|
|
|
|
|
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);
|
2026-04-05 18:20:19 +08:00
|
|
|
commandList->ClearDepthStencil(context.surface.GetDepthAttachment(), 1.0f, 0, 1, clearRects);
|
2026-04-01 16:44:11 +08:00
|
|
|
commandList->SetPrimitiveTopology(RHI::PrimitiveTopology::TriangleList);
|
|
|
|
|
commandList->SetPipelineState(m_pipelineState);
|
|
|
|
|
|
2026-04-05 18:20:19 +08:00
|
|
|
for (const VisibleRenderItem& visibleItem : context.sceneData.visibleItems) {
|
|
|
|
|
DrawVisibleItem(context.renderContext, context.sceneData, visibleItem);
|
2026-04-01 16:44:11 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-04 01:59:28 +08:00
|
|
|
commandList->EndRenderPass();
|
|
|
|
|
|
2026-04-05 18:20:19 +08:00
|
|
|
if (context.surface.IsAutoTransitionEnabled()) {
|
2026-04-01 16:44:11 +08:00
|
|
|
commandList->TransitionBarrier(
|
|
|
|
|
renderTarget,
|
|
|
|
|
RHI::ResourceStates::RenderTarget,
|
2026-04-05 18:20:19 +08:00
|
|
|
context.surface.GetColorStateAfter());
|
2026-04-01 16:44:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BuiltinObjectIdPass::Shutdown() {
|
|
|
|
|
DestroyResources();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Passes
|
|
|
|
|
} // namespace Rendering
|
|
|
|
|
} // namespace XCEngine
|