[OpenGL] Separate GLX out from shareable code so wayland sessions can just use EGL, hopefully

pull/131/head
jackun 4 years ago
parent 2f034c6d1e
commit 8cd3172335
No known key found for this signature in database
GPG Key ID: 119DB3F1D05A9ED3

@ -1,17 +1,17 @@
#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"
#include "imgui_hud_shared.h"
#include "imgui_hud.h"
using namespace MangoHud;
#ifdef IMGUI_GLX
#include "GL/gl3w.h"
#endif
namespace MangoHud { namespace GL {
struct GLVec
{
@ -43,34 +43,12 @@ struct state {
};
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(&notifier, [](notify_thread *n){ stop_notifier(*n); });
void imgui_init()
{
if (cfg_inited)
return;
parse_overlay_config(&params, getenv("MANGOHUD_CONFIG"));
notifier.params = &params;
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)
static void imgui_create(void *ctx)
{
if (inited)
return;
@ -80,7 +58,6 @@ void imgui_create(void *ctx)
return;
imgui_init();
gl3wInit();
std::cerr << "GL version: " << glGetString(GL_VERSION) << std::endl;
glGetIntegerv(GL_MAJOR_VERSION, &sw_stats.version_gl.major);
@ -113,7 +90,7 @@ void imgui_create(void *ctx)
ImGui::GetIO().IniFilename = NULL;
ImGui::GetIO().DisplaySize = ImVec2(last_vp[2], last_vp[3]);
ImGui_ImplOpenGL3_Init();
VARIANT(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.
@ -141,7 +118,34 @@ void imgui_create(void *ctx)
ImGui::SetCurrentContext(saved_ctx);
}
void imgui_shutdown()
#ifdef IMGUI_GLX
void VARIANT(imgui_create)(void *ctx)
{
if (inited)
return;
if (!ctx)
return;
gl3wInit();
imgui_create(ctx);
}
#endif
#ifdef IMGUI_EGL
void VARIANT(imgui_create)(void *ctx)
{
if (inited)
return;
if (!ctx)
return;
imgui_create(ctx);
}
#endif
void VARIANT(imgui_shutdown)()
{
#ifndef NDEBUG
std::cerr << __func__ << std::endl;
@ -149,26 +153,26 @@ void imgui_shutdown()
if (state.imgui_ctx) {
ImGui::SetCurrentContext(state.imgui_ctx);
ImGui_ImplOpenGL3_Shutdown();
VARIANT(ImGui_ImplOpenGL3_Shutdown)();
ImGui::DestroyContext(state.imgui_ctx);
state.imgui_ctx = nullptr;
}
inited = false;
}
void imgui_set_context(void *ctx)
void VARIANT(imgui_set_context)(void *ctx)
{
if (!ctx) {
imgui_shutdown();
VARIANT(imgui_shutdown)();
return;
}
#ifndef NDEBUG
std::cerr << __func__ << ": " << ctx << std::endl;
#endif
imgui_create(ctx);
VARIANT(imgui_create)(ctx);
}
void imgui_render(unsigned int width, unsigned int height)
void VARIANT(imgui_render)(unsigned int width, unsigned int height)
{
if (!state.imgui_ctx)
return;
@ -180,7 +184,7 @@ void imgui_render(unsigned int width, unsigned int height)
ImGui::SetCurrentContext(state.imgui_ctx);
ImGui::GetIO().DisplaySize = ImVec2(width, height);
ImGui_ImplOpenGL3_NewFrame();
VARIANT(ImGui_ImplOpenGL3_NewFrame)();
ImGui::NewFrame();
{
std::lock_guard<std::mutex> lk(notifier.mutex);
@ -190,6 +194,8 @@ void imgui_render(unsigned int width, unsigned int height)
ImGui::PopStyleVar(3);
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
VARIANT(ImGui_ImplOpenGL3_RenderDrawData)(ImGui::GetDrawData());
ImGui::SetCurrentContext(saved_ctx);
}
}} // namespaces

@ -1,7 +1,13 @@
#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);
#include "imgui_impl_opengl3.h"
namespace MangoHud { namespace GL {
void VARIANT(imgui_init)();
void VARIANT(imgui_create)(void *ctx);
void VARIANT(imgui_shutdown)();
void VARIANT(imgui_set_context)(void *ctx);
void VARIANT(imgui_render)(unsigned int width, unsigned int height);
}} // namespace

@ -0,0 +1,31 @@
#include <cstdlib>
#include <functional>
#include <thread>
#include "imgui_hud_shared.h"
namespace MangoHud { namespace GL {
notify_thread notifier;
static bool cfg_inited = false;
ImVec2 window_size;
bool inited = false;
overlay_params params {};
// seems to quit by itself though
static std::unique_ptr<notify_thread, std::function<void(notify_thread *)>>
stop_it(&notifier, [](notify_thread *n){ stop_notifier(*n); });
void imgui_init()
{
if (cfg_inited)
return;
parse_overlay_config(&params, getenv("MANGOHUD_CONFIG"));
notifier.params = &params;
start_notifier(notifier);
window_size = ImVec2(params.width, params.height);
init_system_info();
cfg_inited = true;
init_cpu_stats(params);
}
}} // namespaces

@ -0,0 +1,15 @@
#pragma once
#include <imgui.h>
#include "overlay.h"
#include "notify.h"
namespace MangoHud { namespace GL {
extern notify_thread notifier;
extern ImVec2 window_size;
extern bool inited;
extern overlay_params params;
void imgui_init();
}} // namespaces

@ -63,19 +63,25 @@
// ES 3.0 300 "#version 300 es" = WebGL 2.0
//----------------------------------------
#include "imgui.h"
#include <imgui.h>
#include "imgui_impl_opengl3.h"
#include <stdio.h>
#include <stdint.h> // intptr_t
#ifdef IMGUI_GLX
#include <GL/gl3w.h>
#endif
#ifdef IMGUI_GLX
#define GL_CLIP_ORIGIN 0x935C
#define GL_NEGATIVE_ONE_TO_ONE 0x935E
#define GL_ZERO_TO_ONE 0x935F
#define GL_CLIP_DEPTH_MODE 0x935D
void* get_glx_proc_address(const char* name);
void (*glClipControl)(int origin, int depth);
void (*glClipControl)(int origin, int depth) = nullptr;
#endif
namespace MangoHud {
@ -96,263 +102,7 @@ static int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_Att
static unsigned int g_VboHandle = 0, g_ElementsHandle = 0;
// Functions
bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
{
glClipControl = reinterpret_cast<decltype(glClipControl)> (get_glx_proc_address("glClipControl"));
// Query for GL version
#if !defined(IMGUI_IMPL_OPENGL_ES2)
glsl_version = "#version 130";
GLint major = -1, minor = -1;
glGetIntegerv(GL_MAJOR_VERSION, &major);
glGetIntegerv(GL_MINOR_VERSION, &minor);
g_GlVersion = major * 1000 + minor;
printf("Version: %d.%d\n", major, minor);
if (major >= 4 && minor >= 1)
glsl_version = "#version 410";
else if (major > 3 || (major == 3 && minor >= 2))
glsl_version = "#version 150";
#else
g_GlVersion = 2000; // GLES 2
#endif
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_opengl3";
#if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
if (g_GlVersion >= 3200)
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
#endif
// Store GLSL version string so we can refer to it later in case we recreate shaders.
// Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure.
if (glsl_version == NULL)
glsl_version = "#version 130";
IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString));
strcpy(g_GlslVersionString, glsl_version);
strcat(g_GlslVersionString, "\n");
// 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, &current_texture);
return true;
}
void ImGui_ImplOpenGL3_Shutdown()
{
ImGui_ImplOpenGL3_DestroyDeviceObjects();
}
void ImGui_ImplOpenGL3_NewFrame()
{
if (!g_ShaderHandle)
ImGui_ImplOpenGL3_CreateDeviceObjects();
}
static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
{
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
#ifdef GL_POLYGON_MODE
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
// Setup viewport, orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
float L = draw_data->DisplayPos.x;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
const float ortho_projection[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f },
};
glUseProgram(g_ShaderHandle);
glUniform1i(g_AttribLocationTex, 0);
glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
#ifdef GL_SAMPLER_BINDING
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
#endif
(void)vertex_array_object;
#ifndef IMGUI_IMPL_OPENGL_ES2
glBindVertexArray(vertex_array_object);
#endif
// Bind vertex/index buffers and setup attributes for ImDrawVert
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
glEnableVertexAttribArray(g_AttribLocationVtxPos);
glEnableVertexAttribArray(g_AttribLocationVtxUV);
glEnableVertexAttribArray(g_AttribLocationVtxColor);
glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos));
glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv));
glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col));
}
// OpenGL3 Render function.
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
{
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
if (fb_width <= 0 || fb_height <= 0)
return;
// Backup GL state
GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
glActiveTexture(GL_TEXTURE0);
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
#ifdef GL_SAMPLER_BINDING
GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler);
#endif
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
GLint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object);
#endif
#ifdef GL_POLYGON_MODE
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
#endif
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb);
GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb);
GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha);
GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha);
GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb);
GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha);
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
bool clip_origin_lower_left = true;
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
GLenum last_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT)
GLenum last_clip_depth_mode = 0; glGetIntegerv(GL_CLIP_DEPTH_MODE, (GLint*)&last_clip_depth_mode);
if (last_clip_origin == GL_UPPER_LEFT) {
clip_origin_lower_left = false;
if (glClipControl)
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
}
#endif
// Setup desired GL state
// Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
// The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
GLuint vertex_array_object = 0;
#ifndef IMGUI_IMPL_OPENGL_ES2
glGenVertexArrays(1, &vertex_array_object);
#endif
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
// Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
// Render command lists
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// Upload vertex/index buffers
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != NULL)
{
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
else
pcmd->UserCallback(cmd_list, pcmd);
}
else
{
// Project scissor/clipping rectangles into framebuffer space
ImVec4 clip_rect;
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
{
// Apply scissor/clipping rectangle
//if (clip_origin_lower_left)
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
//else
// glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
// Bind texture, Draw
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
#if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
if (g_GlVersion >= 3200)
glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset);
else
#endif
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
}
}
}
}
// Destroy the temporary VAO
#ifndef IMGUI_IMPL_OPENGL_ES2
glDeleteVertexArrays(1, &vertex_array_object);
#endif
// Restore modified GL state
glUseProgram(last_program);
glBindTexture(GL_TEXTURE_2D, last_texture);
#ifdef GL_SAMPLER_BINDING
glBindSampler(0, last_sampler);
#endif
glActiveTexture(last_active_texture);
#ifndef IMGUI_IMPL_OPENGL_ES2
glBindVertexArray(last_vertex_array_object);
#endif
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
#ifdef GL_POLYGON_MODE
glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
#endif
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
if (!clip_origin_lower_left && glClipControl)
glClipControl(last_clip_origin, last_clip_depth_mode);
#endif
}
bool ImGui_ImplOpenGL3_CreateFontsTexture()
static bool ImGui_ImplOpenGL3_CreateFontsTexture()
{
// Build texture atlas
ImGuiIO& io = ImGui::GetIO();
@ -381,7 +131,7 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture()
return true;
}
void ImGui_ImplOpenGL3_DestroyFontsTexture()
static void ImGui_ImplOpenGL3_DestroyFontsTexture()
{
if (g_FontTexture)
{
@ -428,7 +178,7 @@ static bool CheckProgram(GLuint handle, const char* desc)
return (GLboolean)status == GL_TRUE;
}
bool ImGui_ImplOpenGL3_CreateDeviceObjects()
static bool ImGui_ImplOpenGL3_CreateDeviceObjects()
{
// Backup GL state
GLint last_texture, last_array_buffer;
@ -612,7 +362,7 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
return true;
}
void ImGui_ImplOpenGL3_DestroyDeviceObjects()
static void ImGui_ImplOpenGL3_DestroyDeviceObjects()
{
#ifndef NDEBUG
printf("%s\n", __func__);
@ -627,4 +377,263 @@ void ImGui_ImplOpenGL3_DestroyDeviceObjects()
ImGui_ImplOpenGL3_DestroyFontsTexture();
}
bool VARIANT(ImGui_ImplOpenGL3_Init)(const char* glsl_version)
{
#ifdef IMGUI_GLX
glClipControl = reinterpret_cast<decltype(glClipControl)> (get_glx_proc_address("glClipControl"));
#endif
// Query for GL version
#if !defined(IMGUI_IMPL_OPENGL_ES2)
glsl_version = "#version 130";
GLint major = -1, minor = -1;
glGetIntegerv(GL_MAJOR_VERSION, &major);
glGetIntegerv(GL_MINOR_VERSION, &minor);
g_GlVersion = major * 1000 + minor;
printf("Version: %d.%d\n", major, minor);
if (major >= 4 && minor >= 1)
glsl_version = "#version 410";
else if (major > 3 || (major == 3 && minor >= 2))
glsl_version = "#version 150";
#else
g_GlVersion = 2000; // GLES 2
#endif
// Setup back-end capabilities flags
ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_opengl3";
#if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
if (g_GlVersion >= 3200)
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
#endif
// Store GLSL version string so we can refer to it later in case we recreate shaders.
// Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure.
if (glsl_version == NULL)
glsl_version = "#version 130";
IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString));
strcpy(g_GlslVersionString, glsl_version);
strcat(g_GlslVersionString, "\n");
// 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, &current_texture);
return true;
}
void VARIANT(ImGui_ImplOpenGL3_Shutdown)()
{
ImGui_ImplOpenGL3_DestroyDeviceObjects();
}
void VARIANT(ImGui_ImplOpenGL3_NewFrame)()
{
if (!g_ShaderHandle)
ImGui_ImplOpenGL3_CreateDeviceObjects();
}
static void VARIANT(ImGui_ImplOpenGL3_SetupRenderState)(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
{
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
#ifdef GL_POLYGON_MODE
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
// Setup viewport, orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
float L = draw_data->DisplayPos.x;
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
const float ortho_projection[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f },
};
glUseProgram(g_ShaderHandle);
glUniform1i(g_AttribLocationTex, 0);
glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
#ifdef GL_SAMPLER_BINDING
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
#endif
(void)vertex_array_object;
#ifndef IMGUI_IMPL_OPENGL_ES2
glBindVertexArray(vertex_array_object);
#endif
// Bind vertex/index buffers and setup attributes for ImDrawVert
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
glEnableVertexAttribArray(g_AttribLocationVtxPos);
glEnableVertexAttribArray(g_AttribLocationVtxUV);
glEnableVertexAttribArray(g_AttribLocationVtxColor);
glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos));
glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv));
glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col));
}
// OpenGL3 Render function.
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
void VARIANT(ImGui_ImplOpenGL3_RenderDrawData)(ImDrawData* draw_data)
{
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
if (fb_width <= 0 || fb_height <= 0)
return;
// Backup GL state
GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
glActiveTexture(GL_TEXTURE0);
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
#ifdef GL_SAMPLER_BINDING
GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler);
#endif
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
GLint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object);
#endif
#ifdef GL_POLYGON_MODE
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
#endif
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb);
GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, (GLint*)&last_blend_dst_rgb);
GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, (GLint*)&last_blend_src_alpha);
GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, (GLint*)&last_blend_dst_alpha);
GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, (GLint*)&last_blend_equation_rgb);
GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, (GLint*)&last_blend_equation_alpha);
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
bool clip_origin_lower_left = true;
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
GLenum last_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT)
GLenum last_clip_depth_mode = 0; glGetIntegerv(GL_CLIP_DEPTH_MODE, (GLint*)&last_clip_depth_mode);
if (last_clip_origin == GL_UPPER_LEFT) {
clip_origin_lower_left = false;
if (glClipControl)
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
}
#endif
// Setup desired GL state
// Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
// The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
GLuint vertex_array_object = 0;
#ifndef IMGUI_IMPL_OPENGL_ES2
glGenVertexArrays(1, &vertex_array_object);
#endif
VARIANT(ImGui_ImplOpenGL3_SetupRenderState)(draw_data, fb_width, fb_height, vertex_array_object);
// Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
// Render command lists
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
// Upload vertex/index buffers
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
{
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != NULL)
{
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
VARIANT(ImGui_ImplOpenGL3_SetupRenderState)(draw_data, fb_width, fb_height, vertex_array_object);
else
pcmd->UserCallback(cmd_list, pcmd);
}
else
{
// Project scissor/clipping rectangles into framebuffer space
ImVec4 clip_rect;
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
{
// Apply scissor/clipping rectangle
//if (clip_origin_lower_left)
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
//else
// glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
// Bind texture, Draw
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
#if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
if (g_GlVersion >= 3200)
glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset);
else
#endif
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)));
}
}
}
}
// Destroy the temporary VAO
#ifndef IMGUI_IMPL_OPENGL_ES2
glDeleteVertexArrays(1, &vertex_array_object);
#endif
// Restore modified GL state
glUseProgram(last_program);
glBindTexture(GL_TEXTURE_2D, last_texture);
#ifdef GL_SAMPLER_BINDING
glBindSampler(0, last_sampler);
#endif
glActiveTexture(last_active_texture);
#ifndef IMGUI_IMPL_OPENGL_ES2
glBindVertexArray(last_vertex_array_object);
#endif
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
#ifdef GL_POLYGON_MODE
glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
#endif
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
if (!clip_origin_lower_left && glClipControl)
glClipControl(last_clip_origin, last_clip_depth_mode);
#endif
}
}

