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