From 76aa183ee978e358ecaac32d2c7fbb5a8b991693 Mon Sep 17 00:00:00 2001 From: bennyedlund Date: Sun, 18 Aug 2024 21:48:18 +1200 Subject: [PATCH] Renamed api methods --- examples/hello_blend/main_blend2d.cpp | 178 +++++++++++--------------- lib/platform.cpp | 86 ++++++------- lib/public/imx/platform.h | 14 +- lib/public/imx/platform_details.h | 10 +- lib/public/imx/render.h | 20 +-- lib/render.cpp | 55 ++++---- 6 files changed, 176 insertions(+), 187 deletions(-) diff --git a/examples/hello_blend/main_blend2d.cpp b/examples/hello_blend/main_blend2d.cpp index a8ab980..1192c6d 100644 --- a/examples/hello_blend/main_blend2d.cpp +++ b/examples/hello_blend/main_blend2d.cpp @@ -1,143 +1,115 @@ #include "imx/platform.h" #include "imx/platform_details.h" #include "imx/render.h" +#include #include #include #include #include -#include int main() { - IMGUI_CHECKVERSION(); - int width = 800; - int height = 600; - - + std::string s_ttf_font = "/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf"; - // Setup Dear ImGui context IMGUI_CHECKVERSION(); - auto* ctx = ImGui::CreateContext(); + auto *ctx = ImGui::CreateContext(); assert(ctx && "Unable to create imgui context"); - ImGui::SetCurrentContext(ctx); - ImGuiIO &io = ImGui::GetIO(); - io.ConfigFlags |= - ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - io.ConfigFlags |= - ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls - io.DisplaySize = ImVec2(width, height); - auto &style = ImGui::GetStyle(); - ImFont *fnt = io.Fonts->AddFontFromFileTTF( - "/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf", 24); - io.FontDefault = fnt; - ImFontConfig fontConfig; - fontConfig.GlyphMinAdvanceX = 1.0f; - fontConfig.SizePixels = 24.00; - io.Fonts->AddFontDefault(&fontConfig); - io.FontGlobalScale = 1.; - // Setup Dear ImGui style - ImGui::StyleColorsDark(); - fmt::print("ImGui initialized"); + imx::initialize_platform(); + imx::initialize_renderer(s_ttf_font); - imx_platform_initialize(); - imx_platform_create_window(width, height); - imblend_initialize("/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf"); - fmt::print("initialized\n"); bool show_demo_window = false; bool show_another_window = false; ImVec4 clear_color{0.F, 0.F, 0.F, 1.F}; - BLImage &icon = imblend_add_texture(); + BLImage &icon = imx::add_texture(); if (icon.readFromFile("/home/benny/projects/imgui_blend_backend/icon.png") != BL_SUCCESS) { fmt::print("Failed to load icon\n"); - exit(-1); + _exit(-1); } + ImGui::StyleColorsDark(); + + int width = 800; + int height = 600; + imx::create_window(width, height); + using target_rate = std::chrono::duration>; auto stamp = std::chrono::steady_clock::now(); auto deadline = stamp + target_rate(1); while (true) { - imx_platform_poll_events(); + imx::poll_events(); if (deadline > std::chrono::steady_clock::now()) { continue; } - if (auto *context = reinterpret_cast( - ImGui::GetIO().BackendPlatformUserData)) { - auto &image = *context->windows.front().image; - if (!imblend_new_frame(clear_color, - BLImageData{image.data(), image.stride(), - BLSizeI(image.width(), image.height()), - BL_FORMAT_PRGB32})) { - continue; - } - deadline += target_rate(1); - - static double fps = 0.F; - static double ren = 0.F; - using rate = std::chrono::duration; - stamp = std::chrono::steady_clock::now(); - static auto previous = std::chrono::steady_clock::now(); - io.DeltaTime = std::chrono::duration_cast( - std::chrono::steady_clock::now() - previous) - .count(); - fps = 1. / io.DeltaTime; - previous = stamp; - - ImGui::NewFrame(); - if (show_demo_window) { - ImGui::ShowDemoWindow(&show_demo_window); - } - // 2. Show a simple window that we create ourselves. We use a - // Begin/End pair to create a named window. - { - static float f = 0.0f; - static int counter = 0; + if (!imx::begin_frame()) { + continue; + } + deadline += target_rate(1); + static double fps = 0.F; + static double ren = 0.F; + using rate = std::chrono::duration; + stamp = std::chrono::steady_clock::now(); + static auto previous = std::chrono::steady_clock::now(); + ImGui::GetIO().DeltaTime = std::chrono::duration_cast( + std::chrono::steady_clock::now() - previous) + .count(); + fps = 1. / ImGui::GetIO().DeltaTime; + previous = stamp; - ImGui::Begin("Hello, world!"); - ImGui::Text("This is some useful text."); - ImGui::Checkbox("Demo Window", &show_demo_window); - ImGui::Checkbox("Another Window", &show_another_window); + ImGui::NewFrame(); + if (show_demo_window) { + ImGui::ShowDemoWindow(&show_demo_window); + } + // 2. Show a simple window that we create ourselves. We use a + // Begin/End pair to create a named window. + { + static float f = 0.0F; + static int counter = 0; - ImGui::SliderFloat( - "float", &f, 0.0f, - 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f - ImGui::ColorEdit3( - "clear color", - (float *)&clear_color); // Edit 3 floats representing a color + ImGui::Begin("Hello, world!"); + ImGui::Text("This is some useful text."); + ImGui::Checkbox("Demo Window", &show_demo_window); + ImGui::Checkbox("Another Window", &show_another_window); - if (ImGui::Button("Button")) { + ImGui::SliderFloat("float", &f, 0.0F, + 1.0F); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3( + "clear color", + (float *)&clear_color); // Edit 3 floats representing a color - counter++; - } - ImGui::SameLine(); - ImGui::Text("counter = %d", counter); - ImGui::Text("Application average %.3f ms/frame (%.1f FPS) render(%.1f)", - 1000.0f / io.Framerate, io.Framerate, fps); - ImGui::Image(reinterpret_cast(&icon), - ImVec2(icon.size().w / 2.F, icon.size().h / 2.F)); - ImGui::End(); - } + if (ImGui::Button("Button")) { - // 3. Show another simple window. - if (show_another_window) { - ImGui::Begin("Another Window", - &show_another_window); // Pass a pointer to our bool - // variable (the window will have - // a closing button that will - // clear the bool when clicked) - ImGui::Text("Hello from another window!"); - if (ImGui::Button("Close Me")) - show_another_window = false; - ImGui::End(); - } - ImGui::Render(); - if (!imblend_render(ImGui::GetDrawData(), BL_CONTEXT_FLUSH_SYNC)) { - fmt::print("Imblend render failed\n"); + counter++; } + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + ImGui::Text("Application average %.3f ms/frame (%.1f FPS) render(%.1f)", + 1000.0F / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate, + fps); + ImGui::Image(static_cast(&icon), + ImVec2(icon.size().w / 2.F, icon.size().h / 2.F)); + ImGui::End(); + } - FrameMark; - imx_platform_expose_again(); + // 3. Show another simple window. + if (show_another_window) { + ImGui::Begin("Another Window", + &show_another_window); // Pass a pointer to our bool + // variable (the window will have + // a closing button that will + // clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + ImGui::Render(); + if (!imx::render_frame(ImGui::GetDrawData(), BL_CONTEXT_FLUSH_SYNC)) { + fmt::print("Imblend render failed\n"); } + + FrameMark; + imx::enqueue_expose(); } ImGui::DestroyContext(); return 0; diff --git a/lib/platform.cpp b/lib/platform.cpp index 1c765c9..bc52f2e 100644 --- a/lib/platform.cpp +++ b/lib/platform.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -18,11 +19,13 @@ #include #include +namespace imx { + // Function to find a 32-bit ARGB visual Visual *find_argb_visual(Display *display, int screen) { XVisualInfo visualInfoTemplate{}; visualInfoTemplate.screen = screen; - visualInfoTemplate.depth = 32; + visualInfoTemplate.depth = IMX_32BIT_DEPTH; visualInfoTemplate.c_class = TrueColor; int visualsMatched = 0; @@ -49,15 +52,15 @@ Image::Image(Display *display, Visual *visual, int width, int height, int depth) : display_(display), visual_(visual), width_(sanitize_width(width)), height_(height), depth_(depth), stride_(width_ * 4) { memset(&info_, 0, sizeof(XShmSegmentInfo)); - info_.shmid = - shmget(IPC_PRIVATE, width_ * height_ * (depth_ / sizeof(std::uint8_t)), - IPC_CREAT | 0600); + info_.shmid = shmget(IPC_PRIVATE, + static_cast(width_) * height_ * + (depth_ / sizeof(std::uint8_t)), + IPC_CREAT | 0600); info_.shmaddr = (char *)shmat(info_.shmid, nullptr, IPC_CREAT | 0600); - // shmdt(info_.shmaddr); info_.readOnly = False; // Attach the segment to the display - if (!XShmAttach(display_, &info_)) { + if (XShmAttach(display_, &info_) == 0) { fmt::print("Failed to attach shared memory\n"); memset(&info_, 0, sizeof(XShmSegmentInfo)); } @@ -95,36 +98,36 @@ imx_context::imx_context() visual, AllocNone)), input_method([](Display *display) { XSetLocaleModifiers(""); - return unique_input_method(XOpenIM(display, NULL, NULL, NULL), + return unique_input_method(XOpenIM(display, nullptr, nullptr, nullptr), [](XIM owned) { XCloseIM(owned); }); }(display.get())) { - if (!visual) { + if (visual == nullptr) { fmt::print("No 32-bit ARGB visual found\n"); std::terminate(); } if (!input_method) { XSetLocaleModifiers("@im=none"); - input_method = unique_input_method(XOpenIM(display.get(), NULL, NULL, NULL), - [](XIM owned) { XCloseIM(owned); }); + input_method = + unique_input_method(XOpenIM(display.get(), nullptr, nullptr, nullptr), + [](XIM owned) { XCloseIM(owned); }); } } -bool imx_platform_initialize() { +bool initialize_platform() { static std::unique_ptr s_context; if (s_context) { fmt::print("ImX context already initialized\n"); return false; } - fmt::print("ImX initialized\n"); s_context = std::make_unique(); ImGui::GetIO().BackendPlatformUserData = s_context.get(); return true; } -bool imx_platform_create_window(std::uint32_t width, std::uint32_t height, +bool create_window(std::uint32_t width, std::uint32_t height, std::uint32_t depth) { - if (auto *context = reinterpret_cast( - ImGui::GetIO().BackendPlatformUserData)) { + if (auto *context = + static_cast(ImGui::GetIO().BackendPlatformUserData)) { XSetWindowAttributes attrs; attrs.colormap = context->colormap; attrs.border_pixel = 0; @@ -135,9 +138,9 @@ bool imx_platform_create_window(std::uint32_t width, std::uint32_t height, RootWindow(context->display.get(), context->screen), 0, 0, width, height, 0, depth, InputOutput, context->visual, CWColormap | CWBorderPixel | CWBackPixel, &attrs); - auto xic = XCreateIC(context->input_method.get(), XNInputStyle, - XIMPreeditNothing | XIMStatusNothing, XNClientWindow, - window, XNFocusWindow, window, NULL); + auto *xic = XCreateIC(context->input_method.get(), XNInputStyle, + XIMPreeditNothing | XIMStatusNothing, XNClientWindow, + window, XNFocusWindow, window, NULL); XMapWindow(context->display.get(), window); XSelectInput(context->display.get(), window, @@ -162,9 +165,9 @@ bool imx_platform_create_window(std::uint32_t width, std::uint32_t height, } // Function to translate X11 key codes to ImGui key codes -ImGuiKey imx_platform_translate_key(XKeyEvent &event) { +ImGuiKey translate_key(XKeyEvent &event) { KeySym keysym = XLookupKeysym(&event, 0); - if (event.state & ShiftMask) { + if ((event.state & ShiftMask) != 0U) { keysym = XLookupKeysym(&event, 1); } @@ -218,19 +221,14 @@ ImGuiKey imx_platform_translate_key(XKeyEvent &event) { case XK_Insert: return ImGuiKey_Insert; case XK_Undo: - return ImGuiKey_None; case XK_Redo: return ImGuiKey_None; case XK_Menu: return ImGuiKey_Menu; case XK_Find: - return ImGuiKey_None; case XK_Cancel: - return ImGuiKey_None; case XK_Help: - return ImGuiKey_None; case XK_Break: - return ImGuiKey_None; case XK_Mode_switch: return ImGuiKey_None; case XK_Num_Lock: @@ -532,9 +530,9 @@ ImGuiKey imx_platform_translate_key(XKeyEvent &event) { } } -void imx_platform_poll_events() { - if (auto *context = reinterpret_cast( - ImGui::GetIO().BackendPlatformUserData)) { +void poll_events() { + if (auto *context = + static_cast(ImGui::GetIO().BackendPlatformUserData)) { while (XPending(context->display.get()) > 0) { XEvent event; XNextEvent(context->display.get(), &event); @@ -549,14 +547,12 @@ void imx_platform_poll_events() { io.AddFocusEvent(false); break; } - case MotionNotify: { XMotionEvent motion_event = event.xmotion; ImGuiIO &io = ImGui::GetIO(); io.AddMousePosEvent((float)motion_event.x, (float)motion_event.y); break; } - case ButtonPress: { XButtonPressedEvent press_event = event.xbutton; ImGuiIO &io = ImGui::GetIO(); @@ -587,7 +583,6 @@ void imx_platform_poll_events() { } break; } - case ButtonRelease: { XButtonPressedEvent press_event = event.xbutton; ImGuiIO &io = ImGui::GetIO(); @@ -609,7 +604,6 @@ void imx_platform_poll_events() { } break; } - case KeyPress: { XKeyEvent press_event = event.xkey; ImGuiIO &io = ImGui::GetIO(); @@ -622,27 +616,25 @@ void imx_platform_poll_events() { imx_window &window = *found; static std::array buffer; KeySym key = 0; - Status status; + Status status = 0; std::size_t count = Xutf8LookupString( window.input_context.get(), &event.xkey, buffer.data(), buffer.size() - 1, &key, &status); count = std::min(count, buffer.size() - 1); buffer.at(count) = '\0'; - if (count) { + if (count != 0U) { io.AddInputCharactersUTF8(buffer.data()); } - io.AddKeyEvent(imx_platform_translate_key(press_event), true); + io.AddKeyEvent(translate_key(press_event), true); } break; } case KeyRelease: { - fmt::print("key release\n"); XKeyEvent press_event = event.xkey; ImGuiIO &io = ImGui::GetIO(); - io.AddKeyEvent(imx_platform_translate_key(press_event), false); + io.AddKeyEvent(translate_key(press_event), false); break; } - case ConfigureNotify: { XConfigureEvent configure_event = event.xconfigure; auto found = @@ -656,9 +648,9 @@ void imx_platform_poll_events() { configure_event.height != window.image->height()) { auto width = configure_event.width; auto height = configure_event.height; - window.image.reset(new Image(context->display.get(), - context->visual, width, height, - window.image->depth())); + window.image = + std::make_unique(context->display.get(), context->visual, + width, height, window.image->depth()); ImGui::GetIO().DisplaySize = ImVec2(width, height); } } @@ -674,7 +666,7 @@ void imx_platform_poll_events() { if (found != context->windows.end()) { ZoneScopedN("X11 (render)"); imx_window &window = *found; - auto image_data = window.image->image(); + auto *image_data = window.image->image(); XShmPutImage(context->display.get(), window.window, window.gc.get(), image_data, 0, 0, 0, 0, image_data->width, image_data->height, 0); @@ -688,9 +680,9 @@ void imx_platform_poll_events() { } } -bool imx_platform_expose_again() { - if (auto *context = reinterpret_cast( - ImGui::GetIO().BackendPlatformUserData)) { +bool enqueue_expose() { + if (auto *context = + static_cast(ImGui::GetIO().BackendPlatformUserData)) { for (auto const &handle : context->windows) { XExposeEvent exposeEvent = {Expose, 0, @@ -703,9 +695,11 @@ bool imx_platform_expose_again() { handle.image->height(), 0}; XSendEvent(context->display.get(), handle.window, False, ExposureMask, - (XEvent *)&exposeEvent); + reinterpret_cast(&exposeEvent)); } return true; } return false; } + +} // namespace imx diff --git a/lib/public/imx/platform.h b/lib/public/imx/platform.h index 69c8681..f01f377 100644 --- a/lib/public/imx/platform.h +++ b/lib/public/imx/platform.h @@ -3,10 +3,14 @@ #include "imx/api.h" #include -IMX_API bool imx_platform_initialize(); +namespace imx { + static const std::uint32_t IMX_24BIT_DEPTH = 32; static const std::uint32_t IMX_32BIT_DEPTH = 32; -IMX_API bool imx_platform_create_window(std::uint32_t width, - std::uint32_t height, - std::uint32_t depth = IMX_32BIT_DEPTH); -IMX_API void imx_platform_poll_events(); \ No newline at end of file + +IMX_API bool initialize_platform(); +IMX_API bool create_window(std::uint32_t width, std::uint32_t height, + std::uint32_t depth = IMX_32BIT_DEPTH); +IMX_API void poll_events(); + +} // namespace imx \ No newline at end of file diff --git a/lib/public/imx/platform_details.h b/lib/public/imx/platform_details.h index 2807807..19db5d5 100644 --- a/lib/public/imx/platform_details.h +++ b/lib/public/imx/platform_details.h @@ -8,6 +8,8 @@ #include #include +namespace imx { + struct IMX_API Image { IMX_API Image(Display *display, Visual *visual, int width, int height, int depth); @@ -26,7 +28,7 @@ struct IMX_API Image { [[nodiscard]] IMX_API XImage *image() const; private: - XShmSegmentInfo info_; + XShmSegmentInfo info_{}; Display *display_ = nullptr; Visual *visual_ = nullptr; std::unique_ptr image_{nullptr, [](auto *) {}}; @@ -63,5 +65,7 @@ struct IMX_API imx_context { imx_context(); }; -IMX_API ImGuiKey imx_platform_translate_key(XKeyEvent &event); -IMX_API bool imx_platform_expose_again(); +IMX_API ImGuiKey translate_key(XKeyEvent &event); +IMX_API bool enqueue_expose(); + +} // namespace imx diff --git a/lib/public/imx/render.h b/lib/public/imx/render.h index d4b0833..3c35395 100644 --- a/lib/public/imx/render.h +++ b/lib/public/imx/render.h @@ -5,15 +5,19 @@ #include #include -IMX_API bool imblend_initialize(std::string_view font_filename, - BLContextCreateInfo context_creation_info = {}, - BLImageData shared_image_data = {}); +namespace imx { -IMX_API bool imblend_new_frame(ImVec4 clear_color = {0.F, 0.F, 0.F, 1.F}, - BLImageData shared_image_data = {}); +IMX_API bool initialize_renderer(std::string_view font_filename, + ImVec4 clear_color = {0.F, 0.F, 0.F, 1.F}, + BLContextCreateInfo context_creation_info = {}, + BLImageData shared_image_data = {}); + +IMX_API bool begin_frame(); IMX_API bool -imblend_render(ImDrawData const *draw_data, - BLContextFlushFlags flags = BL_CONTEXT_FLUSH_NO_FLAGS); +render_frame(ImDrawData const *draw_data, + BLContextFlushFlags flags = BL_CONTEXT_FLUSH_NO_FLAGS); + +IMX_API BLImage &add_texture(); -IMX_API BLImage &imblend_add_texture(); +} // namespace imx \ No newline at end of file diff --git a/lib/render.cpp b/lib/render.cpp index 7961209..f60c444 100644 --- a/lib/render.cpp +++ b/lib/render.cpp @@ -1,3 +1,4 @@ +#include "imx/platform_details.h" #include #include #include @@ -18,6 +19,8 @@ #define IMBLEND_COLOR_PICKER_HACK 1; +namespace imx { + struct face_offset { ImWchar c; float x; @@ -82,6 +85,7 @@ struct imblend_context { std::vector textures{}; explicit imblend_context(std::string_view font_filename, + ImVec4 clear_color = {0.45F, 0.55F, 0.60F, 1.00F}, BLContextCreateInfo context_creation_info = {}, BLImageData shared_image_data = {}); }; @@ -566,9 +570,11 @@ void render_draw_list(BLContext &ctx, std::vector const &lists, } imblend_context::imblend_context(std::string_view font_filename, + ImVec4 clear_color, BLContextCreateInfo context_creation_info, BLImageData shared_image_data) - : data(shared_image_data), info(context_creation_info) { + : data(shared_image_data), info(context_creation_info), + clear_color(clear_color) { ImGuiIO &io = ImGui::GetIO(); auto &style = ImGui::GetStyle(); ImFont *fnt = io.Fonts->AddFontFromFileTTF(font_filename.data(), 24); @@ -620,42 +626,45 @@ imblend_context::imblend_context(std::string_view font_filename, } } -bool imblend_initialize(std::string_view font_filename, - BLContextCreateInfo context_creation_info, - BLImageData shared_image_data) { +bool initialize_renderer(std::string_view font_filename, ImVec4 clear_color, + BLContextCreateInfo context_creation_info, + BLImageData shared_image_data) { static std::unique_ptr s_context; - static bool is_initialized = [&]() { + if (s_context == nullptr) { s_context = std::make_unique( - font_filename, context_creation_info, shared_image_data); + font_filename, clear_color, context_creation_info, shared_image_data); ImGui::GetIO().BackendRendererUserData = s_context.get(); - return true; - }(); - return is_initialized; + ImGuiIO &io = ImGui::GetIO(); + io.DisplaySize = ImVec2(shared_image_data.size.w, shared_image_data.size.h); + } + return s_context != nullptr; } -bool imblend_new_frame(ImVec4 clear_color, BLImageData shared_image_data) { - if (auto *data = static_cast( - ImGui::GetIO().BackendRendererUserData)) { - if (shared_image_data.size.h != 0) { - if (data->img.createFromData(shared_image_data.size.w, - shared_image_data.size.w, BL_FORMAT_PRGB32, - shared_image_data.pixelData, - shared_image_data.stride) != BL_SUCCESS) { +bool begin_frame() { + auto &io = ImGui::GetIO(); + if (auto *data = static_cast(io.BackendRendererUserData)) { + if (auto *platform_data = + static_cast(io.BackendPlatformUserData)) { + auto &image = *platform_data->windows.front().image; + if (data->img.createFromData(image.width(), image.height(), + BL_FORMAT_PRGB32, image.data(), + image.stride()) != BL_SUCCESS) { fmt::print("Failed to begin render with new shared image data\n"); return false; } + io.DisplaySize = ImVec2(image.width(), image.height()); } - if (data->ctx.begin(data->img, data->info) == BL_SUCCESS) { - render_draw_list(data->ctx, data->draw_buffers[data->buffer++ % 2], - as_rgba(ImGui::ColorConvertFloat4ToU32(clear_color))); + render_draw_list( + data->ctx, data->draw_buffers[data->buffer++ % 2], + as_rgba(ImGui::ColorConvertFloat4ToU32(data->clear_color))); return true; } } return false; } -bool imblend_render(ImDrawData const *draw_data, BLContextFlushFlags flags) { +bool render_frame(ImDrawData const *draw_data, BLContextFlushFlags flags) { ZoneScoped; if (auto *data = static_cast( ImGui::GetIO().BackendRendererUserData)) { @@ -665,7 +674,7 @@ bool imblend_render(ImDrawData const *draw_data, BLContextFlushFlags flags) { return false; } -BLImage &imblend_add_texture() { +BLImage &add_texture() { if (auto *data = static_cast( ImGui::GetIO().BackendRendererUserData)) { return data->textures.emplace_back(); @@ -674,3 +683,5 @@ BLImage &imblend_add_texture() { invalid.reset(); return invalid; } + +} // namespace imx