Extra2D/Extra2D/include/extra2d/render/text_renderer.h

110 lines
2.2 KiB
C++

#pragma once
#include <extra2d/asset/font_asset.h>
#include <extra2d/render/render_types.h>
#include <extra2d/render/render_device.h>
#include <extra2d/render/buffer.h>
#include <extra2d/render/vao.h>
#include <extra2d/render/material.h>
#include <glad/glad.h>
#include <glm/mat4x4.hpp>
#include <glm/vec2.hpp>
#include <glm/vec4.hpp>
#include <memory>
namespace extra2d {
/**
* @brief 文本顶点
*/
struct TextVertex {
float x, y;
float u, v;
float r, g, b, a;
};
/**
* @brief 文本渲染配置
*/
struct TextConfig {
float fontSize = 32.0f;
glm::vec4 color = glm::vec4(1.0f);
float outlineWidth = 0.0f;
glm::vec4 outlineColor = glm::vec4(0.0f);
};
/**
* @brief 文本渲染器
*
* 支持 MSDF 字体的高质量文本渲染
*/
class TextRenderer {
public:
static constexpr size_t MAX_VERTICES = 65536;
static constexpr size_t VERTICES_PER_CHAR = 6;
TextRenderer();
~TextRenderer();
/**
* @brief 初始化渲染器
*/
bool init();
/**
* @brief 关闭渲染器
*/
void shutdown();
/**
* @brief 开始批量渲染
*/
void begin(const glm::mat4& viewProjection);
/**
* @brief 绘制文本
*/
void drawText(FontAsset* font, const String32& text,
float x, float y, const TextConfig& config = {});
/**
* @brief 测量文本尺寸
*/
glm::vec2 measureText(FontAsset* font, const String32& text, float fontSize);
/**
* @brief 结束批量渲染
*/
void end();
/**
* @brief 获取绘制调用次数
*/
uint32 drawCalls() const { return drawCalls_; }
/**
* @brief 设置材质
*/
void setMaterial(Ref<MaterialInstance> material) { material_ = material; }
private:
std::unique_ptr<VAO> vao_;
std::unique_ptr<VertexBuffer> vbo_;
Array<TextVertex> vertices_;
size_t vertexCount_ = 0;
GLuint shader_ = 0;
glm::mat4 viewProjection_;
FontAsset* currentFont_ = nullptr;
uint32 drawCalls_ = 0;
Ref<MaterialInstance> material_;
bool createShader();
void flush();
void addChar(const GlyphInfo& glyph, float x, float y,
float scale, const glm::vec4& color);
};
} // namespace extra2d