129 lines
4.9 KiB
C++
129 lines
4.9 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include <XCEngine/Components/CameraComponent.h>
|
|
#include <XCEngine/Rendering/SceneRenderRequestPlanner.h>
|
|
#include <XCEngine/Scene/Scene.h>
|
|
|
|
using namespace XCEngine::Components;
|
|
using namespace XCEngine::Rendering;
|
|
|
|
namespace {
|
|
|
|
RenderContext CreateValidContext() {
|
|
RenderContext context;
|
|
context.device = reinterpret_cast<XCEngine::RHI::RHIDevice*>(1);
|
|
context.commandList = reinterpret_cast<XCEngine::RHI::RHICommandList*>(1);
|
|
context.commandQueue = reinterpret_cast<XCEngine::RHI::RHICommandQueue*>(1);
|
|
return context;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
TEST(SceneRenderRequestPlanner_Test, FallsBackToSceneCamerasWhenOverrideCameraIsNotUsable) {
|
|
Scene scene("SceneRenderRequestPlannerOverrideFallback");
|
|
|
|
GameObject* overrideObject = scene.CreateGameObject("Override");
|
|
auto* overrideCamera = overrideObject->AddComponent<CameraComponent>();
|
|
overrideCamera->SetDepth(-10.0f);
|
|
overrideCamera->SetEnabled(false);
|
|
|
|
GameObject* sceneCameraObject = scene.CreateGameObject("SceneCamera");
|
|
auto* sceneCamera = sceneCameraObject->AddComponent<CameraComponent>();
|
|
sceneCamera->SetDepth(3.0f);
|
|
|
|
SceneRenderRequestPlanner planner;
|
|
const std::vector<CameraComponent*> cameras = planner.CollectCameras(scene, overrideCamera);
|
|
|
|
ASSERT_EQ(cameras.size(), 1u);
|
|
EXPECT_EQ(cameras[0], sceneCamera);
|
|
}
|
|
|
|
TEST(SceneRenderRequestPlanner_Test, UsesOverrideCameraExclusivelyWhenItIsUsable) {
|
|
Scene scene("SceneRenderRequestPlannerOverrideOnly");
|
|
|
|
GameObject* overrideObject = scene.CreateGameObject("Override");
|
|
auto* overrideCamera = overrideObject->AddComponent<CameraComponent>();
|
|
overrideCamera->SetDepth(9.0f);
|
|
|
|
GameObject* sceneCameraObject = scene.CreateGameObject("SceneCamera");
|
|
auto* sceneCamera = sceneCameraObject->AddComponent<CameraComponent>();
|
|
sceneCamera->SetDepth(-5.0f);
|
|
|
|
SceneRenderRequestPlanner planner;
|
|
const std::vector<CameraComponent*> cameras = planner.CollectCameras(scene, overrideCamera);
|
|
|
|
ASSERT_EQ(cameras.size(), 1u);
|
|
EXPECT_EQ(cameras[0], overrideCamera);
|
|
}
|
|
|
|
TEST(SceneRenderRequestPlanner_Test, CollectsOnlyUsableSceneCamerasInStableRenderOrder) {
|
|
Scene scene("SceneRenderRequestPlannerCollectScene");
|
|
|
|
GameObject* inactiveObject = scene.CreateGameObject("Inactive");
|
|
auto* inactiveCamera = inactiveObject->AddComponent<CameraComponent>();
|
|
inactiveObject->SetActive(false);
|
|
|
|
GameObject* highBaseObject = scene.CreateGameObject("HighBase");
|
|
auto* highBase = highBaseObject->AddComponent<CameraComponent>();
|
|
highBase->SetDepth(10.0f);
|
|
highBase->SetStackType(CameraStackType::Base);
|
|
|
|
GameObject* firstTieObject = scene.CreateGameObject("FirstTie");
|
|
auto* firstTie = firstTieObject->AddComponent<CameraComponent>();
|
|
firstTie->SetDepth(2.0f);
|
|
firstTie->SetStackType(CameraStackType::Base);
|
|
|
|
GameObject* secondTieObject = scene.CreateGameObject("SecondTie");
|
|
auto* secondTie = secondTieObject->AddComponent<CameraComponent>();
|
|
secondTie->SetDepth(2.0f);
|
|
secondTie->SetStackType(CameraStackType::Base);
|
|
|
|
GameObject* overlayObject = scene.CreateGameObject("Overlay");
|
|
auto* overlay = overlayObject->AddComponent<CameraComponent>();
|
|
overlay->SetDepth(-10.0f);
|
|
overlay->SetStackType(CameraStackType::Overlay);
|
|
|
|
SceneRenderRequestPlanner planner;
|
|
const std::vector<CameraComponent*> cameras = planner.CollectCameras(scene, nullptr);
|
|
|
|
(void)inactiveCamera;
|
|
ASSERT_EQ(cameras.size(), 4u);
|
|
EXPECT_EQ(cameras[0], firstTie);
|
|
EXPECT_EQ(cameras[1], secondTie);
|
|
EXPECT_EQ(cameras[2], highBase);
|
|
EXPECT_EQ(cameras[3], overlay);
|
|
}
|
|
|
|
TEST(SceneRenderRequestPlanner_Test, BuildsRequestsAndDropsZeroSizedViewportsWithoutBreakingClearFlow) {
|
|
Scene scene("SceneRenderRequestPlannerBuildRequests");
|
|
|
|
GameObject* firstBaseObject = scene.CreateGameObject("FirstBase");
|
|
auto* firstBase = firstBaseObject->AddComponent<CameraComponent>();
|
|
firstBase->SetStackType(CameraStackType::Base);
|
|
firstBase->SetDepth(1.0f);
|
|
|
|
GameObject* skippedBaseObject = scene.CreateGameObject("SkippedBase");
|
|
auto* skippedBase = skippedBaseObject->AddComponent<CameraComponent>();
|
|
skippedBase->SetStackType(CameraStackType::Base);
|
|
skippedBase->SetDepth(2.0f);
|
|
skippedBase->SetViewportRect(XCEngine::Math::Rect(0.5f, 0.5f, 0.0f, 1.0f));
|
|
|
|
GameObject* overlayObject = scene.CreateGameObject("Overlay");
|
|
auto* overlay = overlayObject->AddComponent<CameraComponent>();
|
|
overlay->SetStackType(CameraStackType::Overlay);
|
|
overlay->SetDepth(3.0f);
|
|
|
|
SceneRenderRequestPlanner planner;
|
|
const std::vector<CameraRenderRequest> requests = planner.BuildRequests(
|
|
scene,
|
|
nullptr,
|
|
CreateValidContext(),
|
|
RenderSurface(640, 360));
|
|
|
|
ASSERT_EQ(requests.size(), 2u);
|
|
EXPECT_EQ(requests[0].camera, firstBase);
|
|
EXPECT_EQ(requests[0].clearFlags, RenderClearFlags::All);
|
|
EXPECT_EQ(requests[1].camera, overlay);
|
|
EXPECT_EQ(requests[1].clearFlags, RenderClearFlags::Depth);
|
|
}
|