rework API for text rendering
This commit is contained in:
2
3rdParty/msdf/CMakeLists.txt
vendored
2
3rdParty/msdf/CMakeLists.txt
vendored
@@ -36,7 +36,7 @@ if (WIN32)
|
|||||||
set(TRIPLET x64-windows-static-md-release CACHE INTERNAL "triplet")
|
set(TRIPLET x64-windows-static-md-release CACHE INTERNAL "triplet")
|
||||||
elseif(UNIX AND NOT APPLE)
|
elseif(UNIX AND NOT APPLE)
|
||||||
set(TRIPLET x64-linux CACHE INTERNAL "triplet")
|
set(TRIPLET x64-linux CACHE INTERNAL "triplet")
|
||||||
elseif(APPLE)
|
elseif(APPLE AND NOT IOS)
|
||||||
set(TRIPLET arm64-osx CACHE INTERNAL "triplet")
|
set(TRIPLET arm64-osx CACHE INTERNAL "triplet")
|
||||||
elseif(IOS)
|
elseif(IOS)
|
||||||
set(TRIPLET arm64-ios CACHE INTERNAL "triplet")
|
set(TRIPLET arm64-ios CACHE INTERNAL "triplet")
|
||||||
|
|||||||
@@ -63,39 +63,20 @@ namespace OpenVulkano
|
|||||||
auto& resourceLoader = ResourceLoader::GetInstance();
|
auto& resourceLoader = ResourceLoader::GetInstance();
|
||||||
const std::string fontPath = resourceLoader.GetResourcePath("Roboto-Regular.ttf");
|
const std::string fontPath = resourceLoader.GetResourcePath("Roboto-Regular.ttf");
|
||||||
const std::string atlasPath = (fs::path(fontPath).parent_path() / "roboto-regular-atlas.png").string();
|
const std::string atlasPath = (fs::path(fontPath).parent_path() / "roboto-regular-atlas.png").string();
|
||||||
|
|
||||||
m_nodesPool.resize(N);
|
m_nodesPool.resize(N);
|
||||||
m_drawablesPool.resize(N);
|
m_drawablesPool.resize(N);
|
||||||
m_uniBuffers.resize(N);
|
|
||||||
|
|
||||||
for (int i = 0; i < N; i++)
|
|
||||||
{
|
|
||||||
m_uniBuffers[i].Init(sizeof(TextConfig), &texts[i].second, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_shader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/text");
|
|
||||||
m_shader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/text");
|
|
||||||
m_shader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription());
|
|
||||||
m_shader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING);
|
|
||||||
m_shader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING);
|
|
||||||
m_shader.alphaBlend = true;
|
|
||||||
m_shader.cullMode = CullMode::NONE;
|
|
||||||
|
|
||||||
Charset charset = Charset::ASCII;
|
Charset charset = Charset::ASCII;
|
||||||
for (unicode_t c = 0x0410; c <= 0x041F; c++)
|
for (unicode_t c = 0x0410; c <= 0x041F; c++)
|
||||||
{
|
{
|
||||||
// some unicode values
|
// some unicode values
|
||||||
charset.add(c);
|
charset.add(c);
|
||||||
}
|
}
|
||||||
m_atlasGenerator.GenerateAtlas(fontPath, atlasPath, charset);
|
m_atlasGenerator.GenerateAtlas(fontPath, charset);
|
||||||
|
|
||||||
for (int i = 0; i < texts.size(); i++)
|
for (int i = 0; i < texts.size(); i++)
|
||||||
{
|
{
|
||||||
TextDrawable* t = new TextDrawable();
|
TextDrawable* t = new TextDrawable(&m_atlasGenerator, texts[i].second);
|
||||||
t->SetFontAtlasGenerator(&m_atlasGenerator);
|
|
||||||
t->SetConfig(texts[i].second);
|
|
||||||
t->SetUniformBuffer(&m_uniBuffers[i]);
|
|
||||||
t->SetShader(&m_shader);
|
|
||||||
t->GenerateText(texts[i].first);
|
t->GenerateText(texts[i].first);
|
||||||
m_drawablesPool[i] = t;
|
m_drawablesPool[i] = t;
|
||||||
m_nodesPool[i].Init();
|
m_nodesPool[i].Init();
|
||||||
@@ -131,9 +112,7 @@ namespace OpenVulkano
|
|||||||
private:
|
private:
|
||||||
OpenVulkano::Scene::Scene m_scene;
|
OpenVulkano::Scene::Scene m_scene;
|
||||||
PerspectiveCamera m_cam;
|
PerspectiveCamera m_cam;
|
||||||
std::vector<UniformBuffer> m_uniBuffers;
|
|
||||||
OpenVulkano::FreeCamCameraController m_camController;
|
OpenVulkano::FreeCamCameraController m_camController;
|
||||||
Shader m_shader;
|
|
||||||
FontAtlasGenerator m_atlasGenerator;
|
FontAtlasGenerator m_atlasGenerator;
|
||||||
std::vector<SimpleDrawable*> m_drawablesPool;
|
std::vector<SimpleDrawable*> m_drawablesPool;
|
||||||
std::vector<Node> m_nodesPool;
|
std::vector<Node> m_nodesPool;
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ImageLoader.hpp"
|
#include "ImageLoader.hpp"
|
||||||
#include "Base/Logger.hpp"
|
#include "Base/Logger.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|||||||
@@ -12,36 +12,47 @@ namespace OpenVulkano::Scene
|
|||||||
using namespace msdfgen;
|
using namespace msdfgen;
|
||||||
using namespace msdf_atlas;
|
using namespace msdf_atlas;
|
||||||
|
|
||||||
void FontAtlasGenerator::GenerateAtlas(const std::string& fontFile, const std::string& outputFile, const Charset& chset)
|
void FontAtlasGenerator::GenerateAtlas(const std::string& fontFile, const Charset& charset, const std::optional<std::string>& pngOutput)
|
||||||
{
|
{
|
||||||
if (chset.empty())
|
if (charset.empty())
|
||||||
{
|
{
|
||||||
|
Logger::RENDER->info("Provided charset is empty. Atlas will not be generated");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: dynamic atlas and add only those symbols which are not present yet in current atlas
|
// TODO: dynamic atlas and add only those symbols which are not present yet in current atlas
|
||||||
Charset absentSymbols;
|
FreetypeHandle* ft = initializeFreetype();
|
||||||
for (auto c : chset)
|
if (!ft) { throw std::runtime_error("Failed to initialize freetype"); }
|
||||||
|
FontHandle* font = loadFont(ft, fontFile.data());
|
||||||
|
if (!font)
|
||||||
{
|
{
|
||||||
if (!m_symbols.contains(c))
|
deinitializeFreetype(ft);
|
||||||
{
|
throw std::runtime_error(fmt::format("Failed to load font from file {0}", fontFile.data()));
|
||||||
absentSymbols.add(c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (m_loadedFont == fontFile && absentSymbols.empty())
|
Generate(ft, font, charset, pngOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FontAtlasGenerator::GenerateAtlas(const msdfgen::byte* fontData, int length, const Charset& charset,
|
||||||
|
const std::optional<std::string>& pngOutput)
|
||||||
|
{
|
||||||
|
FreetypeHandle* ft = initializeFreetype();
|
||||||
|
if (!ft) { throw std::runtime_error("Failed to initialize freetype"); }
|
||||||
|
FontHandle* font = loadFontData(ft, fontData, length);
|
||||||
|
if (!font)
|
||||||
{
|
{
|
||||||
return;
|
deinitializeFreetype(ft);
|
||||||
|
throw std::runtime_error("Failed to load font data from given buffer");
|
||||||
}
|
}
|
||||||
|
Generate(ft, font, charset, pngOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FontAtlasGenerator::Generate(FreetypeHandle* ft, FontHandle* font, const Charset& chset,
|
||||||
|
const std::optional<std::string>& pngOutput)
|
||||||
|
{
|
||||||
m_symbols.clear();
|
m_symbols.clear();
|
||||||
m_loadedFont = fontFile;
|
|
||||||
|
|
||||||
std::vector<GlyphGeometry> glyphsGeometry;
|
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 is a helper class that loads a set of glyphs from a single font.
|
||||||
FontGeometry fontGeometry(&glyphsGeometry);
|
FontGeometry fontGeometry(&glyphsGeometry);
|
||||||
fontGeometry.loadCharset(font, 1, absentSymbols);
|
fontGeometry.loadCharset(font, 1, chset);
|
||||||
|
|
||||||
TightAtlasPacker packer;
|
TightAtlasPacker packer;
|
||||||
packer.setDimensionsConstraint(DimensionsConstraint::SQUARE);
|
packer.setDimensionsConstraint(DimensionsConstraint::SQUARE);
|
||||||
@@ -66,29 +77,15 @@ namespace OpenVulkano::Scene
|
|||||||
m_atlasTex.size = storage.width * storage.height * 1; // 1 channel
|
m_atlasTex.size = storage.width * storage.height * 1; // 1 channel
|
||||||
for (const auto& glyph: glyphsGeometry)
|
for (const auto& glyph: glyphsGeometry)
|
||||||
{
|
{
|
||||||
GlyphInfo info;
|
GlyphInfo& info = m_symbols[glyph.getCodepoint()];
|
||||||
info.geometry = glyph;
|
info.geometry = glyph;
|
||||||
info.glyphBox = m_generator.getLayout()[idx++];
|
info.glyphBox = m_generator.getLayout()[idx++];
|
||||||
m_symbols[glyph.getCodepoint()] = std::move(info);
|
|
||||||
}
|
}
|
||||||
savePng(m_generator.atlasStorage(), outputFile.c_str());
|
if (pngOutput && !pngOutput->empty())
|
||||||
|
{
|
||||||
|
savePng(m_generator.atlasStorage(), pngOutput->c_str());
|
||||||
|
}
|
||||||
destroyFont(font);
|
destroyFont(font);
|
||||||
deinitializeFreetype(ft);
|
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 };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <optional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "Scene/Texture.hpp"
|
#include "Scene/Texture.hpp"
|
||||||
#include "msdfgen.h"
|
#include "msdfgen.h"
|
||||||
@@ -28,15 +29,18 @@ namespace OpenVulkano::Scene
|
|||||||
class FontAtlasGenerator
|
class FontAtlasGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void GenerateAtlas(const std::string& fontFile, const std::string& outputFile, const Charset& = Charset::ASCII);
|
void GenerateAtlas(const std::string& fontFile, const Charset& charset = Charset::ASCII,
|
||||||
|
const std::optional<std::string>& pngOutput = std::nullopt);
|
||||||
|
void GenerateAtlas(const msdfgen::byte* fontData, int length, const Charset& charset = Charset::ASCII,
|
||||||
|
const std::optional<std::string>& pngOutput = std::nullopt);
|
||||||
const Texture& GetAtlas() const { return m_atlasTex; }
|
const Texture& GetAtlas() const { return m_atlasTex; }
|
||||||
std::map<unicode_t, GlyphInfo>& GetAtlasInfo() { return m_symbols; }
|
std::map<unicode_t, GlyphInfo>& GetAtlasInfo() { return m_symbols; }
|
||||||
private:
|
private:
|
||||||
std::pair<FreetypeHandle*, FontHandle*> GetHandlers(const std::string& fontFile);
|
void Generate(FreetypeHandle* ft, FontHandle* font, const Charset& chset,
|
||||||
|
const std::optional<std::string>& pngOutput);
|
||||||
private:
|
private:
|
||||||
ImmediateAtlasGenerator<float, 1, sdfGenerator, BitmapAtlasStorage<msdfgen::byte, 1>> m_generator;
|
ImmediateAtlasGenerator<float, 1, sdfGenerator, BitmapAtlasStorage<msdfgen::byte, 1>> m_generator;
|
||||||
Texture m_atlasTex;
|
Texture m_atlasTex;
|
||||||
std::map<unicode_t, GlyphInfo> m_symbols;
|
std::map<unicode_t, GlyphInfo> m_symbols;
|
||||||
std::string m_loadedFont;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,6 @@ namespace OpenVulkano::Scene
|
|||||||
|
|
||||||
class SimpleDrawable : public Drawable
|
class SimpleDrawable : public Drawable
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
Geometry* m_mesh = nullptr;
|
Geometry* m_mesh = nullptr;
|
||||||
Material* m_material = nullptr;
|
Material* m_material = nullptr;
|
||||||
UniformBuffer* m_uniBuffer = nullptr;
|
UniformBuffer* m_uniBuffer = nullptr;
|
||||||
|
|||||||
@@ -11,51 +11,51 @@
|
|||||||
#include "Scene/UniformBuffer.hpp"
|
#include "Scene/UniformBuffer.hpp"
|
||||||
#include "Scene/FontAtlasGenerator.hpp"
|
#include "Scene/FontAtlasGenerator.hpp"
|
||||||
#include "Base/Logger.hpp"
|
#include "Base/Logger.hpp"
|
||||||
#include "utf8.h"
|
#include <utf8.h>
|
||||||
#include "fmt/core.h"
|
|
||||||
|
|
||||||
namespace OpenVulkano::Scene
|
namespace OpenVulkano::Scene
|
||||||
{
|
{
|
||||||
using namespace msdfgen;
|
using namespace msdfgen;
|
||||||
using namespace msdf_atlas;
|
using namespace msdf_atlas;
|
||||||
|
|
||||||
TextDrawable::~TextDrawable()
|
Shader& TextDrawable::GetDefaultShader()
|
||||||
{
|
{
|
||||||
delete m_mesh;
|
static bool once = true;
|
||||||
delete m_material;
|
static Shader textDefaultShader;
|
||||||
|
if (once)
|
||||||
|
{
|
||||||
|
textDefaultShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/text");
|
||||||
|
textDefaultShader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/text");
|
||||||
|
textDefaultShader.AddVertexInputDescription(OpenVulkano::Vertex::GetVertexInputDescription());
|
||||||
|
textDefaultShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING);
|
||||||
|
textDefaultShader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING);
|
||||||
|
textDefaultShader.alphaBlend = true;
|
||||||
|
textDefaultShader.cullMode = CullMode::NONE;
|
||||||
|
once = false;
|
||||||
|
}
|
||||||
|
return textDefaultShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextDrawable::TextDrawable(FontAtlasGenerator* fontAtlasGenerator, const TextConfig& config)
|
||||||
|
{
|
||||||
|
if (!fontAtlasGenerator) { throw std::runtime_error("FontAtlasGenerator is nullptr"); }
|
||||||
|
if (fontAtlasGenerator->GetAtlasInfo().empty()) { throw std::runtime_error("Glyphs are not loaded"); }
|
||||||
|
m_fontAtlasGenerator = fontAtlasGenerator;
|
||||||
|
m_cfg = config;
|
||||||
|
m_material.texture = const_cast<Texture*>(&m_fontAtlasGenerator->GetAtlas());
|
||||||
|
m_uniBuffer.Init(sizeof(TextConfig), &m_cfg, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextDrawable::GenerateText(const std::string& text, const Math::Vector3f& pos)
|
void TextDrawable::GenerateText(const std::string& text, const Math::Vector3f& pos)
|
||||||
{
|
{
|
||||||
if (!m_fontAtlasGenerator)
|
|
||||||
{
|
|
||||||
Logger::RENDER->error("Can't draw text. FontAtlasGenerator is nullptr");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_mesh)
|
|
||||||
{
|
|
||||||
delete m_mesh;
|
|
||||||
m_mesh = nullptr;
|
|
||||||
}
|
|
||||||
if (m_material)
|
|
||||||
{
|
|
||||||
delete m_material;
|
|
||||||
m_material = nullptr;
|
|
||||||
}
|
|
||||||
if (text.empty())
|
if (text.empty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::map<unicode_t, GlyphInfo>& symbols = m_fontAtlasGenerator->GetAtlasInfo();
|
std::map<unicode_t, GlyphInfo>& symbols = m_fontAtlasGenerator->GetAtlasInfo();
|
||||||
if (symbols.empty())
|
m_geometry.Close();
|
||||||
{
|
m_geometry.Init(text.size() * 4, text.size() * 6);
|
||||||
throw std::runtime_error("Glyphs are not loaded");
|
const Texture& atlasTex = *m_material.texture;
|
||||||
}
|
|
||||||
|
|
||||||
m_mesh = new Geometry();
|
|
||||||
m_material = new Material();
|
|
||||||
m_mesh->freeAfterUpload = false;
|
|
||||||
m_mesh->Init(text.size() * 4, text.size() * 6);
|
|
||||||
|
|
||||||
struct Bbox
|
struct Bbox
|
||||||
{
|
{
|
||||||
@@ -89,34 +89,31 @@ namespace OpenVulkano::Scene
|
|||||||
double ax = cursorX + bearingX;
|
double ax = cursorX + bearingX;
|
||||||
double ay = pos.y - (h - bearingY);
|
double ay = pos.y - (h - bearingY);
|
||||||
|
|
||||||
const Texture& atlasTex = m_fontAtlasGenerator->GetAtlas();
|
m_geometry.vertices[vIdx].position.x = ax;
|
||||||
m_material->texture = const_cast<Texture*>(&atlasTex);
|
m_geometry.vertices[vIdx].position.y = ay;
|
||||||
|
m_geometry.vertices[vIdx].position.z = 1;
|
||||||
m_mesh->vertices[vIdx].position.x = ax;
|
m_geometry.vertices[vIdx].textureCoordinates.x = l / atlasTex.resolution.x;
|
||||||
m_mesh->vertices[vIdx].position.y = ay;
|
m_geometry.vertices[vIdx].textureCoordinates.y = b / atlasTex.resolution.y;
|
||||||
m_mesh->vertices[vIdx].position.z = 1;
|
|
||||||
m_mesh->vertices[vIdx].textureCoordinates.x = l / atlasTex.resolution.x;
|
m_geometry.vertices[vIdx + 1].position.x = ax + w;
|
||||||
m_mesh->vertices[vIdx].textureCoordinates.y = b / atlasTex.resolution.y;
|
m_geometry.vertices[vIdx + 1].position.y = ay;
|
||||||
|
m_geometry.vertices[vIdx + 1].position.z = 1;
|
||||||
m_mesh->vertices[vIdx + 1].position.x = ax + w;
|
m_geometry.vertices[vIdx + 1].textureCoordinates.x = r / atlasTex.resolution.x;
|
||||||
m_mesh->vertices[vIdx + 1].position.y = ay;
|
m_geometry.vertices[vIdx + 1].textureCoordinates.y = b / atlasTex.resolution.y;
|
||||||
m_mesh->vertices[vIdx + 1].position.z = 1;
|
|
||||||
m_mesh->vertices[vIdx + 1].textureCoordinates.x = r / atlasTex.resolution.x;
|
m_geometry.vertices[vIdx + 2].position.x = ax + w;
|
||||||
m_mesh->vertices[vIdx + 1].textureCoordinates.y = b / atlasTex.resolution.y;
|
m_geometry.vertices[vIdx + 2].position.y = ay + h;
|
||||||
|
m_geometry.vertices[vIdx + 2].position.z = 1;
|
||||||
m_mesh->vertices[vIdx + 2].position.x = ax + w;
|
m_geometry.vertices[vIdx + 2].textureCoordinates.x = r / atlasTex.resolution.x;
|
||||||
m_mesh->vertices[vIdx + 2].position.y = ay + h;
|
m_geometry.vertices[vIdx + 2].textureCoordinates.y = t / atlasTex.resolution.y;
|
||||||
m_mesh->vertices[vIdx + 2].position.z = 1;
|
|
||||||
m_mesh->vertices[vIdx + 2].textureCoordinates.x = r / atlasTex.resolution.x;
|
m_geometry.vertices[vIdx + 3].position.x = ax;
|
||||||
m_mesh->vertices[vIdx + 2].textureCoordinates.y = t / atlasTex.resolution.y;
|
m_geometry.vertices[vIdx + 3].position.y = ay + h;
|
||||||
|
m_geometry.vertices[vIdx + 3].position.z = 1;
|
||||||
m_mesh->vertices[vIdx + 3].position.x = ax;
|
m_geometry.vertices[vIdx + 3].textureCoordinates.x = l / atlasTex.resolution.x;
|
||||||
m_mesh->vertices[vIdx + 3].position.y = ay + h;
|
m_geometry.vertices[vIdx + 3].textureCoordinates.y = t / atlasTex.resolution.y;
|
||||||
m_mesh->vertices[vIdx + 3].position.z = 1;
|
|
||||||
m_mesh->vertices[vIdx + 3].textureCoordinates.x = l / atlasTex.resolution.x;
|
m_geometry.SetIndices(indices, 6, 6 * i);
|
||||||
m_mesh->vertices[vIdx + 3].textureCoordinates.y = t / atlasTex.resolution.y;
|
|
||||||
|
|
||||||
m_mesh->SetIndices(indices, 6, 6 * i);
|
|
||||||
// TODO: change to lower value(or ideally remove completely) to avoid overlapping and make less space between symbols
|
// TODO: change to lower value(or ideally remove completely) to avoid overlapping and make less space between symbols
|
||||||
// when setting for depth comparison operator will be available( <= )
|
// when setting for depth comparison operator will be available( <= )
|
||||||
cursorX += info.glyphBox.advance + 0.08;
|
cursorX += info.glyphBox.advance + 0.08;
|
||||||
@@ -127,5 +124,6 @@ namespace OpenVulkano::Scene
|
|||||||
Logger::RENDER->error("Could not find glyph for character {}", c);
|
Logger::RENDER->error("Could not find glyph for character {}", c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SimpleDrawable::Init(m_shader, &m_geometry, &m_material, &m_uniBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,10 @@
|
|||||||
#include "SimpleDrawable.hpp"
|
#include "SimpleDrawable.hpp"
|
||||||
#include "FontAtlasGenerator.hpp"
|
#include "FontAtlasGenerator.hpp"
|
||||||
#include "Texture.hpp"
|
#include "Texture.hpp"
|
||||||
|
#include "Material.hpp"
|
||||||
|
#include "Geometry.hpp"
|
||||||
|
#include "UniformBuffer.hpp"
|
||||||
|
#include "Base/Logger.hpp"
|
||||||
#include "msdfgen.h"
|
#include "msdfgen.h"
|
||||||
#include "msdfgen-ext.h"
|
#include "msdfgen-ext.h"
|
||||||
#include "msdf-atlas-gen/msdf-atlas-gen.h"
|
#include "msdf-atlas-gen/msdf-atlas-gen.h"
|
||||||
@@ -37,16 +41,30 @@ namespace OpenVulkano::Scene
|
|||||||
class TextDrawable : public SimpleDrawable
|
class TextDrawable : public SimpleDrawable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextDrawable() = default;
|
static Shader& GetDefaultShader();
|
||||||
~TextDrawable();
|
TextDrawable(FontAtlasGenerator* fontAtlasGenerator, const TextConfig& config = TextConfig());
|
||||||
void SetUniformBuffer(UniformBuffer* buffer) { m_uniBuffer = buffer; }
|
|
||||||
void GenerateText(const std::string& text, const Math::Vector3f& pos = Math::Vector3f(0.f));
|
void GenerateText(const std::string& text, const Math::Vector3f& pos = Math::Vector3f(0.f));
|
||||||
void SetConfig(const TextConfig& cfg) { m_cfg = cfg; }
|
void SetConfig(const TextConfig& cfg) { m_cfg = cfg; }
|
||||||
|
void SetShader(Shader* shader) { m_shader = shader; }
|
||||||
TextConfig& GetConfig() { return m_cfg; }
|
TextConfig& GetConfig() { return m_cfg; }
|
||||||
void SetFontAtlasGenerator(FontAtlasGenerator* fontAtlasGenerator) { m_fontAtlasGenerator = fontAtlasGenerator; }
|
Shader* GetShader() { return m_shader; }
|
||||||
|
void SetFontAtlasGenerator(FontAtlasGenerator* fontAtlasGenerator)
|
||||||
|
{
|
||||||
|
if (!fontAtlasGenerator || fontAtlasGenerator->GetAtlasInfo().empty())
|
||||||
|
{
|
||||||
|
Logger::RENDER->error("FontAtlasGenerator is either nullptr or doesn't contain glyphs info");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_fontAtlasGenerator = fontAtlasGenerator;
|
||||||
|
m_material.texture = const_cast<Texture*>(&m_fontAtlasGenerator->GetAtlas());
|
||||||
|
}
|
||||||
FontAtlasGenerator* GetFontAtlasGenerator() { return m_fontAtlasGenerator; }
|
FontAtlasGenerator* GetFontAtlasGenerator() { return m_fontAtlasGenerator; }
|
||||||
private:
|
private:
|
||||||
|
Geometry m_geometry;
|
||||||
|
Material m_material;
|
||||||
|
UniformBuffer m_uniBuffer;
|
||||||
FontAtlasGenerator* m_fontAtlasGenerator = nullptr;
|
FontAtlasGenerator* m_fontAtlasGenerator = nullptr;
|
||||||
|
Shader* m_shader = &GetDefaultShader();
|
||||||
TextConfig m_cfg;
|
TextConfig m_cfg;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user