mirror of
https://github.com/flightlessmango/MangoHud.git
synced 2024-10-31 15:20:13 +00:00
[OpenGL] Move ImGui functions to separate file
This commit is contained in:
parent
c3e50db2f4
commit
59113b3ae2
195
src/gl/imgui_hud.cpp
Normal file
195
src/gl/imgui_hud.cpp
Normal file
@ -0,0 +1,195 @@
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include "GL/gl3w.h"
|
||||
#include <imgui.h>
|
||||
#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<notify_thread, std::function<void(notify_thread *)>>
|
||||
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<std::mutex> 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);
|
||||
}
|
7
src/gl/imgui_hud.h
Normal file
7
src/gl/imgui_hud.h
Normal file
@ -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);
|
@ -1,242 +1,24 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <iostream>
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <dlfcn.h>
|
||||
#include <string>
|
||||
#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 <chrono>
|
||||
#include <iomanip>
|
||||
|
||||
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<notify_thread, std::function<void(notify_thread *)>>
|
||||
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<std::mutex> 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();
|
||||
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user