@ -25,16 +25,31 @@
namespace MangoHud {
#if defined(IMGUI_GLX) && defined(IMGUI_EGL)
#error Both IMGUI_GLX and IMGUI_EGL can not be defined at the same time!
#elif !defined(IMGUI_GLX) && !defined(IMGUI_EGL)
#error Define IMGUI_GLX or IMGUI_EGL!
#endif
#undef VARIANT
#ifdef IMGUI_GLX
#define VARIANT(x) x##_GLX
#endif
#ifdef IMGUI_EGL
#define VARIANT(x) x##_EGL
#endif
// Backend API
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
IMGUI_IMPL_API bool VARIANT(ImGui_ImplOpenGL3_Init)(const char* glsl_version = nullptr);
IMGUI_IMPL_API void VARIANT(ImGui_ImplOpenGL3_Shutdown)();
IMGUI_IMPL_API void VARIANT(ImGui_ImplOpenGL3_NewFrame)();
IMGUI_IMPL_API void VARIANT(ImGui_ImplOpenGL3_RenderDrawData)(ImDrawData* draw_data);
// (Optional) Called by Init/NewFrame/Shutdown
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
//IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture();
//IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
//IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
//IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
}

@ -4,21 +4,24 @@
#include <cstring>
#include "real_dlsym.h"
#include "loaders/loader_glx.h"
#include "imgui_hud.h"
#include "loaders/loader_x11.h"
#include "mesa/util/macros.h"
#include "mesa/util/os_time.h"
#include "overlay.h"
#include <chrono>
#include <iomanip>
#include "imgui_hud_shared.h"
#include "imgui_hud.h"
using namespace MangoHud::GL;
#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 glx_loader glx;
extern overlay_params params;
void* get_proc_address(const char* name) {
void (*func)() = (void (*)())real_dlsym( RTLD_NEXT, name );
@ -47,30 +50,6 @@ void* get_glx_proc_address(const char* name) {
return func;
}
Status XGetGeometry(
Display *display,
Drawable d,
Window *root,
int *x,
int *y,
unsigned int *width,
unsigned int *height,
unsigned int *border_width,
unsigned int *depth
)
{
static decltype(&::XGetGeometry) pfnXGetGeometry = nullptr;
if (!pfnXGetGeometry) {
void *handle = real_dlopen("libX11.so.6", RTLD_LAZY);
if (!handle)
std::cerr << "MANGOHUD: couldn't find libX11.so.6" << std::endl;
pfnXGetGeometry = reinterpret_cast<decltype(pfnXGetGeometry)>(
real_dlsym(handle, "XGetGeometry"));
}
return pfnXGetGeometry(display, d, root, x, y, width, height, border_width, depth);
}
EXPORT_C_(void *) glXCreateContext(void *dpy, void *vis, void *shareList, int direct)
{
glx.Load();
@ -89,7 +68,7 @@ EXPORT_C_(bool) glXMakeCurrent(void* dpy, void* drawable, void* ctx) {
bool ret = glx.MakeCurrent(dpy, drawable, ctx);
if (ret)
imgui_set_context(ctx);
VARIANT(imgui_set_context)(ctx);
if (params.gl_vsync >= -1) {
if (glx.SwapIntervalEXT)
@ -105,7 +84,7 @@ EXPORT_C_(bool) glXMakeCurrent(void* dpy, void* drawable, void* ctx) {
EXPORT_C_(void) glXSwapBuffers(void* dpy, void* drawable) {
glx.Load();
imgui_create(glx.GetCurrentContext());
VARIANT(imgui_create)(glx.GetCurrentContext());
unsigned int width, height;
//glx.QueryDrawable(dpy, drawable, 0x801D /*GLX_WIDTH*/, &width);
@ -114,7 +93,7 @@ EXPORT_C_(void) glXSwapBuffers(void* dpy, void* drawable) {
// glXQueryDrawable is buggy, use XGetGeometry instead
Window unused_window;
int unused;
XGetGeometry((Display*)dpy, (Window)drawable, &unused_window,
g_x11->XGetGeometry((Display*)dpy, (Window)drawable, &unused_window,
&unused, &unused,
&width, &height,
(unsigned int*) &unused, (unsigned int*) &unused);
@ -123,7 +102,7 @@ EXPORT_C_(void) glXSwapBuffers(void* dpy, void* drawable) {
width = vp[2];
height = vp[3];*/
imgui_render(width, height);
VARIANT(imgui_render)(width, height);
glx.SwapBuffers(dpy, drawable);
if (fps_limit_stats.targetFrameTime > 0){
fps_limit_stats.frameStart = os_time_get_nano();

@ -10,6 +10,7 @@ double elapsedF2, elapsedF12, elapsedReloadCfg;
uint64_t last_f2_press, last_f12_press, reload_cfg_press;
pthread_t f2;
#ifdef HAVE_X11
bool key_is_pressed(KeySym ks) {
if (!init_x11())
@ -21,3 +22,4 @@ bool key_is_pressed(KeySym ks) {
bool isPressed = !!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)));
return isPressed;
}
#endif

@ -1,4 +1,5 @@
#include "loader_x11.h"
#include "real_dlsym.h"
libx11_loader::libx11_loader() : loaded_(false) {
}
@ -12,7 +13,7 @@ bool libx11_loader::Load(const std::string& library_name) {
return false;
}
library_ = dlopen(library_name.c_str(), RTLD_LAZY);
library_ = real_dlopen(library_name.c_str(), RTLD_LAZY);
if (!library_)
return false;
@ -80,6 +81,7 @@ void libx11_loader::CleanUp(bool unload) {
XCloseDisplay = NULL;
XQueryKeymap = NULL;
XKeysymToKeycode = NULL;
XStringToKeysym = NULL;
XGetGeometry = NULL;
}

@ -25,8 +25,8 @@ class libx11_loader {
private:
void CleanUp(bool unload);
void* library_;
bool loaded_;
void* library_ = nullptr;
bool loaded_ = false;
// Disallow copy constructor and assignment operator.
libx11_loader(const libx11_loader&);

@ -56,11 +56,15 @@ vklayer_files = files(
)
opengl_files = files(
'gl/imgui_hud.cpp',
'gl/imgui_impl_opengl3.cpp',
'gl/gl3w/GL/gl3w.c',
'gl/imgui_hud_shared.cpp',
)
pre_args += '-DHOOK_DLSYM'
inc_opengl = include_directories('gl/gl3w')
glimgui_glx_dep = null_dep
glimgui_egl_dep = null_dep
if get_option('with_x11').enabled() and \
get_option('with_xnvctrl').enabled()
pre_args += '-DHAVE_XNVCTRL'
@ -72,16 +76,80 @@ endif
if get_option('with_x11').enabled()
pre_args += '-DHAVE_X11'
opengl_files += files(
'gl/inject_glx.cpp',
'loaders/loader_glx.cpp',
vklayer_files += files(
'loaders/loader_x11.cpp',
'shared_x11.cpp',
)
opengl_files += files(
'loaders/loader_glx.cpp',
)
# build with GLX functions
glimgui_glx = static_library(
'glimgui_glx',
files(
'gl/inject_glx.cpp',
'gl/imgui_impl_opengl3.cpp',
'gl/imgui_hud.cpp',
'gl/gl3w/GL/gl3w.c',
),
pic : true,
c_args : [
pre_args,
c_vis_args,
no_override_init_args,
'-DIMGUI_GLX',
],
cpp_args : [
pre_args,
cpp_vis_args,
'-DIMGUI_GLX',
],
dependencies : [
libimgui_core_dep,
],
include_directories : [inc_common, inc_opengl],
)
glimgui_glx_dep = declare_dependency(
link_with : glimgui_glx,
)
endif
pre_args += '-DHOOK_DLSYM'
inc_opengl = include_directories('gl/gl3w')
if false
#if get_option('with_wayland').enabled()
# build with EGL functions
glimgui_egl = static_library(
'glimgui_egl',
files(
'gl/imgui_impl_opengl3.cpp',
'gl/imgui_hud.cpp',
),
pic : true,
c_args : [
pre_args,
c_vis_args,
no_override_init_args,
'-DIMGUI_EGL',
],
cpp_args : [
pre_args,
cpp_vis_args,
'-DIMGUI_EGL',
],
dependencies : [
libimgui_core_dep,
],
include_directories : [inc_common, inc_opengl],
)
glimgui_egl_dep = declare_dependency(
link_with : glimgui_egl,
)
endif
vklayer_mesa_overlay = shared_library(
'MangoHud',
@ -104,7 +172,9 @@ vklayer_mesa_overlay = shared_library(
],
dependencies : [
vulkan_wsi_deps,
libimgui_core_dep,
libimgui_core_dep,
glimgui_glx_dep,
glimgui_egl_dep,
dep_dl,
dep_pthread,
dep_vulkan],

@ -113,6 +113,10 @@ parse_reload_cfg(const char *str)
return g_x11->XStringToKeysym(str);
return 0;
}
#else
#define parse_toggle_hud(x) 0
#define parse_toggle_logging(x) 0
#define parse_reload_cfg(x) 0
#endif
static uint32_t
@ -342,9 +346,6 @@ parse_overlay_config(struct overlay_params *params,
params->width = 280;
params->height = 140;
params->control = -1;
params->toggle_hud = XK_F12;
params->toggle_logging = XK_F2;
params->reload_cfg = XK_F4;
params->fps_limit = 0;
params->vsync = -1;
params->gl_vsync = -2;
@ -364,6 +365,12 @@ parse_overlay_config(struct overlay_params *params,
params->background_color = strtol("020202", NULL, 16);
params->text_color = strtol("ffffff", NULL, 16);
#ifdef HAVE_X11
params->toggle_hud = XK_F12;
params->toggle_logging = XK_F2;
params->reload_cfg = XK_F4;
#endif
// first pass with env var
if (env)
parse_overlay_env(params, env);

Loading…
Cancel
Save