Skip to content

Commit

Permalink
Implement drawing (background) image.
Browse files Browse the repository at this point in the history
options: image <path> / image_max_width (int) / image_background (path)

image : to display an image component (only one component of type image can be rendered)
        note that the texture is never cleared, nor reloaded (in case of configuration modification).

image_max_width: by default, the width of the image is the one of the pannel (value is 0). with this
                 option, you can reduce it.

image_background: global background image to display

Signed-off-by: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com>
  • Loading branch information
nadenislamarre authored and jackun committed Jun 15, 2024
1 parent 44917b7 commit 12620c9
Show file tree
Hide file tree
Showing 13 changed files with 350 additions and 48 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ Parameters that are enabled by default have to be explicitly disabled. These (cu
| `arch` | Show if the application is 32- or 64-bit |
| `autostart_log=` | Starts the log after X seconds from mangohud init |
| `background_alpha` | Set the opacity of the background `0.0`-`1.0` |
| `background_image` | Display a background image from argument path on the whole screen (eventually transparent) |
| `battery_color` | Change the battery text color |
| `battery_icon` | Display battery icon instead of percent |
| `battery_watt` | Display wattage for the battery option |
Expand Down Expand Up @@ -379,6 +380,8 @@ Parameters that are enabled by default have to be explicitly disabled. These (cu
| `horizontal_stretch` | Stretches the background to the screens width in `horizontal` mode |
| `hud_compact` | Display compact version of MangoHud |
| `hud_no_margin` | Remove margins around MangoHud |
| `image` | Display an image from argument path |
| `image_max_width` | Maximize the image by a max number of pixel for the width |
| `io_read`<br> `io_write` | Show non-cached IO read/write, in MiB/s |
| `log_duration` | Set amount of time the logging will run for (in seconds) |
| `log_interval` | Change the default log interval in milliseconds. Default is `0` |
Expand Down
7 changes: 7 additions & 0 deletions data/MangoHud.conf
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,13 @@ frame_timing
### Display output of Bash command in next column
# exec=

### Display a background image from argument path on the whole screen (eventually transparent)
# background_image=
### Display an image from argument path
# image=
### Maximize the image by a max number of pixel for the width
# image_max_width=

### Display media player metadata
# media_player
## for example spotify
Expand Down
25 changes: 14 additions & 11 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ else
dep_rt = null_dep
endif

if get_option('use_vulkan')
# Commented code can be used if mangohud start using latest SDK Vulkan-Headers
# Allowing user to build mangohud using system Vulkan-Headers
#if not dependency('VulkanHeaders').found()
Expand All @@ -177,17 +178,19 @@ endif
# vk_api_xml = files('/usr/share/vulkan/registry/vk.xml')
#endif



vk_enum_to_str = custom_target(
'vk_enum_to_str',
input : ['bin/gen_enum_to_str.py', vk_api_xml],
output : ['vk_enum_to_str.c', 'vk_enum_to_str.h'],
command : [
prog_python, '@INPUT0@', '--xml', '@INPUT1@',
'--outdir', meson.current_build_dir()
],
)
vk_enum_to_str = custom_target(
'vk_enum_to_str',
input : ['bin/gen_enum_to_str.py', vk_api_xml],
output : ['vk_enum_to_str.c', 'vk_enum_to_str.h'],
command : [
prog_python, '@INPUT0@', '--xml', '@INPUT1@',
'--outdir', meson.current_build_dir()
],
)
else
dep_vulkan = null_dep
vk_enum_to_str = []
endif

imgui_options = [
'default_library=static',
Expand Down
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ option('with_nvml', type : 'combo', value : 'enabled', choices: ['enabled', 'sys
option('with_xnvctrl', type : 'feature', value : 'enabled', description: 'Enable XNVCtrl support')
option('with_x11', type : 'feature', value : 'enabled')
option('with_wayland', type : 'feature', value : 'enabled')
option('use_vulkan', type : 'boolean', value : true)
option('with_dbus', type : 'feature', value : 'enabled')
option('loglevel', type: 'combo', choices : ['trace', 'debug', 'info', 'warn', 'err', 'critical', 'off'], value : 'info', description: 'Max log level in non-debug build')
option('mangoapp', type: 'boolean', value : false)
Expand Down
2 changes: 1 addition & 1 deletion src/gl/gl_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ static bool ImGui_ImplOpenGL3_CreateDeviceObjects()
"varying vec4 Frag_Color;\n"
"void main()\n"
"{\n"
" gl_FragColor = Frag_Color * vec4(1, 1, 1, texture2D(Texture, Frag_UV.st).r);\n"
" gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n"
"}\n";

const GLchar* fragment_shader_glsl_130 =
Expand Down
5 changes: 5 additions & 0 deletions src/gl/inject_egl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <chrono>
#include <iomanip>
#include <spdlog/spdlog.h>
#include <glad/glad.h>
#include "real_dlsym.h"
#include "mesa/util/macros.h"
#include "mesa/util/os_time.h"
Expand All @@ -25,6 +26,10 @@ static void* get_egl_proc_address(const char* name) {
SPDLOG_ERROR("Failed to open " MANGOHUD_ARCH " libEGL.so.1: {}", dlerror());
} else {
pfn_eglGetProcAddress = reinterpret_cast<decltype(pfn_eglGetProcAddress)>(real_dlsym(handle, "eglGetProcAddress"));

if(gladLoadGLES2Loader((GLADloadproc)pfn_eglGetProcAddress) == 0) {
pfn_eglGetProcAddress = nullptr;
}
}
}

Expand Down
84 changes: 81 additions & 3 deletions src/hud_elements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#endif
#include "amdgpu.h"
#include "fps_metrics.h"
#include "load_textures.h"

#define CHAR_CELSIUS "\xe2\x84\x83"
#define CHAR_FAHRENHEIT "\xe2\x84\x89"
Expand Down Expand Up @@ -680,6 +681,7 @@ void HudElements::engine_version(){
ImguiNextColumnFirstItem();
ImGui::PushFont(HUDElements.sw_stats->font1);
if (HUDElements.is_vulkan) {
#ifdef HAVE_VULKAN
if ((HUDElements.sw_stats->engine == EngineTypes::DXVK || HUDElements.sw_stats->engine == EngineTypes::VKD3D)){
HUDElements.TextColored(HUDElements.colors.engine,
"%s/%d.%d.%d", HUDElements.sw_stats->engineVersion.c_str(),
Expand All @@ -693,6 +695,7 @@ void HudElements::engine_version(){
HUDElements.sw_stats->version_vk.minor,
HUDElements.sw_stats->version_vk.patch);
}
#endif
} else {
HUDElements.TextColored(HUDElements.colors.engine,
"%d.%d%s", HUDElements.sw_stats->version_gl.major, HUDElements.sw_stats->version_gl.minor,
Expand Down Expand Up @@ -922,6 +925,80 @@ void HudElements::custom_text_center(){
}
}

void HudElements::image(){
const std::string& value = HUDElements.ordered_functions[HUDElements.place].value;

// load the image if needed
if (HUDElements.image_infos.loaded == false) {
unsigned maxwidth = HUDElements.params->width;
if (HUDElements.params->image_max_width != 0 && HUDElements.params->image_max_width < maxwidth) {
maxwidth = HUDElements.params->image_max_width;
}

HUDElements.image_infos.loaded = true;
if (HUDElements.is_vulkan) {
#ifdef HAVE_VULKAN
if ((HUDElements.image_infos.texture = add_texture(HUDElements.sw_stats, value, &(HUDElements.image_infos.width), &(HUDElements.image_infos.height), maxwidth)))
HUDElements.image_infos.valid = true;
#endif
} else {
#ifndef HAVE_VULKAN
HUDElements.image_infos.valid = GL_LoadTextureFromFile(value.c_str(),
reinterpret_cast<unsigned int*>(&(HUDElements.image_infos.texture)),
&(HUDElements.image_infos.width),
&(HUDElements.image_infos.height),
maxwidth);
#endif
}

if (HUDElements.image_infos.valid)
SPDLOG_INFO("Image {} loaded ({}x{})", value, HUDElements.image_infos.width, HUDElements.image_infos.height);
else
SPDLOG_WARN("Failed to load image: {}", value);
}

// render the image
if (HUDElements.image_infos.valid) {
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::Image(HUDElements.image_infos.texture, ImVec2(HUDElements.image_infos.width, HUDElements.image_infos.height));
}
}

void HudElements::background_image(){
const std::string& value = HUDElements.params->background_image;

// load the image if needed
if (HUDElements.background_image_infos.loaded == false) {
HUDElements.background_image_infos.loaded = true;
if (HUDElements.is_vulkan) {
#ifdef HAVE_VULKAN
if ((HUDElements.background_image_infos.texture = add_texture(HUDElements.sw_stats, value, &(HUDElements.background_image_infos.width), &(HUDElements.background_image_infos.height), 0)))
HUDElements.background_image_infos.valid = true;
#endif
} else {
#ifndef HAVE_VULKAN
HUDElements.background_image_infos.valid = GL_LoadTextureFromFile(value.c_str(),
reinterpret_cast<unsigned int*>(&(HUDElements.background_image_infos.texture)),
&(HUDElements.background_image_infos.width),
&(HUDElements.background_image_infos.height),
0);
#endif
}

if (HUDElements.background_image_infos.valid)
SPDLOG_INFO("Image {} loaded ({}x{})", value, HUDElements.background_image_infos.width, HUDElements.background_image_infos.height);
else
SPDLOG_WARN("Failed to load image: {}", value);
}

// render the image
if (HUDElements.background_image_infos.valid) {
ImGui::GetBackgroundDrawList()->AddImage(HUDElements.background_image_infos.texture,
ImVec2(0, 0),
ImVec2(HUDElements.background_image_infos.width, HUDElements.background_image_infos.height));
}
}

void HudElements::custom_text(){
ImguiNextColumnFirstItem();
ImGui::PushFont(HUDElements.sw_stats->font1);
Expand Down Expand Up @@ -1089,7 +1166,7 @@ void HudElements::gamescope_frame_timing(){
HUDElements.gamescope_debug_app.end());
auto max = std::max_element(HUDElements.gamescope_debug_app.begin(),
HUDElements.gamescope_debug_app.end());

ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
HUDElements.TextColored(HUDElements.colors.engine, "%s", "App");
Expand Down Expand Up @@ -1522,8 +1599,9 @@ void HudElements::sort_elements(const std::pair<std::string, std::string>& optio
{"refresh_rate", {refresh_rate}},
{"winesync", {winesync}},
{"present_mode", {present_mode}},
{"network", {network}}

{"network", {network}},
{"background_image", {background_image}},
{"image", {image}},
};

auto check_param = display_params.find(param);
Expand Down
22 changes: 22 additions & 0 deletions src/hud_elements.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,29 @@ struct Function {
std::string value;
};

struct image_infos {
std::string path;
int width;
int height;
bool loaded;
bool valid;
ImTextureID texture;

image_infos() {
loaded = false;
valid = false;
}

~image_infos() {
}
};


struct overlay_params;
class HudElements{
public:
struct image_infos image_infos;
struct image_infos background_image_infos;
struct swapchain_stats *sw_stats;
struct overlay_params *params;
struct exec_entry {
Expand Down Expand Up @@ -83,6 +103,8 @@ class HudElements{
static void show_fps_limit();
static void custom_text_center();
static void custom_text();
static void image();
static void background_image();
static void vkbasalt();
static void gamemode();
static void graphs();
Expand Down
9 changes: 7 additions & 2 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ if is_unixy
'gl/gl_renderer.cpp',
'gl/gl_hud.cpp',
'gl/inject_egl.cpp',
'load_textures.cpp',
)

nvml_h_found = get_option('with_nvml') == 'enabled'
Expand Down Expand Up @@ -174,6 +175,7 @@ link_args = cc.get_supported_link_arguments(['-Wl,-Bsymbolic-functions', '-Wl,-z
# meson fails to check version-script so just force add
link_args += '-Wl,--version-script,@0@'.format(join_paths(meson.current_source_dir(), 'mangohud.version'))

if get_option('use_vulkan')
mangohud_static_lib = static_library(
'MangoHud',
mangohud_version,
Expand All @@ -184,11 +186,13 @@ mangohud_static_lib = static_library(
overlay_spv,
c_args : [
pre_args,
vulkan_wsi_args
vulkan_wsi_args,
'-DHAVE_VULKAN'
],
cpp_args : [
pre_args,
vulkan_wsi_args
vulkan_wsi_args,
'-DHAVE_VULKAN'
],
gnu_symbol_visibility : 'hidden',
dependencies : [
Expand All @@ -209,6 +213,7 @@ mangohud_static_lib = static_library(
install_dir : libdir_mangohud,
install : false
)
endif

mangohud_shared_lib = shared_library(
'MangoHud',
Expand Down
1 change: 1 addition & 0 deletions src/overlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ extern void control_client_check(int control, int& control_client, const std::st
extern void process_control_socket(int& control_client, overlay_params &params);
extern void control_send(int control_client, const char *cmd, unsigned cmdlen, const char *param, unsigned paramlen);
extern int global_control_client;
ImTextureID add_texture(swapchain_stats* stats, const std::string& filename, int* width, int* height, int maxwidth);
#ifdef HAVE_DBUS
void render_mpris_metadata(const overlay_params& params, mutexed_metadata& meta, uint64_t frame_timing);
#endif
Expand Down
4 changes: 4 additions & 0 deletions src/overlay_params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,9 @@ parse_fps_metrics(const char *str){
#define parse_blacklist(s) parse_str_tokenize(s)
#define parse_custom_text_center(s) parse_str(s)
#define parse_custom_text(s) parse_str(s)
#define parse_background_image(s) parse_str(s)
#define parse_image(s) parse_str(s)
#define parse_image_max_width(s) parse_unsigned(s)
#define parse_fps_value(s) parse_load_value(s)
#define parse_fps_color(s) parse_load_color(s)
#define parse_battery_color(s) parse_color(s)
Expand Down Expand Up @@ -783,6 +786,7 @@ static void set_param_defaults(struct overlay_params *params){
params->table_columns = 3;
params->text_outline_color = 0x000000;
params->text_outline_thickness = 1.5;
params->image_max_width = 0;
}

void
Expand Down
6 changes: 6 additions & 0 deletions src/overlay_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_BOOL(fps_color_change) \
OVERLAY_PARAM_BOOL(custom_text_center) \
OVERLAY_PARAM_BOOL(custom_text) \
OVERLAY_PARAM_CUSTOM(background_image) \
OVERLAY_PARAM_CUSTOM(image) \
OVERLAY_PARAM_CUSTOM(image_max_width) \
OVERLAY_PARAM_BOOL(exec) \
OVERLAY_PARAM_BOOL(vkbasalt) \
OVERLAY_PARAM_BOOL(gamemode) \
Expand Down Expand Up @@ -308,6 +311,9 @@ struct overlay_params {
uint32_t font_glyph_ranges;
std::string custom_text_center;
std::string custom_text;
std::string background_image;
std::string image;
unsigned image_max_width;
std::string config_file_path;
std::unordered_map<std::string,std::string> options;
int permit_upload;
Expand Down
Loading

0 comments on commit 12620c9

Please sign in to comment.