Switch to more compact TextGlyph vertex format

This commit is contained in:
Georg Hagen
2025-01-05 00:02:01 +01:00
parent 47a904f572
commit e9a1c629d9
13 changed files with 249 additions and 248 deletions

View File

@@ -7,6 +7,8 @@
#include "LabelDrawable.hpp"
#include "Scene/TextDrawable.hpp"
#include "Scene/DrawEncoder.hpp"
#include "Scene/Vertex.hpp"
#include "Scene/Shader/Shader.hpp"
#include "Scene/IFontAtlasGenerator.hpp"
#include "Base/Logger.hpp"
#include <optional>
@@ -39,10 +41,45 @@ namespace OpenVulkano::Scene
backgroundShader.cullMode = CullMode::NONE;
return backgroundShader;
}
}
Shader LabelDrawable::BACKGROUND_SHADER = MakeLabelBgShader(false);
Shader LabelDrawable::BACKGROUND_BILLBOARD_SHADER = MakeLabelBgShader(true);
Shader MakeLabelTextShader(const FontAtlasType type, const bool billboard)
{
Shader shader = TextDrawable::MakeDefaultShader(type);
shader.depthTest = false;
shader.depthCompareOp = CompareOp::LESS_OR_EQUAL;
if (billboard)
{
for (auto& program : shader.shaderPrograms)
{
if (program.type == ShaderProgramType::VERTEX)
{
program.name = "Shader/textBillboard";
break;
}
}
DescriptorSetLayoutBinding billboardUniformBinding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING;
billboardUniformBinding.stageFlags = ShaderProgramType::Type::VERTEX;
shader.AddDescriptorSetLayoutBinding(billboardUniformBinding, 4);
}
return shader;
}
Shader BACKGROUND_SHADER = MakeLabelBgShader(false);
Shader BACKGROUND_BILLBOARD_SHADER = MakeLabelBgShader(true);
std::array TEXT_SHADERS = {
MakeLabelTextShader(FontAtlasType::SDF, false),
MakeLabelTextShader(FontAtlasType::SDF, true),
MakeLabelTextShader(FontAtlasType::MSDF, false),
MakeLabelTextShader(FontAtlasType::MSDF, true),
MakeLabelTextShader(FontAtlasType::BITMAP, false),
MakeLabelTextShader(FontAtlasType::BITMAP, true),
};
Shader* GetTextShader(const FontAtlasType type, const bool billboard)
{
return &TEXT_SHADERS[static_cast<int>(type) << 1 | billboard];
}
}
LabelDrawable::LabelDrawable(const std::shared_ptr<AtlasData>& atlasData, const LabelDrawableSettings& settings, const bool isBillboard)
: Drawable(DrawEncoder::GetDrawEncoder<LabelDrawable>(), DrawPhase::MAIN), m_atlasData(atlasData), m_isBillboard(isBillboard)
@@ -52,7 +89,7 @@ namespace OpenVulkano::Scene
throw std::runtime_error("Can't create label drawable. Either glyphs or texture is empty");
}
SetLabelSettings(settings);
SetupShaders();
SetShader(IsBillboard() ? &BACKGROUND_BILLBOARD_SHADER : &BACKGROUND_SHADER);
SetupBuffers();
}
@@ -72,11 +109,10 @@ namespace OpenVulkano::Scene
if (text.empty()) return;
TextDrawable& textDrawable = m_texts.emplace_back(m_atlasData, config);
// do not render glyph's background
textDrawable.GetConfig().backgroundColor.a = 0;
textDrawable.GetConfig().backgroundColor.a = 0; // do not render glyph's background
double lineHeight = m_atlasData->meta.lineHeight;
textDrawable.GenerateText(text, m_position);
textDrawable.SetShader(&m_textShader);
textDrawable.SetShader(GetTextShader(m_atlasData->meta.atlasType, m_isBillboard));
m_bbox.Grow(textDrawable.GetBoundingBox());
// update position for next text entry
m_position.y = m_bbox.GetMin().y - lineHeight;
@@ -107,36 +143,6 @@ namespace OpenVulkano::Scene
return ray.IntersectAABB(m_bbox);
}
void LabelDrawable::SetupShaders()
{
SetShader(IsBillboard() ? &BACKGROUND_BILLBOARD_SHADER : &BACKGROUND_SHADER);
FontAtlasType fontAtlasType(static_cast<FontAtlasType::Type>(m_atlasData->meta.atlasType));
if (!m_isBillboard)
{
m_textShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/text");
}
else
{
m_textShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/billboard");
DescriptorSetLayoutBinding billboardUniformBinding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING;
billboardUniformBinding.stageFlags = ShaderProgramType::Type::VERTEX;
m_textShader.AddDescriptorSetLayoutBinding(billboardUniformBinding, 4);
}
DescriptorSetLayoutBinding textUniformBinding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING;
textUniformBinding.stageFlags = ShaderProgramType::FRAGMENT;
m_textShader.AddDescriptorSetLayoutBinding(textUniformBinding, 3);
m_textShader.AddShaderProgram(ShaderProgramType::FRAGMENT,
std::string(fontAtlasType.GetDefaultFragmentShader()));
m_textShader.AddVertexInputDescription(Vertex::GetVertexInputDescription());
m_textShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING, 2);
m_textShader.alphaBlend = true;
m_textShader.cullMode = CullMode::NONE;
m_textShader.depthWrite = false;
m_textShader.depthCompareOp = CompareOp::LESS_OR_EQUAL;
}
void LabelDrawable::SetupBuffers()
{
m_billboardBuffer.size = sizeof(BillboardControlBlock);

View File

@@ -6,12 +6,9 @@
#pragma once
#include "Base/Wrapper.hpp"
#include "Scene/Drawable.hpp"
#include "Scene/Shader/Shader.hpp"
#include "Scene/Texture.hpp"
#include "Scene/UniformBuffer.hpp"
#include "Scene/Vertex.hpp"
#include "Scene/BillboardControlBlock.hpp"
#include "Math/AABB.hpp"
#include "Scene/TextDrawable.hpp"
@@ -19,6 +16,8 @@
namespace OpenVulkano::Scene
{
class Shader;
struct LabelDrawableSettings
{
Math::Vector4f backgroundColor = { 1, 0, 0, 1 };
@@ -45,8 +44,6 @@ namespace OpenVulkano::Scene
class LabelDrawable final : public Drawable
{
static Shader BACKGROUND_SHADER, BACKGROUND_BILLBOARD_SHADER;
public:
LabelDrawable(const std::shared_ptr<AtlasData>& atlasData,
const LabelDrawableSettings& settings = LabelDrawableSettings(), bool isBillboard = false);
@@ -65,13 +62,11 @@ namespace OpenVulkano::Scene
std::optional<RayHit> Intersect(const Ray& ray) const override;
private:
void SetupShaders();
void SetupBuffers();
UniformBuffer m_billboardBuffer;
UniformBuffer m_labelBuffer;
std::list<TextDrawable> m_texts; // Using list instead of vector for stable iterators
Shader m_textShader;
LabelDrawableSettings m_settings;
LabelUniformData m_labelData;
std::shared_ptr<AtlasData> m_atlasData;