From 42217561d43e41ac0eab5d02e56f8a7cd1e1427c Mon Sep 17 00:00:00 2001 From: jackun Date: Tue, 24 Aug 2021 22:45:31 +0300 Subject: [PATCH] Tune shader and check orientation --- charset_ascii.txt | 2 + charset_forkawesome.txt | 1 + src/font.cpp | 109 ++++++++++++++++++++++++++-------------- src/hud_elements.cpp | 6 +++ src/overlay.frag | 36 ++++++++++--- src/vulkan.cpp | 2 + 6 files changed, 112 insertions(+), 44 deletions(-) create mode 100644 charset_ascii.txt create mode 100644 charset_forkawesome.txt diff --git a/charset_ascii.txt b/charset_ascii.txt new file mode 100644 index 0000000..75c1c55 --- /dev/null +++ b/charset_ascii.txt @@ -0,0 +1,2 @@ +[0x20, 0xFF] +[0x2018, 0x201F] \ No newline at end of file diff --git a/charset_forkawesome.txt b/charset_forkawesome.txt new file mode 100644 index 0000000..b0cd318 --- /dev/null +++ b/charset_forkawesome.txt @@ -0,0 +1 @@ +[0xF240, 0xF244] \ No newline at end of file diff --git a/src/font.cpp b/src/font.cpp index 91b0978..75d3546 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -12,7 +12,10 @@ #include "forkawesome.h" // Generate font in binary format arfont with https://github.com/Chlumsky/msdf-atlas-gen -// ./bin/msdf-atlas-gen -type mtsdf -font /usr/share/fonts/TTF/FiraSans-Regular.ttf -format bin -size 16 -pots -charset charset_ascii.txt -arfont ascii.arfont +// ./bin/msdf-atlas-gen -type mtsdf \ +// -font ~/.fonts/unispace\ rg.ttf -fontscale 1.0 -and -fontscale 0.55 -charset charset_ascii.txt \ +// -and -font ~/.fonts/forkawesome-webfont.ttf -fontscale 1.0 -charset charset_forkawesome.txt \ +// -size 18 -format bin -yorigin top -pxrange 8 -arfont mangohud-font.arfont void create_font_from_mtsdf(const overlay_params& params, ImFont*& small_font, ImFont*& text_font) { auto& io = ImGui::GetIO(); @@ -31,19 +34,29 @@ void create_font_from_mtsdf(const overlay_params& params, ImFont*& small_font, I if (arfont.images[0].imageType != artery_font::IMAGE_MTSDF) { - SPDLOG_ERROR("Font type is not MTSDF"); + SPDLOG_ERROR("Font type is not MTSDF: {}", arfont.images[0].imageType); return; } if (arfont.images[0].encoding != artery_font::ImageEncoding::IMAGE_RAW_BINARY) { - SPDLOG_ERROR("Font image encoding is not raw binary"); + SPDLOG_ERROR("Font image encoding is not raw binary: {}", arfont.images[0].encoding); return; } - const auto& v = arfont.variants[0]; - const auto& img = arfont.images[0]; + if (arfont.images[0].channels != 4) + { + SPDLOG_ERROR("Font image does not have 4 channels: {}", arfont.images[0].channels); + return; + } + if (arfont.images[0].pixelFormat != artery_font::PixelFormat::PIXEL_UNSIGNED8) + { + SPDLOG_ERROR("Font image pixel format is not UNSIGNED8: {}", arfont.images[0].pixelFormat); + return; + } + + const auto& img = arfont.images[0]; io.Fonts->ClearInputData(); ImFontAtlasBuildInit(io.Fonts); // Clear atlas @@ -57,43 +70,60 @@ void create_font_from_mtsdf(const overlay_params& params, ImFont*& small_font, I if (io.Fonts->TexWidth < 256) io.Fonts->TexWidth = 256; // give space for custom stuff io.Fonts->TexUvScale = ImVec2(1.0f / io.Fonts->TexWidth, 1.0f / io.Fonts->TexHeight); - - ImFontConfig font_cfg; - io.Fonts->Fonts.push_back(IM_NEW(ImFont)); - ImFont* font = io.Fonts->Fonts.back(); - font->Ascent = v.metrics.ascender * v.metrics.fontSize; - font->Descent = v.metrics.descender * v.metrics.fontSize; - font->FontSize = v.metrics.fontSize; // * v.metrics.lineHeight; - font->Scale = 1.0f; - font->ContainerAtlas = io.Fonts; - font_cfg.DstFont = font; - strncpy(font_cfg.Name, (const char *)v.name, min(40, v.name.length())); - io.Fonts->ConfigData.push_back(font_cfg); - font->ConfigData = &io.Fonts->ConfigData.back(); - font->ConfigDataCount = 1; io.Fonts->ClearTexData(); // invalidate texture data - for (const auto& g : v.glyphs.vector) + size_t i = 0; + for (const auto& v : arfont.variants.vector) { - float u0 = g.imageBounds.l * io.Fonts->TexUvScale.x; - float v0 = (img.height - g.imageBounds.t) * io.Fonts->TexUvScale.y; - float u1 = g.imageBounds.r * io.Fonts->TexUvScale.x; - float v1 = (img.height - g.imageBounds.b) * io.Fonts->TexUvScale.y; - font->AddGlyph(nullptr, (ImWchar)g.codepoint, - g.planeBounds.l * v.metrics.fontSize, - (1.0f - g.planeBounds.t) * v.metrics.fontSize, - g.planeBounds.r * v.metrics.fontSize, - (1.0f - g.planeBounds.b) * v.metrics.fontSize, - u0, v0, u1, v1, - g.advance.h * v.metrics.fontSize); + ImFont* font = nullptr; + i++; + if (i != 3) + { + io.Fonts->Fonts.push_back(IM_NEW(ImFont)); + font = io.Fonts->Fonts.back(); + font->Ascent = v.metrics.ascender * v.metrics.fontSize; + font->Descent = v.metrics.descender * v.metrics.fontSize; + font->FontSize = v.metrics.fontSize; // * v.metrics.lineHeight; + font->Scale = 1.0f; + font->ContainerAtlas = io.Fonts; + } + else + font = io.Fonts->Fonts.front(); + + // Add glyphs, doesn't seem to be affected by orientation + for (const auto& g : v.glyphs.vector) + { + float u0 = g.imageBounds.l * io.Fonts->TexUvScale.x; + float v0 = (img.height - g.imageBounds.t) * io.Fonts->TexUvScale.y; + float u1 = g.imageBounds.r * io.Fonts->TexUvScale.x; + float v1 = (img.height - g.imageBounds.b) * io.Fonts->TexUvScale.y; + font->AddGlyph(nullptr, (ImWchar)g.codepoint, + g.planeBounds.l * v.metrics.fontSize, + (1.0f - g.planeBounds.t) * v.metrics.fontSize, + g.planeBounds.r * v.metrics.fontSize, + (1.0f - g.planeBounds.b) * v.metrics.fontSize, + u0, v0, u1, v1, + g.advance.h * v.metrics.fontSize); + } } // Allocate texture io.Fonts->TexPixelsRGBA32 = (unsigned int*)IM_ALLOC(io.Fonts->TexWidth * io.Fonts->TexHeight * 4); unsigned char* src = (unsigned char*)arfont.images[0].data; memset(io.Fonts->TexPixelsRGBA32, 0, io.Fonts->TexHeight * io.Fonts->TexWidth * 4); - for (size_t y = 0; y < img.height; y++) //TODO check orientation - memcpy(io.Fonts->TexPixelsRGBA32 + (img.height - y - 1) * io.Fonts->TexWidth, src + y * img.width * 4, img.width * 4); + + if (img.rawBinaryFormat.orientation == artery_font::ImageOrientation::ORIENTATION_BOTTOM_UP) + { + for (size_t y = 0; y < img.height; y++) + memcpy(io.Fonts->TexPixelsRGBA32 + (img.height - y - 1) * io.Fonts->TexWidth, + src + y * img.rawBinaryFormat.rowLength, img.rawBinaryFormat.rowLength); + } + else + { + for (size_t y = 0; y < img.height; y++) + memcpy(io.Fonts->TexPixelsRGBA32 + y * io.Fonts->TexWidth, + src + y * img.rawBinaryFormat.rowLength, img.rawBinaryFormat.rowLength); + } // Add custom rects somewhere on texture uint16_t max_h = 0; @@ -116,11 +146,14 @@ void create_font_from_mtsdf(const overlay_params& params, ImFont*& small_font, I ImFontAtlasBuildFinish(io.Fonts); - io.Fonts->Fonts.push_back(IM_NEW(ImFont)); - ImFont* tmp = io.Fonts->Fonts.back(); - *tmp = *io.Fonts->Fonts[0]; - tmp->Scale *= 0.55f; - small_font = io.Fonts->Fonts.back(); + if (io.Fonts->Fonts.size() < 2) + { + io.Fonts->Fonts.push_back(IM_NEW(ImFont)); + ImFont* tmp = io.Fonts->Fonts.back(); + *tmp = *io.Fonts->Fonts[0]; + tmp->Scale *= 0.55f; + } + small_font = io.Fonts->Fonts[1]; text_font = io.Fonts->Fonts[0]; } diff --git a/src/hud_elements.cpp b/src/hud_elements.cpp index 7ef29c0..d077990 100644 --- a/src/hud_elements.cpp +++ b/src/hud_elements.cpp @@ -581,6 +581,12 @@ void HudElements::resolution(){ ImGui::TableNextColumn(); right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width * 1.3, "%ix%i", res_width, res_height); ImGui::PopFont(); + ImGui::TableNextColumn(); + +// ImGuiIO& io = ImGui::GetIO(); +// ImGui::PushFont(io.Fonts->Fonts.back()); + right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%s", ICON_FK_BATTERY_HALF); +// ImGui::PopFont(); } } diff --git a/src/overlay.frag b/src/overlay.frag index 7f73253..8f10b7b 100644 --- a/src/overlay.frag +++ b/src/overlay.frag @@ -17,20 +17,44 @@ float sdf_aastep(float value) { } float screenPxRange() { - return 2.f; + return 8.f; // * u_scale; } float median(float r, float g, float b) { return max(min(r, g), min(max(r, g), b)); } +const vec4 shadowColor = vec4(0, 0, 0, 1); + +// outline +const float smoothing = 1.0/16.0; +const float outlineWidth = 2.0/16.0; +const float outerEdgeCenter = 0.5 - outlineWidth; + void main() { - vec4 msd = texture(sTexture, In.UV.st); - float sd = median(msd.r, msd.g, msd.b); - float screenPxDistance = screenPxRange()*(sd - 0.5); - float opacity = clamp(screenPxDistance/fwidth(screenPxDistance) + 0.5, 0.0, 1.0); - fColor = mix(bgColor, In.Color, opacity); + // Older version, seems nicer + vec2 msdfUnit = screenPxRange()/vec2(textureSize(sTexture, 0)); + vec4 msd = texture(sTexture, In.UV); + + float sigDist = median(msd.r, msd.g, msd.b) - 0.5; + sigDist *= dot(msdfUnit, 0.5/fwidth(In.UV)); + + float opacity = clamp(sigDist + 0.5, 0.0, 1.0); + + fColor = vec4(In.Color.rgb, In.Color.a * opacity); + + // add outline + float alpha = smoothstep(outerEdgeCenter - smoothing, outerEdgeCenter + smoothing, msd.a); + float border = smoothstep(0.5 - smoothing, 0.5 + smoothing, msd.a); + fColor = vec4( mix(shadowColor.rgb, fColor.rgb, border), alpha * In.Color.a ); + + // README version, something's funky +// vec4 msd = texture(sTexture, In.UV.st); +// float sd = median(msd.r, msd.g, msd.b); +// float screenPxDistance = screenPxRange()*(sd - 0.5); +// float opacity = clamp(screenPxDistance + 0.5, 0.0, 1.0); +// fColor = mix(bgColor, In.Color, opacity); // fColor = In.Color * texture(sTexture, In.UV.st); } diff --git a/src/vulkan.cpp b/src/vulkan.cpp index 29c308d..8bc6e41 100644 --- a/src/vulkan.cpp +++ b/src/vulkan.cpp @@ -1080,6 +1080,8 @@ static void setup_swapchain_data_pipeline(struct swapchain_data *data) sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; sampler_info.magFilter = VK_FILTER_LINEAR; sampler_info.minFilter = VK_FILTER_LINEAR; +// sampler_info.magFilter = VK_FILTER_NEAREST; +// sampler_info.minFilter = VK_FILTER_NEAREST; sampler_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; sampler_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; sampler_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;