feat: add explicit camera stack ordering
This commit is contained in:
@@ -19,6 +19,7 @@ TEST(CameraComponent_Test, DefaultValues) {
|
||||
EXPECT_FLOAT_EQ(camera.GetFarClipPlane(), 1000.0f);
|
||||
EXPECT_TRUE(camera.IsPrimary());
|
||||
EXPECT_EQ(camera.GetClearMode(), CameraClearMode::Auto);
|
||||
EXPECT_EQ(camera.GetStackType(), CameraStackType::Base);
|
||||
EXPECT_EQ(camera.GetCullingMask(), 0xFFFFFFFFu);
|
||||
EXPECT_FLOAT_EQ(camera.GetViewportRect().x, 0.0f);
|
||||
EXPECT_FLOAT_EQ(camera.GetViewportRect().y, 0.0f);
|
||||
@@ -53,6 +54,7 @@ TEST(CameraComponent_Test, ViewportRectIsClampedToNormalizedSurfaceRange) {
|
||||
TEST(CameraComponent_Test, SerializeRoundTripPreservesViewportAndClearState) {
|
||||
CameraComponent source;
|
||||
source.SetClearMode(CameraClearMode::DepthOnly);
|
||||
source.SetStackType(CameraStackType::Overlay);
|
||||
source.SetCullingMask(0x0000000Fu);
|
||||
source.SetViewportRect(XCEngine::Math::Rect(0.25f, 0.125f, 0.5f, 0.625f));
|
||||
|
||||
@@ -63,6 +65,7 @@ TEST(CameraComponent_Test, SerializeRoundTripPreservesViewportAndClearState) {
|
||||
target.Deserialize(stream);
|
||||
|
||||
EXPECT_EQ(target.GetClearMode(), CameraClearMode::DepthOnly);
|
||||
EXPECT_EQ(target.GetStackType(), CameraStackType::Overlay);
|
||||
EXPECT_EQ(target.GetCullingMask(), 0x0000000Fu);
|
||||
EXPECT_FLOAT_EQ(target.GetViewportRect().x, 0.25f);
|
||||
EXPECT_FLOAT_EQ(target.GetViewportRect().y, 0.125f);
|
||||
|
||||
@@ -331,6 +331,64 @@ TEST(SceneRenderer_Test, BuildsSortedRequestsForAllUsableCamerasAndHonorsOverrid
|
||||
EXPECT_EQ(overrideRequests[0].clearFlags, RenderClearFlags::All);
|
||||
}
|
||||
|
||||
TEST(SceneRenderer_Test, RendersBaseCamerasBeforeOverlayCamerasAndResolvesAutoClearPerStackType) {
|
||||
Scene scene("SceneRendererCameraStackScene");
|
||||
|
||||
GameObject* lateBaseCameraObject = scene.CreateGameObject("LateBaseCamera");
|
||||
auto* lateBaseCamera = lateBaseCameraObject->AddComponent<CameraComponent>();
|
||||
lateBaseCamera->SetDepth(10.0f);
|
||||
lateBaseCamera->SetStackType(CameraStackType::Base);
|
||||
|
||||
GameObject* earlyBaseCameraObject = scene.CreateGameObject("EarlyBaseCamera");
|
||||
auto* earlyBaseCamera = earlyBaseCameraObject->AddComponent<CameraComponent>();
|
||||
earlyBaseCamera->SetDepth(1.0f);
|
||||
earlyBaseCamera->SetStackType(CameraStackType::Base);
|
||||
|
||||
GameObject* overlayCameraObject = scene.CreateGameObject("OverlayCamera");
|
||||
auto* overlayCamera = overlayCameraObject->AddComponent<CameraComponent>();
|
||||
overlayCamera->SetDepth(-10.0f);
|
||||
overlayCamera->SetStackType(CameraStackType::Overlay);
|
||||
|
||||
SceneRenderer renderer;
|
||||
const std::vector<CameraRenderRequest> requests =
|
||||
renderer.BuildRenderRequests(scene, nullptr, CreateValidContext(), RenderSurface(640, 360));
|
||||
|
||||
ASSERT_EQ(requests.size(), 3u);
|
||||
EXPECT_EQ(requests[0].camera, earlyBaseCamera);
|
||||
EXPECT_EQ(requests[0].cameraStackOrder, 0u);
|
||||
EXPECT_EQ(requests[0].clearFlags, RenderClearFlags::All);
|
||||
EXPECT_EQ(requests[1].camera, lateBaseCamera);
|
||||
EXPECT_EQ(requests[1].cameraStackOrder, 0u);
|
||||
EXPECT_EQ(requests[1].clearFlags, RenderClearFlags::Depth);
|
||||
EXPECT_EQ(requests[2].camera, overlayCamera);
|
||||
EXPECT_EQ(requests[2].cameraStackOrder, 1u);
|
||||
EXPECT_EQ(requests[2].clearFlags, RenderClearFlags::Depth);
|
||||
}
|
||||
|
||||
TEST(SceneRenderer_Test, FallsBackToColorClearForFirstOverlayCameraWhenNoBaseCameraExists) {
|
||||
Scene scene("SceneRendererOverlayOnlyScene");
|
||||
|
||||
GameObject* firstOverlayObject = scene.CreateGameObject("FirstOverlay");
|
||||
auto* firstOverlay = firstOverlayObject->AddComponent<CameraComponent>();
|
||||
firstOverlay->SetDepth(1.0f);
|
||||
firstOverlay->SetStackType(CameraStackType::Overlay);
|
||||
|
||||
GameObject* secondOverlayObject = scene.CreateGameObject("SecondOverlay");
|
||||
auto* secondOverlay = secondOverlayObject->AddComponent<CameraComponent>();
|
||||
secondOverlay->SetDepth(2.0f);
|
||||
secondOverlay->SetStackType(CameraStackType::Overlay);
|
||||
|
||||
SceneRenderer renderer;
|
||||
const std::vector<CameraRenderRequest> requests =
|
||||
renderer.BuildRenderRequests(scene, nullptr, CreateValidContext(), RenderSurface(320, 180));
|
||||
|
||||
ASSERT_EQ(requests.size(), 2u);
|
||||
EXPECT_EQ(requests[0].camera, firstOverlay);
|
||||
EXPECT_EQ(requests[0].clearFlags, RenderClearFlags::All);
|
||||
EXPECT_EQ(requests[1].camera, secondOverlay);
|
||||
EXPECT_EQ(requests[1].clearFlags, RenderClearFlags::Depth);
|
||||
}
|
||||
|
||||
TEST(SceneRenderer_Test, HonorsExplicitOverrideCameraClearMode) {
|
||||
Scene scene("SceneRendererOverrideClearModeScene");
|
||||
|
||||
@@ -493,11 +551,13 @@ TEST(SceneRenderer_Test, SortsManualCameraRequestsByDepthBeforeRendering) {
|
||||
farRequest.context = CreateValidContext();
|
||||
farRequest.surface = RenderSurface(800, 600);
|
||||
farRequest.cameraDepth = farCamera->GetDepth();
|
||||
farRequest.cameraStackOrder = 1;
|
||||
farRequest.clearFlags = RenderClearFlags::None;
|
||||
|
||||
CameraRenderRequest nearRequest = farRequest;
|
||||
nearRequest.camera = nearCamera;
|
||||
nearRequest.cameraDepth = nearCamera->GetDepth();
|
||||
nearRequest.cameraStackOrder = 0;
|
||||
nearRequest.clearFlags = RenderClearFlags::Depth;
|
||||
|
||||
const std::vector<CameraRenderRequest> requests = { farRequest, nearRequest };
|
||||
|
||||
Reference in New Issue
Block a user