在编写着色器程序的时候如果不使用QOpenGLShaderProgram,那么程序写起来将是这样的
static const char* vertexShaderSource =
"#version 330 \n"
"layout(location = 0) in vec3 posVertex;\n"
"void main() {\n"
" gl_Position = vec4(posVertex, 1.0f);\n"
"}\n";
static const char* fragmentShaderSource =
"#version 330\n"
"out vec4 fragColor;\n"
"void main() {\n"
" fragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
"}\n";
/***************************************************/
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource,NULL);
glCompileShader(vertexShader);
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader,1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
可以看到程序都需要放在字符串中,这显然是非常的不方便的。
Qt通过QOpenGLShaderProgram进行了封装,以便方便的使用。
在Qt中使用QOpenGLShaderProgram的步骤
1、为了在QT中正常加载并编辑shader文件:在工具->选项 中设置编码规则为UTF-8。
2、在pro文件目录创建shapes.vert(顶点着色器),shapes.frag(片段着色器)两个文件
3、通过资源文件的方式加载进Qt。
资源文件的使用步骤参考https://mp.csdn.net/mp_blog/creation/editor/122430465
4、在shapes.vert和shapes.frag中写代码
可以看到就像在写C代码一样
5、在代码中使用QOpenGLShaderProgram加载着色器程序
void glWidget::initializeGL()
{
initializeOpenGLFunctions();
glGenVertexArrays(1,&VAO);
glGenBuffers(1,&VBO);
//绑定VBO和VAO对象
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW);
//告知显卡如何解析缓冲里的属性值
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3* sizeof (float),(void*)0);
//开启VAO管理的第一个属性值
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/*************************************************/
//使用QOpenGLShaderProgram
sharedprogram.addShaderFromSourceFile(QOpenGLShader::Vertex,":/opengl/shapes.vert");
sharedprogram.addShaderFromSourceFile(QOpenGLShader::Fragment,":/opengl/shapes.frag");
if (!sharedprogram.link())
qDebug()<<"error";
/*************************************************/
glBindVertexArray(0);
}
void glWidget::paintGL()
{
glClearColor(0.2f, 0.3f, 0.4f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
/*************************************************/
sharedprogram.bind();
/*************************************************/
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
}