diff --git a/README.md b/README.md
index acd61bf9..078fa5ab 100644
--- a/README.md
+++ b/README.md
@@ -135,6 +135,11 @@ A partial list of parameters are below. See the config file for a complete list.
| `ram`
`vram` | Displays system RAM/VRAM usage |
| `full` | Enables all of the above config options |
| `font_size=` | Customizeable font size (default=24) |
+| `font_size_text=` | Customizeable font size for other text like media metadata (default=24) |
+| `font_scale=` | Set global font scale (default=1.0) |
+| `font_file` | Change default font (set location to .TTF/.OTF file ) |
+| `font_file_text` | Change text font. Otherwise `font_file` is used |
+| `font_glyph_ranges` | Specify extra font glyph ranges, comma separated: `korean`, `chinese`, `chinese_simplified`, `japanese`, `cyrillic`, `thai`, `vietnamese`, `latin_ext_a`, `latin_ext_b`. If you experience crashes or text is just squares, reduce font size or glyph ranges. |
| `width=`
`height=` | Customizeable hud dimensions (in pixels) |
| `position=` | Location of the hud: `top-left` (default), `top-right`, `bottom-left`, `bottom-right`, `top-center` |
| `offset_x` `offset_y` | Hud position offsets |
@@ -147,7 +152,6 @@ A partial list of parameters are below. See the config file for a complete list.
| `background_alpha` | Set the opacity of the background `0.0-1.0` |
| `read_cfg` | Add to MANGOHUD_CONFIG as first parameter to also load config file. Otherwise only MANGOHUD_CONFIG parameters are used. |
| `output_file` | Define name and location of the output file (Required for logging) |
-| `font_file` | Change default font (set location to .TTF/.OTF file ) |
| `log_duration` | Set amount of time the logging will run for (in seconds) |
| `vsync`
`gl_vsync` | Set vsync for OpenGL or Vulkan |
| `media_player` | Show media player metadata |
diff --git a/bin/MangoHud.conf b/bin/MangoHud.conf
index 652a933f..4ab60e1e 100644
--- a/bin/MangoHud.conf
+++ b/bin/MangoHud.conf
@@ -48,8 +48,22 @@ frame_timing
### Change the hud font size (default is 24)
font_size=24
+# font_scale=1.0
+# font_size_text=24
# font_scale_media_player = 0.55
+### Change default font (set location to .TTF/.OTF file )
+## Set font for the whole hud
+# font_file=
+
+## Set font only for text like media player metadata
+# font_file_text=
+
+## Set font glyph ranges. Defaults to latin-only. Don't forget to set font_file/text_font_file to font that supports these.
+## Probably don't enable all at once because of memory usage and hardware limits concerns.
+## If you experience crashes or text is just squares, reduce glyph range or reduce font size.
+# font_glyph_ranges=korean, chinese, chinese_simplified, japanese, cyrillic, thai, vietnamese, latin_ext_a, latin_ext_b
+
### Change the hud position (default is top-left)
position=top-left
@@ -91,9 +105,6 @@ background_alpha=0.5
# background_color=020202
# media_player_color=FFFFFF
-### Change default font (set location to .TTF/.OTF file )
-# font_file
-
### Show media player metadata
# media_player
# media_player_name = spotify
@@ -118,4 +129,4 @@ background_alpha=0.5
### Define name and location of the output file (Required for logging)
# output_file
### Permit uploading logs directly to Flightlessmango.com
-# permit_upload=1
\ No newline at end of file
+# permit_upload=1
diff --git a/src/gl/imgui_hud.cpp b/src/gl/imgui_hud.cpp
index f23b12e8..bde2dbac 100644
--- a/src/gl/imgui_hud.cpp
+++ b/src/gl/imgui_hud.cpp
@@ -45,8 +45,6 @@ struct GLVec
struct state {
ImGuiContext *imgui_ctx = nullptr;
- ImFont* font = nullptr;
- ImFont* font1 = nullptr;
};
static GLVec last_vp {}, last_sb {};
@@ -133,8 +131,7 @@ void imgui_create(void *ctx)
GLint current_texture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
- create_fonts(params, state.font, state.font1);
- sw_stats.font1 = state.font1;
+ create_fonts(params, sw_stats.font1, sw_stats.font_text);
// Restore global context or ours might clash with apps that use Dear ImGui
ImGui::SetCurrentContext(saved_ctx);
diff --git a/src/gl/imgui_impl_opengl3.cpp b/src/gl/imgui_impl_opengl3.cpp
index 92bcdce2..38633d23 100644
--- a/src/gl/imgui_impl_opengl3.cpp
+++ b/src/gl/imgui_impl_opengl3.cpp
@@ -72,6 +72,8 @@
#include
+#include "overlay.h"
+
namespace MangoHud {
// Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have.
@@ -110,7 +112,7 @@ static bool ImGui_ImplOpenGL3_CreateFontsTexture()
ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels;
int width, height;
- io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
+ io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height);
// Upload texture to graphics system
GLint last_texture;
@@ -123,7 +125,14 @@ static bool ImGui_ImplOpenGL3_CreateFontsTexture()
if (g_IsGLES || g_GlVersion >= 200)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ // FIXME can compress?
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels);
+
+#ifndef NDEBUG
+ GLint compFlag= 0;
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &compFlag);
+ fprintf(stderr, "GL tex compressed: %s\n", compFlag ? "yes" : "no");
+#endif
// Store our identifier
io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture;
@@ -252,7 +261,7 @@ static bool ImGui_ImplOpenGL3_CreateDeviceObjects()
"varying vec4 Frag_Color;\n"
"void main()\n"
"{\n"
- " gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n"
+ " gl_FragColor = Frag_Color * vec4(1, 1, 1, texture2D(Texture, Frag_UV.st).a);\n"
"}\n";
const GLchar* fragment_shader_glsl_130 =
@@ -262,7 +271,7 @@ static bool ImGui_ImplOpenGL3_CreateDeviceObjects()
"out vec4 Out_Color;\n"
"void main()\n"
"{\n"
- " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
+ " Out_Color = Frag_Color * vec4(1, 1, 1, texture(Texture, Frag_UV.st).a);\n"
"}\n";
const GLchar* fragment_shader_glsl_300_es =
@@ -273,7 +282,7 @@ static bool ImGui_ImplOpenGL3_CreateDeviceObjects()
"layout (location = 0) out vec4 Out_Color;\n"
"void main()\n"
"{\n"
- " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
+ " Out_Color = Frag_Color * vec4(1, 1, 1, texture(Texture, Frag_UV.st).a);\n"
"}\n";
const GLchar* fragment_shader_glsl_410_core =
@@ -283,7 +292,7 @@ static bool ImGui_ImplOpenGL3_CreateDeviceObjects()
"layout (location = 0) out vec4 Out_Color;\n"
"void main()\n"
"{\n"
- " Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n"
+ " Out_Color = Frag_Color * vec4(1, 1, 1, texture(Texture, Frag_UV.st).a);\n"
"}\n";
#ifndef NDEBUG
@@ -547,7 +556,7 @@ 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)
+ if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount == 0)
return;
// Backup GL state
diff --git a/src/overlay.cpp b/src/overlay.cpp
index ed189b10..902ceb4f 100644
--- a/src/overlay.cpp
+++ b/src/overlay.cpp
@@ -181,7 +181,6 @@ struct swapchain_data {
std::list draws; /* List of struct overlay_draw */
- ImFont* font = nullptr;
bool font_uploaded;
VkImage font_image;
VkImageView font_image_view;
@@ -253,39 +252,80 @@ static void unmap_object(uint64_t obj)
/**/
-void create_fonts(const overlay_params& params, ImFont*& default_font, ImFont*& small_font)
+#define CHAR_CELSIUS "\xe2\x84\x83"
+#define CHAR_FAHRENHEIT "\xe2\x84\x89"
+
+void create_fonts(const overlay_params& params, ImFont*& small_font, ImFont*& text_font)
{
auto& io = ImGui::GetIO();
- int font_size = params.font_size;
- if (!font_size)
+ float font_size = params.font_size;
+ if (font_size < FLT_EPSILON)
font_size = 24;
- static const ImWchar glyph_ranges[] =
+ float font_size_text = params.font_size_text;
+ if (font_size_text < FLT_EPSILON)
+ font_size_text = font_size;
+
+ static const ImWchar default_range[] =
{
0x0020, 0x00FF, // Basic Latin + Latin Supplement
- 0x0100, 0x017f, // Latin Extended-A
- 0x0400, 0x052F, // Cyrillic + Cyrillic Supplement
- 0x2DE0, 0x2DFF, // Cyrillic Extended-A
- 0xA640, 0xA69F, // Cyrillic Extended-B
+ //0x0100, 0x017F, // Latin Extended-A
+ //0x2103, 0x2103, // Degree Celsius
+ //0x2109, 0x2109, // Degree Fahrenheit
0,
};
+ ImVector glyph_ranges;
+ ImFontGlyphRangesBuilder builder;
+ builder.AddRanges(io.Fonts->GetGlyphRangesDefault());
+ if (params.font_glyph_ranges & FG_KOREAN)
+ builder.AddRanges(io.Fonts->GetGlyphRangesKorean());
+ if (params.font_glyph_ranges & FG_CHINESE_FULL)
+ builder.AddRanges(io.Fonts->GetGlyphRangesChineseFull());
+ if (params.font_glyph_ranges & FG_CHINESE_SIMPLIFIED)
+ builder.AddRanges(io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
+ if (params.font_glyph_ranges & FG_JAPANESE)
+ builder.AddRanges(io.Fonts->GetGlyphRangesJapanese()); // Not exactly Shift JIS compatible?
+ if (params.font_glyph_ranges & FG_CYRILLIC)
+ builder.AddRanges(io.Fonts->GetGlyphRangesCyrillic());
+ if (params.font_glyph_ranges & FG_THAI)
+ builder.AddRanges(io.Fonts->GetGlyphRangesThai());
+ if (params.font_glyph_ranges & FG_VIETNAMESE)
+ builder.AddRanges(io.Fonts->GetGlyphRangesVietnamese());
+ if (params.font_glyph_ranges & FG_LATIN_EXT_A) {
+ static const ImWchar latin_ext_a[] { 0x0100, 0x017F, 0 };
+ builder.AddRanges(latin_ext_a);
+ }
+ if (params.font_glyph_ranges & FG_LATIN_EXT_B) {
+ static const ImWchar latin_ext_b[] { 0x0180, 0x024F, 0 };
+ builder.AddRanges(latin_ext_b);
+ }
+ builder.BuildRanges(&glyph_ranges);
+
+ // If both font_file and text_font_file are the same then just use "default" font
+ bool same_font = (params.font_file == params.font_file_text || params.font_file_text.empty());
+ bool same_size = (font_size == font_size_text);
+
// ImGui takes ownership of the data, no need to free it
if (!params.font_file.empty() && file_exists(params.font_file)) {
- default_font = io.Fonts->AddFontFromFileTTF(params.font_file.c_str(), font_size, nullptr, glyph_ranges);
- small_font = io.Fonts->AddFontFromFileTTF(params.font_file.c_str(), font_size * 0.55f, nullptr, io.Fonts->GetGlyphRangesDefault());
+ io.Fonts->AddFontFromFileTTF(params.font_file.c_str(), font_size, nullptr, same_font && same_size ? glyph_ranges.Data : default_range);
+ small_font = io.Fonts->AddFontFromFileTTF(params.font_file.c_str(), font_size * 0.55f, nullptr, default_range);
} else {
const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85();
- default_font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size, nullptr, io.Fonts->GetGlyphRangesDefault());
- small_font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size * 0.55, nullptr, io.Fonts->GetGlyphRangesDefault());
+ io.Fonts->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size, nullptr, default_range);
+ small_font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_size * 0.55f, nullptr, default_range);
}
-}
-// FIXME "temporary" hack until Dear ImGui has an actual API for this
-void scale_default_font(ImFont& scaled_font, float scale)
-{
- scaled_font = *ImGui::GetIO().Fonts->Fonts[0];
- scaled_font.Scale = scale;
+ auto font_file_text = params.font_file_text;
+ if (font_file_text.empty())
+ font_file_text = params.font_file;
+
+ if ((!same_font || !same_size) && file_exists(font_file_text))
+ text_font = io.Fonts->AddFontFromFileTTF(font_file_text.c_str(), font_size_text, nullptr, glyph_ranges.Data);
+ else
+ text_font = io.Fonts->Fonts[0];
+
+ io.Fonts->Build();
}
static VkLayerInstanceCreateInfo *get_instance_chain_info(const VkInstanceCreateInfo *pCreateInfo,
@@ -1044,7 +1084,7 @@ static void render_mpris_metadata(struct overlay_params& params, metadata& meta,
void render_benchmark(swapchain_stats& data, struct overlay_params& params, ImVec2& window_size, unsigned height, Clock::time_point now){
// TODO, FIX LOG_DURATION FOR BENCHMARK
- int benchHeight = 6 * params.font_size + 10.0f + 58;
+ int benchHeight = 6 * params.font_size * params.font_scale + 10.0f + 58;
ImGui::SetNextWindowSize(ImVec2(window_size.x, benchHeight), ImGuiCond_Always);
if (height - (window_size.y + data.main_window_pos.y + 5) < benchHeight)
ImGui::SetNextWindowPos(ImVec2(data.main_window_pos.x, data.main_window_pos.y - benchHeight - 5), ImGuiCond_Always);
@@ -1111,6 +1151,7 @@ void render_benchmark(swapchain_stats& data, struct overlay_params& params, ImVe
void render_imgui(swapchain_stats& data, struct overlay_params& params, ImVec2& window_size, bool is_vulkan)
{
+ ImGui::GetIO().FontGlobalScale = params.font_scale;
uint32_t f_idx = (data.n_frames - 1) % ARRAY_SIZE(data.frames_stats);
uint64_t frame_timing = data.frames_stats[f_idx].stats[OVERLAY_PLOTS_frame_timing];
static float char_width = ImGui::CalcTextSize("A").x;
@@ -1349,7 +1390,7 @@ void render_imgui(swapchain_stats& data, struct overlay_params& params, ImVec2&
}
if (params.enabled[OVERLAY_PARAM_ENABLED_frame_timing]){
- ImGui::Dummy(ImVec2(0.0f, params.font_size / 2));
+ ImGui::Dummy(ImVec2(0.0f, params.font_size * params.font_scale / 2));
ImGui::PushFont(data.font1);
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(params.engine_color), "%s", "Frametime");
ImGui::PopFont();
@@ -1366,12 +1407,12 @@ void render_imgui(swapchain_stats& data, struct overlay_params& params, ImVec2&
ImGui::PlotHistogram(hash, get_time_stat, &data,
ARRAY_SIZE(data.frames_stats), 0,
NULL, min_time, max_time,
- ImVec2(ImGui::GetContentRegionAvailWidth() - params.font_size * 2.2, 50));
+ ImVec2(ImGui::GetContentRegionAvailWidth() - params.font_size * params.font_scale * 2.2, 50));
} else {
ImGui::PlotLines(hash, get_time_stat, &data,
ARRAY_SIZE(data.frames_stats), 0,
NULL, min_time, max_time,
- ImVec2(ImGui::GetContentRegionAvailWidth() - params.font_size * 2.2, 50));
+ ImVec2(ImGui::GetContentRegionAvailWidth() - params.font_size * params.font_scale * 2.2, 50));
}
ImGui::PopStyleColor();
}
@@ -1383,8 +1424,8 @@ void render_imgui(swapchain_stats& data, struct overlay_params& params, ImVec2&
}
#ifdef HAVE_DBUS
- ImFont scaled_font;
- scale_default_font(scaled_font, params.font_scale_media_player);
+ ImFont scaled_font = *data.font_text;
+ scaled_font.Scale = params.font_scale_media_player;
ImGui::PushFont(&scaled_font);
render_mpris_metadata(params, main_metadata, frame_timing, true);
render_mpris_metadata(params, generic_mpris, frame_timing, false);
@@ -1436,21 +1477,33 @@ static uint32_t vk_memory_type(struct device_data *data,
return 0xFFFFFFFF; // Unable to find memoryType
}
-static void ensure_swapchain_fonts(struct swapchain_data *data,
- VkCommandBuffer command_buffer)
+static void update_image_descriptor(struct swapchain_data *data, VkImageView image_view, VkDescriptorSet set)
{
- if (data->font_uploaded)
- return;
-
- data->font_uploaded = true;
-
struct device_data *device_data = data->device;
- ImGuiIO& io = ImGui::GetIO();
- unsigned char* pixels;
- int width, height;
- io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
- size_t upload_size = width * height * 4 * sizeof(char);
+ /* Descriptor set */
+ VkDescriptorImageInfo desc_image[1] = {};
+ desc_image[0].sampler = data->font_sampler;
+ desc_image[0].imageView = image_view;
+ desc_image[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ VkWriteDescriptorSet write_desc[1] = {};
+ write_desc[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_desc[0].dstSet = set;
+ write_desc[0].descriptorCount = 1;
+ write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ write_desc[0].pImageInfo = desc_image;
+ device_data->vtable.UpdateDescriptorSets(device_data->device, 1, write_desc, 0, NULL);
+}
+static void upload_image_data(struct device_data *device_data,
+ VkCommandBuffer command_buffer,
+ void *pixels,
+ VkDeviceSize upload_size,
+ uint32_t width,
+ uint32_t height,
+ VkBuffer& upload_buffer,
+ VkDeviceMemory& upload_buffer_mem,
+ VkImage image)
+{
/* Upload buffer */
VkBufferCreateInfo buffer_info = {};
buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@@ -1458,10 +1511,10 @@ static void ensure_swapchain_fonts(struct swapchain_data *data,
buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VK_CHECK(device_data->vtable.CreateBuffer(device_data->device, &buffer_info,
- NULL, &data->upload_font_buffer));
+ NULL, &upload_buffer));
VkMemoryRequirements upload_buffer_req;
device_data->vtable.GetBufferMemoryRequirements(device_data->device,
- data->upload_font_buffer,
+ upload_buffer,
&upload_buffer_req);
VkMemoryAllocateInfo upload_alloc_info = {};
upload_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
@@ -1472,24 +1525,24 @@ static void ensure_swapchain_fonts(struct swapchain_data *data,
VK_CHECK(device_data->vtable.AllocateMemory(device_data->device,
&upload_alloc_info,
NULL,
- &data->upload_font_buffer_mem));
+ &upload_buffer_mem));
VK_CHECK(device_data->vtable.BindBufferMemory(device_data->device,
- data->upload_font_buffer,
- data->upload_font_buffer_mem, 0));
+ upload_buffer,
+ upload_buffer_mem, 0));
/* Upload to Buffer */
char* map = NULL;
VK_CHECK(device_data->vtable.MapMemory(device_data->device,
- data->upload_font_buffer_mem,
+ upload_buffer_mem,
0, upload_size, 0, (void**)(&map)));
memcpy(map, pixels, upload_size);
VkMappedMemoryRange range[1] = {};
range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
- range[0].memory = data->upload_font_buffer_mem;
+ range[0].memory = upload_buffer_mem;
range[0].size = upload_size;
VK_CHECK(device_data->vtable.FlushMappedMemoryRanges(device_data->device, 1, range));
device_data->vtable.UnmapMemory(device_data->device,
- data->upload_font_buffer_mem);
+ upload_buffer_mem);
/* Copy buffer to image */
VkImageMemoryBarrier copy_barrier[1] = {};
@@ -1499,7 +1552,7 @@ static void ensure_swapchain_fonts(struct swapchain_data *data,
copy_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
copy_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
copy_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- copy_barrier[0].image = data->font_image;
+ copy_barrier[0].image = image;
copy_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_barrier[0].subresourceRange.levelCount = 1;
copy_barrier[0].subresourceRange.layerCount = 1;
@@ -1516,8 +1569,8 @@ static void ensure_swapchain_fonts(struct swapchain_data *data,
region.imageExtent.height = height;
region.imageExtent.depth = 1;
device_data->vtable.CmdCopyBufferToImage(command_buffer,
- data->upload_font_buffer,
- data->font_image,
+ upload_buffer,
+ image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, ®ion);
@@ -1529,7 +1582,7 @@ static void ensure_swapchain_fonts(struct swapchain_data *data,
use_barrier[0].newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
use_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
use_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- use_barrier[0].image = data->font_image;
+ use_barrier[0].image = image;
use_barrier[0].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
use_barrier[0].subresourceRange.levelCount = 1;
use_barrier[0].subresourceRange.layerCount = 1;
@@ -1540,9 +1593,90 @@ static void ensure_swapchain_fonts(struct swapchain_data *data,
0, NULL,
0, NULL,
1, use_barrier);
+}
- /* Store our identifier */
- io.Fonts->TexID = (ImTextureID)(intptr_t)data->font_image;
+static VkDescriptorSet create_image_with_desc(struct swapchain_data *data,
+ uint32_t width,
+ uint32_t height,
+ VkFormat format,
+ VkImage& image,
+ VkDeviceMemory& image_mem,
+ VkImageView& image_view)
+{
+ struct device_data *device_data = data->device;
+
+ VkImageCreateInfo image_info = {};
+ image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ image_info.imageType = VK_IMAGE_TYPE_2D;
+ image_info.format = format;
+ image_info.extent.width = width;
+ image_info.extent.height = height;
+ image_info.extent.depth = 1;
+ image_info.mipLevels = 1;
+ image_info.arrayLayers = 1;
+ image_info.samples = VK_SAMPLE_COUNT_1_BIT;
+ image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+ image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ VK_CHECK(device_data->vtable.CreateImage(device_data->device, &image_info,
+ NULL, &image));
+ VkMemoryRequirements font_image_req;
+ device_data->vtable.GetImageMemoryRequirements(device_data->device,
+ image, &font_image_req);
+ VkMemoryAllocateInfo image_alloc_info = {};
+ image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ image_alloc_info.allocationSize = font_image_req.size;
+ image_alloc_info.memoryTypeIndex = vk_memory_type(device_data,
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+ font_image_req.memoryTypeBits);
+ VK_CHECK(device_data->vtable.AllocateMemory(device_data->device, &image_alloc_info,
+ NULL, &image_mem));
+ VK_CHECK(device_data->vtable.BindImageMemory(device_data->device,
+ image,
+ image_mem, 0));
+
+ /* Font image view */
+ VkImageViewCreateInfo view_info = {};
+ view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ view_info.image = image;
+ view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ view_info.format = format;
+ view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ view_info.subresourceRange.levelCount = 1;
+ view_info.subresourceRange.layerCount = 1;
+ VK_CHECK(device_data->vtable.CreateImageView(device_data->device, &view_info,
+ NULL, &image_view));
+
+ VkDescriptorSet descriptor_set;
+
+ VkDescriptorSetAllocateInfo alloc_info = {};
+ alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+ alloc_info.descriptorPool = data->descriptor_pool;
+ alloc_info.descriptorSetCount = 1;
+ alloc_info.pSetLayouts = &data->descriptor_layout;
+ VK_CHECK(device_data->vtable.AllocateDescriptorSets(device_data->device,
+ &alloc_info,
+ &descriptor_set));
+
+ update_image_descriptor(data, image_view, descriptor_set);
+ return descriptor_set;
+}
+
+static void ensure_swapchain_fonts(struct swapchain_data *data,
+ VkCommandBuffer command_buffer)
+{
+ struct device_data *device_data = data->device;
+ if (data->font_uploaded)
+ return;
+
+ data->font_uploaded = true;
+ ImGuiIO& io = ImGui::GetIO();
+ unsigned char* pixels;
+ int width, height;
+ io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height);
+ size_t upload_size = width * height * 1 * sizeof(char);
+ upload_image_data(device_data, command_buffer, pixels, upload_size, width, height, data->upload_font_buffer, data->upload_font_buffer_mem, data->font_image);
}
static void CreateOrResizeBuffer(struct device_data *data,
@@ -1652,100 +1786,110 @@ static struct overlay_draw *render_swapchain_display(struct swapchain_data *data
index_size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
}
- /* Upload vertex & index data */
- ImDrawVert* vtx_dst = NULL;
- ImDrawIdx* idx_dst = NULL;
- VK_CHECK(device_data->vtable.MapMemory(device_data->device, draw->vertex_buffer_mem,
- 0, vertex_size, 0, (void**)(&vtx_dst)));
- VK_CHECK(device_data->vtable.MapMemory(device_data->device, draw->index_buffer_mem,
- 0, index_size, 0, (void**)(&idx_dst)));
- for (int n = 0; n < draw_data->CmdListsCount; n++)
- {
- const ImDrawList* cmd_list = draw_data->CmdLists[n];
- memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
- memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
- vtx_dst += cmd_list->VtxBuffer.Size;
- idx_dst += cmd_list->IdxBuffer.Size;
- }
- VkMappedMemoryRange range[2] = {};
- range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
- range[0].memory = draw->vertex_buffer_mem;
- range[0].size = VK_WHOLE_SIZE;
- range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
- range[1].memory = draw->index_buffer_mem;
- range[1].size = VK_WHOLE_SIZE;
- VK_CHECK(device_data->vtable.FlushMappedMemoryRanges(device_data->device, 2, range));
- device_data->vtable.UnmapMemory(device_data->device, draw->vertex_buffer_mem);
- device_data->vtable.UnmapMemory(device_data->device, draw->index_buffer_mem);
-
- /* Bind pipeline and descriptor sets */
- device_data->vtable.CmdBindPipeline(draw->command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, data->pipeline);
- VkDescriptorSet desc_set[1] = { data->descriptor_set };
- device_data->vtable.CmdBindDescriptorSets(draw->command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
- data->pipeline_layout, 0, 1, desc_set, 0, NULL);
-
- /* Bind vertex & index buffers */
- VkBuffer vertex_buffers[1] = { draw->vertex_buffer };
- VkDeviceSize vertex_offset[1] = { 0 };
- device_data->vtable.CmdBindVertexBuffers(draw->command_buffer, 0, 1, vertex_buffers, vertex_offset);
- device_data->vtable.CmdBindIndexBuffer(draw->command_buffer, draw->index_buffer, 0, VK_INDEX_TYPE_UINT16);
-
- /* Setup viewport */
- VkViewport viewport;
- viewport.x = 0;
- viewport.y = 0;
- viewport.width = draw_data->DisplaySize.x;
- viewport.height = draw_data->DisplaySize.y;
- viewport.minDepth = 0.0f;
- viewport.maxDepth = 1.0f;
- device_data->vtable.CmdSetViewport(draw->command_buffer, 0, 1, &viewport);
-
-
- /* Setup scale and translation through push constants :
- *
- * Our visible imgui space lies from draw_data->DisplayPos (top left) to
- * draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin
- * is typically (0,0) for single viewport apps.
- */
- float scale[2];
- scale[0] = 2.0f / draw_data->DisplaySize.x;
- scale[1] = 2.0f / draw_data->DisplaySize.y;
- float translate[2];
- translate[0] = -1.0f - draw_data->DisplayPos.x * scale[0];
- translate[1] = -1.0f - draw_data->DisplayPos.y * scale[1];
- device_data->vtable.CmdPushConstants(draw->command_buffer, data->pipeline_layout,
- VK_SHADER_STAGE_VERTEX_BIT,
- sizeof(float) * 0, sizeof(float) * 2, scale);
- device_data->vtable.CmdPushConstants(draw->command_buffer, data->pipeline_layout,
- VK_SHADER_STAGE_VERTEX_BIT,
- sizeof(float) * 2, sizeof(float) * 2, translate);
-
- // Render the command lists:
- int vtx_offset = 0;
- int idx_offset = 0;
- ImVec2 display_pos = draw_data->DisplayPos;
- for (int n = 0; n < draw_data->CmdListsCount; n++)
- {
- const ImDrawList* cmd_list = draw_data->CmdLists[n];
- for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
- {
- const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
- // Apply scissor/clipping rectangle
- // FIXME: We could clamp width/height based on clamped min/max values.
- VkRect2D scissor;
- scissor.offset.x = (int32_t)(pcmd->ClipRect.x - display_pos.x) > 0 ? (int32_t)(pcmd->ClipRect.x - display_pos.x) : 0;
- scissor.offset.y = (int32_t)(pcmd->ClipRect.y - display_pos.y) > 0 ? (int32_t)(pcmd->ClipRect.y - display_pos.y) : 0;
- scissor.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x);
- scissor.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // FIXME: Why +1 here?
- device_data->vtable.CmdSetScissor(draw->command_buffer, 0, 1, &scissor);
-
- // Draw
- device_data->vtable.CmdDrawIndexed(draw->command_buffer, pcmd->ElemCount, 1, idx_offset, vtx_offset, 0);
-
- idx_offset += pcmd->ElemCount;
- }
- vtx_offset += cmd_list->VtxBuffer.Size;
- }
+ /* Upload vertex & index data */
+ ImDrawVert* vtx_dst = NULL;
+ ImDrawIdx* idx_dst = NULL;
+ VK_CHECK(device_data->vtable.MapMemory(device_data->device, draw->vertex_buffer_mem,
+ 0, vertex_size, 0, (void**)(&vtx_dst)));
+ VK_CHECK(device_data->vtable.MapMemory(device_data->device, draw->index_buffer_mem,
+ 0, index_size, 0, (void**)(&idx_dst)));
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
+ {
+ const ImDrawList* cmd_list = draw_data->CmdLists[n];
+ memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
+ memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
+ vtx_dst += cmd_list->VtxBuffer.Size;
+ idx_dst += cmd_list->IdxBuffer.Size;
+ }
+ VkMappedMemoryRange range[2] = {};
+ range[0].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+ range[0].memory = draw->vertex_buffer_mem;
+ range[0].size = VK_WHOLE_SIZE;
+ range[1].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+ range[1].memory = draw->index_buffer_mem;
+ range[1].size = VK_WHOLE_SIZE;
+ VK_CHECK(device_data->vtable.FlushMappedMemoryRanges(device_data->device, 2, range));
+ device_data->vtable.UnmapMemory(device_data->device, draw->vertex_buffer_mem);
+ device_data->vtable.UnmapMemory(device_data->device, draw->index_buffer_mem);
+
+ /* Bind pipeline and descriptor sets */
+ device_data->vtable.CmdBindPipeline(draw->command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, data->pipeline);
+
+#if 1 // disable if using >1 font textures
+ VkDescriptorSet desc_set[1] = {
+ //data->descriptor_set
+ reinterpret_cast(ImGui::GetIO().Fonts->Fonts[0]->ContainerAtlas->TexID)
+ };
+ device_data->vtable.CmdBindDescriptorSets(draw->command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
+ data->pipeline_layout, 0, 1, desc_set, 0, NULL);
+#endif
+
+ /* Bind vertex & index buffers */
+ VkBuffer vertex_buffers[1] = { draw->vertex_buffer };
+ VkDeviceSize vertex_offset[1] = { 0 };
+ device_data->vtable.CmdBindVertexBuffers(draw->command_buffer, 0, 1, vertex_buffers, vertex_offset);
+ device_data->vtable.CmdBindIndexBuffer(draw->command_buffer, draw->index_buffer, 0, VK_INDEX_TYPE_UINT16);
+
+ /* Setup viewport */
+ VkViewport viewport;
+ viewport.x = 0;
+ viewport.y = 0;
+ viewport.width = draw_data->DisplaySize.x;
+ viewport.height = draw_data->DisplaySize.y;
+ viewport.minDepth = 0.0f;
+ viewport.maxDepth = 1.0f;
+ device_data->vtable.CmdSetViewport(draw->command_buffer, 0, 1, &viewport);
+
+
+ /* Setup scale and translation through push constants :
+ *
+ * Our visible imgui space lies from draw_data->DisplayPos (top left) to
+ * draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin
+ * is typically (0,0) for single viewport apps.
+ */
+ float scale[2];
+ scale[0] = 2.0f / draw_data->DisplaySize.x;
+ scale[1] = 2.0f / draw_data->DisplaySize.y;
+ float translate[2];
+ translate[0] = -1.0f - draw_data->DisplayPos.x * scale[0];
+ translate[1] = -1.0f - draw_data->DisplayPos.y * scale[1];
+ device_data->vtable.CmdPushConstants(draw->command_buffer, data->pipeline_layout,
+ VK_SHADER_STAGE_VERTEX_BIT,
+ sizeof(float) * 0, sizeof(float) * 2, scale);
+ device_data->vtable.CmdPushConstants(draw->command_buffer, data->pipeline_layout,
+ VK_SHADER_STAGE_VERTEX_BIT,
+ sizeof(float) * 2, sizeof(float) * 2, translate);
+
+ // Render the command lists:
+ int vtx_offset = 0;
+ int idx_offset = 0;
+ ImVec2 display_pos = draw_data->DisplayPos;
+ for (int n = 0; n < draw_data->CmdListsCount; n++)
+ {
+ const ImDrawList* cmd_list = draw_data->CmdLists[n];
+ for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
+ {
+ const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
+ // Apply scissor/clipping rectangle
+ // FIXME: We could clamp width/height based on clamped min/max values.
+ VkRect2D scissor;
+ scissor.offset.x = (int32_t)(pcmd->ClipRect.x - display_pos.x) > 0 ? (int32_t)(pcmd->ClipRect.x - display_pos.x) : 0;
+ scissor.offset.y = (int32_t)(pcmd->ClipRect.y - display_pos.y) > 0 ? (int32_t)(pcmd->ClipRect.y - display_pos.y) : 0;
+ scissor.extent.width = (uint32_t)(pcmd->ClipRect.z - pcmd->ClipRect.x);
+ scissor.extent.height = (uint32_t)(pcmd->ClipRect.w - pcmd->ClipRect.y + 1); // FIXME: Why +1 here?
+ device_data->vtable.CmdSetScissor(draw->command_buffer, 0, 1, &scissor);
+#if 0 //enable if using >1 font textures or use texture array
+ VkDescriptorSet desc_set[1] = { (VkDescriptorSet)pcmd->TextureId };
+ device_data->vtable.CmdBindDescriptorSets(draw->command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
+ data->pipeline_layout, 0, 1, desc_set, 0, NULL);
+#endif
+ // Draw
+ device_data->vtable.CmdDrawIndexed(draw->command_buffer, pcmd->ElemCount, 1, idx_offset, vtx_offset, 0);
+
+ idx_offset += pcmd->ElemCount;
+ }
+ vtx_offset += cmd_list->VtxBuffer.Size;
+ }
device_data->vtable.CmdEndRenderPass(draw->command_buffer);
@@ -1896,6 +2040,7 @@ static void setup_swapchain_data_pipeline(struct swapchain_data *data)
NULL, &data->descriptor_layout));
/* Descriptor set */
+/*
VkDescriptorSetAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloc_info.descriptorPool = data->descriptor_pool;
@@ -1904,6 +2049,7 @@ static void setup_swapchain_data_pipeline(struct swapchain_data *data)
VK_CHECK(device_data->vtable.AllocateDescriptorSets(device_data->device,
&alloc_info,
&data->descriptor_set));
+*/
/* Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full
* 3d projection matrix
@@ -2025,68 +2171,21 @@ static void setup_swapchain_data_pipeline(struct swapchain_data *data)
device_data->vtable.DestroyShaderModule(device_data->device, vert_module, NULL);
device_data->vtable.DestroyShaderModule(device_data->device, frag_module, NULL);
+ create_fonts(device_data->instance->params, data->sw_stats.font1, data->sw_stats.font_text);
+
ImGuiIO& io = ImGui::GetIO();
- create_fonts(device_data->instance->params, data->font, data->sw_stats.font1);
unsigned char* pixels;
int width, height;
- io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
-
- /* Font image */
- VkImageCreateInfo image_info = {};
- image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
- image_info.imageType = VK_IMAGE_TYPE_2D;
- image_info.format = VK_FORMAT_R8G8B8A8_UNORM;
- image_info.extent.width = width;
- image_info.extent.height = height;
- image_info.extent.depth = 1;
- image_info.mipLevels = 1;
- image_info.arrayLayers = 1;
- image_info.samples = VK_SAMPLE_COUNT_1_BIT;
- image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
- image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
- image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- VK_CHECK(device_data->vtable.CreateImage(device_data->device, &image_info,
- NULL, &data->font_image));
- VkMemoryRequirements font_image_req;
- device_data->vtable.GetImageMemoryRequirements(device_data->device,
- data->font_image, &font_image_req);
- VkMemoryAllocateInfo image_alloc_info = {};
- image_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- image_alloc_info.allocationSize = font_image_req.size;
- image_alloc_info.memoryTypeIndex = vk_memory_type(device_data,
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
- font_image_req.memoryTypeBits);
- VK_CHECK(device_data->vtable.AllocateMemory(device_data->device, &image_alloc_info,
- NULL, &data->font_mem));
- VK_CHECK(device_data->vtable.BindImageMemory(device_data->device,
- data->font_image,
- data->font_mem, 0));
- /* Font image view */
- VkImageViewCreateInfo view_info = {};
- view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
- view_info.image = data->font_image;
- view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
- view_info.format = VK_FORMAT_R8G8B8A8_UNORM;
- view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- view_info.subresourceRange.levelCount = 1;
- view_info.subresourceRange.layerCount = 1;
- VK_CHECK(device_data->vtable.CreateImageView(device_data->device, &view_info,
- NULL, &data->font_image_view));
+ // upload default font to VkImage
+ io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height);
+ io.Fonts->TexID = (ImTextureID)create_image_with_desc(data, width, height, VK_FORMAT_R8_UNORM, data->font_image, data->font_mem, data->font_image_view);
+#ifndef NDEBUG
+ std::cerr << "MANGOHUD: Default font tex size: " << width << "x" << height << "px (" << (width*height*1) << " bytes)" << "\n";
+#endif
- /* Descriptor set */
- VkDescriptorImageInfo desc_image[1] = {};
- desc_image[0].sampler = data->font_sampler;
- desc_image[0].imageView = data->font_image_view;
- desc_image[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- VkWriteDescriptorSet write_desc[1] = {};
- write_desc[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- write_desc[0].dstSet = data->descriptor_set;
- write_desc[0].descriptorCount = 1;
- write_desc[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
- write_desc[0].pImageInfo = desc_image;
- device_data->vtable.UpdateDescriptorSets(device_data->device, 1, write_desc, 0, NULL);
+// if (data->descriptor_set)
+// update_image_descriptor(data, data->font_image_view[0], data->descriptor_set);
}
void imgui_custom_style(struct overlay_params& params){
@@ -2710,9 +2809,9 @@ static VkResult overlay_CreateInstance(
// Adjust height for DXVK/VKD3D version number
if (engineName == "DXVK" || engineName == "VKD3D"){
if (instance_data->params.font_size){
- instance_data->params.height += instance_data->params.font_size / 2;
+ instance_data->params.height += instance_data->params.font_size * instance_data->params.font_scale / 2;
} else {
- instance_data->params.height += 24 / 2;
+ instance_data->params.height += 24 * instance_data->params.font_scale / 2;
}
}
diff --git a/src/overlay.frag b/src/overlay.frag
index 313a8880..dc6bb007 100644
--- a/src/overlay.frag
+++ b/src/overlay.frag
@@ -10,5 +10,5 @@ layout(location = 0) in struct{
void main()
{
- fColor = In.Color * texture(sTexture, In.UV.st);
+ fColor = In.Color * vec4(1, 1, 1, texture(sTexture, In.UV.st).r);
}
diff --git a/src/overlay.h b/src/overlay.h
index cb66dcc8..67e1a579 100644
--- a/src/overlay.h
+++ b/src/overlay.h
@@ -1,3 +1,5 @@
+#pragma once
+
#include
#include
#include
@@ -18,6 +20,7 @@ struct swapchain_stats {
struct frame_stat frames_stats[200];
ImFont* font1 = nullptr;
+ ImFont* font_text = nullptr;
std::string time;
double fps;
struct iostats io;
@@ -77,4 +80,4 @@ void FpsLimiter(struct fps_limit& stats);
void imgui_custom_style(struct overlay_params& params);
void get_device_name(int32_t vendorID, int32_t deviceID, struct swapchain_stats& sw_stats);
void calculate_benchmark_data(void);
-void create_fonts(const overlay_params& params, ImFont*& default_font, ImFont*& small_font);
+void create_fonts(const overlay_params& params, ImFont*& small_font, ImFont*& text_font);
diff --git a/src/overlay_params.cpp b/src/overlay_params.cpp
index 39556f16..a597be2e 100644
--- a/src/overlay_params.cpp
+++ b/src/overlay_params.cpp
@@ -202,6 +202,38 @@ parse_media_player_order(const char *str)
return order;
}
+static uint32_t
+parse_font_glyph_ranges(const char *str)
+{
+ uint32_t fg = 0;
+ std::stringstream ss(str);
+ std::string token;
+ while (std::getline(ss, token, ',')) {
+ trim(token);
+ std::transform(token.begin(), token.end(), token.begin(), ::tolower);
+
+ if (token == "korean")
+ fg |= FG_KOREAN;
+ else if (token == "chinese")
+ fg |= FG_CHINESE_FULL;
+ else if (token == "chinese_simplified")
+ fg |= FG_CHINESE_SIMPLIFIED;
+ else if (token == "japanese")
+ fg |= FG_JAPANESE;
+ else if (token == "cyrillic")
+ fg |= FG_CYRILLIC;
+ else if (token == "thai")
+ fg |= FG_THAI;
+ else if (token == "vietnamese")
+ fg |= FG_VIETNAMESE;
+ else if (token == "latin_ext_a")
+ fg |= FG_LATIN_EXT_A;
+ else if (token == "latin_ext_b")
+ fg |= FG_LATIN_EXT_B;
+ }
+ return fg;
+}
+
#define parse_width(s) parse_unsigned(s)
#define parse_height(s) parse_unsigned(s)
#define parse_vsync(s) parse_unsigned(s)
@@ -212,6 +244,7 @@ parse_media_player_order(const char *str)
#define parse_time_format(s) parse_str(s)
#define parse_output_file(s) parse_path(s)
#define parse_font_file(s) parse_path(s)
+#define parse_font_file_text(s) parse_path(s)
#define parse_io_read(s) parse_unsigned(s)
#define parse_io_write(s) parse_unsigned(s)
#define parse_pci_dev(s) parse_str(s)
@@ -221,6 +254,8 @@ parse_media_player_order(const char *str)
#define parse_gpu_text(s) parse_str(s)
#define parse_log_interval(s) parse_unsigned(s)
#define parse_font_size(s) parse_float(s)
+#define parse_font_size_text(s) parse_float(s)
+#define parse_font_scale(s) parse_float(s)
#define parse_background_alpha(s) parse_float(s)
#define parse_alpha(s) parse_float(s)
#define parse_permit_upload(s) parse_unsigned(s)
@@ -389,6 +424,7 @@ parse_overlay_config(struct overlay_params *params,
params->text_color = 0xffffff;
params->media_player_color = 0xffffff;
params->media_player_name = "spotify";
+ params->font_scale = 1.0f;
params->font_scale_media_player = 0.55f;
params->log_interval = 100;
params->media_player_order = { MP_ORDER_TITLE, MP_ORDER_ARTIST, MP_ORDER_ALBUM };
@@ -478,9 +514,9 @@ parse_overlay_config(struct overlay_params *params,
//increase hud width if io read and write
if (!params->width) {
if ((params->enabled[OVERLAY_PARAM_ENABLED_io_read] || params->enabled[OVERLAY_PARAM_ENABLED_io_write])) {
- params->width = 13 * params->font_size;
+ params->width = 13 * params->font_size * params->font_scale;
} else {
- params->width = params->font_size * 11.7;
+ params->width = params->font_size * params->font_scale * 11.7;
}
}
diff --git a/src/overlay_params.h b/src/overlay_params.h
index 05a6181b..84ebe3b0 100644
--- a/src/overlay_params.h
+++ b/src/overlay_params.h
@@ -51,6 +51,12 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_CUSTOM(fps_sampling_period) \
OVERLAY_PARAM_CUSTOM(output_file) \
OVERLAY_PARAM_CUSTOM(font_file) \
+ OVERLAY_PARAM_CUSTOM(font_file_text) \
+ OVERLAY_PARAM_CUSTOM(font_glyph_ranges) \
+ OVERLAY_PARAM_CUSTOM(font_size) \
+ OVERLAY_PARAM_CUSTOM(font_size_text) \
+ OVERLAY_PARAM_CUSTOM(font_scale) \
+ OVERLAY_PARAM_CUSTOM(font_scale_media_player) \
OVERLAY_PARAM_CUSTOM(position) \
OVERLAY_PARAM_CUSTOM(width) \
OVERLAY_PARAM_CUSTOM(height) \
@@ -59,8 +65,6 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_CUSTOM(fps_limit) \
OVERLAY_PARAM_CUSTOM(vsync) \
OVERLAY_PARAM_CUSTOM(gl_vsync) \
- OVERLAY_PARAM_CUSTOM(font_size) \
- OVERLAY_PARAM_CUSTOM(font_scale_media_player) \
OVERLAY_PARAM_CUSTOM(toggle_hud) \
OVERLAY_PARAM_CUSTOM(toggle_logging) \
OVERLAY_PARAM_CUSTOM(reload_cfg) \
@@ -111,6 +115,18 @@ enum media_player_order {
MP_ORDER_ALBUM,
};
+enum font_glyph_ranges {
+ FG_KOREAN = (1u << 0),
+ FG_CHINESE_FULL = (1u << 1),
+ FG_CHINESE_SIMPLIFIED = (1u << 2),
+ FG_JAPANESE = (1u << 3),
+ FG_CYRILLIC = (1u << 4),
+ FG_THAI = (1u << 5),
+ FG_VIETNAMESE = (1u << 6),
+ FG_LATIN_EXT_A = (1u << 7),
+ FG_LATIN_EXT_B = (1u << 8),
+};
+
enum overlay_param_enabled {
#define OVERLAY_PARAM_BOOL(name) OVERLAY_PARAM_ENABLED_##name,
#define OVERLAY_PARAM_CUSTOM(name)
@@ -139,20 +155,24 @@ struct overlay_params {
unsigned cpu_color, gpu_color, vram_color, ram_color, engine_color, io_color, frametime_color, background_color, text_color;
unsigned media_player_color;
unsigned tableCols;
- float font_size;
+ float font_size, font_scale;
+ float font_size_text;
float font_scale_media_player;
float background_alpha, alpha;
std::vector toggle_hud;
std::vector toggle_logging;
std::vector reload_cfg;
std::vector upload_log;
- std::string time_format, output_file, font_file;
+ std::string time_format, output_file;
std::string pci_dev;
std::string media_player_name;
std::string cpu_text, gpu_text;
unsigned log_interval;
std::vector media_player_order;
+ std::string font_file, font_file_text;
+ uint32_t font_glyph_ranges;
+
std::string config_file_path;
std::unordered_map options;
int permit_upload;