refactor(opengl): 优化UTF-8解码并使用simdutf库
替换手动UTF-8解码逻辑为simdutf库实现,提高解码效率和代码可维护性 同时清理头文件中不必要的include并统一代码格式
This commit is contained in:
parent
62b03144a1
commit
b1996dfc44
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue