zoukankan      html  css  js  c++  java
  • 着色器

    #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了黑色。
      中间又有颜色是因为其他角不是黑的
      答案
  • 相关阅读:
    POJ 3411 Paid Roads(DFS)
    POJ 1699 Best Sequence(DFS)
    Codeforces Round #191 (Div. 2)
    Windows && Linux 搭建python开发环境
    zabbix 源码编译安装
    智能运维基础设施
    Redis
    ubuntu16.04 安装 mysql
    Python必须知道的基础语法
    ubuntu && CentOS && RedHat 离线安装docker
  • 原文地址:https://www.cnblogs.com/ch122633/p/12069578.html
Copyright © 2011-2022 走看看