Use same shader instance for all labeldrawables

This commit is contained in:
Georg Hagen
2025-01-03 22:23:24 +01:00
parent b866f5ac46
commit 61fa1546a0
2 changed files with 46 additions and 39 deletions

View File

@@ -15,16 +15,42 @@ namespace OpenVulkano::Scene
{
using namespace Math;
LabelDrawable::LabelDrawable(const std::shared_ptr<AtlasData>& atlasData, const LabelDrawableSettings& settings,
bool isBillboard)
: Drawable(DrawEncoder::GetDrawEncoder<LabelDrawable>(), DrawPhase::MAIN)
namespace
{
Shader MakeLabelBgShader(bool billboard)
{
Shader backgroundShader;
if (!billboard)
{
backgroundShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/label");
}
else
{
backgroundShader.AddShaderProgram(ShaderProgramType::VERTEX, "Shader/labelBillboard");
// binding for billboard's buffer
DescriptorSetLayoutBinding binding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING;
binding.stageFlags = ShaderProgramType::Type::VERTEX;
backgroundShader.AddDescriptorSetLayoutBinding(binding, 4);
}
backgroundShader.AddShaderProgram(ShaderProgramType::FRAGMENT, "Shader/label");
backgroundShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING, 2);
backgroundShader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING, 5);
backgroundShader.topology = Topology::TRIANGLE_STRIP;
backgroundShader.cullMode = CullMode::NONE;
return backgroundShader;
}
}
Shader LabelDrawable::BACKGROUND_SHADER = MakeLabelBgShader(false);
Shader LabelDrawable::BACKGROUND_BILLBOARD_SHADER = MakeLabelBgShader(true);
LabelDrawable::LabelDrawable(const std::shared_ptr<AtlasData>& atlasData, const LabelDrawableSettings& settings, bool isBillboard)
: Drawable(DrawEncoder::GetDrawEncoder<LabelDrawable>(), DrawPhase::MAIN), m_atlasData(atlasData), m_isBillboard(isBillboard)
{
if (atlasData->glyphs.empty() || !atlasData->texture.size)
{
throw std::runtime_error("Can't create label drawable. Either glyphs or texture is empty");
}
m_atlasData = atlasData;
m_isBillboard = isBillboard;
SetLabelSettings(settings);
SetupShaders();
SetupBuffers();
@@ -43,10 +69,7 @@ namespace OpenVulkano::Scene
void LabelDrawable::AddText(const std::string& text, const TextConfig& config)
{
if (text.empty())
{
return;
}
if (text.empty()) return;
TextDrawable& textDrawable = m_texts.emplace_back(m_atlasData, config);
// do not render glyph's background
@@ -104,24 +127,7 @@ namespace OpenVulkano::Scene
void LabelDrawable::SetupShaders()
{
if (!m_isBillboard)
{
m_backgroundShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/label");
}
else
{
m_backgroundShader.AddShaderProgram(OpenVulkano::ShaderProgramType::VERTEX, "Shader/labelBillboard");
// binding for billboard's buffer
DescriptorSetLayoutBinding binding = UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING;
binding.stageFlags = ShaderProgramType::Type::VERTEX;
m_backgroundShader.AddDescriptorSetLayoutBinding(binding, 4);
}
m_backgroundShader.AddShaderProgram(OpenVulkano::ShaderProgramType::FRAGMENT, "Shader/label");
m_backgroundShader.AddDescriptorSetLayoutBinding(Texture::DESCRIPTOR_SET_LAYOUT_BINDING, 2);
m_backgroundShader.AddDescriptorSetLayoutBinding(UniformBuffer::DESCRIPTOR_SET_LAYOUT_BINDING, 5);
m_backgroundShader.topology = Topology::TRIANGLE_STRIP;
m_backgroundShader.cullMode = CullMode::NONE;
SetShader(&m_backgroundShader);
SetShader(IsBillboard() ? &BACKGROUND_BILLBOARD_SHADER : &BACKGROUND_SHADER);
FontAtlasType fontAtlasType(static_cast<FontAtlasType::Type>(m_atlasData->meta.atlasType));
if (!m_isBillboard)

View File

@@ -46,6 +46,8 @@ 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);
@@ -53,25 +55,24 @@ namespace OpenVulkano::Scene
void SetLabelSettings(const LabelDrawableSettings& settings);
void SetBillboardSettings(const BillboardControlBlock& settings);
void SetPosition(const Math::Vector3f& pos) { m_position = pos; }
std::list<TextDrawable>& GetTexts() { return m_texts; }
LabelDrawableSettings& GetSettings() { return m_settings; }
UniformBuffer* GetBillboardBuffer() { return &m_billboardBuffer; }
UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; }
BillboardControlBlock& GetBillboardSettings() { return m_billboardSettings; }
Math::Vector3f& GetPosition() { return m_position; }
bool IsBillboard() const { return m_isBillboard; }
const Math::AABB& GetBoundingBox() const { return m_bbox; }
[[nodiscard]] std::list<TextDrawable>& GetTexts() { return m_texts; }
[[nodiscard]] LabelDrawableSettings& GetSettings() { return m_settings; }
[[nodiscard]] UniformBuffer* GetBillboardBuffer() { return &m_billboardBuffer; }
[[nodiscard]] UniformBuffer* GetLabelBuffer() { return &m_labelBuffer; }
[[nodiscard]] BillboardControlBlock& GetBillboardSettings() { return m_billboardSettings; }
[[nodiscard]] Math::Vector3f& GetPosition() { return m_position; }
[[nodiscard]] bool IsBillboard() const { return m_isBillboard; }
[[nodiscard]] const Math::AABB& GetBoundingBox() const { return m_bbox; }
std::optional<RayHit> Intersect(const Ray& ray) const override;
private:
void RecalculateBbox(const Math::AABB& other);
void SetupShaders();
void SetupBuffers();
private:
Shader m_backgroundShader;
UniformBuffer m_billboardBuffer;
UniformBuffer m_labelBuffer;
// list over vector to prevent memory reallocation and crash
std::list<TextDrawable> m_texts;
std::list<TextDrawable> m_texts; // Using list instead of vector for stable iterators
Shader m_textShader;
LabelDrawableSettings m_settings;
LabelUniformData m_labelData;