working version of text rendering
This commit is contained in:
95
openVulkanoCpp/Scene/FontAtlasGenerator.cpp
Normal file
95
openVulkanoCpp/Scene/FontAtlasGenerator.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "FontAtlasGenerator.hpp"
|
||||
#include "Base/Logger.hpp"
|
||||
|
||||
namespace OpenVulkano::Scene
|
||||
{
|
||||
using namespace msdfgen;
|
||||
using namespace msdf_atlas;
|
||||
|
||||
void FontAtlasGenerator::GenerateAtlas(const std::string& fontFile, const std::string& outputFile, const Charset& chset)
|
||||
{
|
||||
if (chset.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// TODO: dynamic atlas and add only those symbols which are not present yet in current atlas
|
||||
Charset absentSymbols;
|
||||
for (auto c : chset)
|
||||
{
|
||||
if (!m_symbols.contains(c))
|
||||
{
|
||||
absentSymbols.add(c);
|
||||
}
|
||||
}
|
||||
if (m_loadedFont == fontFile && absentSymbols.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_symbols.clear();
|
||||
m_loadedFont = fontFile;
|
||||
|
||||
std::vector<GlyphGeometry> glyphsGeometry;
|
||||
std::pair<FreetypeHandle*, FontHandle*> handlers = GetHandlers(fontFile);
|
||||
FreetypeHandle* ft = handlers.first;
|
||||
FontHandle* font = handlers.second;
|
||||
|
||||
// FontGeometry is a helper class that loads a set of glyphs from a single font.
|
||||
FontGeometry fontGeometry(&glyphsGeometry);
|
||||
fontGeometry.loadCharset(font, 1, absentSymbols);
|
||||
|
||||
TightAtlasPacker packer;
|
||||
packer.setDimensionsConstraint(DimensionsConstraint::SQUARE);
|
||||
int width = 1024, height = 1024;
|
||||
packer.setDimensions(width, height);
|
||||
// more value - more sdf impact
|
||||
packer.setPixelRange(26.0);
|
||||
packer.setMiterLimit(1.0);
|
||||
packer.pack(glyphsGeometry.data(), glyphsGeometry.size());
|
||||
|
||||
m_generator.resize(width, height);
|
||||
GeneratorAttributes attributes;
|
||||
m_generator.setAttributes(attributes);
|
||||
m_generator.setThreadCount(4);
|
||||
m_generator.generate(glyphsGeometry.data(), glyphsGeometry.size());
|
||||
|
||||
int idx = 0;
|
||||
BitmapConstRef<byte, 1> storage = m_generator.atlasStorage();
|
||||
for (const auto& glyph: glyphsGeometry)
|
||||
{
|
||||
unicode_t c = static_cast<char8_t>(glyph.getCodepoint());
|
||||
GlyphInfo info;
|
||||
info.texture.resolution = Math::Vector3ui(storage.width, storage.height, 1);
|
||||
info.texture.textureBuffer = (msdfgen::byte*)storage.pixels;
|
||||
info.texture.format = OpenVulkano::DataFormat::R8_UNORM;
|
||||
info.texture.size = storage.width * storage.height * 1; // 1 channel
|
||||
info.geometry = glyph;
|
||||
info.glyphBox = m_generator.getLayout()[idx++];
|
||||
m_symbols[c] = std::move(info);
|
||||
}
|
||||
savePng(m_generator.atlasStorage(), outputFile.c_str());
|
||||
destroyFont(font);
|
||||
deinitializeFreetype(ft);
|
||||
}
|
||||
|
||||
std::pair<FreetypeHandle*, FontHandle*> FontAtlasGenerator::GetHandlers(const std::string& fontFile)
|
||||
{
|
||||
FreetypeHandle* ft = initializeFreetype();
|
||||
if (!ft)
|
||||
{
|
||||
throw std::runtime_error("Failed to initialize freetype");
|
||||
}
|
||||
FontHandle* font = loadFont(ft, fontFile.data());
|
||||
if (!font)
|
||||
{
|
||||
deinitializeFreetype(ft);
|
||||
throw std::runtime_error(fmt::format("Failed to load font from file {0}", fontFile.data()));
|
||||
}
|
||||
return { ft, font };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user