QOpenGLWidget 中freetype渲染汉字的程序
时间: 2024-05-04 19:20:42 浏览: 79
FreeType字体渲染引擎
以下是一个简单的在QOpenGLWidget中使用freetype库渲染汉字的示例程序:
```cpp
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <ft2build.h>
#include FT_FREETYPE_H
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
GLWidget(QWidget *parent = 0) : QOpenGLWidget(parent), m_fontSize(32) {}
protected:
virtual void initializeGL()
{
initializeOpenGLFunctions();
// 初始化freetype库
FT_Library ft;
if (FT_Init_FreeType(&ft)) {
qFatal("Failed to initialize FreeType library");
}
// 加载字体文件
FT_Face face;
if (FT_New_Face(ft, "/path/to/font.ttf", 0, &face)) {
qFatal("Failed to load font");
}
// 设置字体大小
FT_Set_Pixel_Sizes(face, 0, m_fontSize);
// 构建字形纹理
glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// 预先渲染所有需要的字符
for (int i = 0; i < 256; ++i) {
if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {
qWarning("Failed to load glyph for character %d", i);
continue;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, face->glyph->bitmap.width, face->glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer);
Character character = {
m_textureId,
QVector2D(face->glyph->bitmap.width, face->glyph->bitmap.rows),
QVector2D(face->glyph->bitmap_left, m_fontSize - face->glyph->bitmap_top),
face->glyph->advance.x
};
m_characters.insert(i, character);
}
// 释放资源
FT_Done_Face(face);
FT_Done_FreeType(ft);
// 设置OpenGL状态
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
virtual void paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
// 绘制文本
QString text = "你好,世界!";
QVector2D position(50, 50);
for (int i = 0; i < text.length(); ++i) {
QChar c = text.at(i);
if (!m_characters.contains(c.unicode())) {
qWarning("Character %d not found in font", c.unicode());
continue;
}
Character character = m_characters.value(c.unicode());
glBindTexture(GL_TEXTURE_2D, character.textureId);
QVector2D topLeft = position + character.bearing;
QVector2D bottomRight = topLeft + character.size;
GLfloat vertices[] = {
topLeft.x(), topLeft.y(), 0.0f, 0.0f,
bottomRight.x(), topLeft.y(), 1.0f, 0.0f,
bottomRight.x(), bottomRight.y(), 1.0f, 1.0f,
topLeft.x(), bottomRight.y(), 0.0f, 1.0f
};
GLuint indices[] = {
0, 1, 2,
2, 3, 0
};
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), vertices);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), vertices + 2);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
position += QVector2D(character.advance, 0);
}
}
private:
struct Character {
GLuint textureId;
QVector2D size;
QVector2D bearing;
GLuint advance;
};
QHash<int, Character> m_characters;
GLuint m_textureId;
int m_fontSize;
};
```
这个程序使用了freetype库来加载指定的字体文件,预先渲染了需要的所有字符,并将它们存储在一个哈希表中以供使用。在绘制时,程序会遍历需要绘制的字符串,对于每个字符找到对应的字符纹理并绘制出来。
阅读全文