213 lines
6.1 KiB
C++
213 lines
6.1 KiB
C++
#include "Lightkeeper.h"
|
|
|
|
#include <destrum/Components/CameraComponent.h>
|
|
#include <destrum/FS/AssetFS.h>
|
|
#include <destrum/Scene/Scene.h>
|
|
|
|
#include <components/FirstPersonController.h>
|
|
#include <components/GameComponentRegistry.h>
|
|
|
|
LightKeeper::LightKeeper() : App()
|
|
{
|
|
}
|
|
|
|
LightKeeper::~LightKeeper()
|
|
{
|
|
if (!cleanedUp) {
|
|
try {
|
|
cleanup();
|
|
} catch (...) {
|
|
}
|
|
}
|
|
}
|
|
|
|
void LightKeeper::customInit()
|
|
{
|
|
RegisterGameComponents();
|
|
|
|
resources.init(gfxDevice);
|
|
renderer.init(gfxDevice, resources, m_params.renderSize);
|
|
|
|
const float aspectRatio = static_cast<float>(m_params.renderSize.x) / static_cast<float>(m_params.renderSize.y);
|
|
camera.setAspectRatio(aspectRatio);
|
|
camera.SetRotation(glm::radians(glm::vec2(90.f, 0.f)));
|
|
window.Maximize();
|
|
|
|
setupSkybox();
|
|
|
|
auto& scene = SceneManager::GetInstance().CreateScene("Main");
|
|
mainScene = BuildMainScene(scene, gfxDevice, resources);
|
|
|
|
debug2DTexture = resources.loadImageFromFile(
|
|
gfxDevice, AssetFS::GetInstance().GetFullPath("engine://textures/kobe.png"));
|
|
|
|
}
|
|
|
|
void LightKeeper::setupSkybox()
|
|
{
|
|
const auto skyboxPath = AssetFS::GetInstance().GetCookedPathForFile("engine://DJI_0001_stitch.jpg");
|
|
const auto vertShaderPath = AssetFS::GetInstance().GetCookedPathForFile("engine://shaders/cubemap.vert");
|
|
const auto fragShaderPath = AssetFS::GetInstance().GetCookedPathForFile("engine://shaders/cubemap.frag");
|
|
|
|
skyboxCubemap = std::make_unique<CubeMap>();
|
|
skyboxCubemap->LoadCubeMap(gfxDevice, resources, skyboxPath.generic_string());
|
|
skyboxCubemap->InitCubemapPipeline(gfxDevice, resources, vertShaderPath.generic_string(), fragShaderPath.generic_string());
|
|
skyboxCubemap->CreateCubeMap(gfxDevice, resources);
|
|
|
|
renderer.setSkyboxTexture(skyboxCubemap->GetCubeMapImageID());
|
|
}
|
|
|
|
void LightKeeper::customUpdate(float dt)
|
|
{
|
|
updateViewMode();
|
|
|
|
// LightKeeper owns a camera that hides App::camera; update this instance
|
|
// after SDL events have been consumed.
|
|
if (!isPlayerViewActive() && getSceneCamera() == nullptr)
|
|
{
|
|
camera.Update(dt);
|
|
}
|
|
if (InputManager::GetInstance().WasKeyPressed(SDL_SCANCODE_F11))
|
|
{
|
|
window.ToggleFullscreen();
|
|
}
|
|
|
|
SceneManager::GetInstance().Update(dt);
|
|
SceneManager::GetInstance().LateUpdate(dt);
|
|
|
|
updateDebugUi();
|
|
}
|
|
|
|
void LightKeeper::updateViewMode()
|
|
{
|
|
auto& input = InputManager::GetInstance();
|
|
FirstPersonController* player = mainScene.playerController;
|
|
|
|
if (isPlaying() && !isPaused() && player != nullptr && input.WasKeyPressed(SDL_SCANCODE_F6))
|
|
{
|
|
player->SetPossessed(!player->IsPossessed());
|
|
}
|
|
|
|
if (!isPlayerViewActive())
|
|
{
|
|
const bool looking = input.IsMouseDown(SDL_BUTTON_RIGHT);
|
|
if (looking != input.IsMouseCaptured())
|
|
{
|
|
input.SetMouseCaptured(looking);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool LightKeeper::isPlayerViewActive() const
|
|
{
|
|
return isPlaying() && !isPaused() && mainScene.playerController != nullptr && mainScene.playerController->IsPossessed();
|
|
}
|
|
|
|
CameraComponent* LightKeeper::getSceneCamera() const
|
|
{
|
|
const auto& activeScenes = SceneManager::GetInstance().GetActiveScenes();
|
|
if (!isPlaying() || useFreeCamera || activeScenes.empty()) {
|
|
return nullptr;
|
|
}
|
|
return activeScenes.front()->GetCurrentCamera();
|
|
}
|
|
|
|
Camera& LightKeeper::getViewCamera()
|
|
{
|
|
CameraComponent* sceneCamera = isPlayerViewActive() ? nullptr : getSceneCamera();
|
|
return sceneCamera != nullptr ? sceneCamera->GetCamera(camera.GetAspectRatio()) : camera;
|
|
}
|
|
|
|
void LightKeeper::customDraw()
|
|
{
|
|
const auto cmd = gfxDevice.beginFrame();
|
|
if (cmd == VK_NULL_HANDLE) {
|
|
return;
|
|
}
|
|
|
|
renderer.beginDrawing(gfxDevice);
|
|
submitDebugDraws();
|
|
|
|
if (isPlayerViewActive())
|
|
{
|
|
camera.SetRotation(mainScene.playerController->GetYaw(), mainScene.playerController->GetPitch());
|
|
camera.m_position = mainScene.playerController->GetEyePosition();
|
|
camera.CalculateViewMatrix();
|
|
camera.CalculateProjectionMatrix();
|
|
}
|
|
|
|
Camera& viewCamera = getViewCamera();
|
|
|
|
const SceneEnvironment& environment = SceneManager::GetInstance().GetCurrentScene().GetEnvironment();
|
|
const GameRenderer::SceneData sceneData{
|
|
.camera = viewCamera,
|
|
.ambientColor = environment.ambientColor,
|
|
.ambientIntensity = environment.ambientIntensity,
|
|
.fogColor = environment.fogColor,
|
|
.fogDensity = environment.fogDensity,
|
|
.skyboxRotation = environment.skyboxRotation,
|
|
};
|
|
|
|
const RenderContext ctx{
|
|
.renderer = renderer,
|
|
.camera = viewCamera,
|
|
.sceneData = sceneData,
|
|
};
|
|
|
|
SceneManager::GetInstance().Render(ctx);
|
|
renderer.endDrawing();
|
|
|
|
const auto& drawImage = renderer.getDrawImage();
|
|
|
|
renderer.draw(cmd, gfxDevice, viewCamera, sceneData);
|
|
|
|
gfxDevice.endFrame(
|
|
cmd, drawImage, {
|
|
.clearColor = {{0.f, 0.f, 0.5f, 1.f}},
|
|
.drawImageBlitRect = glm::ivec4{},
|
|
.imguiPass = &imguiPass,
|
|
});
|
|
}
|
|
|
|
void LightKeeper::customCleanup()
|
|
{
|
|
SceneManager::GetInstance().Destroy();
|
|
|
|
if (skyboxCubemap)
|
|
{
|
|
skyboxCubemap->cleanup(gfxDevice);
|
|
skyboxCubemap.reset();
|
|
}
|
|
|
|
renderer.cleanup(gfxDevice);
|
|
}
|
|
|
|
void LightKeeper::customFixedUpdate(float dt)
|
|
{
|
|
SceneManager::GetInstance().FixedUpdate(dt);
|
|
}
|
|
|
|
void LightKeeper::onPlayModeChanged(bool nowPlaying)
|
|
{
|
|
findPlayer();
|
|
if (nowPlaying) {
|
|
// The player view moves the free camera, put it back where the editor left it on Stop
|
|
editorCamera = camera;
|
|
if (mainScene.playerController != nullptr) {
|
|
mainScene.playerController->SetPossessed(true);
|
|
}
|
|
} else if (editorCamera) {
|
|
const float aspectRatio = camera.GetAspectRatio();
|
|
camera = *editorCamera;
|
|
camera.setAspectRatio(aspectRatio);
|
|
editorCamera.reset();
|
|
}
|
|
}
|
|
|
|
void LightKeeper::onWindowResize(int newWidth, int newHeight)
|
|
{
|
|
renderer.resize(gfxDevice, glm::ivec2{newWidth, newHeight});
|
|
const float aspectRatio = static_cast<float>(newWidth) / static_cast<float>(newHeight);
|
|
camera.setAspectRatio(aspectRatio);
|
|
}
|