Qt QOpenGLShaderProgram详解
1. 概述
QOpenGLShaderProgram
是 Qt 框架中用于管理 OpenGL 着色器程序的类。它提供了一种方便的方式来创建、编译和链接着色器,以及管理着色器程序中的属性和统一变量。通过 QOpenGLShaderProgram
,开发者可以轻松地将顶点着色器和片段着色器组合成一个完整的着色器程序,并在 OpenGL 渲染中使用。
2. 重要函数
构造函数和析构函数
-
QOpenGLShaderProgram(QObject *parent = nullptr)
构造一个新的着色器程序。 -
virtual ~QOpenGLShaderProgram()
析构函数,删除着色器程序。
添加着色器
-
bool addShader(QOpenGLShader *shader)
添加一个已编译的着色器。 -
bool addShaderFromSourceCode(QOpenGLShader::ShaderType type, const char *source)
从源代码编译并添加着色器。 -
bool addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QByteArray &source)
从 QByteArray 源代码编译并添加着色器。 -
bool addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QString &source)
从 QString 源代码编译并添加着色器。 -
bool addShaderFromSourceFile(QOpenGLShader::ShaderType type, const QString &fileName)
从文件编译并添加着色器。
缓存着色器
-
bool addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type, const char *source)
编译并添加一个可缓存的着色器(源码为 C 字符串)。 -
bool addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type, const QByteArray &source)
编译并添加一个可缓存的着色器(源码为 QByteArray)。 -
bool addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type, const QString &source)
编译并添加一个可缓存的着色器(源码为 QString)。 -
bool addCacheableShaderFromSourceFile(QOpenGLShader::ShaderType type, const QString &fileName)
从文件编译并添加一个可缓存的着色器。
链接和绑定
-
bool link()
链接着色器程序。 -
bool bind()
绑定着色器程序到当前的 OpenGL 上下文。 -
void release()
释放当前绑定的着色器程序。 -
bool isLinked() const
检查着色器程序是否已成功链接。
属性和统一变量
-
int attributeLocation(const char *name) const
获取属性的位置。 -
int uniformLocation(const char *name) const
获取统一变量的位置。 -
void setUniformValue(const char *name, const QVariant &value)
设置统一变量的值。 -
void setUniformValueArray(const char *name, const GLfloat *values, int count, int tupleSize)
设置统一变量数组的值。
其他
-
QString log() const
获取最近一次编译或链接操作的错误日志。 -
GLuint programId() const
获取 OpenGL 着色器程序的 ID。 -
void removeAllShaders()
移除所有着色器。 -
void removeShader(QOpenGLShader *shader)
移除指定的着色器。 -
QVector<float> defaultInnerTessellationLevels() const
获取默认的内部分割级别。 -
QVector<float> defaultOuterTessellationLevels() const
获取默认的外部分割级别。 -
int maxGeometryOutputVertices() const
获取几何着色器的最大输出顶点数。 -
int patchVertexCount() const
获取补丁顶点数。 -
void setDefaultInnerTessellationLevels(const QVector<float> &levels)
设置默认的内部分割级别。 -
void setDefaultOuterTessellationLevels(const QVector<float> &levels)
设置默认的外部分割级别。 -
void setPatchVertexCount(int count)
设置补丁顶点数。
静态成员函数
-
static bool hasOpenGLShaderPrograms(QOpenGLContext *context = nullptr)
检查当前 OpenGL 上下文是否支持着色器程序。如果context
为nullptr
,则使用当前上下文。
3. 重要信号
QOpenGLShaderProgram
没有提供信号。它主要用于着色器的管理和操作,不涉及信号与槽机制。
4. 常用枚举类型
QOpenGLShaderProgram
本身没有定义枚举类型,但与之紧密相关的 QOpenGLShader
类定义了以下枚举类型:
-
QOpenGLShader::ShaderType
用于指定着色器的类型,如:-
Vertex
:顶点着色器 -
Fragment
:片段着色器 -
Geometry
:几何着色器 -
TessellationControl
:细分控制着色器 -
TessellationEvaluation
:细分评估着色器
-
#include "widget.h"
float vertices[] = {
// 位置 // 颜色
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 右下
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 左下
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 顶部
};
MyGLWidget::MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) {}
MyGLWidget::~MyGLWidget()
{
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
}
void MyGLWidget::initializeGL()
{
initializeOpenGLFunctions(); // 初始化 OpenGL 函数
//创建、绑定VAO
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//创建、绑定VBO + 填充数据
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// 颜色属性
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float)));
glEnableVertexAttribArray(1);
//解绑缓冲区和 VAO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
shader = new QOpenGLShaderProgram;
if (!shader->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader/shader.vert")) {
qDebug() << "Vertex shader compile failed:" << shader->log();
return;
}
if (!shader->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader/shader.frag")) {
qDebug() << "Fragment shader compile failed:" << shader->log();
return;
}
// 链接着色器程序
if (!shader->link())
{
qDebug() << "Shader program link failed:" << shader->log();
return;
}
}
void MyGLWidget::paintGL()
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲区
shader->bind();
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
}
void MyGLWidget::resizeGL(int w, int h)
{
glViewport(0, 0, w, h); // 设置视口大小
}
觉得有帮助的话,打赏一下呗。。
需要商务合作(定制程序)的欢迎私信!!