Wire depth and shadow requests through camera renderer
This commit is contained in:
@@ -131,6 +131,59 @@ private:
|
||||
bool m_renderResult = true;
|
||||
};
|
||||
|
||||
class MockScenePass final : public RenderPass {
|
||||
public:
|
||||
MockScenePass(
|
||||
std::shared_ptr<MockPipelineState> state,
|
||||
const char* label,
|
||||
bool initializeResult = true,
|
||||
bool executeResult = true)
|
||||
: m_state(std::move(state))
|
||||
, m_label(label)
|
||||
, m_initializeResult(initializeResult)
|
||||
, m_executeResult(executeResult) {
|
||||
}
|
||||
|
||||
const char* GetName() const override {
|
||||
return m_label;
|
||||
}
|
||||
|
||||
bool Initialize(const RenderContext&) override {
|
||||
m_state->eventLog.push_back(std::string("init:") + m_label);
|
||||
return m_initializeResult;
|
||||
}
|
||||
|
||||
bool Execute(const RenderPassContext& context) override {
|
||||
m_state->eventLog.push_back(m_label);
|
||||
lastViewportWidth = context.sceneData.cameraData.viewportWidth;
|
||||
lastViewportHeight = context.sceneData.cameraData.viewportHeight;
|
||||
lastClearFlags = context.sceneData.cameraData.clearFlags;
|
||||
lastClearColor = context.sceneData.cameraData.clearColor;
|
||||
lastWorldPosition = context.sceneData.cameraData.worldPosition;
|
||||
lastSurfaceWidth = context.surface.GetRenderAreaWidth();
|
||||
lastSurfaceHeight = context.surface.GetRenderAreaHeight();
|
||||
return m_executeResult;
|
||||
}
|
||||
|
||||
void Shutdown() override {
|
||||
m_state->eventLog.push_back(std::string("shutdown:") + m_label);
|
||||
}
|
||||
|
||||
uint32_t lastViewportWidth = 0;
|
||||
uint32_t lastViewportHeight = 0;
|
||||
RenderClearFlags lastClearFlags = RenderClearFlags::All;
|
||||
XCEngine::Math::Color lastClearColor = XCEngine::Math::Color::Black();
|
||||
XCEngine::Math::Vector3 lastWorldPosition = XCEngine::Math::Vector3::Zero();
|
||||
uint32_t lastSurfaceWidth = 0;
|
||||
uint32_t lastSurfaceHeight = 0;
|
||||
|
||||
private:
|
||||
std::shared_ptr<MockPipelineState> m_state;
|
||||
const char* m_label = "";
|
||||
bool m_initializeResult = true;
|
||||
bool m_executeResult = true;
|
||||
};
|
||||
|
||||
class TrackingPass final : public RenderPass {
|
||||
public:
|
||||
TrackingPass(
|
||||
@@ -334,6 +387,92 @@ TEST(CameraRenderer_Test, ExecutesObjectIdPassBetweenPipelineAndPostPassesWhenRe
|
||||
"shutdown:pre" }));
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, ExecutesShadowCasterAndDepthOnlyRequestsBeforeMainPipeline) {
|
||||
Scene scene("CameraRendererDepthAndShadowScene");
|
||||
|
||||
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));
|
||||
|
||||
auto shadowPass = std::make_unique<MockScenePass>(state, "shadowCaster");
|
||||
MockScenePass* shadowPassRaw = shadowPass.get();
|
||||
renderer.SetShadowCasterPass(std::move(shadowPass));
|
||||
|
||||
auto depthPass = std::make_unique<MockScenePass>(state, "depthOnly");
|
||||
MockScenePass* depthPassRaw = depthPass.get();
|
||||
renderer.SetDepthOnlyPass(std::move(depthPass));
|
||||
|
||||
CameraRenderRequest request;
|
||||
request.scene = &scene;
|
||||
request.camera = camera;
|
||||
request.context = CreateValidContext();
|
||||
request.surface = RenderSurface(320, 180);
|
||||
request.cameraDepth = camera->GetDepth();
|
||||
|
||||
request.shadowCaster.surface = RenderSurface(128, 64);
|
||||
request.shadowCaster.surface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1));
|
||||
request.shadowCaster.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(2));
|
||||
request.shadowCaster.hasCameraDataOverride = true;
|
||||
request.shadowCaster.cameraDataOverride.worldPosition = XCEngine::Math::Vector3(7.0f, 8.0f, 9.0f);
|
||||
|
||||
request.depthOnly.surface = RenderSurface(96, 48);
|
||||
request.depthOnly.surface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(3));
|
||||
request.depthOnly.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(4));
|
||||
request.depthOnly.hasClearColorOverride = true;
|
||||
request.depthOnly.clearColorOverride = XCEngine::Math::Color(0.3f, 0.2f, 0.1f, 1.0f);
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{
|
||||
"init:shadowCaster",
|
||||
"shadowCaster",
|
||||
"init:depthOnly",
|
||||
"depthOnly",
|
||||
"pipeline" }));
|
||||
EXPECT_EQ(shadowPassRaw->lastViewportWidth, 128u);
|
||||
EXPECT_EQ(shadowPassRaw->lastViewportHeight, 64u);
|
||||
EXPECT_EQ(shadowPassRaw->lastSurfaceWidth, 128u);
|
||||
EXPECT_EQ(shadowPassRaw->lastSurfaceHeight, 64u);
|
||||
EXPECT_EQ(shadowPassRaw->lastClearFlags, RenderClearFlags::Depth);
|
||||
EXPECT_EQ(shadowPassRaw->lastWorldPosition, XCEngine::Math::Vector3(7.0f, 8.0f, 9.0f));
|
||||
EXPECT_EQ(depthPassRaw->lastViewportWidth, 96u);
|
||||
EXPECT_EQ(depthPassRaw->lastViewportHeight, 48u);
|
||||
EXPECT_EQ(depthPassRaw->lastClearFlags, RenderClearFlags::Depth);
|
||||
EXPECT_FLOAT_EQ(depthPassRaw->lastClearColor.r, 0.3f);
|
||||
EXPECT_FLOAT_EQ(depthPassRaw->lastClearColor.g, 0.2f);
|
||||
EXPECT_FLOAT_EQ(depthPassRaw->lastClearColor.b, 0.1f);
|
||||
EXPECT_FLOAT_EQ(depthPassRaw->lastClearColor.a, 1.0f);
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, StopsRenderingWhenShadowCasterRequestIsInvalid) {
|
||||
Scene scene("CameraRendererInvalidShadowScene");
|
||||
|
||||
GameObject* cameraObject = scene.CreateGameObject("Camera");
|
||||
auto* camera = cameraObject->AddComponent<CameraComponent>();
|
||||
camera->SetPrimary(true);
|
||||
|
||||
auto state = std::make_shared<MockPipelineState>();
|
||||
CameraRenderer renderer(std::make_unique<MockPipeline>(state));
|
||||
|
||||
CameraRenderRequest request;
|
||||
request.scene = &scene;
|
||||
request.camera = camera;
|
||||
request.context = CreateValidContext();
|
||||
request.surface = RenderSurface(320, 180);
|
||||
request.shadowCaster.surface = RenderSurface(64, 64);
|
||||
request.shadowCaster.surface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1));
|
||||
|
||||
EXPECT_FALSE(renderer.Render(request));
|
||||
EXPECT_TRUE(state->eventLog.empty());
|
||||
}
|
||||
|
||||
TEST(CameraRenderer_Test, ShutsDownInitializedPassesWhenPipelineRenderFails) {
|
||||
Scene scene("CameraRendererFailureScene");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user