您的位置:首页 > 编程语言 > Qt开发

基于Qt的OpenGL编程(3.x以上GLSL可编程管线版)---(三)着色器

2018-04-10 14:52 543 查看
本篇目的是生成彩色三角形,如下图所示。并且按照Vries的方法优化类结构,详细的优化类思想及每条OpenGL函数的解析请看源教程。
[b](这是基于visual studio教程的原地址[/b]
[b]https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/)
[/b]




项目组织结构如下:





因为QOpenGLShader与QOpenGLShaderProgram对glfw繁杂的shader创立过程进行了大量简化,故我使用他们建立使用shader对象。QOpenGLShaderProgram对shader的数据管理非常方便,故不再在shader.h中移植下图这些成员函数,具体如何应用,直接使用shaderprogram.setUniformValue(shaderprogram.UniformLocation(name), value)即可。




shader.h#ifndef SHADER_H
#define SHADER_H

#include <QDebug>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QString>

class Shader {
public:
Shader(const QString& vertexSourcePath, const QString& fragmentSourcePath);
~Shader();
QOpenGLShaderProgram shaderProgram;

void use(){
shaderProgram.bind();
}

};

#endif // SHADER_Hshader.cpp#include "shader.h"

Shader::Shader(const QString& vertexPath, const QString& fragmentPath){
QOpenGLShader vertexShader(QOpenGLShader::Vertex);
bool success = vertexShader.compileSourceFile(vertexPath);
if(!success){
qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED" << endl;
qDebug() << vertexShader.log() << endl;
}

QOpenGLShader fragmentShader(QOpenGLShader::Fragment);
success =fragmentShader.compileSourceFile(fragmentPath);
if(!success){
qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED" << endl;
qDebug() << fragmentShader.log() << endl;
}

shaderProgram.addShader(&vertexShader);
shaderProgram.addShader(&fragmentShader);
success = shaderProgram.link();
if(!success){
qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED" << endl;
qDebug() << shaderProgram.log() << endl;
}
}

Shader::~Shader(){
}对于widget.h里的Triangle类,仍打算使用QOpenGLFunctions_3_3_core核心类对象,作为数据传输工具,因为QOpenGLFunctions类没有Vries所使用的glGenVertexArray()函数,即没有顶点数组对象这一概念,下图是原教程截图。现在在初学阶段,暂时仍使用core核心类,解决这一问题。



widget.h#ifndef WIDGET_H
#define WIDGET_H

#include <QOpenGLWidget>
#include <QDebug>
#include <QOpenGLFunctions_3_3_Core>
#include "shader.h"

class Triangle : public QOpenGLWidget
{
public:
Triangle();
GLuint a;
~Triangle();
protected:
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void paintGL();
private:
Shader *ourShader;
QOpenGLFunctions_3_3_Core *core;

};

#endif // WIDGET_Hwidget.cpp#include "widget.h"
GLuint VBO, VAO;

Triangle::Triangle(){
}

Triangle::~Triangle(){
}

void Triangle::initializeGL(){

//着色器部分
core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
ourShader = new Shader(":/shaders/vertexshadersource.vert", ":/shaders/fragmentshadersource.frag");

//VAO,VBO数据部分
GLfloat vertices[] = {
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // Bottom Left
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // Top
};

core->glGenVertexArrays(1, &VAO);//两个参数,第一个为需要创建的缓存数量。第二个为用于存储单一ID或多个ID的GLuint变量或数组的地址
core->glGenBuffers(1, &VBO);
core->glBindVertexArray(VAO);
core->glBindBuffer(GL_ARRAY_BUFFER, VBO);

core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0);
core->glEnableVertexAttribArray(0);
core->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
core->glEnableVertexAttribArray(1);

core->glBindBuffer(GL_ARRAY_BUFFER, 0);
core->glBindVertexArray(0);

core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);

}

void Triangle::resizeGL(int w, int h){
core->glViewport(0, 0, w, h);
}

void Triangle::paintGL(){

core->glClear(GL_COLOR_BUFFER_BIT);

ourShader->use();
core->glBindVertexArray(VAO);
core->glDrawArrays(GL_TRIANGLES, 0, 3);

}main.cpp#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Triangle t;
t.show();

return a.exec();
}这里对与shader。我们将其当作资源文件,放进资源进行管理,


想项目添加资源文件,增加资源前缀,这里网络上向qt添加资源的方法有很多,不再赘述。

vertexshadersource.vert#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;

out vec3 ourColor;

void main(){
gl_Position = vec4(aPos, 1.0f);
ourColor = aColor;
}fragmentshadersource.frag#version 330 core
out vec4 FragColor;
in vec3 ourColor;

void main(void)
{
FragColor = vec4(ourColor, 1.0f);
}将上述代码进行组装,则生成三角形窗口
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: