/****************************************************************************** * 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" // Sub Systems #include #include #include namespace lunarium { Core* Core::mpInstance = nullptr; Core::Core() : mbIsInit(false), mpArgs(nullptr), mpWindow(nullptr), mpGraphics(nullptr), mpInput(nullptr), mGUI(GUI::GetInstance()) { } Core& Core::GetInstance() { if (!mpInstance) { mpInstance = new Core; } return *mpInstance; } void Core::Shutdown() { if (!mpInstance) return; Logger::Log(LogCategory::CORE, LogLevel::INFO, "Lunarium is shutting down!"); // Shutdown subsystems 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->mbIsInit = false; delete mpInstance; mpInstance = nullptr; } 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)); 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"); } // Parse command line args -- None right now std::vector sd; mpArgs = new Args(argc, argv, '-', sd); OpRes result; // 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); mbIsInit = true; } bool Core::IsInit() const { return mbIsInit; } const State& Core::GetState() const { return mState; } 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); } // DEBUG: Graphics testing static int width = 500; if (mpInput->IsKeyDown(KeyCode::LEFT)) { width -= 10; } if (mpInput->IsKeyDown(KeyCode::RIGHT)) { width += 10; } // Update game state // Render mGUI.NewFrame(); mpGraphics->BeginDraw(); // DEBUG: Render test ImGUI window mGUI.ShowDemoWindow(); // DEBUG: Graphics tests mpGraphics->DrawFilledEllipse(glm::vec2(600, 300), glm::vec2(100, 150), Color(1.0f, 0.0f, 1.0f, 1.0f), 100); mpGraphics->DrawString("This is a test of the text renderer!", Rectangle(100, 200, width, 300), Color(0.0f, 1.0f, 1.0f, 1.0f), 0.5f, mpGraphics->DefaultFont()); mpGraphics->EndDraw(); } } }