2025-07-10 13:29:03 +03:30
|
|
|
#include <asset_manager/asset_manager.hpp>
|
2025-07-11 00:24:44 +03:30
|
|
|
#include <debug/assertions.hpp>
|
2025-07-05 13:28:41 +03:30
|
|
|
#include <engine/core/application.hpp>
|
|
|
|
#include <engine/core/window.hpp>
|
|
|
|
#include <engine/layer/layer.hpp>
|
|
|
|
#include <engine/time/timer.hpp>
|
2025-07-10 13:29:03 +03:30
|
|
|
#include <input/events/event.hpp>
|
|
|
|
#include <input/events/keyboard.hpp>
|
|
|
|
#include <input/events/window.hpp>
|
2025-07-06 16:30:38 +03:30
|
|
|
#include <ranges>
|
2025-07-10 13:29:03 +03:30
|
|
|
#include <renderer/blender.hpp>
|
|
|
|
#include <renderer/graphics_context.hpp>
|
|
|
|
#include <renderer/render_command.hpp>
|
|
|
|
#include <renderer/renderer.hpp>
|
|
|
|
#include <ui/ui.hpp>
|
2021-07-01 19:25:46 +04:30
|
|
|
|
2025-07-11 00:05:48 +03:30
|
|
|
namespace lt {
|
2021-05-20 10:21:08 +04:30
|
|
|
|
2025-07-06 17:45:40 +03:30
|
|
|
Application *Application::s_instance = nullptr;
|
|
|
|
|
2025-07-06 17:23:28 +03:30
|
|
|
Application::Application(): m_window(nullptr)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-06 17:45:40 +03:30
|
|
|
lt_assert(!s_instance, "Application constructed twice");
|
|
|
|
s_instance = this;
|
2021-10-02 08:51:54 +03:30
|
|
|
|
2025-07-06 17:23:28 +03:30
|
|
|
m_window = Window::create([this](auto &&PH1) { on_event(std::forward<decltype(PH1)>(PH1)); });
|
2025-07-10 13:29:03 +03:30
|
|
|
|
|
|
|
// create graphics context
|
|
|
|
m_graphics_context = GraphicsContext::create(
|
|
|
|
GraphicsAPI::OpenGL,
|
|
|
|
(GLFWwindow *)m_window->get_handle()
|
|
|
|
);
|
|
|
|
|
|
|
|
AssetManager::load_shader(
|
|
|
|
"LT_ENGINE_RESOURCES_TEXTURE_SHADER",
|
|
|
|
"data/assets/shaders/texture/vs.asset",
|
|
|
|
"data/assets/shaders/texture/ps.asset"
|
|
|
|
);
|
|
|
|
|
|
|
|
AssetManager::load_shader(
|
|
|
|
"LT_ENGINE_RESOURCES_TINTED_TEXTURE_SHADER",
|
|
|
|
"data/assets/shaders/tinted_texture/vs.asset",
|
|
|
|
"data/assets/shaders/tinted_texture/ps.asset"
|
|
|
|
);
|
|
|
|
|
|
|
|
AssetManager::load_shader(
|
|
|
|
"LT_ENGINE_RESOURCES_QUAD_SHADER",
|
|
|
|
"data/assets/shaders/quads/vs.asset",
|
|
|
|
"data/assets/shaders/quads/ps.asset"
|
|
|
|
);
|
|
|
|
|
|
|
|
m_renderer = Renderer::create(
|
|
|
|
(GLFWwindow *)m_window->get_handle(),
|
|
|
|
m_graphics_context->get_shared_context(),
|
|
|
|
Renderer::CreateInfo {
|
|
|
|
.quad_renderer_shader = AssetManager::get_shader("LT_ENGINE_RESOURCES_QUAD_SHADER"),
|
|
|
|
.texture_renderer_shader = AssetManager::get_shader("LT_ENGINE_RESOURCES_TEXTURE_SHADER"
|
|
|
|
),
|
|
|
|
.tinted_texture_renderer_shader = AssetManager::get_shader("LT_ENGINE_RESOURCES_TINTED_"
|
|
|
|
"TEXTURE_SHADER"),
|
|
|
|
}
|
|
|
|
);
|
|
|
|
lt_assert(m_graphics_context, "lWindow::lWindow: failed to create 'GraphicsContext'");
|
|
|
|
|
|
|
|
m_user_interface = UserInterface::create(
|
|
|
|
(GLFWwindow *)m_window->get_handle(),
|
|
|
|
m_graphics_context->get_shared_context()
|
|
|
|
);
|
2025-07-11 00:56:57 +03:30
|
|
|
|
|
|
|
m_layer_stack = create_scope<LayerStack>();
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
2021-05-20 10:21:08 +04:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
void Application::game_loop()
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-05 15:36:53 +03:30
|
|
|
m_window->set_visibility(true);
|
2021-06-14 10:01:28 +04:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
while (!m_window->is_closed())
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-11 00:49:04 +03:30
|
|
|
update_layers();
|
|
|
|
render_layers();
|
|
|
|
render_user_interface();
|
|
|
|
poll_events();
|
|
|
|
}
|
|
|
|
}
|
2025-07-07 15:13:05 +03:30
|
|
|
|
2025-07-11 00:49:04 +03:30
|
|
|
void Application::quit()
|
|
|
|
{
|
|
|
|
s_instance->m_window->close();
|
|
|
|
}
|
2021-07-21 15:14:22 +04:30
|
|
|
|
2025-07-11 00:49:04 +03:30
|
|
|
void Application::update_layers()
|
|
|
|
{
|
2025-07-11 00:56:57 +03:30
|
|
|
for (auto &it : *m_layer_stack)
|
2025-07-11 00:49:04 +03:30
|
|
|
{
|
|
|
|
it->on_update(m_timer.get_elapsed_time());
|
|
|
|
}
|
2021-07-21 15:14:22 +04:30
|
|
|
|
2025-07-11 00:49:04 +03:30
|
|
|
// TODO(Light): each layer should have their own "delta time"
|
|
|
|
m_timer.reset();
|
|
|
|
}
|
2021-07-12 15:20:47 +04:30
|
|
|
|
2025-07-11 00:49:04 +03:30
|
|
|
void Application::render_layers()
|
|
|
|
{
|
|
|
|
m_renderer->begin_frame();
|
2021-07-21 15:14:22 +04:30
|
|
|
|
2025-07-11 00:56:57 +03:30
|
|
|
for (auto &it : *m_layer_stack)
|
2025-07-11 00:49:04 +03:30
|
|
|
{
|
|
|
|
it->on_render();
|
|
|
|
}
|
2021-07-21 15:14:22 +04:30
|
|
|
|
2025-07-11 00:49:04 +03:30
|
|
|
m_renderer->end_frame();
|
|
|
|
}
|
2021-07-12 15:20:47 +04:30
|
|
|
|
2025-07-11 00:49:04 +03:30
|
|
|
void Application::render_user_interface()
|
|
|
|
{
|
|
|
|
m_user_interface->begin();
|
2021-07-09 09:55:05 +04:30
|
|
|
|
2025-07-11 00:56:57 +03:30
|
|
|
for (auto &it : *m_layer_stack)
|
2025-07-11 00:49:04 +03:30
|
|
|
{
|
|
|
|
it->on_user_interface_update();
|
2021-10-02 08:51:54 +03:30
|
|
|
}
|
|
|
|
|
2025-07-11 00:49:04 +03:30
|
|
|
m_user_interface->end();
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
2021-07-14 00:17:30 +04:30
|
|
|
|
2025-07-11 00:49:04 +03:30
|
|
|
void Application::poll_events()
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-11 00:49:04 +03:30
|
|
|
m_window->poll_events();
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
2021-05-27 18:55:30 +04:30
|
|
|
|
2025-07-05 15:36:53 +03:30
|
|
|
void Application::on_event(const Event &event)
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
|
|
|
// window
|
2025-07-05 15:36:53 +03:30
|
|
|
if (event.has_category(WindowEventCategory))
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-05 15:36:53 +03:30
|
|
|
m_window->on_event(event);
|
2021-07-21 20:03:39 +04:30
|
|
|
|
2025-07-06 17:23:28 +03:30
|
|
|
if (event.get_event_type() == EventType::WindowResized)
|
|
|
|
{
|
2025-07-10 13:29:03 +03:30
|
|
|
m_renderer->on_window_resize(dynamic_cast<const WindowResizedEvent &>(event));
|
2025-07-06 17:23:28 +03:30
|
|
|
}
|
2021-05-23 18:10:11 +04:30
|
|
|
}
|
|
|
|
|
2022-03-07 21:57:00 +03:30
|
|
|
// input
|
2025-07-05 15:36:53 +03:30
|
|
|
if (event.has_category(InputEventCategory))
|
2021-06-15 09:39:11 +04:30
|
|
|
{
|
2025-07-06 17:23:28 +03:30
|
|
|
Input::instance().on_event(event);
|
2022-03-07 21:57:00 +03:30
|
|
|
|
2025-07-06 17:23:28 +03:30
|
|
|
if (!Input::instance().is_receiving_game_events())
|
2025-07-06 16:30:38 +03:30
|
|
|
{
|
2022-03-07 21:57:00 +03:30
|
|
|
return;
|
2025-07-06 16:30:38 +03:30
|
|
|
}
|
2021-06-15 09:39:11 +04:30
|
|
|
}
|
|
|
|
|
2025-07-11 00:56:57 +03:30
|
|
|
for (auto &it : std::ranges::reverse_view(*m_layer_stack))
|
2025-07-06 16:30:38 +03:30
|
|
|
{
|
|
|
|
if (it->on_event(event))
|
|
|
|
{
|
2022-03-07 21:57:00 +03:30
|
|
|
return;
|
2025-07-06 16:30:38 +03:30
|
|
|
}
|
|
|
|
}
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
|
|
|
|
2025-07-11 00:24:44 +03:30
|
|
|
[[nodiscard]] auto Application::sanity_check() const -> bool
|
|
|
|
{
|
2025-07-11 00:49:04 +03:30
|
|
|
log_inf("Checking application sanity...");
|
|
|
|
lt_assert(s_instance, "Application not constructed!?");
|
|
|
|
lt_assert(m_window, "Window is not initialized");
|
|
|
|
lt_assert(m_user_interface, "User interface is not initialized");
|
|
|
|
lt_assert(m_graphics_context, "Graphics context is not initialized");
|
|
|
|
lt_assert(m_renderer, "Renderer is not initialized");
|
2025-07-11 00:56:57 +03:30
|
|
|
lt_assert(m_layer_stack, "Layer_stack is not initialized");
|
|
|
|
lt_assert(!m_layer_stack->is_empty(), "Layer_stack is empty");
|
2025-07-11 00:49:04 +03:30
|
|
|
|
|
|
|
log_inf("Logging application state...");
|
|
|
|
this->log_debug_data();
|
|
|
|
m_graphics_context->log_debug_data();
|
|
|
|
m_user_interface->log_debug_data();
|
|
|
|
|
2025-07-11 00:24:44 +03:30
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2025-07-11 00:49:04 +03:30
|
|
|
void Application::log_debug_data() const
|
2022-03-07 21:57:00 +03:30
|
|
|
{
|
2025-07-06 16:30:38 +03:30
|
|
|
log_inf("Platform::");
|
|
|
|
log_inf(" Platform name: {}", constants::platform_name);
|
|
|
|
log_inf(" Platform identifier: {}", std::to_underlying(constants::platform));
|
|
|
|
log_inf(" CWD: {}", std::filesystem::current_path().generic_string());
|
2022-03-07 21:57:00 +03:30
|
|
|
}
|
|
|
|
|
2025-07-11 00:05:48 +03:30
|
|
|
} // namespace lt
|