From 59113b3ae2f9cc49a05f9e98a23a04e5c2562412 Mon Sep 17 00:00:00 2001 From: jackun Date: Wed, 1 Apr 2020 11:25:55 +0300 Subject: [PATCH] [OpenGL] Move ImGui functions to separate file --- src/gl/imgui_hud.cpp | 195 +++++++++++++++++++++++++++++++++ src/gl/imgui_hud.h | 7 ++ src/gl/inject_glx.cpp | 245 ++++-------------------------------------- src/meson.build | 1 + 4 files changed, 224 insertions(+), 224 deletions(-) create mode 100644 src/gl/imgui_hud.cpp create mode 100644 src/gl/imgui_hud.h diff --git a/src/gl/imgui_hud.cpp b/src/gl/imgui_hud.cpp new file mode 100644 index 00000000..1f116e02 --- /dev/null +++ b/src/gl/imgui_hud.cpp @@ -0,0 +1,195 @@ +#include +#include +#include +#include +#include "GL/gl3w.h" +#include +#include "imgui_impl_opengl3.h" +#include "font_default.h" +#include "overlay.h" +#include "cpu.h" +#include "file_utils.h" +#include "notify.h" + +using namespace MangoHud; + +struct GLVec +{ + GLint v[4]; + + GLint operator[] (size_t i) + { + return v[i]; + } + + bool operator== (const GLVec& r) + { + return v[0] == r.v[0] + && v[1] == r.v[1] + && v[2] == r.v[2] + && v[3] == r.v[3]; + } + + bool operator!= (const GLVec& r) + { + return !(*this == r); + } +}; + +struct state { + ImGuiContext *imgui_ctx = nullptr; + ImFont* font = nullptr; + ImFont* font1 = nullptr; +}; + +static GLVec last_vp {}, last_sb {}; +static ImVec2 window_size; +static swapchain_stats sw_stats {}; +static state state; +static notify_thread notifier; +static bool cfg_inited = false; +static bool inited = false; +static uint32_t vendorID; +static std::string deviceName; +overlay_params params {}; + +// seems to quit by itself though +static std::unique_ptr> + stop_it(¬ifier, [](notify_thread *n){ stop_notifier(*n); }); + +void imgui_init() +{ + if (cfg_inited) + return; + parse_overlay_config(¶ms, getenv("MANGOHUD_CONFIG")); + notifier.params = ¶ms; + start_notifier(notifier); + window_size = ImVec2(params.width, params.height); + init_system_info(); + cfg_inited = true; + init_cpu_stats(params); +} + +void imgui_create(void *ctx) +{ + if (inited) + return; + inited = true; + + if (!ctx) + return; + + imgui_init(); + gl3wInit(); + + std::cerr << "GL version: " << glGetString(GL_VERSION) << std::endl; + glGetIntegerv(GL_MAJOR_VERSION, &sw_stats.version_gl.major); + glGetIntegerv(GL_MINOR_VERSION, &sw_stats.version_gl.minor); + + deviceName = (char*)glGetString(GL_RENDERER); + if (deviceName.find("Radeon") != std::string::npos + || deviceName.find("AMD") != std::string::npos){ + vendorID = 0x1002; + } else { + vendorID = 0x10de; + } + init_gpu_stats(vendorID, params); + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGuiContext *saved_ctx = ImGui::GetCurrentContext(); + state.imgui_ctx = ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); + imgui_custom_style(params); + + glGetIntegerv (GL_VIEWPORT, last_vp.v); + glGetIntegerv (GL_SCISSOR_BOX, last_sb.v); + + ImGui::GetIO().IniFilename = NULL; + ImGui::GetIO().DisplaySize = ImVec2(last_vp[2], last_vp[3]); + + ImGui_ImplOpenGL3_Init(); + // Make a dummy GL call (we don't actually need the result) + // IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this code. + // Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above. + GLint current_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); + + int font_size = params.font_size; + if (!font_size) + font_size = 24; + + if (!params.font_file.empty() && file_exists(params.font_file)) { + state.font = io.Fonts->AddFontFromFileTTF(params.font_file.c_str(), font_size); + state.font1 = io.Fonts->AddFontFromFileTTF(params.font_file.c_str(), font_size * 0.55f); + } else { + ImFontConfig font_cfg = ImFontConfig(); + const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85(); + const ImWchar* glyph_ranges = io.Fonts->GetGlyphRangesDefault(); + + state.font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size, &font_cfg, glyph_ranges); + state.font1 = io.Fonts->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size * 0.55, &font_cfg, glyph_ranges); + } + sw_stats.font1 = state.font1; + + // Restore global context or ours might clash with apps that use Dear ImGui + ImGui::SetCurrentContext(saved_ctx); +} + +void imgui_shutdown() +{ +#ifndef NDEBUG + std::cerr << __func__ << std::endl; +#endif + + if (state.imgui_ctx) { + ImGui::SetCurrentContext(state.imgui_ctx); + ImGui_ImplOpenGL3_Shutdown(); + ImGui::DestroyContext(state.imgui_ctx); + state.imgui_ctx = nullptr; + } + inited = false; +} + +void imgui_set_context(void *ctx) +{ + if (!ctx) { + imgui_shutdown(); + return; + } +#ifndef NDEBUG + std::cerr << __func__ << ": " << ctx << std::endl; +#endif + imgui_create(ctx); +} + +void imgui_render(unsigned int width, unsigned int height) +{ + if (!state.imgui_ctx) + return; + + check_keybinds(params); + update_hud_info(sw_stats, params, vendorID); + + ImGuiContext *saved_ctx = ImGui::GetCurrentContext(); + ImGui::SetCurrentContext(state.imgui_ctx); + ImGui::GetIO().DisplaySize = ImVec2(width, height); + + ImGui_ImplOpenGL3_NewFrame(); + ImGui::NewFrame(); + { + std::lock_guard lk(notifier.mutex); + position_layer(params, window_size); + render_imgui(sw_stats, params, window_size, false); + } + ImGui::PopStyleVar(3); + + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + ImGui::SetCurrentContext(saved_ctx); +} diff --git a/src/gl/imgui_hud.h b/src/gl/imgui_hud.h new file mode 100644 index 00000000..79a18226 --- /dev/null +++ b/src/gl/imgui_hud.h @@ -0,0 +1,7 @@ +#pragma once + +void imgui_init(); +void imgui_create(void *ctx); +void imgui_shutdown(); +void imgui_set_context(void *ctx); +void imgui_render(unsigned int width, unsigned int height); diff --git a/src/gl/inject_glx.cpp b/src/gl/inject_glx.cpp index b18233c1..e625e6bd 100644 --- a/src/gl/inject_glx.cpp +++ b/src/gl/inject_glx.cpp @@ -1,242 +1,24 @@ #include #include #include -#include -#include -#include #include -#include -#include -#include #include "real_dlsym.h" #include "loaders/loader_gl.h" -#include "GL/gl3w.h" - -#include "imgui.h" -#include "imgui_impl_opengl3.h" -#include "font_default.h" -#include "overlay.h" -#include "cpu.h" +#include "imgui_hud.h" #include "mesa/util/macros.h" #include "mesa/util/os_time.h" -#include "file_utils.h" -#include "notify.h" +#include "overlay.h" #include #include -using namespace MangoHud; - #define EXPORT_C_(type) extern "C" __attribute__((__visibility__("default"))) type EXPORT_C_(void *) glXGetProcAddress(const unsigned char* procName); EXPORT_C_(void *) glXGetProcAddressARB(const unsigned char* procName); static gl_loader gl; - -struct state { - ImGuiContext *imgui_ctx = nullptr; - ImFont* font = nullptr; - ImFont* font1 = nullptr; -}; - -struct GLVec -{ - GLint v[4]; - - GLint operator[] (size_t i) - { - return v[i]; - } - - bool operator== (const GLVec& r) - { - return v[0] == r.v[0] - && v[1] == r.v[1] - && v[2] == r.v[2] - && v[3] == r.v[3]; - } - - bool operator!= (const GLVec& r) - { - return !(*this == r); - } -}; - -static GLVec last_vp {}, last_sb {}; -static ImVec2 window_size; -static overlay_params params {}; -static swapchain_stats sw_stats {}; -static state state; -static notify_thread notifier; -static bool cfg_inited = false; -static bool inited = false; -static uint32_t vendorID; -static std::string deviceName; - -// seems to quit by itself though -static std::unique_ptr> - stop_it(¬ifier, [](notify_thread *n){ stop_notifier(*n); }); - -void imgui_init() -{ - if (cfg_inited) - return; - parse_overlay_config(¶ms, getenv("MANGOHUD_CONFIG")); - notifier.params = ¶ms; - start_notifier(notifier); - window_size = ImVec2(params.width, params.height); - init_system_info(); - cfg_inited = true; - init_cpu_stats(params); -} - -void imgui_create(void *ctx) -{ - if (inited) - return; - inited = true; - - if (!ctx) - return; - - imgui_init(); - gl3wInit(); - - std::cerr << "GL version: " << glGetString(GL_VERSION) << std::endl; - glGetIntegerv(GL_MAJOR_VERSION, &sw_stats.version_gl.major); - glGetIntegerv(GL_MINOR_VERSION, &sw_stats.version_gl.minor); - - deviceName = (char*)glGetString(GL_RENDERER); - if (deviceName.find("Radeon") != std::string::npos - || deviceName.find("AMD") != std::string::npos){ - vendorID = 0x1002; - } else { - vendorID = 0x10de; - } - init_gpu_stats(vendorID, params); - // Setup Dear ImGui context - IMGUI_CHECKVERSION(); - ImGuiContext *saved_ctx = ImGui::GetCurrentContext(); - state.imgui_ctx = ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); (void)io; - //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls - - // Setup Dear ImGui style - ImGui::StyleColorsDark(); - //ImGui::StyleColorsClassic(); - imgui_custom_style(params); - - glGetIntegerv (GL_VIEWPORT, last_vp.v); - glGetIntegerv (GL_SCISSOR_BOX, last_sb.v); - - ImGui::GetIO().IniFilename = NULL; - ImGui::GetIO().DisplaySize = ImVec2(last_vp[2], last_vp[3]); - - ImGui_ImplOpenGL3_Init(); - // Make a dummy GL call (we don't actually need the result) - // IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this code. - // Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above. - GLint current_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); - - int font_size = params.font_size; - if (!font_size) - font_size = 24; - - if (!params.font_file.empty() && file_exists(params.font_file)) { - state.font = io.Fonts->AddFontFromFileTTF(params.font_file.c_str(), font_size); - state.font1 = io.Fonts->AddFontFromFileTTF(params.font_file.c_str(), font_size * 0.55f); - } else { - ImFontConfig font_cfg = ImFontConfig(); - const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85(); - const ImWchar* glyph_ranges = io.Fonts->GetGlyphRangesDefault(); - - state.font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size, &font_cfg, glyph_ranges); - state.font1 = io.Fonts->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size * 0.55, &font_cfg, glyph_ranges); - } - sw_stats.font1 = state.font1; - - // Restore global context or ours might clash with apps that use Dear ImGui - ImGui::SetCurrentContext(saved_ctx); -} - -void imgui_shutdown() -{ -#ifndef NDEBUG - std::cerr << __func__ << std::endl; -#endif - - if (state.imgui_ctx) { - ImGui::SetCurrentContext(state.imgui_ctx); - ImGui_ImplOpenGL3_Shutdown(); - ImGui::DestroyContext(state.imgui_ctx); - state.imgui_ctx = nullptr; - } - inited = false; -} - -void imgui_set_context(void *ctx) -{ - if (!ctx) { - imgui_shutdown(); - return; - } -#ifndef NDEBUG - std::cerr << __func__ << ": " << ctx << std::endl; -#endif - imgui_create(ctx); -} - -void imgui_render() -{ - if (!state.imgui_ctx) - return; - - ImGuiContext *saved_ctx = ImGui::GetCurrentContext(); - ImGui::SetCurrentContext(state.imgui_ctx); - - // check which one is affected by window resize and use that - GLVec vp; glGetIntegerv (GL_VIEWPORT, vp.v); - GLVec sb; glGetIntegerv (GL_SCISSOR_BOX, sb.v); - - bool invalid_scissor = (sb[2] == 1 && sb[3] == 1); - - if (vp != last_vp || invalid_scissor) { -#ifndef NDEBUG - printf("viewport: %d %d %d %d\n", vp[0], vp[1], vp[2], vp[3]); -#endif - ImGui::GetIO().DisplaySize = ImVec2(vp[2], vp[3]); - } - - if (!invalid_scissor && - (sb != last_sb - || last_vp == sb) // openmw initial viewport size is the same (correct) - // at start as scissor box, so apply it instead - ) { -#ifndef NDEBUG - printf("scissor box: %d %d %d %d\n", sb[0], sb[1], sb[2], sb[3]); -#endif - ImGui::GetIO().DisplaySize = ImVec2(sb[2], sb[3]); - } - - last_vp = vp; - last_sb = sb; - - ImGui_ImplOpenGL3_NewFrame(); - ImGui::NewFrame(); - { - std::lock_guard lk(notifier.mutex); - position_layer(params, window_size); - render_imgui(sw_stats, params, window_size, false); - } - ImGui::PopStyleVar(3); - - ImGui::Render(); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - ImGui::SetCurrentContext(saved_ctx); -} +extern overlay_params params; void* get_proc_address(const char* name) { void (*func)() = (void (*)())real_dlsym( RTLD_NEXT, name ); @@ -330,9 +112,24 @@ EXPORT_C_(bool) glXMakeCurrent(void* dpy, void* drawable, void* ctx) { EXPORT_C_(void) glXSwapBuffers(void* dpy, void* drawable) { gl.Load(); imgui_create(gl.glXGetCurrentContext()); - check_keybinds(params); - update_hud_info(sw_stats, params, vendorID); - imgui_render(); + + unsigned int width, height; + //gl.glXQueryDrawable(dpy, drawable, 0x801D /*GLX_WIDTH*/, &width); + //gl.glXQueryDrawable(dpy, drawable, 0x801E /*GLX_HEIGTH*/, &height); + + // glXQueryDrawable is buggy, use XGetGeometry instead + Window unused_window; + int unused; + XGetGeometry((Display*)dpy, (Window)drawable, &unused_window, + &unused, &unused, + &width, &height, + (unsigned int*) &unused, (unsigned int*) &unused); + + /*GLint vp[4]; glGetIntegerv (GL_VIEWPORT, vp); + width = vp[2]; + height = vp[3];*/ + + imgui_render(width, height); gl.glXSwapBuffers(dpy, drawable); if (fps_limit_stats.targetFrameTime > 0){ fps_limit_stats.frameStart = os_time_get_nano(); diff --git a/src/meson.build b/src/meson.build index 63062420..f80a4312 100644 --- a/src/meson.build +++ b/src/meson.build @@ -55,6 +55,7 @@ vklayer_files = files( ) opengl_files = files( + 'gl/imgui_hud.cpp', 'gl/inject_glx.cpp', 'gl/real_dlsym.cpp', 'gl/imgui_impl_opengl3.cpp',