Introduce CameraRenderRequest scheduling and fix Vulkan build
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <XCEngine/Scene/Scene.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
using namespace XCEngine::Components;
|
||||
using namespace XCEngine::Rendering;
|
||||
@@ -21,6 +22,7 @@ struct MockPipelineState {
|
||||
uint32_t lastSurfaceHeight = 0;
|
||||
CameraComponent* lastCamera = nullptr;
|
||||
size_t lastVisibleItemCount = 0;
|
||||
std::vector<CameraComponent*> renderedCameras;
|
||||
};
|
||||
|
||||
class MockPipeline final : public RenderPipeline {
|
||||
@@ -47,6 +49,7 @@ public:
|
||||
m_state->lastSurfaceHeight = surface.GetHeight();
|
||||
m_state->lastCamera = sceneData.camera;
|
||||
m_state->lastVisibleItemCount = sceneData.visibleItems.size();
|
||||
m_state->renderedCameras.push_back(sceneData.camera);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -80,8 +83,14 @@ TEST(CameraRenderer_Test, UsesOverrideCameraAndSurfaceSizeWhenSubmittingScene) {
|
||||
auto state = std::make_shared<MockPipelineState>();
|
||||
CameraRenderer renderer(std::make_unique<MockPipeline>(state));
|
||||
|
||||
const RenderSurface surface(640, 480);
|
||||
ASSERT_TRUE(renderer.Render(scene, overrideCamera, CreateValidContext(), surface));
|
||||
CameraRenderRequest request;
|
||||
request.scene = &scene;
|
||||
request.camera = overrideCamera;
|
||||
request.context = CreateValidContext();
|
||||
request.surface = RenderSurface(640, 480);
|
||||
request.cameraDepth = overrideCamera->GetDepth();
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
EXPECT_EQ(state->renderCalls, 1);
|
||||
EXPECT_EQ(state->lastSurfaceWidth, 640u);
|
||||
EXPECT_EQ(state->lastSurfaceHeight, 480u);
|
||||
@@ -90,6 +99,37 @@ TEST(CameraRenderer_Test, UsesOverrideCameraAndSurfaceSizeWhenSubmittingScene) {
|
||||
EXPECT_EQ(state->lastVisibleItemCount, 0u);
|
||||
}
|
||||
|
||||
TEST(SceneRenderer_Test, BuildsSingleExplicitRequestFromSelectedCamera) {
|
||||
Scene scene("SceneRendererRequestScene");
|
||||
|
||||
GameObject* lowCameraObject = scene.CreateGameObject("LowCamera");
|
||||
auto* lowCamera = lowCameraObject->AddComponent<CameraComponent>();
|
||||
lowCamera->SetPrimary(true);
|
||||
lowCamera->SetDepth(1.0f);
|
||||
|
||||
GameObject* highCameraObject = scene.CreateGameObject("HighCamera");
|
||||
auto* highCamera = highCameraObject->AddComponent<CameraComponent>();
|
||||
highCamera->SetPrimary(true);
|
||||
highCamera->SetDepth(5.0f);
|
||||
|
||||
SceneRenderer renderer;
|
||||
const RenderContext context = CreateValidContext();
|
||||
const RenderSurface surface(320, 180);
|
||||
|
||||
const std::vector<CameraRenderRequest> defaultRequests =
|
||||
renderer.BuildRenderRequests(scene, nullptr, context, surface);
|
||||
ASSERT_EQ(defaultRequests.size(), 1u);
|
||||
EXPECT_EQ(defaultRequests[0].camera, highCamera);
|
||||
EXPECT_EQ(defaultRequests[0].cameraDepth, 5.0f);
|
||||
EXPECT_EQ(defaultRequests[0].surface.GetWidth(), 320u);
|
||||
EXPECT_EQ(defaultRequests[0].surface.GetHeight(), 180u);
|
||||
|
||||
const std::vector<CameraRenderRequest> overrideRequests =
|
||||
renderer.BuildRenderRequests(scene, lowCamera, context, surface);
|
||||
ASSERT_EQ(overrideRequests.size(), 1u);
|
||||
EXPECT_EQ(overrideRequests[0].camera, lowCamera);
|
||||
}
|
||||
|
||||
TEST(SceneRenderer_Test, ForwardsPipelineLifetimeAndRenderCallsToCameraRenderer) {
|
||||
Scene scene("SceneRendererScene");
|
||||
|
||||
@@ -125,3 +165,37 @@ TEST(SceneRenderer_Test, ForwardsPipelineLifetimeAndRenderCallsToCameraRenderer)
|
||||
EXPECT_EQ(initialState->shutdownCalls, 1);
|
||||
EXPECT_EQ(replacementState->shutdownCalls, 1);
|
||||
}
|
||||
|
||||
TEST(SceneRenderer_Test, SortsManualCameraRequestsByDepthBeforeRendering) {
|
||||
Scene scene("SceneRendererManualRequests");
|
||||
|
||||
GameObject* farCameraObject = scene.CreateGameObject("FarCamera");
|
||||
auto* farCamera = farCameraObject->AddComponent<CameraComponent>();
|
||||
farCamera->SetPrimary(true);
|
||||
farCamera->SetDepth(10.0f);
|
||||
|
||||
GameObject* nearCameraObject = scene.CreateGameObject("NearCamera");
|
||||
auto* nearCamera = nearCameraObject->AddComponent<CameraComponent>();
|
||||
nearCamera->SetPrimary(false);
|
||||
nearCamera->SetDepth(1.0f);
|
||||
|
||||
auto state = std::make_shared<MockPipelineState>();
|
||||
SceneRenderer renderer(std::make_unique<MockPipeline>(state));
|
||||
|
||||
CameraRenderRequest farRequest;
|
||||
farRequest.scene = &scene;
|
||||
farRequest.camera = farCamera;
|
||||
farRequest.context = CreateValidContext();
|
||||
farRequest.surface = RenderSurface(800, 600);
|
||||
farRequest.cameraDepth = farCamera->GetDepth();
|
||||
|
||||
CameraRenderRequest nearRequest = farRequest;
|
||||
nearRequest.camera = nearCamera;
|
||||
nearRequest.cameraDepth = nearCamera->GetDepth();
|
||||
|
||||
const std::vector<CameraRenderRequest> requests = { farRequest, nearRequest };
|
||||
ASSERT_TRUE(renderer.Render(requests));
|
||||
ASSERT_EQ(state->renderedCameras.size(), 2u);
|
||||
EXPECT_EQ(state->renderedCameras[0], nearCamera);
|
||||
EXPECT_EQ(state->renderedCameras[1], farCamera);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user