diff --git a/CMakeLists.txt b/CMakeLists.txt index 21d6b8d..26bed19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,6 +80,10 @@ FetchContent_Declare( GIT_TAG v3.4.0 ) FetchContent_MakeAvailable(tomlplusplus) + +add_subdirectory(third_party/imgui) + + set(INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include) add_executable(${PROJECT_NAME} @@ -88,6 +92,7 @@ add_executable(${PROJECT_NAME} src/debug_collector.cpp src/camera.cpp src/config.cpp + src/dev_panel.cpp src/gameplay/biome.cpp src/gameplay/chunk.cpp src/gameplay/player.cpp @@ -143,6 +148,7 @@ target_link_libraries(${PROJECT_NAME} soil2 Freetype::Freetype tomlplusplus::tomlplusplus + imgui ) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") diff --git a/include/Cubed/app.hpp b/include/Cubed/app.hpp index af23e54..045b18c 100644 --- a/include/Cubed/app.hpp +++ b/include/Cubed/app.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -18,16 +19,26 @@ public: static void window_focus_callback(GLFWwindow* window, int focused); static void window_reshape_callback(GLFWwindow* window, int new_width, int new_height); static void mouse_scroll_callback(GLFWwindow* window, double xoffset, double yoffset); - + static void cursor_enter_callback(GLFWwindow* window, int entered); static int start_cubed_application(int argc, char** argv); static unsigned int seed(); static float delte_time(); static float get_fps(); + + Camera& camera(); + DevPanel& dev_panel(); + Renderer& renderer(); + TextureManager& texture_manager(); + Window& window(); + World& world(); + + private: Camera m_camera; TextureManager m_texture_manager; World m_world; - Renderer m_renderer{m_camera, m_world, m_texture_manager}; + DevPanel m_dev_panel{*this}; + Renderer m_renderer{m_camera, m_world, m_texture_manager, m_dev_panel}; Window m_window{m_renderer}; diff --git a/include/Cubed/config.hpp b/include/Cubed/config.hpp index a80f9ea..a52a417 100644 --- a/include/Cubed/config.hpp +++ b/include/Cubed/config.hpp @@ -114,8 +114,14 @@ public: std::abort(); } table->insert_or_assign(n_key, std::forward(val)); + + } + template + void set_and_save(std::string_view key, T&& val) { + set(key, std::forward(val)); save_to_file(); } + toml::node_view val_view(std::string_view key); private: diff --git a/include/Cubed/dev_panel.hpp b/include/Cubed/dev_panel.hpp new file mode 100644 index 0000000..930a003 --- /dev/null +++ b/include/Cubed/dev_panel.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include + +namespace Cubed { + +class App; +class Player; +class DevPanel { + struct ConfigView { + float fov; + bool fullscreen; + bool v_sync; + float mouse_sensitivity; + int width; + int height; + int rendering_distance; + }; +public: + DevPanel(App& app); + void init(); + void render(); + +private: + App& m_app; + ConfigView m_config; + Player* m_player; + + bool m_need_save_config = false; + int m_theme = 0; + void show_settings_tab_item(); +}; + + +} \ No newline at end of file diff --git a/include/Cubed/renderer.hpp b/include/Cubed/renderer.hpp index 2d4ebb5..9f6ec4b 100644 --- a/include/Cubed/renderer.hpp +++ b/include/Cubed/renderer.hpp @@ -13,11 +13,12 @@ namespace Cubed { class Camera; class TextureManager; class World; +class DevPanel; class Renderer { public: constexpr static int NUM_VAO = 5; - Renderer(const Camera& camera, World& world, const TextureManager& texture_manager); + Renderer(const Camera& camera, World& world, const TextureManager& texture_manager, DevPanel& dev_panel); ~Renderer(); void hot_reload(); void init(); @@ -28,6 +29,7 @@ public: private: const Camera& m_camera; + DevPanel& m_dev_panel; const TextureManager& m_texture_manager; World& m_world; @@ -57,6 +59,7 @@ private: void render_text(); void render_ui(); void render_world(); + void render_dev_panel(); }; } \ No newline at end of file diff --git a/include/Cubed/tools/font.hpp b/include/Cubed/tools/font.hpp index 6b4437c..cc6f7a6 100644 --- a/include/Cubed/tools/font.hpp +++ b/include/Cubed/tools/font.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -31,6 +32,7 @@ public: static std::vector vertices(const std::string& text, float x = 0.0f, float y = 0.0f, float scale = 1.0f); static GLuint text_texture(); + static const std::filesystem::path& font_path(); private: FT_Library m_ft; FT_Face m_face; @@ -39,6 +41,7 @@ private: float m_texture_height = 64; static inline GLuint m_text_texture; + static inline std::filesystem::path m_font_path{ASSETS_PATH "fonts/IBMPlexSans-Regular.ttf"}; std::unordered_map m_characters; void load_character(char8_t c); diff --git a/include/Cubed/window.hpp b/include/Cubed/window.hpp index 4ef58e9..4c59667 100644 --- a/include/Cubed/window.hpp +++ b/include/Cubed/window.hpp @@ -12,6 +12,7 @@ public: const GLFWwindow* get_glfw_window() const; GLFWwindow* get_glfw_window(); void init(); + void imgui_init(); void update_viewport(); // end of frame to reload! void hot_reload(); diff --git a/src/app.cpp b/src/app.cpp index 05dff14..299a908 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include namespace Cubed { @@ -21,8 +23,15 @@ App::~App() { } void App::cursor_position_callback(GLFWwindow* window, double xpos, double ypos) { + ImGuiIO& io = ImGui::GetIO(); + App* app = static_cast(glfwGetWindowUserPointer(window)); + ASSERT_MSG(app, "nullptr"); + if (io.WantCaptureMouse && app->m_window.is_mouse_enable()) { + ImGui_ImplGlfw_CursorPosCallback(window, xpos, ypos); + return; + } if (!app->m_window.is_mouse_enable()) { app->m_camera.update_cursor_position_camera(xpos, ypos); } @@ -30,6 +39,7 @@ void App::cursor_position_callback(GLFWwindow* window, double xpos, double ypos) } void App::init() { m_window.init(); + m_window.imgui_init(); Logger::info("Window Init Success"); glfwSetWindowUserPointer(m_window.get_glfw_window(), this); @@ -40,6 +50,9 @@ void App::init() { glfwSetWindowSizeCallback(m_window.get_glfw_window(), window_reshape_callback); glfwSetKeyCallback(m_window.get_glfw_window(), key_callback); glfwSetScrollCallback(m_window.get_glfw_window(), mouse_scroll_callback); + glfwSetCursorEnterCallback(m_window.get_glfw_window(), cursor_enter_callback); + + PerlinNoise::init(); m_renderer.init(); @@ -52,21 +65,27 @@ void App::init() { Logger::info("World Init Success"); m_camera.camera_init(&m_world.get_player("TestPlayer")); - + m_dev_panel.init(); } void App::key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { + ImGuiIO& io = ImGui::GetIO(); + App* app = static_cast(glfwGetWindowUserPointer(window)); ASSERT_MSG(app, "nullptr"); + //ImGui_ImplGlfw_CursorEnterCallback(window, !app->m_window.is_mouse_enable()); + if (io.WantCaptureKeyboard && app->m_window.is_mouse_enable()) { + if ((key == GLFW_KEY_LEFT_ALT || key == GLFW_KEY_ESCAPE) && action == GLFW_PRESS) { + app->m_window.toggle_mouse_able(); + app->m_camera.reset_camera(); + return; + } + ImGui_ImplGlfw_KeyCallback(window, key, scancode, action, mods); + return; + } switch(key) { case GLFW_KEY_Q: if (action == GLFW_PRESS) { - - if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) { - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); - } else if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_NORMAL) { - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - } } break; case GLFW_KEY_ESCAPE: @@ -84,9 +103,10 @@ void App::key_callback(GLFWwindow* window, int key, int scancode, int action, in app->m_texture_manager.need_reload(); } break; - case GLFW_KEY_P: + case GLFW_KEY_LEFT_ALT: if (action == GLFW_PRESS) { app->m_window.toggle_mouse_able(); + app->m_camera.reset_camera(); } break; @@ -95,10 +115,22 @@ void App::key_callback(GLFWwindow* window, int key, int scancode, int action, in app->m_world.get_player("TestPlayer").update_player_move_state(key, action); } -void App::mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { +void App::mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { + ImGuiIO& io = ImGui::GetIO(); + App* app = static_cast(glfwGetWindowUserPointer(window)); + ASSERT_MSG(app, "nullptr"); + if (io.WantCaptureMouse && app->m_window.is_mouse_enable()) { + ImGui_ImplGlfw_MouseButtonCallback(window, button, action, mods); + return; + } switch (button) { case GLFW_MOUSE_BUTTON_LEFT: if (action == GLFW_PRESS) { + if(app->m_window.is_mouse_enable()) { + app->m_window.toggle_mouse_able(); + app->m_camera.reset_camera(); + break;; + } Input::get_input_state().mouse_state.left = true; } if (action == GLFW_RELEASE) { @@ -117,8 +149,13 @@ void App::mouse_button_callback(GLFWwindow* window, int button, int action, int } void App::window_focus_callback(GLFWwindow* window, int focused) { + ImGuiIO& io = ImGui::GetIO(); App* app = static_cast(glfwGetWindowUserPointer(window)); ASSERT_MSG(app, "nullptr"); + if (io.WantCaptureMouse && app->m_window.is_mouse_enable()) { + ImGui_ImplGlfw_WindowFocusCallback(window, focused); + return; + } if (focused) { app->m_camera.reset_camera(); } @@ -126,23 +163,45 @@ void App::window_focus_callback(GLFWwindow* window, int focused) { } void App::window_reshape_callback(GLFWwindow* window, int new_width, int new_height) { + App* app = static_cast(glfwGetWindowUserPointer(window)); ASSERT_MSG(app, "nullptr"); app->m_window.update_viewport(); } void App::mouse_scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { + ImGuiIO& io = ImGui::GetIO(); + App* app = static_cast(glfwGetWindowUserPointer(window)); + ASSERT_MSG(app, "nullptr"); + if (io.WantCaptureMouse && app->m_window.is_mouse_enable()) { + ImGui_ImplGlfw_ScrollCallback(window, xoffset, yoffset); + return; + } auto& player = app->m_world.get_player("TestPlayer"); player.update_scroll(yoffset); } -void App::render() { +void App::cursor_enter_callback(GLFWwindow* window, int entered) { + ImGuiIO& io = ImGui::GetIO(); + App* app = static_cast(glfwGetWindowUserPointer(window)); + ASSERT_MSG(app, "nullptr"); + if (io.WantCaptureMouse && app->m_window.is_mouse_enable()) { + ImGui_ImplGlfw_CursorEnterCallback(window, entered); + return; + } +} +void App::render() { + + if (glfwGetWindowAttrib(m_window.get_glfw_window(), GLFW_ICONIFIED) != 0) + { + ImGui_ImplGlfw_Sleep(10); + return; + } m_renderer.render(); glfwSwapBuffers(m_window.get_glfw_window()); - } void App::run() { @@ -178,11 +237,12 @@ void App::update() { const auto& player= m_world.get_player("TestPlayer"); if (player_gait != player.get_gait()) { player_gait = player.get_gait(); + float fov = static_cast(Config::get().get("player.fov")); if (player_gait == Gait::WALK) { - m_renderer.update_fov(NORMAL_FOV); + m_renderer.update_fov(fov); } if (player_gait == Gait::RUN) { - m_renderer.update_fov(NORMAL_FOV + 3.0f); + m_renderer.update_fov(fov + 5.0f); } } @@ -216,4 +276,23 @@ float App::get_fps() { return fps; } +Camera& App::camera() { + return m_camera; +} +DevPanel& App::dev_panel() { + return m_dev_panel; +} +Renderer& App::renderer() { + return m_renderer; +} +TextureManager& App::texture_manager() { + return m_texture_manager; +} +Window& App::window() { + return m_window; +} +World& App::world() { + return m_world; +} + } \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp index adfdd89..a6d962c 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -44,6 +44,8 @@ void Config::create_config() { [world] rendering_distance = 24 + [devpanel] + theme = 0 # 0 is Dark Theme, 1 is Light Theme )"sv; try { @@ -79,5 +81,40 @@ void Config::save_to_file() { Logger::info("Save File Success"); } +toml::node_view Config::val_view(std::string_view key) { + size_t cur = 0; + auto pos = key.find('.'); + toml::table* table = &m_tbl; + while (pos != std::string_view::npos) { + std::string_view s = key.substr(cur, pos - cur); + if (s.empty()) { + Logger::error("Empty key/table name in path '{}'", key); + ASSERT(false); + std::abort(); + } + cur = pos + 1; + pos = key.find('.', cur); + if (auto* next = (*table)[s].as_table()) { + table = next; + } else { + Logger::error("Can't find table {}", s); + ASSERT(false); + std::abort(); + } + } + std::string_view n_key = key.substr(cur); + if (n_key.empty()) { + Logger::error("Trailing dot in path '{}'", key); + ASSERT(false); + std::abort(); + } + auto view = (*table)[n_key]; + if (!view) { + Logger::error("The view is null"); + ASSERT(false); + std::abort(); + } + return view; +} } \ No newline at end of file diff --git a/src/dev_panel.cpp b/src/dev_panel.cpp new file mode 100644 index 0000000..4ab2075 --- /dev/null +++ b/src/dev_panel.cpp @@ -0,0 +1,115 @@ +#include +#include +#include +#include + +#include +#include +#include + +namespace Cubed { + +DevPanel::DevPanel(App& app) : + m_app(app) +{ + +} + +void DevPanel::init() { + m_player = &m_app.world().get_player("TestPlayer"); + auto config = Config::get(); + m_config.fov = static_cast(config.val_view("player.fov").value_or(70.0)); + m_config.fullscreen = config.val_view("window.fullscreen").value_or(false); + m_config.v_sync = config.val_view("window.V-Sync").value_or(true); + m_config.mouse_sensitivity = static_cast(config.val_view("player.mouse_sensitivity").value_or(0.15)); + m_config.width = config.val_view("window.width").value_or(800); + m_config.height = config.val_view("window.height").value_or(600); + m_config.rendering_distance = config.val_view("world.rendering_distance").value_or(24); + m_theme = config.val_view("devpanel.theme").value_or(0); + if (m_theme != 1 && m_theme != 0) { + m_theme = 0; + } +} + +void DevPanel::render() { + ASSERT_MSG(m_player, "Player Is Null"); + /* + if (glfwGetWindowAttrib(window, GLFW_ICONIFIED) != 0) + { + ImGui_ImplGlfw_Sleep(10); + continue; + } + */ + + + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + ImGui::Begin("DevPanel"); + ImGui::Text("This is a DevPanel to control the game\n"); + if (ImGui::BeginTabBar("Bar")) { + show_settings_tab_item(); + ImGui::EndTabBar(); + } + ImGui::End(); + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + +} + +void DevPanel::show_settings_tab_item() { + if (ImGui::BeginTabItem("settings")) { + if(ImGui::SliderFloat("FOV", &m_config.fov, 1.0f, 140.0f)) { + Config::get().set("player.fov", static_cast(m_config.fov)); + m_app.renderer().hot_reload(); + } + ImGui::SameLine(); + if (ImGui::Button("default##1")) { + m_config.fov = NORMAL_FOV; + Config::get().set("player.fov", static_cast(m_config.fov)); + m_app.renderer().hot_reload(); + } + if (ImGui::SliderFloat("Sensitivity", &m_config.mouse_sensitivity, 0.01f, 1.0f)) { + Config::get().set("player.mouse_sensitivity", static_cast(m_config.mouse_sensitivity)); + m_player->hot_reload(); + } + ImGui::SameLine(); + if (ImGui::Button("default##2")) { + m_config.mouse_sensitivity = 0.15f; + Config::get().set("player.mouse_sensitivity", static_cast(m_config.mouse_sensitivity)); + m_player->hot_reload(); + } + if (ImGui::SliderInt("Distance", &m_config.rendering_distance, 2, 128)) { + Config::get().set("world.rendering_distance", m_config.rendering_distance); + m_app.world().hot_reload(); + } + if (ImGui::Checkbox("Fullscreen", &m_config.fullscreen)) { + Config::get().set("window.fullscreen", m_config.fullscreen); + m_app.window().hot_reload(); + } + ImGui::SameLine(); + if (ImGui::Checkbox("V-Sync", &m_config.v_sync)) { + Config::get().set("window.V-Sync", m_config.v_sync); + m_app.window().hot_reload(); + } + constexpr const char* THEMES[] = {"Dark", "Light"}; + if (ImGui::Combo("Theme", &m_theme, THEMES, IM_ARRAYSIZE(THEMES))) { + if (m_theme == 0) { + ImGui::StyleColorsDark(); + } else if (m_theme == 1) { + ImGui::StyleColorsLight(); + } + Config::get().set("devpanel.theme", m_theme); + } + if (ImGui::Button("save")) { + Config::get().save_to_file(); + } + + ImGui::EndTabItem(); + } + +} + +} \ No newline at end of file diff --git a/src/renderer.cpp b/src/renderer.cpp index 8191fd9..9409d12 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -19,8 +20,9 @@ #include namespace Cubed { -Renderer::Renderer(const Camera& camera, World& world, const TextureManager& texture_manager): +Renderer::Renderer(const Camera& camera, World& world, const TextureManager& texture_manager, DevPanel& dev_panel): m_camera(camera), + m_dev_panel(dev_panel), m_texture_manager(texture_manager), m_world(world) { @@ -144,6 +146,7 @@ void Renderer::render() { glBindVertexArray(m_vao[4]); render_text(); glBindVertexArray(0); + render_dev_panel(); } void Renderer::render_outline() { @@ -282,4 +285,10 @@ void Renderer::render_world() { m_world.render(m_mvp_mat); } +void Renderer::render_dev_panel() { + glDisable(GL_DEPTH_TEST); + m_dev_panel.render(); + glEnable(GL_DEPTH_TEST); +} + } \ No newline at end of file diff --git a/src/tools/font.cpp b/src/tools/font.cpp index d89eb0c..0cc360d 100644 --- a/src/tools/font.cpp +++ b/src/tools/font.cpp @@ -4,6 +4,8 @@ #include #include +namespace fs = std::filesystem; + namespace Cubed { @@ -12,7 +14,7 @@ Font::Font() { if (FT_Init_FreeType(&m_ft)) { Logger::error("FREETYPE: Could not init FreeType Library"); } - if (FT_New_Face(m_ft, ASSETS_PATH "fonts/IBMPlexSans-Regular.ttf", 0, &m_face)) { + if (FT_New_Face(m_ft, font_path().c_str(), 0, &m_face)) { Logger::error("FREETYPE: Failed to load font"); } @@ -125,4 +127,8 @@ GLuint Font::text_texture() { return m_text_texture; } +const fs::path& Font::font_path() { + return m_font_path; +} + } \ No newline at end of file diff --git a/src/window.cpp b/src/window.cpp index c7dbdf2..3dbc886 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -3,6 +3,13 @@ #include #include #include + +#include + +#include +#include +#include + namespace Cubed { static int windowed_xpos = 0, windowed_ypos = 0; @@ -15,6 +22,11 @@ Window::Window(Renderer& renderer) : } Window::~Window() { + + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + if (m_window) { glfwDestroyWindow(m_window); m_window = nullptr; @@ -44,6 +56,7 @@ void Window::update_viewport() { config.set("window.width", windowed_width); config.set("window.height", windowed_height); + } void Window::init() { @@ -84,7 +97,6 @@ void Window::init() { GLFWmonitor* primary = glfwGetPrimaryMonitor(); const GLFWvidmode* mode = glfwGetVideoMode(primary); glfwSetWindowPos(m_window, static_cast(mode->width / 2.0f) - 400, static_cast(mode->height / 2.0f) - 300); - //update_viewport(); } @@ -100,23 +112,7 @@ void Window::hot_reload() { windowed_width = config.get("window.width"); windowed_height = config.get("window.height"); - if (config.get("window.fullscreen.V-Sync")) { - GLFWmonitor* monitor = glfwGetWindowMonitor(m_window); - if (monitor != nullptr) { - glfwSetWindowMonitor( - m_window, - nullptr, - windowed_xpos, - windowed_ypos, - windowed_width, - windowed_height, - 0 - ); - } else { - - } - config.set("window.fullscreen", false); - } else { + if (config.get("window.fullscreen")) { glfwGetWindowPos(m_window, &windowed_xpos, &windowed_ypos); glfwGetWindowSize(m_window, &windowed_width, &windowed_height); @@ -132,11 +128,28 @@ void Window::hot_reload() { mode->height, GL_DONT_CARE ); - config.set("window.fullscreen", true); - + } else { + GLFWmonitor* monitor = glfwGetWindowMonitor(m_window); + if (monitor != nullptr) { + glfwSetWindowMonitor( + m_window, + nullptr, + windowed_xpos, + windowed_ypos, + windowed_width, + windowed_height, + 0 + ); + } else { + Logger::error("Can't Find Monitor"); + } } update_viewport(); - + if (!m_mouse_enable) { + glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + } else { + glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } } void Window::toggle_fullscreen() { @@ -178,13 +191,54 @@ void Window::toggle_fullscreen() { } void Window::toggle_mouse_able() { + //auto& io = ImGui::GetIO(); if (m_mouse_enable) { + //io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange; + //Logger::info("ImGuiConfigFlags_NoMouseCursorChange"); + //ImGui::SetMouseCursor(ImGuiMouseCursor_None); + //glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); m_mouse_enable = false; } else { + //io.ConfigFlags &= ~ImGuiConfigFlags_NoMouseCursorChange; + //Logger::info("Disable ImGuiConfigFlags_NoMouseCursorChange"); glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); m_mouse_enable = true; } } +void Window::imgui_init() { + float dpi_scale_x, dpi_scale_y; + glfwGetWindowContentScale(m_window, &dpi_scale_x, &dpi_scale_y); + //float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); + float main_scale = dpi_scale_x; + Logger::info("Main Scale {}", main_scale); + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange; // Prevent ImGui from automatically changing the system cursor shape, allowing the game to fully control cursor appearance (e.g., hidden/disabled custom cursor). + auto theme = Config::get().get("devpanel.theme"); + if (theme == 0) { + ImGui::StyleColorsDark(); + } else if (theme == 1) { + ImGui::StyleColorsLight(); + } else { + ImGui::StyleColorsDark(); + Config::get().set("devpanel.theme", 0); + } + + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) + style.FontScaleDpi = main_scale; + style.FontSizeBase = 20.0f; + ImFont* font = io.Fonts->AddFontFromFileTTF(Font::font_path().c_str()); + ASSERT_MSG(font != nullptr, "Font Load Fail"); + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOpenGL(m_window, false); + ImGui_ImplOpenGL3_Init(); +} + } \ No newline at end of file