• 着色器


    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QGLWidget>
    #include <QOpenGLShader>
    #include <QOpenGLShaderProgram>
    #include <QDebug>
    #include <QOpenGLFunctions>
    #include <QOpenGLFunctions_3_3_Core>
    #include <QTime>
    #include <QtMath>
    #include <QTimer>
    
    namespace Ui {
    class Widget;
    }
    
    class Triangle : public QGLWidget, protected QOpenGLFunctions
    {
        Q_OBJECT
    
    public:
        explicit Triangle();
        ~Triangle();
    protected:
        virtual void initializeGL();
        virtual void paintGL();
        virtual void resizeGL(int w, int h);
    private:
        GLuint shaderProgram;
        QOpenGLFunctions_3_3_Core *core;
        shader *ourShader;
    };
    
    #endif // WIDGET_H
    widget.h
    #include "widget.h"
    #include "ui_widget.h"
    
    GLuint VBO, VAO;
    const char *vertexShaderSource ="#version 330 core
    "
        "layout (location = 0) in vec3 aPos;
    "
        "void main()
    "
        "{
    "
        "   gl_Position = vec4(aPos, 1.0);
    "
        "}";
    
    const char *fragmentShaderSource = "#version 330 core
    "
        "out vec4 FragColor;
    "
        "uniform vec4 ourColor;
    "
        "void main()
    "
        "{
    "
        "   FragColor = ourColor;
    "
        "}
    ";
    
    
    Triangle::Triangle()
    {
    
    }
    
    Triangle::~Triangle()
    {
    
    }
    
    void Triangle::initializeGL()
    {
        //着色器部分
        core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
        if (!core) {
              qWarning() << "Could not obtain required OpenGL context version";
              exit(1);
        }
    
        GLuint vertexShader = core->glCreateShader(GL_VERTEX_SHADER);
        core->glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
        core->glCompileShader(vertexShader);
        // check for shader compile errors
        int success;
        char infoLog[512];
        core->glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
        if (!success) {
            core->glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << endl;
        }
        // fragment shader
        GLuint fragmentShader;
        fragmentShader = core->glCreateShader(GL_FRAGMENT_SHADER);
        core->glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
        core->glCompileShader(fragmentShader);
        core->glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
        if (!success) {
            core->glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
    " << infoLog << endl;
        }
    
        shaderProgram = core->glCreateProgram();
        core->glAttachShader(shaderProgram, vertexShader);
        core->glAttachShader(shaderProgram, fragmentShader);
        core->glLinkProgram(shaderProgram);
        core->glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
        if (!success) {
            core->glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED
    " << infoLog << endl;
        }
    
        core->glDeleteShader(vertexShader);
        core->glDeleteShader(fragmentShader);
    
        float vertices[] = {
            // positions         // colors
             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);
        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), nullptr);
        core->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (void*)(3 * sizeof(float)));
        core->glEnableVertexAttribArray(0);
    
        QTimer *timer = new QTimer(this);
        timer->setInterval(100);
        connect(timer, &QTimer::timeout, this, [=](){
            repaint();});
        timer->start();
    }
    
    void Triangle::paintGL()
    {
        core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        core->glClear(GL_COLOR_BUFFER_BIT);
    
        core->glUseProgram(shaderProgram);
        core->glBindVertexArray(VAO);
    
        float timeValue = QTime(0,0,0).msecsTo(QTime::currentTime())/1000.0f;
        float greenValue = qSin(timeValue) / 2.0f + 0.5f;
        qDebug()<<"greenValue"<<greenValue;
        int vertexColorLocation = core->glGetUniformLocation(shaderProgram, "ourColor");
        core->glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
    
    
        core->glDrawArrays(GL_TRIANGLES, 0, 3);
        core->glUseProgram(0);
    }
    
    void Triangle::resizeGL(int w, int h)
    {
        core->glViewport(0, 0, w, h);
    }
    widget.cpp

    更多属性

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QGLWidget>
    #include <QOpenGLShader>
    #include <QOpenGLShaderProgram>
    #include <QDebug>
    #include <QOpenGLFunctions>
    #include <QOpenGLFunctions_3_3_Core>
    #include <QTime>
    #include <QtMath>
    #include <QTimer>
    
    #include "shader.h"
    
    namespace Ui {
    class Widget;
    }
    
    class Triangle : public QGLWidget, protected QOpenGLFunctions
    {
        Q_OBJECT
    
    public:
        explicit Triangle();
        ~Triangle();
    protected:
        virtual void initializeGL();
        virtual void paintGL();
        virtual void resizeGL(int w, int h);
    private:
        GLuint shaderProgram;
        QOpenGLFunctions_3_3_Core *core;
        shader *m_shader;
    };
    
    #endif // WIDGET_H
    widget.h
    #include "widget.h"
    #include "ui_widget.h"
    
    GLuint VBO, VAO;
    const char *vertexShaderSource ="#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.0);
    "
        "   ourColor = aColor;
    "
        "}";
    
    const char *fragmentShaderSource = "#version 330 core
    "
        "out vec4 FragColor;
    "
        "in vec3 ourColor;
    "
        "void main()
    "
        "{
    "
        "   FragColor = vec4(ourColor, 1.0f);
    "
        "}
    ";
    
    
    Triangle::Triangle()
    {
    
    }
    
    Triangle::~Triangle()
    {
    
    }
    
    void Triangle::initializeGL()
    {
        //着色器部分
        core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
        if (!core) {
              qWarning() << "Could not obtain required OpenGL context version";
              exit(1);
        }
    
        GLuint vertexShader = core->glCreateShader(GL_VERTEX_SHADER);
        core->glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
        core->glCompileShader(vertexShader);
        // check for shader compile errors
        int success;
        char infoLog[512];
        core->glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
        if (!success) {
            core->glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << endl;
        }
        // fragment shader
        GLuint fragmentShader;
        fragmentShader = core->glCreateShader(GL_FRAGMENT_SHADER);
        core->glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
        core->glCompileShader(fragmentShader);
        // check for shader compile errors
        core->glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
        if (!success) {
            core->glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
    " << infoLog << endl;
        }
    
        // link shaders
        shaderProgram = core->glCreateProgram();
        core->glAttachShader(shaderProgram, vertexShader);
        core->glAttachShader(shaderProgram, fragmentShader);
        core->glLinkProgram(shaderProgram);
        core->glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
        if (!success) {
            core->glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED
    " << infoLog << endl;
        }
    
        core->glDeleteShader(vertexShader);
        core->glDeleteShader(fragmentShader);
    
        float vertices[] = {
            // positions         // colors
             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);
        core->glGenBuffers(1, &VBO);
        core->glBindVertexArray(VAO);
    
        core->glBindBuffer(GL_ARRAY_BUFFER, VBO);
        core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
        //position attribute
        core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), nullptr);
        core->glEnableVertexAttribArray(0);
        //color attribute
        core->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (void*)(3 * sizeof(float)));
        core->glEnableVertexAttribArray(1);
    }
    
    void Triangle::paintGL()
    {
        core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        core->glClear(GL_COLOR_BUFFER_BIT);
    
        core->glUseProgram(shaderProgram);
        core->glBindVertexArray(VAO);
        core->glDrawArrays(GL_TRIANGLES, 0, 3);
        core->glUseProgram(0);
    }
    
    void Triangle::resizeGL(int w, int h)
    {
        core->glViewport(0, 0, w, h);
    }
    widget.cpp

    自己的着色器

    #ifndef SHADER_H
    #define SHADER_H
    
    #include <QObject>
    #include <QDebug>
    #include <QOpenGLShader>
    #include <QOpenGLShaderProgram>
    #include <QString>
    
    class shader : public QObject
    {
        Q_OBJECT
    public:
        shader(const QString& vertexSourcePath, const QString &fragmentSourcePath);
        ~shader();
        QOpenGLShaderProgram shaderProgram;
    
        void use() {
            shaderProgram.bind();
        }
    
    signals:
    
    public slots:
    };
    
    #endif // SHADER_H
    shader.h
    #include "shader.h"
    
    shader::shader(const QString &vertexSourcePath, const QString &fragmentSourcePath)
    {
        QOpenGLShader vertexShader(QOpenGLShader::Vertex);
        bool success = vertexShader.compileSourceFile(vertexSourcePath);
        if(!success){
            qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED" << endl;
            qDebug() << vertexShader.log() << endl;
        }
    
        QOpenGLShader fragmentShader(QOpenGLShader::Fragment);
        success  =fragmentShader.compileSourceFile(fragmentSourcePath);
        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()
    {
    
    }
    shader.cpp
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QGLWidget>
    #include <QOpenGLShader>
    #include <QOpenGLShaderProgram>
    #include <QDebug>
    #include <QOpenGLFunctions>
    #include <QOpenGLFunctions_3_3_Core>
    #include <QTime>
    #include <QtMath>
    #include <QTimer>
    
    #include "shader.h"
    
    namespace Ui {
    class Widget;
    }
    
    class Triangle : public QGLWidget, protected QOpenGLFunctions
    {
        Q_OBJECT
    
    public:
        explicit Triangle();
        ~Triangle();
    protected:
        virtual void initializeGL();
        virtual void paintGL();
        virtual void resizeGL(int w, int h);
    private:
    //    GLuint shaderProgram;
        QOpenGLFunctions_3_3_Core *core;
        shader *ourShader;
    };
    
    #endif // WIDGET_H
    widget.h
    #include "widget.h"
    #include "ui_widget.h"
    
    GLuint VBO, VAO;
    const char *vertexShaderSource ="#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.0);
    "
        "   ourColor = aColor;
    "
        "}";
    
    const char *fragmentShaderSource = "#version 330 core
    "
        "out vec4 FragColor;
    "
        "in vec3 ourColor;
    "
        "void main()
    "
        "{
    "
        "   FragColor = vec4(ourColor, 1.0f);
    "
        "}
    ";
    
    
    Triangle::Triangle()
    {
    
    }
    
    Triangle::~Triangle()
    {
    
    }
    
    void Triangle::initializeGL()
    {
        //着色器部分
        core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
        if (!core) {
              qWarning() << "Could not obtain required OpenGL context version";
              exit(1);
        }
        ourShader = new shader(":/vertexshadersource.vert", ":/fragmentshadersource.frag");
    
        GLuint vertexShader = core->glCreateShader(GL_VERTEX_SHADER);
        core->glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
        core->glCompileShader(vertexShader);
        // check for shader compile errors
        int success;
        char infoLog[512];
        core->glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
        if (!success) {
            core->glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << endl;
        }
        // fragment shader
        GLuint fragmentShader;
        fragmentShader = core->glCreateShader(GL_FRAGMENT_SHADER);
        core->glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
        core->glCompileShader(fragmentShader);
        // check for shader compile errors
        core->glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
        if (!success) {
            core->glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
    " << infoLog << endl;
        }
    
        // link shaders
    //    shaderProgram = core->glCreateProgram();
    //    core->glAttachShader(shaderProgram, vertexShader);
    //    core->glAttachShader(shaderProgram, fragmentShader);
    //    core->glLinkProgram(shaderProgram);
    //    core->glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    //    if (!success) {
    //        core->glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
    //        qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED
    " << infoLog << endl;
    //    }
    
        core->glDeleteShader(vertexShader);
        core->glDeleteShader(fragmentShader);
    
        float vertices[] = {
            // positions         // colors
             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);
        core->glGenBuffers(1, &VBO);
        core->glBindVertexArray(VAO);
    
        core->glBindBuffer(GL_ARRAY_BUFFER, VBO);
        core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
        //position attribute
        core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), nullptr);
        core->glEnableVertexAttribArray(0);
        //color attribute
        core->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (void*)(3 * sizeof(float)));
        core->glEnableVertexAttribArray(1);
    }
    
    void Triangle::paintGL()
    {
        core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        core->glClear(GL_COLOR_BUFFER_BIT);
    
        ourShader->use();
    //    core->glUseProgram(shaderProgram);
        core->glBindVertexArray(VAO);
        core->glDrawArrays(GL_TRIANGLES, 0, 3);
        core->glUseProgram(0);
    }
    
    void Triangle::resizeGL(int w, int h)
    {
        core->glViewport(0, 0, w, h);
    }
    widget.cpp

    着色器练习

    1. 修改顶点着色器让三角形上下颠倒:
      #version 330 core
      layout (location = 0) in vec3 aPos;
      layout (location = 1) in vec3 aColor;
      
      out vec3 ourColor;
      
      void main(){
        gl_Position = vec4(aPos.x, -aPos.y, aPos.z, 1.0f);
        ourColor = aColor;
      }
      vertexshadersource.vert
    2. 使用uniform定义一个水平偏移量,在顶点着色器中使用这个偏移量把三角形移动到屏幕右侧:
      void Triangle::paintGL()
      {
          core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
          core->glClear(GL_COLOR_BUFFER_BIT);
      
          ourShader->use();
          ourShader->shaderProgram.setUniformValue("xOffset", 0.5f);
      //    core->glUseProgram(shaderProgram);
          core->glBindVertexArray(VAO);
          core->glDrawArrays(GL_TRIANGLES, 0, 3);
          core->glUseProgram(0);
      }
      
      //vertexshadersource.vert
      #version 330 core
      layout (location = 0) in vec3 aPos;
      layout (location = 1) in vec3 aColor;
      
      out vec3 ourColor;
      
      uniform float xOffset;
      
      void main(){
        gl_Position = vec4(aPos.x + xOffset, -aPos.y, aPos.z, 1.0f);
        ourColor = aColor;
      }
      答案
    3. 使用out关键字把顶点位置输出到片段着色器,并将片段的颜色设置为与顶点位置相等(来看看连顶点位置值都在三角形中被插值的结果)。做完这些后,尝试回答下面的问题:为什么在三角形的左下角是黑的?:
      fragmentshadersource.frag
      #version 330 core
      out vec4 FragColor;
      //in vec3 ourColor;
      in vec3 ourPosition;
      
      void main(void)
      {
          FragColor = vec4(ourPosition, 1.0f);
      }
      
      vertexshadersource.vert
      #version 330 core
      layout (location = 0) in vec3 aPos;
      layout (location = 1) in vec3 aColor;
      
      out vec3 ourPosition;
      
      void main(){
        gl_Position = vec4(aPos, 1.0f);
        ourPosition = aPos;
      }
      
      /* 
      Answer to the question: Do you know why the bottom-left side is black?
      -- --------------------------------------------------------------------
      Think about this for a second: the output of our fragment's color is equal to the (interpolated) coordinate of 
      the triangle. What is the coordinate of the bottom-left point of our triangle? This is (-0.5f, -0.5f, 0.0f). Since the
      xy values are negative they are clamped to a value of 0.0f. This happens all the way to the center sides of the 
      triangle since from that point on the values will be interpolated positively again. Values of 0.0f are of course black
      and that explains the black side of the triangle.
      */
      
      位置做了颜色,左下角是-0.5,-0.50.0。然后颜色没有负的。就是0,0,0了黑色。
      中间又有颜色是因为其他角不是黑的
      答案
  • 相关阅读:
    django模型系统(二)
    css基础
    css进阶
    django模型系统(一)
    自定义过滤器及标签
    django模板标签
    模板变量及模板过滤器
    第六章 异常
    第三章:多态
    第三章:提高系统性能:从数据访问开始
  • 原文地址:https://www.cnblogs.com/ch122633/p/12069578.html
Copyright © 2020-2023  润新知