refactor(opengl): 优化UTF-8解码并使用simdutf库

替换手动UTF-8解码逻辑为simdutf库实现,提高解码效率和代码可维护性
同时清理头文件中不必要的include并统一代码格式
This commit is contained in:
ChestnutYueyue 2026-02-18 19:48:14 +08:00
parent 62b03144a1
commit b1996dfc44
5 changed files with 80983 additions and 170 deletions

View File

@ -1,7 +1,6 @@
#pragma once
#include <glad/glad.h>
#include <cstdint>
#include <string>
namespace extra2d {
@ -10,9 +9,9 @@ namespace extra2d {
// OpenGL 版本信息
// ============================================================================
struct GLVersion {
int major = 0;
int minor = 0;
bool es = false; // 是否为 ES 版本
int major = 0;
int minor = 0;
bool es = false; // 是否为 ES 版本
};
// ============================================================================
@ -20,120 +19,120 @@ struct GLVersion {
// ============================================================================
class GLContext {
public:
/**
* @brief GLContext
*/
static GLContext& get();
/**
* @brief GLContext
*/
static GLContext &get();
/**
* @brief OpenGL
* @return true
*/
bool init();
/**
* @brief OpenGL
* @return true
*/
bool init();
/**
* @brief OpenGL
*/
void shutdown();
/**
* @brief OpenGL
*/
void shutdown();
/**
* @brief
* @return true
*/
bool isValid() const { return initialized_; }
/**
* @brief
* @return true
*/
bool isValid() const { return initialized_; }
/**
* @brief OpenGL
*/
const GLVersion& getVersion() const { return version_; }
/**
* @brief OpenGL
*/
const GLVersion &getVersion() const { return version_; }
/**
* @brief OpenGL
*/
std::string getVersionString() const;
/**
* @brief OpenGL
*/
std::string getVersionString() const;
/**
* @brief GPU
*/
std::string getVendor() const;
/**
* @brief GPU
*/
std::string getVendor() const;
/**
* @brief GPU
*/
std::string getRenderer() const;
/**
* @brief GPU
*/
std::string getRenderer() const;
/**
* @brief
* @param extension
* @return true
*/
bool hasExtension(const std::string& extension) const;
/**
* @brief
* @param extension
* @return true
*/
bool hasExtension(const std::string &extension) const;
/**
* @brief
*/
int getMaxTextureSize() const;
/**
* @brief
*/
int getMaxTextureSize() const;
/**
* @brief
*/
int getMaxTextureUnits() const;
/**
* @brief
*/
int getMaxTextureUnits() const;
/**
* @brief
*/
int getMaxVertexAttribs() const;
/**
* @brief
*/
int getMaxVertexAttribs() const;
/**
* @brief uniform
*/
int getMaxUniformBufferBindings() const;
/**
* @brief uniform
*/
int getMaxUniformBufferBindings() const;
/**
* @brief OpenGL ES
*/
bool isGLES() const { return version_.es; }
/**
* @brief OpenGL ES
*/
bool isGLES() const { return version_.es; }
/**
* @brief VAO
*/
bool hasVAO() const;
/**
* @brief VAO
*/
bool hasVAO() const;
/**
* @brief FBO
*/
bool hasFBO() const;
/**
* @brief FBO
*/
bool hasFBO() const;
/**
* @brief Shader
*/
bool hasShader() const;
/**
* @brief Shader
*/
bool hasShader() const;
private:
GLContext() = default;
~GLContext() = default;
GLContext() = default;
~GLContext() = default;
GLContext(const GLContext&) = delete;
GLContext& operator=(const GLContext&) = delete;
GLContext(const GLContext &) = delete;
GLContext &operator=(const GLContext &) = delete;
bool initialized_ = false;
GLVersion version_;
bool initialized_ = false;
GLVersion version_;
// 缓存的限制值
mutable int maxTextureSize_ = -1;
mutable int maxTextureUnits_ = -1;
mutable int maxVertexAttribs_ = -1;
mutable int maxUniformBufferBindings_ = -1;
// 缓存的限制值
mutable int maxTextureSize_ = -1;
mutable int maxTextureUnits_ = -1;
mutable int maxVertexAttribs_ = -1;
mutable int maxUniformBufferBindings_ = -1;
/**
* @brief OpenGL
*/
void parseVersion();
/**
* @brief OpenGL
*/
void parseVersion();
/**
* @brief OpenGL
*/
bool loadExtensions();
/**
* @brief OpenGL
*/
bool loadExtensions();
};
} // namespace extra2d

View File

@ -5,7 +5,6 @@
#include <extra2d/graphics/batch/sprite_batch.h>
#include <extra2d/graphics/shader/shader_interface.h>
#include <array>
#include <glad/glad.h>
#include <vector>
@ -17,52 +16,53 @@ namespace extra2d {
// ============================================================================
class GLSpriteBatch {
public:
GLSpriteBatch();
~GLSpriteBatch();
GLSpriteBatch();
~GLSpriteBatch();
// 初始化/关闭
bool init();
void shutdown();
// 初始化/关闭
bool init();
void shutdown();
// 批处理生命周期
void begin(const glm::mat4& viewProjection);
void end();
// 批处理生命周期
void begin(const glm::mat4 &viewProjection);
void end();
// 绘制单个精灵
void draw(const Texture& texture, const SpriteData& data);
// 绘制单个精灵
void draw(const Texture &texture, const SpriteData &data);
// 批量绘制(用于文本渲染优化)
void drawBatch(const Texture& texture, const std::vector<SpriteData>& sprites);
// 批量绘制(用于文本渲染优化)
void drawBatch(const Texture &texture,
const std::vector<SpriteData> &sprites);
// 获取绘制调用次数
uint32_t getDrawCallCount() const { return drawCallCount_; }
// 获取绘制调用次数
uint32_t getDrawCallCount() const { return drawCallCount_; }
private:
// OpenGL 对象
GLuint vao_;
GLBuffer vbo_; // 顶点缓冲区(动态)
GLBuffer ebo_; // 索引缓冲区(静态)
// OpenGL 对象
GLuint vao_;
GLBuffer vbo_; // 顶点缓冲区(动态)
GLBuffer ebo_; // 索引缓冲区(静态)
// 后端无关的批处理层
SpriteBatch batch_;
// 后端无关的批处理层
SpriteBatch batch_;
// 批次管理
struct Batch {
const GLTexture* texture;
size_t startVertex;
size_t vertexCount;
};
std::vector<Batch> batches_;
const GLTexture* currentTexture_;
// 批次管理
struct Batch {
const GLTexture *texture;
size_t startVertex;
size_t vertexCount;
};
std::vector<Batch> batches_;
const GLTexture *currentTexture_;
// 着色器和矩阵
Ptr<IShader> shader_;
uint32_t drawCallCount_;
glm::mat4 viewProjection_;
// 着色器和矩阵
Ptr<IShader> shader_;
uint32_t drawCallCount_;
glm::mat4 viewProjection_;
// 内部方法
void flush();
void submitBatch();
// 内部方法
void flush();
void submitBatch();
};
} // namespace extra2d

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@
#include <algorithm>
#include <cstring>
#include <fstream>
#include <simdutf/simdutf.h>
// 在实现文件中定义 STB 实现
#define STB_TRUETYPE_IMPLEMENTATION
@ -97,51 +98,18 @@ const Glyph *GLFontAtlas::getGlyph(char32_t codepoint) const {
// 测量文本尺寸 - 支持多行文本
// ============================================================================
Vec2 GLFontAtlas::measureText(const std::string &text) {
float width = 0.0f;
float maxWidth = 0.0f;
float height = lineHeight_;
float currentWidth = 0.0f;
for (size_t i = 0; i < text.length();) {
// 处理 UTF-8 编码
char32_t codepoint = 0;
unsigned char c = static_cast<unsigned char>(text[i]);
size_t utf32Length = simdutf::count_utf8(text.data(), text.size());
std::vector<char32_t> utf32Buffer(utf32Length);
size_t converted = simdutf::convert_utf8_to_utf32(text.data(), text.size(),
utf32Buffer.data());
if ((c & 0x80) == 0) {
// 单字节 ASCII
codepoint = c;
i++;
} else if ((c & 0xE0) == 0xC0) {
// 2字节 UTF-8
if (i + 1 >= text.length())
break;
codepoint =
((c & 0x1F) << 6) | (static_cast<unsigned char>(text[i + 1]) & 0x3F);
i += 2;
} else if ((c & 0xF0) == 0xE0) {
// 3字节 UTF-8
if (i + 2 >= text.length())
break;
codepoint = ((c & 0x0F) << 12) |
((static_cast<unsigned char>(text[i + 1]) & 0x3F) << 6) |
(static_cast<unsigned char>(text[i + 2]) & 0x3F);
i += 3;
} else if ((c & 0xF8) == 0xF0) {
// 4字节 UTF-8
if (i + 3 >= text.length())
break;
codepoint = ((c & 0x07) << 18) |
((static_cast<unsigned char>(text[i + 1]) & 0x3F) << 12) |
((static_cast<unsigned char>(text[i + 2]) & 0x3F) << 6) |
(static_cast<unsigned char>(text[i + 3]) & 0x3F);
i += 4;
} else {
// 无效的 UTF-8跳过
i++;
continue;
}
for (size_t i = 0; i < converted; ++i) {
char32_t codepoint = utf32Buffer[i];
// 处理换行
if (codepoint == '\n') {
maxWidth = std::max(maxWidth, currentWidth);
currentWidth = 0.0f;

File diff suppressed because it is too large Load Diff