feat: add gpu object id scene picking
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <XCEngine/Components/CameraComponent.h>
|
||||
#include <XCEngine/Rendering/CameraRenderer.h>
|
||||
#include <XCEngine/Rendering/ObjectIdPass.h>
|
||||
#include <XCEngine/Rendering/RenderPipelineAsset.h>
|
||||
#include <XCEngine/Rendering/RenderSurface.h>
|
||||
#include <XCEngine/Rendering/SceneRenderer.h>
|
||||
@@ -100,6 +101,32 @@ private:
|
||||
std::shared_ptr<MockPipelineAssetState> m_state;
|
||||
};
|
||||
|
||||
class MockObjectIdPass final : public ObjectIdPass {
|
||||
public:
|
||||
MockObjectIdPass(
|
||||
std::shared_ptr<MockPipelineState> state,
|
||||
bool renderResult = true)
|
||||
: m_state(std::move(state))
|
||||
, m_renderResult(renderResult) {
|
||||
}
|
||||
|
||||
bool Render(
|
||||
const RenderContext&,
|
||||
const RenderSurface&,
|
||||
const RenderSceneData&) override {
|
||||
m_state->eventLog.push_back("objectId");
|
||||
return m_renderResult;
|
||||
}
|
||||
|
||||
void Shutdown() override {
|
||||
m_state->eventLog.push_back("shutdown:objectId");
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<MockPipelineState> m_state;
|
||||
bool m_renderResult = true;
|
||||
};
|
||||
|
||||
class TrackingPass final : public RenderPass {
|
||||
public:
|
||||
TrackingPass(
|
||||
@@ -227,6 +254,51 @@ TEST(CameraRenderer_Test, ExecutesInjectedPreAndPostPassSequencesAroundPipelineR
|
||||
"shutdown:pre" }));
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, ExecutesObjectIdPassBetweenPipelineAndPostPassesWhenRequested) {
|
||||
Scene scene("CameraRendererObjectIdPassScene");
|
||||
|
||||
GameObject* cameraObject = scene.CreateGameObject("Camera");
|
||||
auto* camera = cameraObject->AddComponent<CameraComponent>();
|
||||
camera->SetPrimary(true);
|
||||
camera->SetDepth(3.0f);
|
||||
|
||||
auto state = std::make_shared<MockPipelineState>();
|
||||
CameraRenderer renderer(
|
||||
std::make_unique<MockPipeline>(state),
|
||||
std::make_unique<MockObjectIdPass>(state));
|
||||
|
||||
RenderPassSequence prePasses;
|
||||
prePasses.AddPass(std::make_unique<TrackingPass>(state, "pre"));
|
||||
|
||||
RenderPassSequence postPasses;
|
||||
postPasses.AddPass(std::make_unique<TrackingPass>(state, "post"));
|
||||
|
||||
CameraRenderRequest request;
|
||||
request.scene = &scene;
|
||||
request.camera = camera;
|
||||
request.context = CreateValidContext();
|
||||
request.surface = RenderSurface(320, 180);
|
||||
request.cameraDepth = camera->GetDepth();
|
||||
request.preScenePasses = &prePasses;
|
||||
request.postScenePasses = &postPasses;
|
||||
request.objectId.surface = RenderSurface(320, 180);
|
||||
request.objectId.surface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1));
|
||||
request.objectId.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(2));
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{
|
||||
"init:pre",
|
||||
"pre",
|
||||
"pipeline",
|
||||
"objectId",
|
||||
"init:post",
|
||||
"post",
|
||||
"shutdown:post",
|
||||
"shutdown:pre" }));
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, ShutsDownInitializedPassesWhenPipelineRenderFails) {
|
||||
Scene scene("CameraRendererFailureScene");
|
||||
|
||||
@@ -256,6 +328,43 @@ TEST(CameraRenderer_Test, ShutsDownInitializedPassesWhenPipelineRenderFails) {
|
||||
(std::vector<std::string>{ "init:pre", "pre", "pipeline", "shutdown:pre" }));
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, StopsRenderingWhenObjectIdPassFails) {
|
||||
Scene scene("CameraRendererObjectIdFailureScene");
|
||||
|
||||
GameObject* cameraObject = scene.CreateGameObject("Camera");
|
||||
auto* camera = cameraObject->AddComponent<CameraComponent>();
|
||||
camera->SetPrimary(true);
|
||||
camera->SetDepth(2.0f);
|
||||
|
||||
auto state = std::make_shared<MockPipelineState>();
|
||||
CameraRenderer renderer(
|
||||
std::make_unique<MockPipeline>(state),
|
||||
std::make_unique<MockObjectIdPass>(state, false));
|
||||
|
||||
RenderPassSequence prePasses;
|
||||
prePasses.AddPass(std::make_unique<TrackingPass>(state, "pre"));
|
||||
|
||||
RenderPassSequence postPasses;
|
||||
postPasses.AddPass(std::make_unique<TrackingPass>(state, "post"));
|
||||
|
||||
CameraRenderRequest request;
|
||||
request.scene = &scene;
|
||||
request.camera = camera;
|
||||
request.context = CreateValidContext();
|
||||
request.surface = RenderSurface(320, 180);
|
||||
request.cameraDepth = camera->GetDepth();
|
||||
request.preScenePasses = &prePasses;
|
||||
request.postScenePasses = &postPasses;
|
||||
request.objectId.surface = RenderSurface(320, 180);
|
||||
request.objectId.surface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1));
|
||||
request.objectId.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(2));
|
||||
|
||||
EXPECT_FALSE(renderer.Render(request));
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{ "init:pre", "pre", "pipeline", "objectId", "shutdown:pre" }));
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, ShutsDownSequencesWhenPostPassInitializationFails) {
|
||||
Scene scene("CameraRendererPostPassInitFailureScene");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user