feat: add explicit camera stack ordering

This commit is contained in:
2026-04-01 13:10:32 +08:00
parent f80fb9860e
commit a908e61ecb
6 changed files with 100 additions and 5 deletions

View File

@@ -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 };