You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lunarium_OLD/src/core/core.cpp

301 lines
8.9 KiB
C++

/******************************************************************************
* File - core.cpp
* Author - Joey Pollack
* Date - 2021/08/30 (y/m/d)
* Mod Date - 2021/08/30 (y/m/d)
* Description - The Core Engine Class. Manages the engine components.
******************************************************************************/
#include "core.h"
#include "version.h"
// Run modes
#include <tester/tester.h>
// Sub Systems
#include <window/window.h>
#include <graphics/image.h>
#include <graphics/opengl/glGraphics.h>
#include <graphics/gui/gui.h>
#include <graphics/gui/logGui.h>
namespace lunarium
{
Core* Core::mpInstance = nullptr;
Core::Core()
: mbIsInit(false), mpArgs(nullptr), mpWindow(nullptr), mpGraphics(nullptr), mpInput(nullptr),
mGUI(GUI::GetInstance()), mbMidRender(false), mbMidTextureRender(false), mpRunMode(nullptr)
{
}
Core& Core::GetInstance()
{
if (!mpInstance)
{
mpInstance = new Core;
}
return *mpInstance;
}
////////////////////////////////////////////////////////////
// SHUTDOWN
////////////////////////////////////////////////////////////
void Core::Shutdown()
{
if (!mpInstance)
return;
Logger::Log(LogCategory::CORE, LogLevel::INFO, "Lunarium is shutting down!");
// Shutdown subsystems
LogGui::FreeInstance();
GUI::GetInstance().Shutdown();
GUI::FreeInstance();
mpInstance->mpInput->Shutdown();
delete mpInstance->mpInput;
mpInstance->mpInput = nullptr;
mpInstance->mpGraphics->Shutdown();
delete mpInstance->mpGraphics;
mpInstance->mpGraphics = nullptr;
mpInstance->mpWindow->Shutdown();
delete mpInstance->mpWindow;
mpInstance->mpWindow = nullptr;
delete mpInstance->mpArgs;
mpInstance->mpArgs = nullptr;
mpInstance->mpRunMode->Shutdown();
delete mpInstance->mpRunMode;
mpInstance->mpRunMode = nullptr;
mpInstance->mbIsInit = false;
delete mpInstance;
mpInstance = nullptr;
}
////////////////////////////////////////////////////////////
// INITIALIZATION
////////////////////////////////////////////////////////////
void Core::Initialize(int argc, char** argv)
{
// Setup the log system
mMasterLogFile.open("Lunarium_Master.log", std::ios_base::app);
mMasterLogFile << "\n\n";
mErrorLogFile.open("Lunarium_Errors.log", std::ios_base::app);
mErrorLogFile << "\n\n";
if (mMasterLogFile.is_open())
Logger::GetInstance()->AddListener(new FileListener(mMasterLogFile));
if (mErrorLogFile.is_open())
Logger::GetInstance()->AddListener(new FileListener(mErrorLogFile, LogLevel::ERROR | LogLevel::FATAL_ERROR));
// Init the Debug log window
OpRes result;
result = LogGui::GetInstance().Initialize();
if (Failed(result))
{
Logger::Log(LogCategory::CORE, LogLevel::WARNING,
"Could not initialized the debug log window: %s", result.Description);
}
Logger::Log(LogCategory::CORE, LogLevel::INFO, "Running Lunarium version %s", Version::GetVersion().ToString().c_str());
// Attempt to load the engine state file. This file should be placed in the same directory as the lunarium program.
if (Failed(State::CreateFromFile("lunarium_state.xml", mState)))
{
Logger::Log(LogCategory::CORE, LogLevel::WARNING, "Unable to load state file: lunarium_state.xml. Loading default state.");
mState = State::CreateDefault();
}
else
{
Logger::Log(LogCategory::CORE, LogLevel::INFO, "Loaded state file: lunarium_state.xml");
}
// RUN MODE
const char* types[] = { "game", "editor", "test"};
Logger::Log(LogCategory::CORE, LogLevel::INFO, "Running in mode: %s", types[mState.Mode]);
if (RunMode::MODE_TEST == mState.Mode)
{
mpRunMode = new Tester;
}
// Initialize the Run Mode
result = mpRunMode->Initialize();
if (Failed(result))
{
Logger::Log(LogCategory::CORE, LogLevel::FATAL_ERROR,
"Could not initialize the Run Mode: %s", result.Description);
return;
}
// Parse command line args -- None right now
std::vector<Args::SwitchDesc> sd;
mpArgs = new Args(argc, argv, '-', sd);
// Init Graphics/Window system
mpWindow = new Window;
result = mpWindow->Initialize(mState);
if (Failed(result))
{
Logger::Log(LogCategory::CORE, LogLevel::FATAL_ERROR,
"Could not initialize the Window system: %s", result.Description);
return;
}
if (Renderer::OPENGL == mState.Display.RenderFramework)
{
mpGraphics = new OglGraphics;
}
else if (Renderer::VULKAN == mState.Display.RenderFramework)
{
Logger::Log(LogCategory::CORE, LogLevel::FATAL_ERROR,
"Can not create Vulkan graphics system because it is not yet implemented. Must use OpenGL instead.");
return;
}
else
{
Logger::Log(LogCategory::CORE, LogLevel::FATAL_ERROR,
"Could not create graphics system: Unknown render framework specified.");
return;
}
// TODO: This should probably be based on a state setting instead
#ifdef _DEBUG
result = mpGraphics->Initialize(mpWindow);
#else
result = mpGraphics->Initialize(mpWindow, false);
#endif
if (Failed(result))
{
Logger::Log(LogCategory::CORE, LogLevel::FATAL_ERROR,
"Could not initialized the graphics system: %s", result.Description);
return;
}
mpGraphics->SetClearColor(Color(0.5f, 0.5f, 0.75f, 1.0f));
// INPUT
mpInput = new InputManager;
mpInput->Initialize(mpWindow);
// GUI
mGUI.Initialize(mpWindow);
result = LogGui::GetInstance().Initialize();
if (Failed(result))
{
Logger::Log(LogCategory::CORE, LogLevel::WARNING,
"Could not initialized the debug log window: %s", result.Description);
}
mbIsInit = true;
}
bool Core::IsInit() const
{
return mbIsInit;
}
const State& Core::GetState() const
{
return mState;
}
////////////////////////////////////////////////////////////
// GAME LOOP
////////////////////////////////////////////////////////////
void Core::RunGameLoop()
{
mFrameCounter.Reset();
// TODO: Init frame counter
while (!mpWindow->ShouldWindowClose())
{
mFrameCounter.NewFrame();
// Display FPS in window title for now
std::string title = "Lunarium - FPS: ";
title += std::to_string(mFrameCounter.GetFrameData().CurrentFPS);
glfwSetWindowTitle(mpWindow->GetWindow(), title.c_str());
// Poll input
Window::PollEvents();
mKeyEvents = mpInput->PollKeys();
// HACK: Temporary solution to close the program
if (mpInput->IsKeyDown(KeyCode::ESCAPE))
{
mpWindow->SetShouldCloseFlag(true);
}
if (mpInput->IsKeyPressed(KeyCode::F3))
{
//Logger::Log(LogCategory::CORE, LogLevel::INFO, "Toggling the Debug Log Window");
LogGui::GetInstance().SetShow(!LogGui::GetInstance().IsShown());
}
// TODO: Send input events
// Update game state
mpRunMode->OnTick(mFrameCounter.GetFrameData().LastFrameTime);
// Render
if (mbMidTextureRender)
{
Logger::Log(LogCategory::CORE, LogLevel::WARNING, "Render to texture was not ended!");
EndRenderToTexture();
}
mGUI.NewFrame();
mpGraphics->BeginDraw();
mbMidRender = true;
// DEBUG: Render test ImGUI window
// mGUI.ShowDemoWindow();
LogGui::GetInstance().Show();
mpRunMode->OnRender();
mGUI.EndFrame();
mpGraphics->EndDraw();
mbMidRender = false;
}
}
OpRes Core::BeginRenderToTexture()
{
if (mbMidRender)
{
return OpRes::Fail("Can not switch render targets in the middle of rendering");
}
mbMidTextureRender = true;
mpGraphics->BeginDraw(RenderTarget::RT_IMAGE);
return OpRes::OK();
}
Image* Core::EndRenderToTexture()
{
if (!mbMidTextureRender)
{
return nullptr;
}
mbMidTextureRender = false;
return mpGraphics->EndDraw();
}
}