Tune shader and check orientation

mtsdf
jackun 3 years ago
parent fd7404d9cd
commit 42217561d4
No known key found for this signature in database
GPG Key ID: 119DB3F1D05A9ED3

@ -0,0 +1,2 @@
[0x20, 0xFF]
[0x2018, 0x201F]

@ -0,0 +1 @@
[0xF240, 0xF244]

@ -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];
}

@ -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();
}
}

@ -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);
}

@ -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;

Loading…
Cancel
Save