From 4bbe6eff607c3e07ce24b6f11a213c6b9fbfa2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Tue, 30 Jan 2024 17:59:53 +0100 Subject: [PATCH 01/34] Added changing the font and size to the gui. --- examples/02-scene_simple/main.cpp | 2 +- examples/04-point_cloud/main.cpp | 2 +- include/frame/gui/draw_gui_factory.h | 6 +++++- src/frame/gui/draw_gui_factory.cpp | 5 +++-- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 22 +++++++++++++++----- src/frame/opengl/gui/sdl_opengl_draw_gui.h | 9 +++++++- 6 files changed, 35 insertions(+), 11 deletions(-) diff --git a/examples/02-scene_simple/main.cpp b/examples/02-scene_simple/main.cpp index 4cd43f0..8ce5003 100644 --- a/examples/02-scene_simple/main.cpp +++ b/examples/02-scene_simple/main.cpp @@ -39,7 +39,7 @@ try frame::RenderingAPIEnum::OPENGL, size); auto& device = win->GetDevice(); - auto gui_window = frame::gui::CreateDrawGui(*win.get()); + auto gui_window = frame::gui::CreateDrawGui(*win.get(), {}, 20.0f); auto gui_resolution = std::make_unique( "Resolution", size, win->GetDesktopSize(), win->GetPixelPerInch()); ptr_window_resolution = gui_resolution.get(); diff --git a/examples/04-point_cloud/main.cpp b/examples/04-point_cloud/main.cpp index 2173368..3951102 100644 --- a/examples/04-point_cloud/main.cpp +++ b/examples/04-point_cloud/main.cpp @@ -52,7 +52,7 @@ try frame::gui::WindowResolution* ptr_window_resolution = nullptr; frame::gui::WindowCamera* ptr_window_camera = nullptr; frame::gui::WindowCubemap* ptr_window_cubemap = nullptr; - auto gui_window = frame::gui::CreateDrawGui(*win.get()); + auto gui_window = frame::gui::CreateDrawGui(*win.get(), {}, 20.0f); { auto gui_resolution = std::make_unique( "Resolution", size, win->GetDesktopSize(), win->GetPixelPerInch()); diff --git a/include/frame/gui/draw_gui_factory.h b/include/frame/gui/draw_gui_factory.h index 6d24071..93e6fa3 100644 --- a/include/frame/gui/draw_gui_factory.h +++ b/include/frame/gui/draw_gui_factory.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "frame/device_interface.h" #include "frame/gui/draw_gui_interface.h" @@ -9,6 +10,9 @@ namespace frame::gui { -std::unique_ptr CreateDrawGui(WindowInterface& window); +std::unique_ptr CreateDrawGui( + WindowInterface& window, + const std::filesystem::path& font_path, + float font_size); } // End namespace frame::gui. diff --git a/src/frame/gui/draw_gui_factory.cpp b/src/frame/gui/draw_gui_factory.cpp index b3fc130..2775007 100644 --- a/src/frame/gui/draw_gui_factory.cpp +++ b/src/frame/gui/draw_gui_factory.cpp @@ -6,13 +6,14 @@ namespace frame::gui { std::unique_ptr CreateDrawGui( - WindowInterface& window) + WindowInterface& window, const std::filesystem::path& font_path, float font_size) { auto& device = window.GetDevice(); switch (device.GetDeviceEnum()) { case RenderingAPIEnum::OPENGL: - return std::make_unique(window); + return std::make_unique( + window, font_path, font_size); default: return nullptr; } diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index d9a5898..1352a63 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -14,8 +14,14 @@ namespace frame::opengl::gui { -SDL2OpenGLDrawGui::SDL2OpenGLDrawGui(frame::WindowInterface& window) - : window_(window), device_(window_.GetDevice()) +SDL2OpenGLDrawGui::SDL2OpenGLDrawGui( + frame::WindowInterface& window, + const std::filesystem::path& font_path, + float font_size) + : window_(window), + device_(window_.GetDevice()), + font_path_(font_path), + font_size_(font_size) { // Setup Dear ImGui context IMGUI_CHECKVERSION(); @@ -35,9 +41,15 @@ SDL2OpenGLDrawGui::SDL2OpenGLDrawGui(frame::WindowInterface& window) ImGuiStyle& style = ImGui::GetStyle(); style.WindowRounding = 5.0f; - io.Fonts->AddFontFromFileTTF( - file::FindFile("asset/font/poppins/Poppins-Light.ttf").string().c_str(), - 20.0f); + if (font_path_.empty()) + { + io.Fonts->AddFontDefault(); + } + else + { + io.Fonts->AddFontFromFileTTF( + reinterpret_cast(font_path_.c_str()), font_size_); + } // Setup Platform/Renderer back ends ImGui_ImplSDL2_InitForOpenGL( diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.h b/src/frame/opengl/gui/sdl_opengl_draw_gui.h index be1068a..3d7a2e3 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.h +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "frame/device_interface.h" #include "frame/gui/draw_gui_interface.h" @@ -19,8 +20,12 @@ class SDL2OpenGLDrawGui : public frame::gui::DrawGuiInterface /** * @brief Constructor. * @param window: The window to use. + * @param font_path: The path to the font. */ - SDL2OpenGLDrawGui(frame::WindowInterface& window); + SDL2OpenGLDrawGui( + frame::WindowInterface& window, + const std::filesystem::path& font_path, + float font_size); //! @brief Destructor. virtual ~SDL2OpenGLDrawGui(); @@ -121,12 +126,14 @@ class SDL2OpenGLDrawGui : public frame::gui::DrawGuiInterface protected: std::map> callbacks_ = {}; + std::filesystem::path font_path_; WindowInterface& window_; DeviceInterface& device_; std::string name_; glm::uvec2 size_ = {0, 0}; bool is_keyboard_passed_ = false; bool is_visible_ = true; + float font_size_ = 20.0f; }; } // End namespace frame::opengl::gui. From 755d3d8590bc71050afac57a4eae3d8074d6c80b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Fri, 2 Feb 2024 18:23:18 +0100 Subject: [PATCH 02/34] Added #define GLM_ENABLE_EXPERIMENTAL to the GLM include. --- include/frame/camera.h | 1 + include/frame/image_interface.h | 1 + include/frame/input_interface.h | 1 + include/frame/json/proto.h | 2 ++ include/frame/light_interface.h | 1 + include/frame/node_interface.h | 1 + include/frame/plugin_interface.h | 1 + include/frame/program_interface.h | 1 + include/frame/renderer_interface.h | 1 + include/frame/texture_interface.h | 1 + include/frame/uniform_interface.h | 1 + src/frame/json/parse_uniform.h | 1 + src/frame/node_camera.h | 1 + src/frame/node_light.h | 1 + src/frame/node_matrix.h | 1 + 15 files changed, 16 insertions(+) diff --git a/include/frame/camera.h b/include/frame/camera.h index b8bb156..58e8351 100644 --- a/include/frame/camera.h +++ b/include/frame/camera.h @@ -1,6 +1,7 @@ #pragma once #include +#define GLM_ENABLE_EXPERIMENTAL #include namespace frame diff --git a/include/frame/image_interface.h b/include/frame/image_interface.h index 885efc7..c1b072e 100644 --- a/include/frame/image_interface.h +++ b/include/frame/image_interface.h @@ -1,5 +1,6 @@ #pragma once +#define GLM_ENABLE_EXPERIMENTAL #include #include "frame/json/proto.h" diff --git a/include/frame/input_interface.h b/include/frame/input_interface.h index 6deae58..8359c73 100644 --- a/include/frame/input_interface.h +++ b/include/frame/input_interface.h @@ -1,5 +1,6 @@ #pragma once +#define GLM_ENABLE_EXPERIMENTAL #include namespace frame diff --git a/include/frame/json/proto.h b/include/frame/json/proto.h index 67cf933..7a93fc2 100644 --- a/include/frame/json/proto.h +++ b/include/frame/json/proto.h @@ -21,3 +21,5 @@ #if defined(_WIN32) || defined(_WIN64) #pragma warning(pop) #endif + +#define GLM_ENABLE_EXPERIMENTAL diff --git a/include/frame/light_interface.h b/include/frame/light_interface.h index a354eb5..cf2c5ff 100644 --- a/include/frame/light_interface.h +++ b/include/frame/light_interface.h @@ -1,6 +1,7 @@ #pragma once #include +#define GLM_ENABLE_EXPERIMENTAL #include namespace frame diff --git a/include/frame/node_interface.h b/include/frame/node_interface.h index 2befb95..bea63ab 100644 --- a/include/frame/node_interface.h +++ b/include/frame/node_interface.h @@ -1,6 +1,7 @@ #pragma once #include +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/include/frame/plugin_interface.h b/include/frame/plugin_interface.h index fc434b4..af6132d 100644 --- a/include/frame/plugin_interface.h +++ b/include/frame/plugin_interface.h @@ -1,5 +1,6 @@ #pragma once +#define GLM_ENABLE_EXPERIMENTAL #include #include diff --git a/include/frame/program_interface.h b/include/frame/program_interface.h index c128afe..bb38fe0 100644 --- a/include/frame/program_interface.h +++ b/include/frame/program_interface.h @@ -1,5 +1,6 @@ #pragma once +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/include/frame/renderer_interface.h b/include/frame/renderer_interface.h index 9646c8c..0f2e413 100644 --- a/include/frame/renderer_interface.h +++ b/include/frame/renderer_interface.h @@ -1,5 +1,6 @@ #pragma once +#define GLM_ENABLE_EXPERIMENTAL #include #include "frame/material_interface.h" diff --git a/include/frame/texture_interface.h b/include/frame/texture_interface.h index 693d9ac..03db3fb 100644 --- a/include/frame/texture_interface.h +++ b/include/frame/texture_interface.h @@ -3,6 +3,7 @@ #include #include #include +#define GLM_ENABLE_EXPERIMENTAL #include #include diff --git a/include/frame/uniform_interface.h b/include/frame/uniform_interface.h index c50a429..c25bf43 100644 --- a/include/frame/uniform_interface.h +++ b/include/frame/uniform_interface.h @@ -1,5 +1,6 @@ #pragma once +#define GLM_ENABLE_EXPERIMENTAL #include #include diff --git a/src/frame/json/parse_uniform.h b/src/frame/json/parse_uniform.h index 1ad53a1..7a5fba7 100644 --- a/src/frame/json/parse_uniform.h +++ b/src/frame/json/parse_uniform.h @@ -1,5 +1,6 @@ #pragma once +#define GLM_ENABLE_EXPERIMENTAL #include #include diff --git a/src/frame/node_camera.h b/src/frame/node_camera.h index 0efaca7..693ed6b 100644 --- a/src/frame/node_camera.h +++ b/src/frame/node_camera.h @@ -1,5 +1,6 @@ #pragma once +#define GLM_ENABLE_EXPERIMENTAL #include #include "frame/camera.h" diff --git a/src/frame/node_light.h b/src/frame/node_light.h index 6fb344f..2ebc1af 100644 --- a/src/frame/node_light.h +++ b/src/frame/node_light.h @@ -1,5 +1,6 @@ #pragma once +#define GLM_ENABLE_EXPERIMENTAL #include #include "frame/node_interface.h" diff --git a/src/frame/node_matrix.h b/src/frame/node_matrix.h index 32468d3..a6ff247 100644 --- a/src/frame/node_matrix.h +++ b/src/frame/node_matrix.h @@ -1,5 +1,6 @@ #pragma once +#define GLM_ENABLE_EXPERIMENTAL #include #include From 3b3cdc926f61af715d0bcd205fde0a6dc2cd63c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Sun, 11 Feb 2024 12:42:05 +0100 Subject: [PATCH 03/34] Changed the logging so it could be used in the window (and on the console). --- CMakeLists.txt | 2 +- examples/02-scene_simple/main.cpp | 2 + include/frame/gui/draw_gui_interface.h | 15 +----- include/frame/gui/gui_logger_sink.h | 58 +++++++++++++++++++++++ include/frame/gui/gui_window_interface.h | 22 +++++++++ include/frame/gui/window_logger.h | 42 +++++++++++++++++ include/frame/logger.h | 55 ++++++++++++++++++++-- src/frame/gui/CMakeLists.txt | 4 ++ src/frame/gui/window_logger.cpp | 42 +++++++++++++++++ src/frame/logger.cpp | 60 ++++++++++++++++++++++-- src/frame/opengl/message_callback.cpp | 3 +- 11 files changed, 283 insertions(+), 22 deletions(-) create mode 100644 include/frame/gui/gui_logger_sink.h create mode 100644 include/frame/gui/gui_window_interface.h create mode 100644 include/frame/gui/window_logger.h create mode 100644 src/frame/gui/window_logger.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1acb317..d8123a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_POSITION_INDEPENDENT_CODE ON) # C++ standard version. -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Adding subfolder property. diff --git a/examples/02-scene_simple/main.cpp b/examples/02-scene_simple/main.cpp index 8ce5003..e2a13e3 100644 --- a/examples/02-scene_simple/main.cpp +++ b/examples/02-scene_simple/main.cpp @@ -14,6 +14,7 @@ #include "frame/file/image_stb.h" #include "frame/gui/draw_gui_factory.h" #include "frame/gui/window_resolution.h" +#include "frame/gui/window_logger.h" #include "frame/window_factory.h" // From: https://sourceforge.net/p/predef/wiki/OperatingSystems/ @@ -44,6 +45,7 @@ try "Resolution", size, win->GetDesktopSize(), win->GetPixelPerInch()); ptr_window_resolution = gui_resolution.get(); gui_window->AddWindow(std::move(gui_resolution)); + gui_window->AddWindow(std::make_unique("Logger")); win->GetDevice().AddPlugin(std::move(gui_window)); frame::common::Application app(std::move(win)); do diff --git a/include/frame/gui/draw_gui_interface.h b/include/frame/gui/draw_gui_interface.h index 24143dd..28b65e6 100644 --- a/include/frame/gui/draw_gui_interface.h +++ b/include/frame/gui/draw_gui_interface.h @@ -4,24 +4,11 @@ #include "frame/name_interface.h" #include "frame/plugin_interface.h" +#include "frame/gui/gui_window_interface.h" namespace frame::gui { -/** - * @class GuiWindowInterface - * @brief Draw GUI Window interface. - * - * It has a name interface that will be used as a pointer to the window. - */ -struct GuiWindowInterface : public NameInterface -{ - //! @brief Draw callback setting. - virtual bool DrawCallback() = 0; - //! @brief Is it the end of the gui? - virtual bool End() const = 0; -}; - /** * @class DrawGuiInterface * @brief Interface for drawing GUI elements. diff --git a/include/frame/gui/gui_logger_sink.h b/include/frame/gui/gui_logger_sink.h new file mode 100644 index 0000000..8f676bd --- /dev/null +++ b/include/frame/gui/gui_logger_sink.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include +#include + +namespace frame::gui +{ + +/** + * @brief A sink for spdlog that stores log messages in a vector of strings. + * + * This sink is useful for testing and debugging, as it allows to check the + * log messages that have been generated by the application. + * + * The sink stores the log messages in a vector of strings, which can be + * accessed using the GetLogs() method. The logs are stored in the order they + * were generated, and can be cleared using the ClearLogs() method. + * + * The sink is thread safe, and can be used with multiple threads. + */ +class GuiLoggerSink : public spdlog::sinks::base_sink +{ + protected: + void sink_it_(const spdlog::details::log_msg& msg) override + { + // log_msg is a struct containing the log entry info like level, + // timestamp, thread id etc. msg.raw contains pre formatted log + + // If needed (very likely but not mandatory), the sink formats the + // message before sending it to its final desination: + spdlog::memory_buf_t formatted; + spdlog::sinks::base_sink::formatter_->format( + msg, formatted); + std::string formatted_message(msg.payload.begin(), msg.payload.end()); + logs.push_back(std::move(formatted_message)); + } + void flush_() override + { + } + + public: + /// @brief Get the logs that have been generated. + const std::vector& GetLogs() const + { + return logs; + } + /// @brief Clear the logs that have been generated. + void ClearLogs() + { + logs.clear(); + } + + private: + std::vector logs; +}; + +} // namespace frame::gui. diff --git a/include/frame/gui/gui_window_interface.h b/include/frame/gui/gui_window_interface.h new file mode 100644 index 0000000..f3d035d --- /dev/null +++ b/include/frame/gui/gui_window_interface.h @@ -0,0 +1,22 @@ +#pragma once + +#include "frame/name_interface.h" + +namespace frame::gui +{ + +/** + * @class GuiWindowInterface + * @brief Draw GUI Window interface. + * + * It has a name interface that will be used as a pointer to the window. + */ +struct GuiWindowInterface : public NameInterface +{ + //! @brief Draw callback setting. + virtual bool DrawCallback() = 0; + //! @brief Is it the end of the gui? + virtual bool End() const = 0; +}; + +} // namespace frame::gui. diff --git a/include/frame/gui/window_logger.h b/include/frame/gui/window_logger.h new file mode 100644 index 0000000..0d79980 --- /dev/null +++ b/include/frame/gui/window_logger.h @@ -0,0 +1,42 @@ +#pragma once + +#include + +#include "frame/api.h" +#include "frame/gui/draw_gui_interface.h" +#include "frame/logger.h" + +namespace frame::gui +{ + +class WindowLogger : public GuiWindowInterface +{ + public: + WindowLogger(const std::string& name); + virtual ~WindowLogger() = default; + + public: + //! @brief Draw callback setting. + bool DrawCallback() override; + /** + * @brief Get the name of the window. + * @return The name of the window. + */ + std::string GetName() const override; + /** + * @brief Set the name of the window. + * @param name: The name of the window. + */ + void SetName(const std::string& name) override; + /** + * @brief Check if this is the end of the software. + * @return True if this is the end false if not. + */ + bool End() const override; + + private: + frame::Logger& logger_ = frame::Logger::GetInstance(); + std::string name_; +}; + +} // namespace frame::gui diff --git a/include/frame/logger.h b/include/frame/logger.h index 6765001..82db1bb 100644 --- a/include/frame/logger.h +++ b/include/frame/logger.h @@ -1,12 +1,51 @@ #pragma once -#include - #include +#include +#include +#include +#include namespace frame { +/** + * @enum LoggerType + * + * This enum is used to define the type of logger that will be used in the + * logger class. + */ +enum class LoggerType : std::uint8_t +{ + BUFFER = 1 << 0, + CONSOLE = 1 << 1, + FILE = 1 << 2, +}; + +/** + * @brief The operator | is used to combine the logger type. + * @param a The first logger type. + * @param b The second logger type. + * @return The combined logger type. + */ +inline LoggerType operator|(LoggerType a, LoggerType b) +{ + return static_cast( + static_cast(a) | static_cast(b)); +} + +/** + * @brief The operator & is used to combine the logger type. + * @param a The first logger type. + * @param b The second logger type. + * @return The combined logger type. + */ +inline LoggerType operator&(LoggerType a, LoggerType b) +{ + return static_cast( + static_cast(a) & static_cast(b)); +} + /** * @class Logger * @brief This is where the speed log logging system is wrapped. This should @@ -20,7 +59,7 @@ class Logger * @brief Private constructor this is a singleton class so no view on * the constructor is allowed. */ - Logger(); + Logger(LoggerType logger_type); public: //! @brief Virtual destructor. @@ -39,9 +78,19 @@ class Logger * @return A shared pointer to the logger class. */ const std::shared_ptr operator->() const; + /** + * @brief The get logs function is used to get the logs that have been + * added. + * @return A vector of strings that contains the logs. + */ + const std::vector& GetLogs() const; + /// @brief Clear the logs. + void ClearLogs(); private: std::shared_ptr logger_ptr_ = nullptr; + std::shared_ptr> gui_logger_sink_ = + nullptr; }; } // End namespace frame. diff --git a/src/frame/gui/CMakeLists.txt b/src/frame/gui/CMakeLists.txt index d41b925..64cb328 100644 --- a/src/frame/gui/CMakeLists.txt +++ b/src/frame/gui/CMakeLists.txt @@ -4,8 +4,11 @@ add_library(FrameGui STATIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/frame/gui/draw_gui_interface.h ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/frame/gui/draw_gui_factory.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/frame/gui/gui_logger_sink.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/frame/gui/gui_window_interface.h ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/frame/gui/window_camera.h ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/frame/gui/window_cubemap.h + ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/frame/gui/window_logger.h ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/frame/gui/window_resolution.h ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/frame/gui/input_factory.h draw_gui_factory.cpp @@ -18,6 +21,7 @@ add_library(FrameGui input_wasd_mouse.h window_camera.cpp window_cubemap.cpp + window_logger.cpp window_resolution.cpp ) diff --git a/src/frame/gui/window_logger.cpp b/src/frame/gui/window_logger.cpp new file mode 100644 index 0000000..df7899a --- /dev/null +++ b/src/frame/gui/window_logger.cpp @@ -0,0 +1,42 @@ +#include "frame/gui/window_logger.h" + +#include + +namespace frame::gui +{ + +WindowLogger::WindowLogger(const std::string& name) + : name_(name) +{ + SetName(name); +} + +bool WindowLogger::DrawCallback() +{ + for (const auto& message : logger_.GetLogs()) + { + ImGui::TextUnformatted(message.c_str()); + } + if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) + { + ImGui::SetScrollHereY(1.0f); + } + return true; +} + +std::string WindowLogger::GetName() const +{ + return name_; +} + +void WindowLogger::SetName(const std::string& name) +{ + name_ = name; +} + +bool WindowLogger::End() const +{ + return false; +} + +} // namespace frame::gui. diff --git a/src/frame/logger.cpp b/src/frame/logger.cpp index 83285a9..f7d1980 100644 --- a/src/frame/logger.cpp +++ b/src/frame/logger.cpp @@ -1,13 +1,34 @@ #include "frame/logger.h" +#include "include/frame/gui/gui_logger_sink.h" #include +#include namespace frame { -Logger::Logger() +Logger::Logger(LoggerType logger_type) { - logger_ptr_ = spdlog::basic_logger_mt("log", "./log.txt", true); + std::vector sinks; + if (static_cast(logger_type & LoggerType::CONSOLE)) + { + sinks.push_back( + std::make_shared()); + } + if (static_cast(logger_type & LoggerType::BUFFER)) + { + gui_logger_sink_ = std::make_shared(); + sinks.push_back(gui_logger_sink_); + } + if (static_cast(logger_type & LoggerType::FILE)) + { + sinks.push_back(std::make_shared( + "./log.txt", true)); + } + logger_ptr_ = + std::make_shared("frame", begin(sinks), end(sinks)); + spdlog::register_logger(logger_ptr_); + spdlog::set_default_logger(logger_ptr_); logger_ptr_->info("start logging!"); } @@ -15,7 +36,12 @@ Logger::~Logger() = default; Logger& Logger::GetInstance() { - static Logger logger_; +#ifdef _DEBUG + static Logger logger_( + LoggerType::BUFFER | LoggerType::FILE | LoggerType::CONSOLE); +#else + static Logger logger_(LoggerType::BUFFER | LoggerType::FILE); +#endif return logger_; } @@ -24,4 +50,32 @@ const std::shared_ptr Logger::operator->() const return logger_ptr_; } +const std::vector& Logger::GetLogs() const +{ + auto gui_logger_sink = + std::dynamic_pointer_cast(gui_logger_sink_); + if (gui_logger_sink) + { + return gui_logger_sink->GetLogs(); + } + else + { + throw std::runtime_error("no buffer sink?"); + } +} + +void Logger::ClearLogs() +{ + auto gui_logger_sink = + std::dynamic_pointer_cast(gui_logger_sink_); + if (gui_logger_sink) + { + gui_logger_sink->ClearLogs(); + } + else + { + throw std::runtime_error("no buffer sink?"); + } +} + } // End namespace frame. diff --git a/src/frame/opengl/message_callback.cpp b/src/frame/opengl/message_callback.cpp index adbf25c..30755b6 100644 --- a/src/frame/opengl/message_callback.cpp +++ b/src/frame/opengl/message_callback.cpp @@ -112,7 +112,8 @@ void GLAPIENTRY MessageCallback( } else { - logger->info(str_message); + // CHECKME(anirul): This is a lot of noise. + // logger->info(str_message); } } From acdc368ff710c4843156b80a5f3cd91e5374eb17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Sun, 11 Feb 2024 13:36:53 +0100 Subject: [PATCH 04/34] Now only show the last 100 logs. --- include/frame/logger.h | 3 ++- src/frame/gui/window_logger.cpp | 4 +++- src/frame/logger.cpp | 14 ++++++++++++-- src/frame/opengl/message_callback.cpp | 2 +- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/frame/logger.h b/include/frame/logger.h index 82db1bb..59c0554 100644 --- a/include/frame/logger.h +++ b/include/frame/logger.h @@ -83,7 +83,7 @@ class Logger * added. * @return A vector of strings that contains the logs. */ - const std::vector& GetLogs() const; + const std::vector& GetLastLogs(std::uint32_t max_log) const; /// @brief Clear the logs. void ClearLogs(); @@ -91,6 +91,7 @@ class Logger std::shared_ptr logger_ptr_ = nullptr; std::shared_ptr> gui_logger_sink_ = nullptr; + mutable std::vector display_logs_; }; } // End namespace frame. diff --git a/src/frame/gui/window_logger.cpp b/src/frame/gui/window_logger.cpp index df7899a..a5fe26d 100644 --- a/src/frame/gui/window_logger.cpp +++ b/src/frame/gui/window_logger.cpp @@ -13,7 +13,8 @@ WindowLogger::WindowLogger(const std::string& name) bool WindowLogger::DrawCallback() { - for (const auto& message : logger_.GetLogs()) + ImGui::BeginChild("Scrolling"); + for (const auto& message : logger_.GetLastLogs(100)) { ImGui::TextUnformatted(message.c_str()); } @@ -21,6 +22,7 @@ bool WindowLogger::DrawCallback() { ImGui::SetScrollHereY(1.0f); } + ImGui::EndChild(); return true; } diff --git a/src/frame/logger.cpp b/src/frame/logger.cpp index f7d1980..b2cc1c0 100644 --- a/src/frame/logger.cpp +++ b/src/frame/logger.cpp @@ -50,13 +50,23 @@ const std::shared_ptr Logger::operator->() const return logger_ptr_; } -const std::vector& Logger::GetLogs() const +const std::vector& Logger::GetLastLogs(std::uint32_t max_log) const { auto gui_logger_sink = std::dynamic_pointer_cast(gui_logger_sink_); if (gui_logger_sink) { - return gui_logger_sink->GetLogs(); + if (display_logs_.capacity() != max_log) + { + display_logs_.reserve(max_log); + } + const auto& logs = gui_logger_sink->GetLogs(); + display_logs_.clear(); + for (std::size_t i = logs.size() - max_log; i < logs.size(); ++i) + { + display_logs_.push_back(logs[i]); + } + return display_logs_; } else { diff --git a/src/frame/opengl/message_callback.cpp b/src/frame/opengl/message_callback.cpp index 30755b6..d8fb480 100644 --- a/src/frame/opengl/message_callback.cpp +++ b/src/frame/opengl/message_callback.cpp @@ -113,7 +113,7 @@ void GLAPIENTRY MessageCallback( else { // CHECKME(anirul): This is a lot of noise. - // logger->info(str_message); + logger->info(str_message); } } From 2c53700d48d6033e58ff104966ac860b0c568daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Sun, 11 Feb 2024 17:32:13 +0100 Subject: [PATCH 05/34] Remove the log of info messages from GL. It was getting difficult to debug as this message was always messing with the output. --- src/frame/opengl/message_callback.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frame/opengl/message_callback.cpp b/src/frame/opengl/message_callback.cpp index d8fb480..30755b6 100644 --- a/src/frame/opengl/message_callback.cpp +++ b/src/frame/opengl/message_callback.cpp @@ -113,7 +113,7 @@ void GLAPIENTRY MessageCallback( else { // CHECKME(anirul): This is a lot of noise. - logger->info(str_message); + // logger->info(str_message); } } From 3a54166825b63b3a1c8d6ee3972dd9bd4cf209f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Sun, 11 Feb 2024 18:11:24 +0100 Subject: [PATCH 06/34] Corrected a bug in the display. --- src/frame/logger.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/frame/logger.cpp b/src/frame/logger.cpp index b2cc1c0..150b1eb 100644 --- a/src/frame/logger.cpp +++ b/src/frame/logger.cpp @@ -61,6 +61,10 @@ const std::vector& Logger::GetLastLogs(std::uint32_t max_log) const display_logs_.reserve(max_log); } const auto& logs = gui_logger_sink->GetLogs(); + if (logs.size() <= max_log) + { + return logs; + } display_logs_.clear(); for (std::size_t i = logs.size() - max_log; i < logs.size(); ++i) { From 4f713ee19e8073aecbe6b725c60ccc5b81d001fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Tue, 13 Feb 2024 10:24:14 +0100 Subject: [PATCH 07/34] Now log with colors! --- include/frame/gui/gui_logger_sink.h | 8 +++--- include/frame/gui/window_logger.h | 6 ++++- include/frame/logger.h | 15 +++++++++-- src/frame/gui/window_logger.cpp | 40 ++++++++++++++++++++++++++--- src/frame/logger.cpp | 2 +- 5 files changed, 60 insertions(+), 11 deletions(-) diff --git a/include/frame/gui/gui_logger_sink.h b/include/frame/gui/gui_logger_sink.h index 8f676bd..b60c19d 100644 --- a/include/frame/gui/gui_logger_sink.h +++ b/include/frame/gui/gui_logger_sink.h @@ -4,6 +4,8 @@ #include #include +#include "frame/logger.h" + namespace frame::gui { @@ -33,7 +35,7 @@ class GuiLoggerSink : public spdlog::sinks::base_sink spdlog::sinks::base_sink::formatter_->format( msg, formatted); std::string formatted_message(msg.payload.begin(), msg.payload.end()); - logs.push_back(std::move(formatted_message)); + logs.push_back({msg.level, std::move(formatted_message)}); } void flush_() override { @@ -41,7 +43,7 @@ class GuiLoggerSink : public spdlog::sinks::base_sink public: /// @brief Get the logs that have been generated. - const std::vector& GetLogs() const + const std::vector& GetLogs() const { return logs; } @@ -52,7 +54,7 @@ class GuiLoggerSink : public spdlog::sinks::base_sink } private: - std::vector logs; + std::vector logs; }; } // namespace frame::gui. diff --git a/include/frame/gui/window_logger.h b/include/frame/gui/window_logger.h index 0d79980..324f63f 100644 --- a/include/frame/gui/window_logger.h +++ b/include/frame/gui/window_logger.h @@ -34,9 +34,13 @@ class WindowLogger : public GuiWindowInterface */ bool End() const override; + protected: + //! @brief Log with color. + void LogWithColor(const LogMessage& log_message) const; + private: frame::Logger& logger_ = frame::Logger::GetInstance(); - std::string name_; + std::string name_; }; } // namespace frame::gui diff --git a/include/frame/logger.h b/include/frame/logger.h index 59c0554..1433d27 100644 --- a/include/frame/logger.h +++ b/include/frame/logger.h @@ -46,6 +46,17 @@ inline LoggerType operator&(LoggerType a, LoggerType b) static_cast(a) & static_cast(b)); } +/** + * @brief The log message structure. + * + * This structure contains the log message and the level of the log message. + */ +struct LogMessage +{ + spdlog::level::level_enum level; + std::string message; +}; + /** * @class Logger * @brief This is where the speed log logging system is wrapped. This should @@ -83,7 +94,7 @@ class Logger * added. * @return A vector of strings that contains the logs. */ - const std::vector& GetLastLogs(std::uint32_t max_log) const; + const std::vector& GetLastLogs(std::uint32_t max_log) const; /// @brief Clear the logs. void ClearLogs(); @@ -91,7 +102,7 @@ class Logger std::shared_ptr logger_ptr_ = nullptr; std::shared_ptr> gui_logger_sink_ = nullptr; - mutable std::vector display_logs_; + mutable std::vector display_logs_; }; } // End namespace frame. diff --git a/src/frame/gui/window_logger.cpp b/src/frame/gui/window_logger.cpp index a5fe26d..6dca52e 100644 --- a/src/frame/gui/window_logger.cpp +++ b/src/frame/gui/window_logger.cpp @@ -5,8 +5,7 @@ namespace frame::gui { -WindowLogger::WindowLogger(const std::string& name) - : name_(name) +WindowLogger::WindowLogger(const std::string& name) : name_(name) { SetName(name); } @@ -14,9 +13,9 @@ WindowLogger::WindowLogger(const std::string& name) bool WindowLogger::DrawCallback() { ImGui::BeginChild("Scrolling"); - for (const auto& message : logger_.GetLastLogs(100)) + for (const auto& log_message : logger_.GetLastLogs(100)) { - ImGui::TextUnformatted(message.c_str()); + ImGui::TextUnformatted(log_message.message.c_str()); } if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) { @@ -41,4 +40,37 @@ bool WindowLogger::End() const return false; } +void WindowLogger::LogWithColor(const LogMessage& log_message) const +{ + switch (log_message.level) + { + case spdlog::level::trace: + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.5f, 0.5f, 1.0f)); + break; + case spdlog::level::debug: + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 1.0f, 0.0f, 1.0f)); + break; + case spdlog::level::info: + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); + break; + case spdlog::level::warn: + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 0.5f, 1.0f)); + break; + case spdlog::level::err: + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.5f, 0.5f, 1.0f)); + break; + case spdlog::level::critical: + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); + break; + case spdlog::level::off: + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); + break; + default: + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); + break; + } + ImGui::TextUnformatted(log_message.message.c_str()); + ImGui::PopStyleColor(); +} + } // namespace frame::gui. diff --git a/src/frame/logger.cpp b/src/frame/logger.cpp index 150b1eb..bc8817c 100644 --- a/src/frame/logger.cpp +++ b/src/frame/logger.cpp @@ -50,7 +50,7 @@ const std::shared_ptr Logger::operator->() const return logger_ptr_; } -const std::vector& Logger::GetLastLogs(std::uint32_t max_log) const +const std::vector& Logger::GetLastLogs(std::uint32_t max_log) const { auto gui_logger_sink = std::dynamic_pointer_cast(gui_logger_sink_); From 31bdf1e10d2e2449e03c8d8631247ae7294b3858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Tue, 13 Feb 2024 13:28:59 +0100 Subject: [PATCH 08/34] Now log with colors (second try). --- src/frame/gui/window_logger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frame/gui/window_logger.cpp b/src/frame/gui/window_logger.cpp index 6dca52e..ac7cfb1 100644 --- a/src/frame/gui/window_logger.cpp +++ b/src/frame/gui/window_logger.cpp @@ -15,7 +15,7 @@ bool WindowLogger::DrawCallback() ImGui::BeginChild("Scrolling"); for (const auto& log_message : logger_.GetLastLogs(100)) { - ImGui::TextUnformatted(log_message.message.c_str()); + LogWithColor(log_message); } if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) { From 370abe34e8f1ca1d0623d16370cbd2f84e57d8a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Wed, 14 Feb 2024 10:57:22 +0100 Subject: [PATCH 09/34] Added support for modal windows. --- examples/02-scene_simple/CMakeLists.txt | 1 + examples/02-scene_simple/main.cpp | 7 +++- examples/02-scene_simple/modal_info.h | 39 ++++++++++++++++++++ include/frame/gui/draw_gui_interface.h | 13 ++++++- include/frame/gui/window_logger.h | 5 ++- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 27 +++++++++++++- src/frame/opengl/gui/sdl_opengl_draw_gui.h | 17 ++++++++- 7 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 examples/02-scene_simple/modal_info.h diff --git a/examples/02-scene_simple/CMakeLists.txt b/examples/02-scene_simple/CMakeLists.txt index 16c1892..bd6a5ff 100644 --- a/examples/02-scene_simple/CMakeLists.txt +++ b/examples/02-scene_simple/CMakeLists.txt @@ -3,6 +3,7 @@ add_executable(02_SceneSimple WIN32 main.cpp + modal_info.h ${CMAKE_CURRENT_SOURCE_DIR}/../../asset/json/scene_simple.json ) diff --git a/examples/02-scene_simple/main.cpp b/examples/02-scene_simple/main.cpp index e2a13e3..d30c5e2 100644 --- a/examples/02-scene_simple/main.cpp +++ b/examples/02-scene_simple/main.cpp @@ -16,6 +16,7 @@ #include "frame/gui/window_resolution.h" #include "frame/gui/window_logger.h" #include "frame/window_factory.h" +#include "modal_info.h" // From: https://sourceforge.net/p/predef/wiki/OperatingSystems/ #if defined(_WIN32) || defined(_WIN64) @@ -45,7 +46,11 @@ try "Resolution", size, win->GetDesktopSize(), win->GetPixelPerInch()); ptr_window_resolution = gui_resolution.get(); gui_window->AddWindow(std::move(gui_resolution)); - gui_window->AddWindow(std::make_unique("Logger")); + gui_window->AddWindow( + std::make_unique("Logger")); + // gui_window->SetVisible(false); + gui_window->AddModalWindow( + std::make_unique("Info", "This is a test modal window.")); win->GetDevice().AddPlugin(std::move(gui_window)); frame::common::Application app(std::move(win)); do diff --git a/examples/02-scene_simple/modal_info.h b/examples/02-scene_simple/modal_info.h new file mode 100644 index 0000000..8d2be1f --- /dev/null +++ b/examples/02-scene_simple/modal_info.h @@ -0,0 +1,39 @@ +#pragma once + +#include "frame/gui/gui_window_interface.h" +#include + +class ModalInfo : public frame::gui::GuiWindowInterface +{ + public: + ModalInfo(const std::string& name, const std::string& text) : + name_(name), text_(text) + { + } + bool DrawCallback() override + { + ImGui::Text(text_.c_str()); + if (ImGui::Button("Ok")) + { + end_ = true; + } + return true; + } + bool End() const override + { + return end_; + } + std::string GetName() const override + { + return name_; + } + void SetName(const std::string& name) override + { + name_ = name; + } + + private: + bool end_ = false; + std::string name_; + std::string text_; +}; diff --git a/include/frame/gui/draw_gui_interface.h b/include/frame/gui/draw_gui_interface.h index 28b65e6..518b85d 100644 --- a/include/frame/gui/draw_gui_interface.h +++ b/include/frame/gui/draw_gui_interface.h @@ -2,9 +2,9 @@ #include +#include "frame/gui/gui_window_interface.h" #include "frame/name_interface.h" #include "frame/plugin_interface.h" -#include "frame/gui/gui_window_interface.h" namespace frame::gui { @@ -22,7 +22,16 @@ class DrawGuiInterface : public PluginInterface * @brief Add sub window to the main window. * @param callback: A window callback that can add buttons, etc. */ - virtual void AddWindow(std::unique_ptr&& callback) = 0; + virtual void AddWindow(std::unique_ptr callback) = 0; + /** + * @brief Add a modal window. + * @param callback: A window callback that can add buttons, etc. + * + * If the callback return is 0 the callback stay and if it is other it is + * removed. This will trigger an internal boolean that will decide if the + * modal is active or not. + */ + virtual void AddModalWindow(std::unique_ptr callback) = 0; /** * @brief Get a specific window (associated with a name). * @param name: The name of the window. diff --git a/include/frame/gui/window_logger.h b/include/frame/gui/window_logger.h index 324f63f..5462fe9 100644 --- a/include/frame/gui/window_logger.h +++ b/include/frame/gui/window_logger.h @@ -35,7 +35,10 @@ class WindowLogger : public GuiWindowInterface bool End() const override; protected: - //! @brief Log with color. + /** + * @brief Log with color. + * @param log_message: The log message to log. + */ void LogWithColor(const LogMessage& log_message) const; private: diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index 1352a63..8dd0132 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -137,6 +137,26 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) { ImGui::Begin(texture.GetName().c_str()); } + if (is_default_output && modal_callback_) + { + if (!start_modal_) + { + ImGui::OpenPopup(modal_callback_->GetName().c_str()); + start_modal_ = true; + } + ImGui::BeginPopupModal( + modal_callback_->GetName().c_str(), + nullptr, + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove); + modal_callback_->DrawCallback(); + if (modal_callback_->End()) + { + start_modal_ = false; + ImGui::CloseCurrentPopup(); + modal_callback_.reset(); + } + ImGui::EndPopup(); + } // Check if you should enable default window keyboard and mouse. if (ImGui::IsWindowHovered() && is_default_output) { @@ -200,7 +220,7 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) } void SDL2OpenGLDrawGui::AddWindow( - std::unique_ptr&& callback) + std::unique_ptr callback) { std::string name = callback->GetName(); if (name.empty()) @@ -210,6 +230,11 @@ void SDL2OpenGLDrawGui::AddWindow( callbacks_.insert({name, std::move(callback)}); } +void SDL2OpenGLDrawGui::AddModalWindow(std::unique_ptr callback) +{ + modal_callback_ = std::move(callback); +} + std::vector SDL2OpenGLDrawGui::GetWindowTitles() const { std::vector name_list; diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.h b/src/frame/opengl/gui/sdl_opengl_draw_gui.h index 3d7a2e3..a83662f 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.h +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.h @@ -88,13 +88,24 @@ class SDL2OpenGLDrawGui : public frame::gui::DrawGuiInterface * @param callback: A window callback that can add buttons, etc. */ void AddWindow( - std::unique_ptr&& callback) override; + std::unique_ptr callback) override; + /** + * @brief Add a modal window. + * @param callback: A window callback that can add buttons, etc. + * + * If the callback return is 0 the callback stay and if it is other it is + * removed. This will trigger an internal boolean that will decide if the + * modal is active or not. + */ + void AddModalWindow( + std::unique_ptr callback) override; /** * @brief Get a specific window (associated with a name). * @param name: The name of the window. * @return A pointer to the window. */ - frame::gui::GuiWindowInterface& GetWindow(const std::string& name) override; + frame::gui::GuiWindowInterface& GetWindow( + const std::string& name) override; /** * @brief Get all sub window name (title). * @return A list of all the sub windows. @@ -126,6 +137,8 @@ class SDL2OpenGLDrawGui : public frame::gui::DrawGuiInterface protected: std::map> callbacks_ = {}; + std::unique_ptr modal_callback_ = nullptr; + bool start_modal_ = false; std::filesystem::path font_path_; WindowInterface& window_; DeviceInterface& device_; From 0df4ef5a1278eff86131d39a7fcb0e2da2b33b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Wed, 14 Feb 2024 16:06:34 +0100 Subject: [PATCH 10/34] Changed the interface to Application and added a new method to get the window. --- examples/02-scene_simple/main.cpp | 11 ++++++++--- include/frame/common/application.h | 9 +++++++-- src/frame/common/application.cpp | 10 ++++++++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/examples/02-scene_simple/main.cpp b/examples/02-scene_simple/main.cpp index d30c5e2..e467fe6 100644 --- a/examples/02-scene_simple/main.cpp +++ b/examples/02-scene_simple/main.cpp @@ -9,12 +9,14 @@ #include #endif +#include + #include "frame/common/application.h" #include "frame/file/file_system.h" #include "frame/file/image_stb.h" #include "frame/gui/draw_gui_factory.h" -#include "frame/gui/window_resolution.h" #include "frame/gui/window_logger.h" +#include "frame/gui/window_resolution.h" #include "frame/window_factory.h" #include "modal_info.h" @@ -46,9 +48,12 @@ try "Resolution", size, win->GetDesktopSize(), win->GetPixelPerInch()); ptr_window_resolution = gui_resolution.get(); gui_window->AddWindow(std::move(gui_resolution)); - gui_window->AddWindow( - std::make_unique("Logger")); + gui_window->AddWindow(std::make_unique("Logger")); + // Set the main window in full. // gui_window->SetVisible(false); + ImGuiStyle& style = ImGui::GetStyle(); + style.Colors[ImGuiCol_PopupBg] = ImVec4( + 0.1f, 0.5f, 0.1f, 0.9f); // Dark background with some transparency gui_window->AddModalWindow( std::make_unique("Info", "This is a test modal window.")); win->GetDevice().AddPlugin(std::move(gui_window)); diff --git a/include/frame/common/application.h b/include/frame/common/application.h index 44931ae..6190d53 100644 --- a/include/frame/common/application.h +++ b/include/frame/common/application.h @@ -22,7 +22,12 @@ class Application * @param window: The unique pointer to the window (should have been * created prior). */ - Application(std::unique_ptr&& window); + Application(std::unique_ptr window); + /** + * @brief Get the Window object. + * @return The window. + */ + frame::WindowInterface& GetWindow(); /** * @brief Startup this will initialized the inner level of the window * according to a path. @@ -34,7 +39,7 @@ class Application * @brief Same as previously but this use a level. * @param level: A unique pointer to a level. */ - void Startup(std::unique_ptr&& level); + void Startup(std::unique_ptr level); /** * @brief A helper function that call the inner resize of the window. * @param size: The new size of the window. diff --git a/src/frame/common/application.cpp b/src/frame/common/application.cpp index d00abc3..6b0cc04 100644 --- a/src/frame/common/application.cpp +++ b/src/frame/common/application.cpp @@ -5,12 +5,18 @@ namespace frame::common { -Application::Application(std::unique_ptr&& window) +Application::Application(std::unique_ptr window) : window_(std::move(window)) { assert(window_); } +frame::WindowInterface& Application::GetWindow() +{ + assert(window_); + return *window_; +} + void Application::Startup(std::filesystem::path path) { assert(window_); @@ -25,7 +31,7 @@ void Application::Startup(std::filesystem::path path) device.AddPlugin(std::move(plugin)); } -void Application::Startup(std::unique_ptr&& level) +void Application::Startup(std::unique_ptr level) { assert(window_); auto& device = window_->GetDevice(); From b774e1d119f0f894670f2f25b9511e40870a00e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Wed, 14 Feb 2024 17:42:36 +0100 Subject: [PATCH 11/34] Supressed the catch of ESC for debug mode. --- examples/02-scene_simple/main.cpp | 5 ----- src/frame/opengl/sdl_opengl_window.cpp | 24 ++++++------------------ 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/examples/02-scene_simple/main.cpp b/examples/02-scene_simple/main.cpp index e467fe6..cee732c 100644 --- a/examples/02-scene_simple/main.cpp +++ b/examples/02-scene_simple/main.cpp @@ -9,8 +9,6 @@ #include #endif -#include - #include "frame/common/application.h" #include "frame/file/file_system.h" #include "frame/file/image_stb.h" @@ -51,9 +49,6 @@ try gui_window->AddWindow(std::make_unique("Logger")); // Set the main window in full. // gui_window->SetVisible(false); - ImGuiStyle& style = ImGui::GetStyle(); - style.Colors[ImGuiCol_PopupBg] = ImVec4( - 0.1f, 0.5f, 0.1f, 0.9f); // Dark background with some transparency gui_window->AddModalWindow( std::make_unique("Info", "This is a test modal window.")); win->GetDevice().AddPlugin(std::move(gui_window)); diff --git a/src/frame/opengl/sdl_opengl_window.cpp b/src/frame/opengl/sdl_opengl_window.cpp index 07b1d98..29c6702 100644 --- a/src/frame/opengl/sdl_opengl_window.cpp +++ b/src/frame/opengl/sdl_opengl_window.cpp @@ -92,15 +92,18 @@ void SDLOpenGLWindow::Run(std::function lambda) } } if (skip) + { continue; + } if (!RunEvent(event, dt)) { loop = false; } } if (input_interface_) + { input_interface_->NextFrame(); - + } device_->Display(time.count()); // Draw the Scene not used? @@ -122,7 +125,9 @@ void SDLOpenGLWindow::Run(std::function lambda) // TODO(anirul): Fix me to check which device this is. if (device_) + { SDL_GL_SwapWindow(sdl_window_); + } } while (loop); } @@ -140,23 +145,6 @@ bool SDLOpenGLWindow::RunEvent(const SDL_Event& event, const double dt) { switch (event.key.keysym.sym) { - case SDLK_ESCAPE: { - if (has_window_plugin) - { - for (PluginInterface* plugin : device_->GetPluginPtrs()) - { - auto* window_plugin = - dynamic_cast(plugin); - if (window_plugin) - { - auto is_visible = window_plugin->IsVisible(); - window_plugin->SetVisible(!is_visible); - } - } - return true; - } - return false; - } case SDLK_PRINTSCREEN: device_->ScreenShot("ScreenShot.png"); return true; From a118b29dc571273fedc3f5a456cafb037d8ee243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Thu, 15 Feb 2024 09:29:48 +0100 Subject: [PATCH 12/34] Changed the way string are passed to the IMGUI library (needed to be strict u8). --- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index 8dd0132..da948ea 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -48,7 +48,8 @@ SDL2OpenGLDrawGui::SDL2OpenGLDrawGui( else { io.Fonts->AddFontFromFileTTF( - reinterpret_cast(font_path_.c_str()), font_size_); + reinterpret_cast(font_path_.u8string().c_str()), + font_size_); } // Setup Platform/Renderer back ends From 91479bab5238e8cfc0363632f47554774e367759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Thu, 15 Feb 2024 17:32:03 +0100 Subject: [PATCH 13/34] Changed the way the DrawGuiInterface is registered now with a name! --- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index da948ea..67e317e 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -23,6 +23,8 @@ SDL2OpenGLDrawGui::SDL2OpenGLDrawGui( font_path_(font_path), font_size_(font_size) { + // Set the name this is a way to find the plugin. + SetName("DrawGuiInterface"); // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); From 7355ff6d8061677aa44a862cb72a9592abec95a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Sat, 17 Feb 2024 11:14:19 +0100 Subject: [PATCH 14/34] Added a remove key to the window interface. --- include/frame/window_interface.h | 5 +++++ src/frame/opengl/sdl_opengl_none.h | 4 ++++ src/frame/opengl/sdl_opengl_window.h | 4 ++++ src/frame/vulkan/sdl_vulkan_none.h | 4 ++++ src/frame/vulkan/sdl_vulkan_window.h | 4 ++++ 5 files changed, 21 insertions(+) diff --git a/include/frame/window_interface.h b/include/frame/window_interface.h index 77b836d..c4337f6 100644 --- a/include/frame/window_interface.h +++ b/include/frame/window_interface.h @@ -38,6 +38,11 @@ struct WindowInterface */ virtual void AddKeyCallback( std::int32_t key, std::function func) = 0; + /** + * @brief Remove a callback to a key. + * @param key: The key to remove the callback from. + */ + virtual void RemoveKeyCallback(std::int32_t key) = 0; /** * @brief Set the unique device (this is suppose to be variable to the * one you are using see : DirectX, OpenGL, etc...). diff --git a/src/frame/opengl/sdl_opengl_none.h b/src/frame/opengl/sdl_opengl_none.h index 0c125c2..b014543 100644 --- a/src/frame/opengl/sdl_opengl_none.h +++ b/src/frame/opengl/sdl_opengl_none.h @@ -35,6 +35,10 @@ class SDLOpenGLNone : public WindowInterface { throw std::runtime_error("Not implemented."); } + void RemoveKeyCallback(std::int32_t key) override + { + throw std::runtime_error("Not implemented."); + } void SetUniqueDevice(std::unique_ptr&& device) override { device_ = std::move(device); diff --git a/src/frame/opengl/sdl_opengl_window.h b/src/frame/opengl/sdl_opengl_window.h index 67eeafd..73d2d1f 100644 --- a/src/frame/opengl/sdl_opengl_window.h +++ b/src/frame/opengl/sdl_opengl_window.h @@ -31,6 +31,10 @@ class SDLOpenGLWindow : public WindowInterface { key_callbacks_.insert({key, func}); } + void RemoveKeyCallback(std::int32_t key) override + { + key_callbacks_.erase(key); + } void SetUniqueDevice(std::unique_ptr&& device) override { device_ = std::move(device); diff --git a/src/frame/vulkan/sdl_vulkan_none.h b/src/frame/vulkan/sdl_vulkan_none.h index ebf8fa0..ff32244 100644 --- a/src/frame/vulkan/sdl_vulkan_none.h +++ b/src/frame/vulkan/sdl_vulkan_none.h @@ -36,6 +36,10 @@ class SDLVulkanNone : public WindowInterface { throw std::runtime_error("Not implemented yet!"); } + void RemoveKeyCallback(std::int32_t key) override + { + throw std::runtime_error("Not implemented yet!"); + } void SetUniqueDevice(std::unique_ptr&& device) override { device_ = std::move(device); diff --git a/src/frame/vulkan/sdl_vulkan_window.h b/src/frame/vulkan/sdl_vulkan_window.h index 2596dc3..a689e65 100644 --- a/src/frame/vulkan/sdl_vulkan_window.h +++ b/src/frame/vulkan/sdl_vulkan_window.h @@ -32,6 +32,10 @@ class SDLVulkanWindow : public WindowInterface { throw std::runtime_error("Not implemented yet!"); } + void RemoveKeyCallback(std::int32_t key) override + { + throw std::runtime_error("Not implemented yet!"); + } void SetUniqueDevice(std::unique_ptr&& device) override { device_ = std::move(device); From ee3d75128ff7dab26c01af50e4af9c199b35bf75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Tue, 20 Feb 2024 09:36:51 +0100 Subject: [PATCH 15/34] Fix a bug in the logger. --- src/frame/gui/window_logger.cpp | 3 +-- src/frame/logger.cpp | 9 +++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/frame/gui/window_logger.cpp b/src/frame/gui/window_logger.cpp index ac7cfb1..2aed8b6 100644 --- a/src/frame/gui/window_logger.cpp +++ b/src/frame/gui/window_logger.cpp @@ -66,8 +66,7 @@ void WindowLogger::LogWithColor(const LogMessage& log_message) const ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); break; default: - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); - break; + throw std::runtime_error("Unknown log level!"); } ImGui::TextUnformatted(log_message.message.c_str()); ImGui::PopStyleColor(); diff --git a/src/frame/logger.cpp b/src/frame/logger.cpp index bc8817c..46ac8fb 100644 --- a/src/frame/logger.cpp +++ b/src/frame/logger.cpp @@ -56,19 +56,16 @@ const std::vector& Logger::GetLastLogs(std::uint32_t max_log) const std::dynamic_pointer_cast(gui_logger_sink_); if (gui_logger_sink) { - if (display_logs_.capacity() != max_log) - { - display_logs_.reserve(max_log); - } const auto& logs = gui_logger_sink->GetLogs(); if (logs.size() <= max_log) { return logs; } display_logs_.clear(); - for (std::size_t i = logs.size() - max_log; i < logs.size(); ++i) + std::size_t start = logs.size() - max_log; + for (std::size_t i = 0; i < max_log; ++i) { - display_logs_.push_back(logs[i]); + display_logs_.push_back(logs[start + i]); } return display_logs_; } From b857a02c625afcd4e1d7c3423e812ade87df2c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Fri, 23 Feb 2024 12:13:13 +0100 Subject: [PATCH 16/34] Now you can add vector into the uniform. --- include/frame/program_interface.h | 24 ++++++++++++++++ src/frame/opengl/program.cpp | 46 +++++++++++++++++++++++++++++++ src/frame/opengl/program.h | 24 ++++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/include/frame/program_interface.h b/include/frame/program_interface.h index bb38fe0..0336918 100644 --- a/include/frame/program_interface.h +++ b/include/frame/program_interface.h @@ -144,6 +144,30 @@ struct ProgramInterface : public NameInterface * @param name: Name of the uniform. * @param vector: Vector to be inputed into the uniform. */ + virtual void Uniform( + const std::string& name, + const std::vector& vector) const = 0; + /** + * @brief Create a uniform from a string and a vector. + * @param name: Name of the uniform. + * @param vector: Vector to be inputed into the uniform. + */ + virtual void Uniform( + const std::string& name, + const std::vector& vector) const = 0; + /** + * @brief Create a uniform from a string and a vector. + * @param name: Name of the uniform. + * @param vector: Vector to be inputed into the uniform. + */ + virtual void Uniform( + const std::string& name, + const std::vector& vector) const = 0; + /** + * @brief Create a uniform from a string and a vector. + * @param name: Name of the uniform. + * @param vector: Vector to be inputed into the uniform. + */ virtual void Uniform( const std::string& name, const std::vector& vector, diff --git a/src/frame/opengl/program.cpp b/src/frame/opengl/program.cpp index 003df8c..12f208c 100644 --- a/src/frame/opengl/program.cpp +++ b/src/frame/opengl/program.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "frame/logger.h" @@ -138,6 +139,51 @@ void Program::Uniform(const std::string& name, const glm::mat4 mat) const GetMemoizeUniformLocation(name), 1, GL_FALSE, &mat[0][0]); } +void Program::Uniform( + const std::string& name, + const std::vector& vector) const +{ + if (vector.size() == 0) + { + logger_->warn("Entered a uniform [{}] without size.", name); + return; + } + glUniform2fv( + GetMemoizeUniformLocation(name), + static_cast(vector.size()), + glm::value_ptr(vector[0])); +} + +void Program::Uniform( + const std::string& name, + const std::vector& vector) const +{ + if (vector.size() == 0) + { + logger_->warn("Entered a uniform [{}] without size.", name); + return; + } + glUniform3fv( + GetMemoizeUniformLocation(name), + static_cast(vector.size()), + glm::value_ptr(vector[0])); +} + +void Program::Uniform( + const std::string& name, + const std::vector& vector) const +{ + if (vector.size() == 0) + { + logger_->warn("Entered a uniform [{}] without size.", name); + return; + } + glUniform4fv( + GetMemoizeUniformLocation(name), + static_cast(vector.size()), + glm::value_ptr(vector[0])); +} + void Program::Uniform( const std::string& name, const std::vector& vector, diff --git a/src/frame/opengl/program.h b/src/frame/opengl/program.h index 7bb7cae..c059518 100644 --- a/src/frame/opengl/program.h +++ b/src/frame/opengl/program.h @@ -165,6 +165,30 @@ class Program : public ProgramInterface * @param value: Matrix. */ void Uniform(const std::string& name, const glm::mat4 mat) const override; + /** + * @brief Create a uniform from a string and a vector. + * @param name: Name of the uniform. + * @param vector: Vector to be inputed into the uniform. + */ + void Uniform( + const std::string& name, + const std::vector& vector) const override; + /** + * @brief Create a uniform from a string and a vector. + * @param name: Name of the uniform. + * @param vector: Vector to be inputed into the uniform. + */ + void Uniform( + const std::string& name, + const std::vector& vector) const override; + /** + * @brief Create a uniform from a string and a vector. + * @param name: Name of the uniform. + * @param vector: Vector to be inputed into the uniform. + */ + void Uniform( + const std::string& name, + const std::vector& vector) const override; /** * @brief Create a uniform from a string and a vector. * For now this is checking the size of the vector to input in the From 60ee90772ef05c1b40526667bf60af947a41f609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Fri, 23 Feb 2024 15:39:36 +0100 Subject: [PATCH 17/34] Now you can parse vecX from JSON. --- src/frame/json/parse_program.cpp | 12 ++++++++++++ src/frame/json/parse_uniform.cpp | 30 ++++++++++++++++++++++++++++++ src/frame/json/parse_uniform.h | 18 ++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/src/frame/json/parse_program.cpp b/src/frame/json/parse_program.cpp index e4a5d78..bd7bad7 100644 --- a/src/frame/json/parse_program.cpp +++ b/src/frame/json/parse_program.cpp @@ -94,6 +94,18 @@ std::unique_ptr ParseProgramOpenGL( program->Uniform( parameter.name(), ParseUniform(parameter.uniform_mat4())); break; + case Uniform::kUniformVec2S: + program->Uniform( + parameter.name(), ParseUniform(parameter.uniform_vec2s())); + break; + case Uniform::kUniformVec3S: + program->Uniform( + parameter.name(), ParseUniform(parameter.uniform_vec3s())); + break; + case Uniform::kUniformVec4S: + program->Uniform( + parameter.name(), ParseUniform(parameter.uniform_vec4s())); + break; case Uniform::kUniformFloatPlugin: break; case Uniform::kUniformIntPlugin: diff --git a/src/frame/json/parse_uniform.cpp b/src/frame/json/parse_uniform.cpp index 5eca71b..745350d 100644 --- a/src/frame/json/parse_uniform.cpp +++ b/src/frame/json/parse_uniform.cpp @@ -42,6 +42,36 @@ glm::mat4 ParseUniform(const UniformMatrix4& uniform_mat4) uniform_mat4.m44()); } +std::vector ParseUniform(const UniformVector2s& uniform_vec2s) +{ + std::vector vec2s; + for (const auto& vec2 : uniform_vec2s.values()) + { + vec2s.push_back(ParseUniform(vec2)); + } + return vec2s; +} + +std::vector ParseUniform(const UniformVector3s& uniform_vec3s) +{ + std::vector vec3s; + for (const auto& vec3 : uniform_vec3s.values()) + { + vec3s.push_back(ParseUniform(vec3)); + } + return vec3s; +} + +std::vector ParseUniform(const UniformVector4s& uniform_vec4s) +{ + std::vector vec4s; + for (const auto& vec4 : uniform_vec4s.values()) + { + vec4s.push_back(ParseUniform(vec4)); + } + return vec4s; +} + glm::quat ParseUniform(const UniformQuaternion& uniform_quat) { return { diff --git a/src/frame/json/parse_uniform.h b/src/frame/json/parse_uniform.h index 7a5fba7..0bc99c3 100644 --- a/src/frame/json/parse_uniform.h +++ b/src/frame/json/parse_uniform.h @@ -48,6 +48,24 @@ glm::vec4 ParseUniform(const UniformVector4& uniform_vec4); * @return Glm mat4 output. */ glm::mat4 ParseUniform(const UniformMatrix4& uniform_mat4); +/** + * @brief Specialization into vector types. + * @param uniform_vec2s: Uniform vector 2s input. + * @return Glm vec2s output. + */ +std::vector ParseUniform(const UniformVector2s& uniform_vec2s); +/** + * @brief Specialization into vector types. + * @param uniform_vec3s: Uniform vector 3s input. + * @return Glm vec3s output. + */ +std::vector ParseUniform(const UniformVector3s& uniform_vec3s); +/** + * @brief Specialization into vector types. + * @param uniform_vec4s: Uniform vector 4s input. + * @return Glm vec4s output. + */ +std::vector ParseUniform(const UniformVector4s& uniform_vec4s); /** * @brief Specialization into glm types (quat). * @param uniform_quat: Uniform quaternion input. From 43784dde4b951d5e966a0da9a85bed71b0416195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Sat, 24 Feb 2024 08:24:40 +0100 Subject: [PATCH 18/34] Added Use to the program uniform adding function (the one that is called from JSON). --- src/frame/json/parse_program.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/frame/json/parse_program.cpp b/src/frame/json/parse_program.cpp index bd7bad7..ebc6167 100644 --- a/src/frame/json/parse_program.cpp +++ b/src/frame/json/parse_program.cpp @@ -66,6 +66,7 @@ std::unique_ptr ParseProgramOpenGL( "No way {}?", static_cast(proto_program.input_scene_type().value()))); } + program->Use(); for (const auto& parameter : proto_program.parameters()) { switch (parameter.value_oneof_case()) @@ -116,6 +117,7 @@ std::unique_ptr ParseProgramOpenGL( static_cast(parameter.value_oneof_case()))); } } + program->UnUse(); return program; } From a85afd2aaf5e96448c6c23b21ea75f74fc2a5b88 Mon Sep 17 00:00:00 2001 From: Rolf Jordi Date: Sat, 24 Feb 2024 22:36:50 +0100 Subject: [PATCH 19/34] linux compile --- include/frame/buffer_interface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/frame/buffer_interface.h b/include/frame/buffer_interface.h index f07dcf6..eb4d11c 100644 --- a/include/frame/buffer_interface.h +++ b/include/frame/buffer_interface.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "frame/name_interface.h" From bf468de2a4a2fdb7b2ed1d9462eaaae70bf91ce5 Mon Sep 17 00:00:00 2001 From: Rolf Jordi Date: Sun, 25 Feb 2024 21:11:13 +0100 Subject: [PATCH 20/34] fix linking on linux the issue is with tests/frame/file build frame/file/image.h is using frame/json/parse_pixel.h --- tests/frame/file/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/frame/file/CMakeLists.txt b/tests/frame/file/CMakeLists.txt index cc02ca0..68cdc93 100644 --- a/tests/frame/file/CMakeLists.txt +++ b/tests/frame/file/CMakeLists.txt @@ -24,6 +24,7 @@ target_link_libraries(FrameFileTest PUBLIC Frame FrameFile + FrameJson GTest::gmock GTest::gtest ) From 9d80c535ec9c017cb48fe822482e333fd4db05f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Tue, 27 Feb 2024 11:03:44 +0100 Subject: [PATCH 21/34] Changed the interface to the window to now take unique pointer instead of left references. --- include/frame/window_interface.h | 4 ++-- src/frame/opengl/sdl_opengl_none.h | 4 ++-- src/frame/opengl/sdl_opengl_window.h | 4 ++-- src/frame/vulkan/sdl_vulkan_none.h | 4 ++-- src/frame/vulkan/sdl_vulkan_window.h | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/frame/window_interface.h b/include/frame/window_interface.h index c4337f6..52ab405 100644 --- a/include/frame/window_interface.h +++ b/include/frame/window_interface.h @@ -29,7 +29,7 @@ struct WindowInterface * @param input_interface: Move a input interface to the window object. */ virtual void SetInputInterface( - std::unique_ptr&& input_interface) = 0; + std::unique_ptr input_interface) = 0; /** * @brief Add a callback for a key. * @param key: The key to add a callback for. @@ -48,7 +48,7 @@ struct WindowInterface * one you are using see : DirectX, OpenGL, etc...). * @param device: Move a device to the window object. */ - virtual void SetUniqueDevice(std::unique_ptr&& device) = 0; + virtual void SetUniqueDevice(std::unique_ptr device) = 0; /** * @brief Get the current device the one that was assign to this window. * @return A pointer to a device interface. diff --git a/src/frame/opengl/sdl_opengl_none.h b/src/frame/opengl/sdl_opengl_none.h index b014543..ea3c391 100644 --- a/src/frame/opengl/sdl_opengl_none.h +++ b/src/frame/opengl/sdl_opengl_none.h @@ -27,7 +27,7 @@ class SDLOpenGLNone : public WindowInterface public: void SetInputInterface( - std::unique_ptr&& input_interface) override + std::unique_ptr input_interface) override { input_interface_ = std::move(input_interface); } @@ -39,7 +39,7 @@ class SDLOpenGLNone : public WindowInterface { throw std::runtime_error("Not implemented."); } - void SetUniqueDevice(std::unique_ptr&& device) override + void SetUniqueDevice(std::unique_ptr device) override { device_ = std::move(device); } diff --git a/src/frame/opengl/sdl_opengl_window.h b/src/frame/opengl/sdl_opengl_window.h index 73d2d1f..fda0e87 100644 --- a/src/frame/opengl/sdl_opengl_window.h +++ b/src/frame/opengl/sdl_opengl_window.h @@ -23,7 +23,7 @@ class SDLOpenGLWindow : public WindowInterface public: void SetInputInterface( - std::unique_ptr&& input_interface) override + std::unique_ptr input_interface) override { input_interface_ = std::move(input_interface); } @@ -35,7 +35,7 @@ class SDLOpenGLWindow : public WindowInterface { key_callbacks_.erase(key); } - void SetUniqueDevice(std::unique_ptr&& device) override + void SetUniqueDevice(std::unique_ptr device) override { device_ = std::move(device); } diff --git a/src/frame/vulkan/sdl_vulkan_none.h b/src/frame/vulkan/sdl_vulkan_none.h index ff32244..826783e 100644 --- a/src/frame/vulkan/sdl_vulkan_none.h +++ b/src/frame/vulkan/sdl_vulkan_none.h @@ -28,7 +28,7 @@ class SDLVulkanNone : public WindowInterface public: void SetInputInterface( - std::unique_ptr&& input_interface) override + std::unique_ptr input_interface) override { input_interface_ = std::move(input_interface); } @@ -40,7 +40,7 @@ class SDLVulkanNone : public WindowInterface { throw std::runtime_error("Not implemented yet!"); } - void SetUniqueDevice(std::unique_ptr&& device) override + void SetUniqueDevice(std::unique_ptr device) override { device_ = std::move(device); } diff --git a/src/frame/vulkan/sdl_vulkan_window.h b/src/frame/vulkan/sdl_vulkan_window.h index a689e65..8a7b38c 100644 --- a/src/frame/vulkan/sdl_vulkan_window.h +++ b/src/frame/vulkan/sdl_vulkan_window.h @@ -24,7 +24,7 @@ class SDLVulkanWindow : public WindowInterface public: void SetInputInterface( - std::unique_ptr&& input_interface) override + std::unique_ptr input_interface) override { input_interface_ = std::move(input_interface); } @@ -36,7 +36,7 @@ class SDLVulkanWindow : public WindowInterface { throw std::runtime_error("Not implemented yet!"); } - void SetUniqueDevice(std::unique_ptr&& device) override + void SetUniqueDevice(std::unique_ptr device) override { device_ = std::move(device); } From d97dc044be9fff07d18ca473cf057d9b7039f315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Fri, 1 Mar 2024 15:24:23 +0100 Subject: [PATCH 22/34] Fix a warning on linux. --- examples/02-scene_simple/modal_info.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/02-scene_simple/modal_info.h b/examples/02-scene_simple/modal_info.h index 8d2be1f..43019b8 100644 --- a/examples/02-scene_simple/modal_info.h +++ b/examples/02-scene_simple/modal_info.h @@ -12,7 +12,7 @@ class ModalInfo : public frame::gui::GuiWindowInterface } bool DrawCallback() override { - ImGui::Text(text_.c_str()); + ImGui::TextUnformatted(text_.c_str()); if (ImGui::Button("Ok")) { end_ = true; From 474f5a00e5c03891c4b2dce44549f995b08a6e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Fri, 1 Mar 2024 16:33:10 +0100 Subject: [PATCH 23/34] Changed the version of the shader for other platform than windows. --- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index 67e317e..1923748 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -58,7 +58,11 @@ SDL2OpenGLDrawGui::SDL2OpenGLDrawGui( ImGui_ImplSDL2_InitForOpenGL( static_cast(window_.GetWindowContext()), device_.GetDeviceContext()); +#ifdef _WIN32 || _WIN64 ImGui_ImplOpenGL3_Init("#version 450"); +#else + ImGui_ImplOpenGL3_Init("#version 330"); +#endif } SDL2OpenGLDrawGui::~SDL2OpenGLDrawGui() From 78fc317b32351ff661c8232c3d160a6d36f28734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Fri, 1 Mar 2024 16:46:42 +0100 Subject: [PATCH 24/34] Update for linux. --- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index 1923748..af2026e 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -58,7 +58,7 @@ SDL2OpenGLDrawGui::SDL2OpenGLDrawGui( ImGui_ImplSDL2_InitForOpenGL( static_cast(window_.GetWindowContext()), device_.GetDeviceContext()); -#ifdef _WIN32 || _WIN64 +#if defined(_WIN32) || defined(_WIN64) ImGui_ImplOpenGL3_Init("#version 450"); #else ImGui_ImplOpenGL3_Init("#version 330"); From 1bad0b3f887daaec4bbe4381a9fcd4cdd58294b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Fri, 15 Mar 2024 13:28:45 +0100 Subject: [PATCH 25/34] Corrected modal window issue. --- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 37 ++++++++++++++------ src/frame/opengl/gui/sdl_opengl_draw_gui.h | 2 ++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index af2026e..ad36fb9 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -128,6 +128,20 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) if (is_default_output) { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); + original_image_size_ = texture.GetSize(); + } + // This is in window addition to the main window. + bool is_invisible_window = name_[0] == '#' && name_[1] == '#'; + if (is_invisible_window && is_default_output) + { + ImGui::SetNextWindowPos( + ImVec2( + static_cast(next_window_position_.x), + static_cast(next_window_position_.y))); + ImGui::SetNextWindowSize( + ImVec2( + static_cast(original_image_size_.x), + static_cast(original_image_size_.y))); } // If the window are not visible and it is not the main window then // bail out. @@ -151,18 +165,21 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) ImGui::OpenPopup(modal_callback_->GetName().c_str()); start_modal_ = true; } - ImGui::BeginPopupModal( - modal_callback_->GetName().c_str(), - nullptr, - ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove); - modal_callback_->DrawCallback(); - if (modal_callback_->End()) + if (ImGui::BeginPopupModal( + modal_callback_->GetName().c_str(), + nullptr, + ImGuiWindowFlags_AlwaysAutoResize | + ImGuiWindowFlags_NoMove)) { - start_modal_ = false; - ImGui::CloseCurrentPopup(); - modal_callback_.reset(); + modal_callback_->DrawCallback(); + if (modal_callback_->End()) + { + start_modal_ = false; + ImGui::CloseCurrentPopup(); + modal_callback_.reset(); + } + ImGui::EndPopup(); } - ImGui::EndPopup(); } // Check if you should enable default window keyboard and mouse. if (ImGui::IsWindowHovered() && is_default_output) diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.h b/src/frame/opengl/gui/sdl_opengl_draw_gui.h index a83662f..5942328 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.h +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.h @@ -144,6 +144,8 @@ class SDL2OpenGLDrawGui : public frame::gui::DrawGuiInterface DeviceInterface& device_; std::string name_; glm::uvec2 size_ = {0, 0}; + glm::uvec2 next_window_position_ = {0, 0}; + glm::uvec2 original_image_size_ = {0, 0}; bool is_keyboard_passed_ = false; bool is_visible_ = true; float font_size_ = 20.0f; From 318f6b4dad6249ea3638d84a0d1de9718a85cc0b Mon Sep 17 00:00:00 2001 From: Rolf Jordi Date: Sun, 17 Mar 2024 09:43:15 +0100 Subject: [PATCH 26/34] ajout de githubaction pour le build et test de Frame --- .github/workflows/cmake-multi-platform.yml | 77 ++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 .github/workflows/cmake-multi-platform.yml diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml new file mode 100644 index 0000000..7683477 --- /dev/null +++ b/.github/workflows/cmake-multi-platform.yml @@ -0,0 +1,77 @@ +# build the Frame code on linux and run the test +# copy from https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml +name: CMake on multiple platforms + +on: + push: + +jobs: + build: + runs-on: ${{ matrix.os }} + + strategy: + # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. + fail-fast: true + # Matrix not used, missing windows knowledge to do build it + # clang compiler not working with ubuntu because issue with std lib and clang (tested with clang15) + matrix: + os: [ubuntu-latest] + build_type: [Release] + c_compiler: [gcc] + cpp_compiler: [g++] + triplet: [x64-linux-release] + include: + - os: ubuntu-latest + c_compiler: gcc + cpp_compiler: g++ + triplet: x64-linux-release + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + lfs: true + submodules: true + - name: Set reusable strings + # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file. + id: strings + shell: bash + run: | + echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + - name: apt install + if: ${{ matrix.os == 'ubuntu-latest' }} + run: | + sudo apt update + sudo apt install -y libxmu-dev libxi-dev libgl-dev libglx-dev libgles-dev \ + build-essential libx11-xcb-dev libegl1-mesa-dev libopengl-dev \ + libxkbcommon-dev libwayland-dev libxrandr-dev mesa-vulkan-drivers libglu1-mesa-dev libdrm-dev libegl-dev libglm-dev + # the dependency list is too big but at least it works + # https://packages.ubuntu.com/search + - name: vcpkg build + id: vcpkg + uses: johnwason/vcpkg-action@v6 #cache build so improve the build time a lot + with: + manifest-dir: ${{ github.workspace }} # Set to directory containing vcpkg.json + triplet: "${{ matrix.triplet }}" + token: ${{ github.token }} + github-binarycache: true + cache-key: "${{ matrix.triplet }}" # TODO must use sha1 of vcpkg.json and triplet + - name: Configure CMake + run: > + cmake -B ${{ steps.strings.outputs.build-output-dir }} + -DBUILD_SKIP_CLIENT=ON + ${{ steps.vcpkg.outputs.vcpkg-cmake-config }} + -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} + -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} + -S ${{ github.workspace }} ; + - name: Build + # Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). + run: > + CC="${{ matrix.c_compiler }}" CXX="${{ matrix.cpp_compiler }}" cmake + --build ${{ steps.strings.outputs.build-output-dir }} --verbose -j 4 + - name: Show files after + run: ls -ltrR ${{ github.workspace }} + - name: Run tests + working-directory: ${{ steps.strings.outputs.build-output-dir }} + run: xvfb-run ctest --build-config ${{ matrix.build_type }} From e3eb4a8c04396e557fa535c47a4f896fc6d4f8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Sun, 17 Mar 2024 15:50:30 +0100 Subject: [PATCH 27/34] Update main.yml Selected a tag from VCPKG so that maybe it will build better? --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2761ad9..822ab8e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,6 +25,7 @@ jobs: run: | git clone https://github.com/microsoft/vcpkg.git cd vcpkg + git checkout tags/2024.02.14 ./bootstrap-vcpkg.bat ./vcpkg integrate install From 748964b42ad79516ab5612a3031ccd323405acb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Mon, 18 Mar 2024 19:21:50 +0100 Subject: [PATCH 28/34] Keyboard lock can be skipped. --- include/frame/gui/draw_gui_interface.h | 23 +++++++++++++++----- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 4 +++- src/frame/opengl/gui/sdl_opengl_draw_gui.h | 19 ++++++++++++++++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/include/frame/gui/draw_gui_interface.h b/include/frame/gui/draw_gui_interface.h index 518b85d..d629b29 100644 --- a/include/frame/gui/draw_gui_interface.h +++ b/include/frame/gui/draw_gui_interface.h @@ -26,12 +26,13 @@ class DrawGuiInterface : public PluginInterface /** * @brief Add a modal window. * @param callback: A window callback that can add buttons, etc. - * - * If the callback return is 0 the callback stay and if it is other it is - * removed. This will trigger an internal boolean that will decide if the - * modal is active or not. + * + * If the callback return is 0 the callback stay and if it is other it is + * removed. This will trigger an internal boolean that will decide if the + * modal is active or not. */ - virtual void AddModalWindow(std::unique_ptr callback) = 0; + virtual void AddModalWindow( + std::unique_ptr callback) = 0; /** * @brief Get a specific window (associated with a name). * @param name: The name of the window. @@ -58,6 +59,18 @@ class DrawGuiInterface : public PluginInterface * @return True if enable. */ virtual bool IsVisible() const = 0; + /** + * @brief Poll event. + * @param event: The event to be polled. + * @return True if the event is captured. + */ + virtual void SetKeyboardPassed(bool is_keyboard_passed) = 0; + /** + * @brief Poll event. + * @param event: The event to be polled. + * @return True if the event is captured. + */ + virtual bool IsKeyboardPassed() const = 0; }; } // End namespace frame::gui. diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index ad36fb9..33af66b 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -182,7 +182,9 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) } } // Check if you should enable default window keyboard and mouse. - if (ImGui::IsWindowHovered() && is_default_output) + if (ImGui::IsWindowHovered() && + is_default_output && + !is_keyboard_passed_locked_) { is_keyboard_passed_ = true; } diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.h b/src/frame/opengl/gui/sdl_opengl_draw_gui.h index 5942328..7eddc46 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.h +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.h @@ -83,6 +83,24 @@ class SDL2OpenGLDrawGui : public frame::gui::DrawGuiInterface } public: + /** + * @brief Poll event. + * @param event: The event to be polled. + * @return True if the event is captured. + */ + void SetKeyboardPassed(bool is_keyboard_passed) override + { + is_keyboard_passed_locked_ = is_keyboard_passed; + } + /** + * @brief Poll event. + * @param event: The event to be polled. + * @return True if the event is captured. + */ + bool IsKeyboardPassed() const override + { + return is_keyboard_passed_locked_; + } /** * @brief Add sub window to the main window. * @param callback: A window callback that can add buttons, etc. @@ -146,6 +164,7 @@ class SDL2OpenGLDrawGui : public frame::gui::DrawGuiInterface glm::uvec2 size_ = {0, 0}; glm::uvec2 next_window_position_ = {0, 0}; glm::uvec2 original_image_size_ = {0, 0}; + bool is_keyboard_passed_locked_ = false; bool is_keyboard_passed_ = false; bool is_visible_ = true; float font_size_ = 20.0f; From 82225580bd2a969735c6cab5aed4d9f58360c5fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Mon, 18 Mar 2024 19:39:02 +0100 Subject: [PATCH 29/34] Keyboard lock can be skipped. --- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index 33af66b..ce09d51 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -182,9 +182,7 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) } } // Check if you should enable default window keyboard and mouse. - if (ImGui::IsWindowHovered() && - is_default_output && - !is_keyboard_passed_locked_) + if (ImGui::IsWindowHovered() && is_default_output ) { is_keyboard_passed_ = true; } @@ -288,7 +286,9 @@ bool SDL2OpenGLDrawGui::PollEvent(void* event) if (is_keyboard_passed_) return false; auto& io = ImGui::GetIO(); - return io.WantCaptureMouse || io.WantCaptureKeyboard; + return (is_keyboard_passed_locked_) + ? io.WantCaptureMouse || io.WantCaptureKeyboard + : false; } frame::gui::GuiWindowInterface& SDL2OpenGLDrawGui::GetWindow( From 3dfc956854952f1a702df68b9a695965bcd2f401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Mon, 18 Mar 2024 19:48:52 +0100 Subject: [PATCH 30/34] No more screenshot on windows 10. --- src/frame/opengl/sdl_opengl_window.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/frame/opengl/sdl_opengl_window.cpp b/src/frame/opengl/sdl_opengl_window.cpp index 29c6702..a0d715b 100644 --- a/src/frame/opengl/sdl_opengl_window.cpp +++ b/src/frame/opengl/sdl_opengl_window.cpp @@ -143,12 +143,6 @@ bool SDLOpenGLWindow::RunEvent(const SDL_Event& event, const double dt) } if (event.type == SDL_KEYDOWN) { - switch (event.key.keysym.sym) - { - case SDLK_PRINTSCREEN: - device_->ScreenShot("ScreenShot.png"); - return true; - } if (key_callbacks_.count(event.key.keysym.sym)) { return key_callbacks_[event.key.keysym.sym](); From 0c675f14a6e728520d5b22d848ae478773fc74a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Mon, 18 Mar 2024 20:01:41 +0100 Subject: [PATCH 31/34] Inverted the logic for the keyboard pass. --- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index ce09d51..406890e 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -286,7 +286,7 @@ bool SDL2OpenGLDrawGui::PollEvent(void* event) if (is_keyboard_passed_) return false; auto& io = ImGui::GetIO(); - return (is_keyboard_passed_locked_) + return (!is_keyboard_passed_locked_) ? io.WantCaptureMouse || io.WantCaptureKeyboard : false; } From 11aa026b8e2dd28bac2a0b1b9d1fc554d73f66e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Tue, 19 Mar 2024 15:46:20 +0100 Subject: [PATCH 32/34] Try to add overlay. --- include/frame/gui/draw_gui_interface.h | 15 +++- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 86 +++++++++++++++----- src/frame/opengl/gui/sdl_opengl_draw_gui.h | 22 ++++- 3 files changed, 99 insertions(+), 24 deletions(-) diff --git a/include/frame/gui/draw_gui_interface.h b/include/frame/gui/draw_gui_interface.h index d629b29..95363c5 100644 --- a/include/frame/gui/draw_gui_interface.h +++ b/include/frame/gui/draw_gui_interface.h @@ -23,6 +23,19 @@ class DrawGuiInterface : public PluginInterface * @param callback: A window callback that can add buttons, etc. */ virtual void AddWindow(std::unique_ptr callback) = 0; + /** + * @brief Add a overlay window. + * @param position: The position of the window. + * @param callback: A window callback that can add buttons, etc. + * + * Overlay window are drawn on top of the main window and are not + * affected. Also note that they are only display when the main window + * is fullscreen. + */ + virtual void AddOverlayWindow( + glm::vec2 position, + glm::vec2 size, + std::unique_ptr callback) = 0; /** * @brief Add a modal window. * @param callback: A window callback that can add buttons, etc. @@ -46,7 +59,7 @@ class DrawGuiInterface : public PluginInterface virtual std::vector GetWindowTitles() const = 0; /** * @brief Delete a sub window. - * @param name: the name of the window to be deleted. + * @param name: the name of the window or overlay to be deleted. */ virtual void DeleteWindow(const std::string& name) = 0; /** diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index 406890e..978ebf6 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -103,11 +103,11 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) { ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()); // Make the other window visible. - for (const auto& pair : callbacks_) + for (const auto& pair : window_callbacks_) { // Call the callback! - ImGui::Begin(pair.second->GetName().c_str()); - if (!pair.second->DrawCallback()) + ImGui::Begin(pair.second.callback->GetName().c_str()); + if (!pair.second.callback->DrawCallback()) returned_value = false; ImGui::End(); } @@ -130,19 +130,7 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); original_image_size_ = texture.GetSize(); } - // This is in window addition to the main window. - bool is_invisible_window = name_[0] == '#' && name_[1] == '#'; - if (is_invisible_window && is_default_output) - { - ImGui::SetNextWindowPos( - ImVec2( - static_cast(next_window_position_.x), - static_cast(next_window_position_.y))); - ImGui::SetNextWindowSize( - ImVec2( - static_cast(original_image_size_.x), - static_cast(original_image_size_.y))); - } + // If the window are not visible and it is not the main window then // bail out. if (!is_visible_ && !is_default_output) @@ -224,6 +212,30 @@ bool SDL2OpenGLDrawGui::Update(DeviceInterface& device, double dt) } } + if (!is_visible_) + { + for (const auto& pair : overlay_callbacks_) + { + ImGui::SetNextWindowPos( + ImVec2( + static_cast(pair.second.position.x), + static_cast(pair.second.position.y))); + ImGui::SetNextWindowSize( + ImVec2( + static_cast(pair.second.size.x), + static_cast(pair.second.size.y))); + // Setup overlay window with appropriate flags + ImGui::Begin( + pair.first.c_str(), + nullptr, + ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoInputs); + pair.second.callback->DrawCallback(); + ImGui::End(); + } + } + // Rendering ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); @@ -251,10 +263,27 @@ void SDL2OpenGLDrawGui::AddWindow( { throw std::runtime_error("Cannot create a sub window without a name!"); } - callbacks_.insert({name, std::move(callback)}); + window_callbacks_.insert( + {name, {std::move(callback), {0.0f, 0.0f}, {0.0f, 0.0f}}}); +} + +void SDL2OpenGLDrawGui::AddOverlayWindow( + glm::vec2 position, + glm::vec2 size, + std::unique_ptr callback) +{ + std::string name = callback->GetName(); + if (name.empty()) + { + throw std::runtime_error( + "Cannot create a sub window without a name!"); + } + overlay_callbacks_.insert( + {name, {std::move(callback), position, size}}); } -void SDL2OpenGLDrawGui::AddModalWindow(std::unique_ptr callback) +void SDL2OpenGLDrawGui::AddModalWindow( + std::unique_ptr callback) { modal_callback_ = std::move(callback); } @@ -262,7 +291,7 @@ void SDL2OpenGLDrawGui::AddModalWindow(std::unique_ptr SDL2OpenGLDrawGui::GetWindowTitles() const { std::vector name_list; - for (const auto& [name, _] : callbacks_) + for (const auto& [name, _] : window_callbacks_) { name_list.push_back(name); } @@ -271,7 +300,14 @@ std::vector SDL2OpenGLDrawGui::GetWindowTitles() const void SDL2OpenGLDrawGui::DeleteWindow(const std::string& name) { - callbacks_.erase(name); + if (window_callbacks_.contains(name)) + { + window_callbacks_.erase(name); + } + if (overlay_callbacks_.contains(name)) + { + overlay_callbacks_.erase(name); + } } bool SDL2OpenGLDrawGui::PollEvent(void* event) @@ -294,7 +330,15 @@ bool SDL2OpenGLDrawGui::PollEvent(void* event) frame::gui::GuiWindowInterface& SDL2OpenGLDrawGui::GetWindow( const std::string& name) { - return *callbacks_.at(name).get(); + if (window_callbacks_.contains(name)) + { + return *window_callbacks_.at(name).callback.get(); + } + if (overlay_callbacks_.contains(name)) + { + return *overlay_callbacks_.at(name).callback.get(); + } + throw std::runtime_error("Cannot find the window with the name: " + name); } } // End namespace frame::opengl::gui. diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.h b/src/frame/opengl/gui/sdl_opengl_draw_gui.h index 7eddc46..cd34cc3 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.h +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.h @@ -107,6 +107,19 @@ class SDL2OpenGLDrawGui : public frame::gui::DrawGuiInterface */ void AddWindow( std::unique_ptr callback) override; + /** + * @brief Add a overlay window. + * @param position: The position of the window. + * @param callback: A window callback that can add buttons, etc. + * + * Overlay window are drawn on top of the main window and are not + * affected. Also note that they are only display when the main window + * is fullscreen. + */ + void AddOverlayWindow( + glm::vec2 position, + glm::vec2 size, + std::unique_ptr callback) override; /** * @brief Add a modal window. * @param callback: A window callback that can add buttons, etc. @@ -153,8 +166,13 @@ class SDL2OpenGLDrawGui : public frame::gui::DrawGuiInterface bool PollEvent(void* event) override; protected: - std::map> - callbacks_ = {}; + struct CallbackData { + std::unique_ptr callback = nullptr; + glm::vec2 position = { 0.0f, 0.0f }; + glm::vec2 size = { 0.0f, 0.0f }; + }; + std::map window_callbacks_ = {}; + std::map overlay_callbacks_ = {}; std::unique_ptr modal_callback_ = nullptr; bool start_modal_ = false; std::filesystem::path font_path_; From bca13afe2c0340650b98269fe2a88ee55e11f220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dubouchet?= Date: Sat, 23 Mar 2024 16:43:01 +0100 Subject: [PATCH 33/34] Ported to linux. --- src/frame/opengl/gui/sdl_opengl_draw_gui.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp index 978ebf6..c11be0f 100644 --- a/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp +++ b/src/frame/opengl/gui/sdl_opengl_draw_gui.cpp @@ -263,8 +263,11 @@ void SDL2OpenGLDrawGui::AddWindow( { throw std::runtime_error("Cannot create a sub window without a name!"); } - window_callbacks_.insert( - {name, {std::move(callback), {0.0f, 0.0f}, {0.0f, 0.0f}}}); + CallbackData callback_data; + callback_data.callback = std::move(callback); + callback_data.position = glm::vec2(0.0f, 0.0f); + callback_data.size = glm::vec2(0.0f, 0.0f); + window_callbacks_.emplace(name, std::move(callback_data)); } void SDL2OpenGLDrawGui::AddOverlayWindow( @@ -278,8 +281,11 @@ void SDL2OpenGLDrawGui::AddOverlayWindow( throw std::runtime_error( "Cannot create a sub window without a name!"); } - overlay_callbacks_.insert( - {name, {std::move(callback), position, size}}); + CallbackData callback_data; + callback_data.callback = std::move(callback); + callback_data.position = position; + callback_data.size = size; + overlay_callbacks_.emplace(name, std::move(callback_data)); } void SDL2OpenGLDrawGui::AddModalWindow( From cdf09100bdf3c576d895f6bfddc63c77b4f4a73c Mon Sep 17 00:00:00 2001 From: Rolf Jordi Date: Sat, 30 Mar 2024 14:39:28 +0100 Subject: [PATCH 34/34] add time and milli second to gui logs --- include/frame/gui/gui_logger_sink.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/frame/gui/gui_logger_sink.h b/include/frame/gui/gui_logger_sink.h index b60c19d..d33f56b 100644 --- a/include/frame/gui/gui_logger_sink.h +++ b/include/frame/gui/gui_logger_sink.h @@ -34,8 +34,14 @@ class GuiLoggerSink : public spdlog::sinks::base_sink spdlog::memory_buf_t formatted; spdlog::sinks::base_sink::formatter_->format( msg, formatted); + const auto time = std::chrono::current_zone() + ->to_local(std::chrono::system_clock::now()); + const auto current_milli{ + duration_cast(time.time_since_epoch()) + .count() % 1000}; + const auto time_p = std::format("{:%X}.{:03} ", time, current_milli); std::string formatted_message(msg.payload.begin(), msg.payload.end()); - logs.push_back({msg.level, std::move(formatted_message)}); + logs.push_back({msg.level, std::move(time_p + formatted_message)}); } void flush_() override {