improve atlas texture size handling

This commit is contained in:
ohyzha
2024-08-08 17:41:02 +03:00
parent 1659cee9eb
commit ae39847d95
3 changed files with 30 additions and 20 deletions

View File

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

View File

@@ -82,7 +82,7 @@ namespace OpenVulkano::Scene
}
void MsdfFontAtlasGenerator::GenerateAtlas(const std::string& fontFile, const Charset& charset,
const std::optional<std::string>& pngOutput)
const std::optional<std::string>& 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<std::string>& pngOutput)
const std::optional<std::string>& 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<std::string>& pngOutput)
const std::optional<std::string>& pngOutput)
{
m_symbols.clear();
std::vector<GlyphGeometry> 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);
}

View File

@@ -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<float, 1, msdf_atlas::sdfGenerator,
msdf_atlas::BitmapAtlasStorage<msdfgen::byte, 1>>;
using Config = MsdfFontAtlasGeneratorConfig;
static msdf_atlas::Charset LoadAllGlyphs(const std::variant<std::string, Array<char>>& data);
void GenerateAtlas(const std::string& fontFile, const std::set<uint32_t>& charset,
const std::optional<std::string>& pngOutput = std::nullopt) override;
@@ -37,11 +46,12 @@ namespace OpenVulkano::Scene
const msdf_atlas::Charset& charset = msdf_atlas::Charset::ASCII,
const std::optional<std::string>& 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<uint32_t, GlyphInfo>& 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<uint32_t, GlyphInfo> m_symbols;
};
}