From ae39847d9527e86b34d1faacb4f5ef641e11f764 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Thu, 8 Aug 2024 17:41:02 +0300 Subject: [PATCH] improve atlas texture size handling --- examples/ExampleApps/TextExampleApp.cpp | 4 +-- .../Scene/MsdfFontAtlasGenerator.cpp | 33 +++++++++---------- .../Scene/MsdfFontAtlasGenerator.hpp | 13 +++++++- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/examples/ExampleApps/TextExampleApp.cpp b/examples/ExampleApps/TextExampleApp.cpp index 1df7521..879de78 100644 --- a/examples/ExampleApps/TextExampleApp.cpp +++ b/examples/ExampleApps/TextExampleApp.cpp @@ -70,8 +70,8 @@ namespace OpenVulkano #ifdef MSDFGEN_AVAILABLE msdf_atlas::Charset charset = MsdfFontAtlasGenerator::LoadAllGlyphs(fontPath); - //Charset charset = Charset::ASCII; - //for (unicode_t c = 0x0410; c <= 0x041F; c++) + //msdf_atlas::Charset charset = msdf_atlas::Charset::ASCII; + //for (msdf_atlas::unicode_t c = 0x0410; c <= 0x041F; c++) //{ // // some unicode values // charset.add(c); diff --git a/openVulkanoCpp/Scene/MsdfFontAtlasGenerator.cpp b/openVulkanoCpp/Scene/MsdfFontAtlasGenerator.cpp index 59d24d9..2179491 100644 --- a/openVulkanoCpp/Scene/MsdfFontAtlasGenerator.cpp +++ b/openVulkanoCpp/Scene/MsdfFontAtlasGenerator.cpp @@ -82,7 +82,7 @@ namespace OpenVulkano::Scene } void MsdfFontAtlasGenerator::GenerateAtlas(const std::string& fontFile, const Charset& charset, - const std::optional& pngOutput) + const std::optional& pngOutput) { // TODO: dynamic atlas and add only those symbols which are not present yet in current atlas FreetypeHandle* ft; @@ -92,7 +92,7 @@ namespace OpenVulkano::Scene } void MsdfFontAtlasGenerator::GenerateAtlas(const msdfgen::byte* fontData, int length, const Charset& charset, - const std::optional& pngOutput) + const std::optional& pngOutput) { FreetypeHandle* ft; FontHandle* font; @@ -165,7 +165,7 @@ namespace OpenVulkano::Scene } void MsdfFontAtlasGenerator::Generate(FreetypeHandle* ft, FontHandle* font, const Charset& chset, - const std::optional& pngOutput) + const std::optional& pngOutput) { m_symbols.clear(); std::vector glyphsGeometry; @@ -175,15 +175,17 @@ namespace OpenVulkano::Scene TightAtlasPacker packer; packer.setDimensionsConstraint(DimensionsConstraint::SQUARE); - int width = 1024, height = 1024; - packer.setDimensions(width, height); + int width, height; + const int glyphsPerRow = std::sqrt(glyphsGeometry.size()); + const int glyphSize = m_config.glyphSize; + const int rowWidth = glyphSize * glyphsPerRow; + packer.setDimensions(rowWidth, rowWidth); + // something to play with. should not be too high. // more value - more sdf impact - // this setup is tricky. with low value and large amount of characters visible artifacts (extra lines) may appear. - // with high value and large amount of characters sdf deals huge impact and characters are not readable anymore. - const double pixelRange = std::min((width / (double)chset.size()) * 3, 26.0); - packer.setPixelRange(pixelRange); - packer.setMiterLimit(1.0); + packer.setPixelRange(m_config.pixelRange); + packer.setMiterLimit(m_config.miterLimit); packer.pack(glyphsGeometry.data(), glyphsGeometry.size()); + packer.getDimensions(width, height); m_generator.resize(width, height); GeneratorAttributes attributes; @@ -197,9 +199,9 @@ namespace OpenVulkano::Scene m_atlasTex.textureBuffer = (msdfgen::byte*) storage.pixels; m_atlasTex.format = OpenVulkano::DataFormat::R8_UNORM; m_atlasTex.size = storage.width * storage.height * 1; // 1 channel - + m_meta.lineHeight = fontGeometry.getMetrics().lineHeight; - + struct Bbox { double l = 0, r = 0, t = 0, b = 0; @@ -212,7 +214,7 @@ namespace OpenVulkano::Scene Bbox glyphBaselineBbox, glyphAtlasBbox; glyph.getQuadPlaneBounds(glyphBaselineBbox.l, glyphBaselineBbox.b, glyphBaselineBbox.r, - glyphBaselineBbox.t); + glyphBaselineBbox.t); glyph.getQuadAtlasBounds(glyphAtlasBbox.l, glyphAtlasBbox.b, glyphAtlasBbox.r, glyphAtlasBbox.t); double bearingX = glyphBox.bounds.l; double bearingY = glyphBox.bounds.t; @@ -250,10 +252,7 @@ namespace OpenVulkano::Scene info.advance = glyphBox.advance; } - if (pngOutput && !pngOutput->empty()) - { - SavePng(storage, pngOutput.value(), 1); - } + if (pngOutput && !pngOutput->empty()) { SavePng(storage, pngOutput.value(), 1); } destroyFont(font); deinitializeFreetype(ft); } diff --git a/openVulkanoCpp/Scene/MsdfFontAtlasGenerator.hpp b/openVulkanoCpp/Scene/MsdfFontAtlasGenerator.hpp index b094065..c1e7411 100644 --- a/openVulkanoCpp/Scene/MsdfFontAtlasGenerator.hpp +++ b/openVulkanoCpp/Scene/MsdfFontAtlasGenerator.hpp @@ -21,11 +21,20 @@ namespace OpenVulkano::Scene { + + struct MsdfFontAtlasGeneratorConfig + { + int glyphSize = 42; + double miterLimit = 1.0; + msdfgen::Range pixelRange = 5; + }; + class MsdfFontAtlasGenerator : public FontAtlasGenerator { public: using SdfGenerator = msdf_atlas::ImmediateAtlasGenerator>; + using Config = MsdfFontAtlasGeneratorConfig; static msdf_atlas::Charset LoadAllGlyphs(const std::variant>& data); void GenerateAtlas(const std::string& fontFile, const std::set& charset, const std::optional& pngOutput = std::nullopt) override; @@ -37,11 +46,12 @@ namespace OpenVulkano::Scene const msdf_atlas::Charset& charset = msdf_atlas::Charset::ASCII, const std::optional& pngOutput = std::nullopt); void SaveAtlasMetadataInfo(const std::string& outputFile, bool packIntoSingleFile = true) const override; + void SetGeneratorConfig(const Config& config) { m_config = config; } const Texture& GetAtlas() const override { return m_atlasTex; } std::map& GetGlyphsInfo() override { return m_symbols; } AtlasMetadata& GetAtlasMetadata() override { return m_meta; } SdfGenerator& GetFontAtlasGenerator() { return m_generator; } - + Config& GetGeneratorConfig() { return m_config; } private: void InitFreetypeFromFile(msdfgen::FreetypeHandle*& ft, msdfgen::FontHandle*& font, const std::string& file); void InitFreetypeFromBuffer(msdfgen::FreetypeHandle*& ft, msdfgen::FontHandle*& font, @@ -55,6 +65,7 @@ namespace OpenVulkano::Scene SdfGenerator m_generator; Texture m_atlasTex; AtlasMetadata m_meta; + Config m_config; std::map m_symbols; }; }