QOpenGLShaderProgram绘制文本文字, 给出列子
时间: 2023-05-26 13:01:02 浏览: 118
首先,我们需要加载字体文件,并创建一个QFont对象:
```cpp
QFont font;
font.setPixelSize(16);
QFontDatabase fontDB;
QString fontPath = "path/to/font.ttf";
int fontId = fontDB.addApplicationFont(fontPath);
QString fontName = fontDB.applicationFontFamilies(fontId).at(0);
font.setFamily(fontName);
```
然后,我们创建一个QPainter对象,设置字体和颜色,绘制文本文字:
```cpp
QPainter painter(this);
painter.setFont(font);
painter.setPen(QColor(Qt::white));
QPointF textPos(10, 20);
QString text = "Hello, World!";
painter.drawText(textPos, text);
```
最后,我们创建一个简单的QOpenGLWidget子类,使用QOpenGLShaderProgram渲染文本文字:
```cpp
#include <QOpenGLWidget>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
class TextWidget : public QOpenGLWidget
{
Q_OBJECT
public:
explicit TextWidget(QWidget *parent = nullptr);
protected:
void initializeGL() override;
void paintGL() override;
private:
QOpenGLShaderProgram m_program;
QOpenGLBuffer m_vertexBuffer;
QOpenGLBuffer m_indexBuffer;
};
TextWidget::TextWidget(QWidget *parent)
: QOpenGLWidget(parent)
{
}
void TextWidget::initializeGL()
{
// 顶点数据
const QVector<float> vertexData = {
// 位置 // 纹理坐标
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f, 0.0f
};
// 索引数据
const QVector<GLuint> indexData = {
0, 1, 2,
2, 3, 0
};
// 编译顶点着色器
QOpenGLShader vertexShader(QOpenGLShader::Vertex);
vertexShader.compileSourceCode(
"attribute vec2 vertexPosition;\n"
"attribute vec2 vertexTexCoord;\n"
"uniform mat4 modelViewProjectionMatrix;\n"
"varying vec2 texCoord;\n"
"void main() {\n"
" gl_Position = modelViewProjectionMatrix * vec4(vertexPosition, 0.0, 1.0);\n"
" texCoord = vertexTexCoord;\n"
"}\n"
);
// 编译片元着色器
QOpenGLShader fragmentShader(QOpenGLShader::Fragment);
fragmentShader.compileSourceCode(
"uniform sampler2D texture;\n"
"varying vec2 texCoord;\n"
"void main() {\n"
" gl_FragColor = texture2D(texture, texCoord);\n"
"}\n"
);
// 绑定着色器程序
m_program.addShader(&vertexShader);
m_program.addShader(&fragmentShader);
m_program.bindAttributeLocation("vertexPosition", 0);
m_program.bindAttributeLocation("vertexTexCoord", 1);
m_program.link();
// 创建顶点缓冲
m_vertexBuffer.create();
m_vertexBuffer.bind();
m_vertexBuffer.allocate(vertexData.constData(), vertexData.count() * sizeof(GLfloat));
m_vertexBuffer.release();
// 创建索引缓冲
m_indexBuffer.create();
m_indexBuffer.bind();
m_indexBuffer.allocate(indexData.constData(), indexData.count() * sizeof(GLuint));
m_indexBuffer.release();
}
void TextWidget::paintGL()
{
// 清空背景
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 绑定着色器程序和缓冲
m_program.bind();
m_vertexBuffer.bind();
m_indexBuffer.bind();
// 设置模型矩阵和投影矩阵
QMatrix4x4 modelMatrix;
modelMatrix.setToIdentity();
modelMatrix.translate(0.5f, 0.5f, 0.0f);
QMatrix4x4 projectionMatrix;
projectionMatrix.setToIdentity();
projectionMatrix.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
QMatrix4x4 modelViewProjectionMatrix = projectionMatrix * modelMatrix;
m_program.setUniformValue("modelViewProjectionMatrix", modelViewProjectionMatrix);
// 加载字体纹理并绑定到0号纹理单元
QImage img("path/to/font.jpg");
GLuint textureId = 0;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.constBits());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
// 激活纹理单元
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
m_program.setUniformValue("texture", 0);
// 绘制
m_program.enableAttributeArray(0);
m_program.enableAttributeArray(1);
m_program.setAttributeBuffer(0, GL_FLOAT, 0, 2, sizeof(GLfloat) * 4);
m_program.setAttributeBuffer(1, GL_FLOAT, sizeof(GLfloat) * 2, 2, sizeof(GLfloat) * 4);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
// 解绑缓冲
m_indexBuffer.release();
m_vertexBuffer.release();
m_program.disableAttributeArray(0);
m_program.disableAttributeArray(1);
m_program.release();
}
```
这样,我们就可以渲染出一段文本文字。需要注意的是,上述代码中的字体纹理文件是一张包含所有字符的图片,每个字符对应纹理中的一个矩形区域,需要根据需要进行纹理坐标的计算。
阅读全文