From 8d389db50ccdc36751b254aa7bfa134095828376 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Tue, 31 Dec 2024 10:13:36 +0200 Subject: [PATCH] some more refactoring and improvements --- examples/ExampleApps/TextExampleApp.cpp | 11 ++--- openVulkanoCpp/Base/Utils.hpp | 41 ++++++++++--------- .../Scene/BitmapFontAtlasGenerator.cpp | 23 +++++++++-- .../Scene/BitmapFontAtlasGenerator.hpp | 10 ++++- .../Scene/FontAtlasGeneratorBase.cpp | 22 ++++------ 5 files changed, 61 insertions(+), 46 deletions(-) diff --git a/examples/ExampleApps/TextExampleApp.cpp b/examples/ExampleApps/TextExampleApp.cpp index 1a762fe..6348aa5 100644 --- a/examples/ExampleApps/TextExampleApp.cpp +++ b/examples/ExampleApps/TextExampleApp.cpp @@ -80,14 +80,9 @@ namespace OpenVulkano } #if defined(MSDFGEN_AVAILABLE) && CREATE_NEW_ATLAS - std::set s = SdfFontAtlasGenerator::LoadAllGlyphs(fontPath); - msdf_atlas::Charset charset; - for (uint32_t c : s) - { - charset.add(c); - } - m_atlasGenerator.GenerateAtlas(fontPath, charset); - m_msdfAtlasGenerator.GenerateAtlas(fontPath, charset); + std::set s = SdfFontAtlasGeneratorT::LoadAllGlyphs(fontPath); + m_atlasGenerator.GenerateAtlas(fontPath, s); + m_msdfAtlasGenerator.GenerateAtlas(fontPath, s); m_atlasGenerator.SaveAtlasMetadataInfo("sdf_atlas.png"); m_msdfAtlasGenerator.SaveAtlasMetadataInfo("msdf_atlas"); #else diff --git a/openVulkanoCpp/Base/Utils.hpp b/openVulkanoCpp/Base/Utils.hpp index c8ac6e0..8419419 100644 --- a/openVulkanoCpp/Base/Utils.hpp +++ b/openVulkanoCpp/Base/Utils.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include "Data/Containers/Array.hpp" namespace OpenVulkano @@ -195,25 +196,7 @@ namespace OpenVulkano static Array ReadFile(const char (&filePath)[N], bool emptyOnMissing = false, bool nullTerminateString = false) { - std::ifstream file(filePath, std::ios::ate | std::ios::binary); - if (!file.is_open()) - { - if (emptyOnMissing) - { - return {}; - } - throw std::runtime_error("Failed to open file '" + std::string(filePath) + "'!"); - } - const size_t fileSize = static_cast(file.tellg()); - Array data(fileSize + nullTerminateString); - file.seekg(0); - file.read(data.Data(), fileSize); - if (nullTerminateString) - { - data[fileSize] = '\0'; - } - file.close(); - return data; + return ReadFile(std::string(filePath), emptyOnMissing, nullTerminateString); } template @@ -222,6 +205,26 @@ namespace OpenVulkano static const int id = uniqueTypeID++; return id; } + + static unsigned char* STBZlibCompressor(unsigned char* data, int data_len, int* out_len, int quality) + { + uLong maxCompressedSize = compressBound(data_len); + void* outData = malloc(maxCompressedSize); + if (!outData) + { + *out_len = 0; + return nullptr; + } + int result = compress2(static_cast(outData), &maxCompressedSize, data, data_len, Z_BEST_COMPRESSION); + if (result != Z_OK) + { + free(outData); + *out_len = 0; + return nullptr; + } + *out_len = static_cast(maxCompressedSize); + return static_cast(outData); + } static std::string DemangleTypeName(const char* name); }; diff --git a/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.cpp b/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.cpp index 723dc99..a0ff547 100644 --- a/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.cpp +++ b/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.cpp @@ -34,10 +34,23 @@ namespace OpenVulkano::Scene m_atlasData = std::make_shared(); const auto& [lib, face] = FontAtlasGeneratorBase::InitFreetype(source); - // TODO: add flexibility to set your own size - const Math::Vector2ui cellSize = { 24, 24 }; - // set pixel width/height lower than glyph size above, otherwise some glyphs will be cropped or some overlapping will be present - FT_Set_Pixel_Sizes(face.get(), 0, cellSize.y - cellSize.y / 3); + Math::Vector2ui cellSize; + if (m_pixelSizeConfig.isPixelSize) + { + cellSize = { m_pixelSizeConfig.size, m_pixelSizeConfig.size }; + // set pixel width/height lower than glyph size above, otherwise some glyphs will be cropped or some overlapping will be present + FT_Set_Pixel_Sizes(face.get(), 0, cellSize.y - cellSize.y / 3); + } + else + { + const float pixelSize = (m_pixelSizeConfig.size * m_pixelSizeConfig.dpi) / 72.0f; + //int fontHeight = round((face->bbox.yMax - face->bbox.yMin) * pixelSize / face->units_per_EM); + //int fontWidth = round((face->bbox.xMax - face->bbox.xMin) * pixelSize / face->units_per_EM); + cellSize = { pixelSize, pixelSize }; + FT_Set_Char_Size(face.get(), 0, static_cast(m_pixelSizeConfig.size) * 64, + static_cast(m_pixelSizeConfig.dpi), static_cast(m_pixelSizeConfig.dpi)); + } + const double sq = std::sqrt(chset.size()); const size_t glyphsPerRow = (static_cast(sq)) + (sq - static_cast(sq) != 0); const size_t rows = (chset.size() / glyphsPerRow) + (chset.size() % glyphsPerRow != 0); @@ -68,6 +81,8 @@ namespace OpenVulkano::Scene if (slot->bitmap.width > cellSize.x || slot->bitmap.rows > cellSize.y) { Logger::APP->warn("Glyph size exceeds grid cell size: {}x{} exceeds {}x{}", slot->bitmap.width, slot->bitmap.rows, cellSize.x, cellSize.y); + // skip such glyph for now to avoid crash + continue; } const size_t firstGlyphByte = (gridPos.y * cellSize.x + gridPos.x * atlasResolution.x * cellSize.y); diff --git a/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.hpp b/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.hpp index 949b323..7ec1fad 100644 --- a/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.hpp +++ b/openVulkanoCpp/Scene/BitmapFontAtlasGenerator.hpp @@ -10,16 +10,24 @@ namespace OpenVulkano::Scene { + struct FontPixelSizeConfig + { + float size = 16.f; + float dpi = 72.f; + bool isPixelSize = true; + }; class BitmapFontAtlasGenerator : public FontAtlasGeneratorBase { public: - BitmapFontAtlasGenerator() : FontAtlasGeneratorBase(1) {} + BitmapFontAtlasGenerator(FontPixelSizeConfig config = FontPixelSizeConfig()) : FontAtlasGeneratorBase(1), m_pixelSizeConfig(config) {} void GenerateAtlas(const std::string& fontFile, const std::set& charset, const std::optional& pngOutput = std::nullopt) override; void GenerateAtlas(const Array& fontData, const std::set& charset, const std::optional& pngOutput = std::nullopt) override; private: void Generate(const std::variant>& source, const std::set& chset, const std::optional& pngOutput); + private: + FontPixelSizeConfig m_pixelSizeConfig; }; } diff --git a/openVulkanoCpp/Scene/FontAtlasGeneratorBase.cpp b/openVulkanoCpp/Scene/FontAtlasGeneratorBase.cpp index 3fba677..7259916 100644 --- a/openVulkanoCpp/Scene/FontAtlasGeneratorBase.cpp +++ b/openVulkanoCpp/Scene/FontAtlasGeneratorBase.cpp @@ -6,11 +6,13 @@ #include "FontAtlasGeneratorBase.hpp" #include "Base/Logger.hpp" -#define STBI_MSC_SECURE_CRT -#define STB_IMAGE_WRITE_IMPLEMENTATION -#include +#include #include #include +#define STBI_MSC_SECURE_CRT +#define STB_IMAGE_WRITE_IMPLEMENTATION +#define STBIW_ZLIB_COMPRESS OpenVulkano::Utils::STBZlibCompressor +#include namespace OpenVulkano::Scene { @@ -86,6 +88,7 @@ namespace OpenVulkano::Scene } fs.write(reinterpret_cast(&metadataBytes), sizeof(uint64_t)); fs.write(reinterpret_cast(&packedFlag), sizeof(uint32_t)); + fs.close(); } void FontAtlasGeneratorBase::SavePng(std::string output) const @@ -105,17 +108,8 @@ namespace OpenVulkano::Scene // generate texture m_atlasData->img = std::make_unique(); m_atlasData->img->resolution = Math::Vector3ui(textureResolution, 1); - if (m_channelsCount == 1) - { - m_atlasData->img->data = Array(textureResolution.x * textureResolution.y); - m_atlasData->img->dataFormat = OpenVulkano::DataFormat::R8_UNORM; - } - else - { - // RGBA - m_atlasData->img->data = Array(textureResolution.x * textureResolution.y * 4); - m_atlasData->img->dataFormat = OpenVulkano::DataFormat::R8G8B8A8_UNORM; - } + m_atlasData->img->dataFormat = m_channelsCount == 1 ? DataFormat::R8_UNORM : DataFormat::R8G8B8A8_UNORM; + m_atlasData->img->data = Array(m_atlasData->img->dataFormat.CalculatedSize(textureResolution.x, textureResolution.y)); m_atlasData->texture.resolution = m_atlasData->img->resolution; m_atlasData->texture.textureBuffer = m_atlasData->img->data.Data(); m_atlasData->texture.format = m_atlasData->img->dataFormat;