基于Qt的OpenGL编程(3.x以上GLSL可编程管线版)---(二)你好,三角形_QOpenGLShader版

(这篇文章,代码部分感谢RyuZhihao123的技术支持,他的blog如下,一个很有趣的技术blog

https://my.csdn.net/mahabharata_)

本篇文章,是一项带引号的“翻译”类型文章。

Joey De Vries  的现代OpenGL教程是我看过最好的图形学教程,没有之一。奈何原作者是在Visual Studio平台进行开发,针对GUI和OpenGL的结合,没有多言。在自己实际开发应用中,没有好的GUI确是造成不少困扰,故我欲作为一名搬运工,将Vries大神的代码进行Qt平台的“移植”。预了解代码中关于OpenGL函数的详细解释,请看Vries的教程,连接如下。

(这是此篇教程的原地址https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/)

本篇目的是创立窗口,生成三角形,如下图所示。

Qt对OpenGL的支持,要求,必须public继承QOpenGLWidget类,然后重写这三个函数。

这里介绍第三种方法,使用符合Qt自身编程风格的QOpenGLShader,QOpenGLShaderProgram类,创造Shader类,用QOpenGLFunctions进行数据传送。目前已知,这种基于Qt自身的OpenGL较之原版,缺少顶点数组对象VertexArrayObject,即VAO的功能

 

项目组织结构如下:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QOpenGLWidget>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QDebug>
#include <QOpenGLFunctions>

class Triangle : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    Triangle();
    ~Triangle();
protected:
    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();
private:
    QOpenGLShaderProgram shaderProgram;
    QVector<QVector3D> vertices;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"

const char *vertexShaderSource =
        "#version 330 core\n"
        "layout(location = 0) in vec3 aPos;\n"
        "void main(){\n"
        "  gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0f);\n"
        "}\n\0";
const char *fragmentShaderSource =
        "#version 330 core\n"
        "out vec4 FragColor;\n"
        "void main(){\n"
        "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
        "}\n\0";
Triangle::Triangle(){

}

Triangle::~Triangle(){

}

void Triangle::initializeGL(){
    this->initializeOpenGLFunctions();//这个init()函数至关重要,如果继承QOpenGlFunctions,必须使用这个初始化函数
    //着色器部分
    QOpenGLShader vertexShader(QOpenGLShader::Vertex);
    bool success = vertexShader.compileSourceCode(vertexShaderSource);
    if(!success){
        qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED" << endl;
        return;
    }

    QOpenGLShader fragmentShader(QOpenGLShader::Fragment);
    success = fragmentShader.compileSourceCode(fragmentShaderSource);
    if(!success){
        qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED" << endl;
        return;
    }

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

    //VAO,VBO数据部分
    vertices.append(QVector3D(-0.5, -0.5, 0.0));
    vertices.append(QVector3D(0.5, -0.5, 0.0));
    vertices.append(QVector3D(0.0, 0.5, 0.0));
}

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

void Triangle::paintGL(){
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);


    shaderProgram.bindAttributeLocation("aPos", 0);// 等于glUseProgram(shaderProgram)
    shaderProgram.enableAttributeArray(0);
    shaderProgram.setAttributeArray(0, vertices.data());
    glDrawArrays(GL_TRIANGLES, 0, vertices.size());

}

main.cpp

#include "widget.h"
#include <QApplication>

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

    return a.exec();
}

 

展开阅读全文

没有更多推荐了,返回首页