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

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