#include "application.h" #include #include #include "command_line.h" #include "imgui_impl_sdl3.h" #include "imgui_internal.h" #include "filesystem/stb_image.h" #include "rhi/texture.h" #include "spdlog/async.h" #include "spdlog/spdlog.h" #include "spdlog/sinks/basic_file_sink.h" #if WIN32 #include "rhi/windows/dx11/renderer_dx11.h" #endif bool g_is_running = true; bool g_exit_requested = false; application::~application() { application::shutdown(); } void application::init(window_params in_window_params, int argc, char** argv) { try { auto async_file = spdlog::basic_logger_mt("async_file_logger", "logs/log.txt"); } catch (const spdlog::spdlog_ex &ex) { std::cout << "Log init failed: " << ex.what() << std::endl; } command_line::instance().init(argc, argv); SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER); // Setup Dear ImGui context IMGUI_CHECKVERSION(); init_imgui(ImGui::CreateContext()); ImGuiIO& io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls ImGui::StyleColorsDark(); //ImGui::StyleColorsLight(); unsigned int window_flags = 0; #if WIN32 bool use_dx11 = false; bool use_dx12 = false; bool use_vulkan = false; #else bool use_vulkan = true; #endif #if WIN32 command_line::instance().get_arg("dx11", use_dx11); command_line::instance().get_arg("dx12", use_dx12); command_line::instance().get_arg("vulkan", use_vulkan); // only one renderer can be used at a time const int renderer_count = use_dx11 + use_dx12 + use_vulkan; assert(renderer_count <= 1); // if no renderer is specified, use dx11 if (!(use_dx11 || use_dx12 || use_vulkan)) { use_dx11 = true; } if (use_dx11) { renderer_ = new renderer_dx11(); } // if (use_dx12) // { // renderer_ = new renderer_dx12(); // } // if (use_vulkan) // { // renderer_ = new renderer_vulkan(); // window_flags |= SDL_WINDOW_VULKAN; // } #else if (use_vulkan) { renderer_ = new renderer_vulkan(); window_flags |= SDL_WINDOW_VULKAN; } #endif // if (!renderer_) // renderer_ = new renderer_null(); if (in_window_params.fullscreen) window_flags |= SDL_WINDOW_FULLSCREEN; if (in_window_params.borderless) window_flags |= SDL_WINDOW_BORDERLESS; if (in_window_params.resizable) window_flags |= SDL_WINDOW_RESIZABLE; if (in_window_params.minimized) window_flags |= SDL_WINDOW_MINIMIZED; if (in_window_params.maximized) window_flags |= SDL_WINDOW_MAXIMIZED; if (in_window_params.hi_dpi) window_flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY; if (in_window_params.always_on_top) window_flags |= SDL_WINDOW_ALWAYS_ON_TOP; // new SDL window window_ = SDL_CreateWindow(in_window_params.title.c_str(), in_window_params.width, in_window_params.height, window_flags); if (!window_) { spdlog::error("Failed to create SDL window: {}", SDL_GetError()); return; } SDL_SetWindowPosition(window_, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); SDL_ShowWindow(window_); renderer_->init(window_); renderer_->resize(in_window_params.width, in_window_params.height); g_is_running = true; } int application::run() { while (!g_exit_requested) { SDL_Event event; while (SDL_PollEvent(&event)) { ImGui_ImplSDL3_ProcessEvent(&event); if (event.type == SDL_EVENT_QUIT) g_exit_requested = true; if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window_)) g_exit_requested = true; if (event.type == SDL_EVENT_WINDOW_RESIZED) { const int width = event.window.data1; const int height = event.window.data2; renderer_->resize(width, height); } } if (g_exit_requested) break; renderer_->new_frame(); draw_gui(); renderer_->end_frame(); } return 0; } void application::shutdown() { renderer_->shutdown(); ImGui::DestroyContext(); delete renderer_; } texture* application::load_texture(const std::string& path) const { int width = 0; int height = 0; unsigned char* image_data = stbi_load(path.c_str(), &width, &height, nullptr, 4); if (!image_data) { spdlog::error("Failed to load texture: {}", path.c_str()); return nullptr; } const auto texture = renderer_->create_texture(image_data, width, height); stbi_image_free(image_data); return texture; } texture* application::create_texture(const unsigned char* data, const int width, const int height) const { return renderer_->create_texture(data, width, height); }