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

View File

@ -5,7 +5,6 @@
#include <extra2d/graphics/batch/sprite_batch.h> #include <extra2d/graphics/batch/sprite_batch.h>
#include <extra2d/graphics/shader/shader_interface.h> #include <extra2d/graphics/shader/shader_interface.h>
#include <array>
#include <glad/glad.h> #include <glad/glad.h>
#include <vector> #include <vector>
@ -17,52 +16,53 @@ namespace extra2d {
// ============================================================================ // ============================================================================
class GLSpriteBatch { class GLSpriteBatch {
public: public:
GLSpriteBatch(); GLSpriteBatch();
~GLSpriteBatch(); ~GLSpriteBatch();
// 初始化/关闭 // 初始化/关闭
bool init(); bool init();
void shutdown(); void shutdown();
// 批处理生命周期 // 批处理生命周期
void begin(const glm::mat4& viewProjection); void begin(const glm::mat4 &viewProjection);
void end(); 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: private:
// OpenGL 对象 // OpenGL 对象
GLuint vao_; GLuint vao_;
GLBuffer vbo_; // 顶点缓冲区(动态) GLBuffer vbo_; // 顶点缓冲区(动态)
GLBuffer ebo_; // 索引缓冲区(静态) GLBuffer ebo_; // 索引缓冲区(静态)
// 后端无关的批处理层 // 后端无关的批处理层
SpriteBatch batch_; SpriteBatch batch_;
// 批次管理 // 批次管理
struct Batch { struct Batch {
const GLTexture* texture; const GLTexture *texture;
size_t startVertex; size_t startVertex;
size_t vertexCount; size_t vertexCount;
}; };
std::vector<Batch> batches_; std::vector<Batch> batches_;
const GLTexture* currentTexture_; const GLTexture *currentTexture_;
// 着色器和矩阵 // 着色器和矩阵
Ptr<IShader> shader_; Ptr<IShader> shader_;
uint32_t drawCallCount_; uint32_t drawCallCount_;
glm::mat4 viewProjection_; glm::mat4 viewProjection_;
// 内部方法 // 内部方法
void flush(); void flush();
void submitBatch(); void submitBatch();
}; };
} // namespace extra2d } // namespace extra2d

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff