你好,三角形

#ifndef TRIANGLE_H
#define TRIANGLE_H

#include <QWidget>
#include <QOpenGLWidget>
#include <QDebug>
#include <QOpenGLFunctions_3_3_Core>

namespace Ui {
class Triangle;
}

class Triangle : public QOpenGLWidget
{
    Q_OBJECT

public:
    Triangle();
    ~Triangle();
protected:
    virtual void initializeGL();
    virtual void resizeGL(int w, int h);
    virtual void paintGL();
private:
    Ui::Triangle *ui;
    GLuint shaderProgram;
    QOpenGLFunctions_3_3_Core *core;
};

#endif // TRIANGLE_H
triangle.h
#include "triangle.h"
#include "ui_triangle.h"

GLuint VBO, VAO;
const char *vertexShaderSource =
        "#version 330 core
"
        "layout(location = 0) in vec3 aPos;
"
        "void main(){
"
        "  gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
"
        "}
";
const char *fragmentShaderSource =
        "#version 330 core
"
        "out vec4 FragColor;
"
        "void main(){
"
        "   FragColor = vec4(1.0f, 0.5f, 0.2f, 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 = 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;
    }
    shaderProgram = core->glCreateProgram();
    core->glAttachShader(shaderProgram, vertexShader);
    core->glAttachShader(shaderProgram, fragmentShader);
    core->glLinkProgram(shaderProgram);
    // check for linking errors
    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);

    //VAO,VBO数据部分
    GLfloat vertices[] = {
            -0.5f, -0.5f, 0.0f, // left
             0.5f, -0.5f, 0.0f, // right
             0.0f,  0.5f, 0.0f  // top
    };


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

    // 0. 复制顶点数组到缓冲中供OpenGL使用
    core->glBindBuffer(GL_ARRAY_BUFFER, VBO);
    core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    // 1. 设置顶点属性指针
    core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);
    core->glEnableVertexAttribArray(0);

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

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

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

    // 2. 当我们渲染一个物体时要使用着色器程序
    core->glUseProgram(shaderProgram);
    // 3. 绘制物体
    core->glBindVertexArray(VAO);
    core->glDrawArrays(GL_TRIANGLES, 0, 3);
    core->glUseProgram(0);
}
triangle.cpp
#include "triangle.h"
#include <QApplication>

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

    return a.exec();
}
main.cpp
#include "triangle.h"
#include "ui_triangle.h"

GLuint VBO, VAO, EBO;
const char *vertexShaderSource =
        "#version 330 core
"
        "layout(location = 0) in vec3 aPos;
"
        "void main(){
"
        "  gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
"
        "}
";
const char *fragmentShaderSource =
        "#version 330 core
"
        "out vec4 FragColor;
"
        "void main(){
"
        "   FragColor = vec4(1.0f, 0.5f, 0.2f, 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 = 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;
    }
    shaderProgram = core->glCreateProgram();
    core->glAttachShader(shaderProgram, vertexShader);
    core->glAttachShader(shaderProgram, fragmentShader);
    core->glLinkProgram(shaderProgram);
    // check for linking errors
    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);

    //VAO,VBO数据部分
    GLfloat vertices[] = {
        0.5f, 0.5f, 0.0f,   // 右上角
        0.5f, -0.5f, 0.0f,  // 右下角
        -0.5f, -0.5f, 0.0f, // 左下角
        -0.5f, 0.5f, 0.0f   // 左上角
    };
    unsigned int indices[] = { // 注意索引从0开始!
        0, 1, 3, // 第一个三角形
        1, 2, 3  // 第二个三角形
    };

    core->glGenVertexArrays(1, &VAO);
    core->glGenBuffers(1, &VBO);
    core->glGenBuffers(1, &EBO);
    core->glBindVertexArray(VAO);

    // 0. 复制顶点数组到缓冲中供OpenGL使用
    core->glBindBuffer(GL_ARRAY_BUFFER, VBO);
    core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    core->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    core->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);
    core->glEnableVertexAttribArray(0);

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

    // 0. 复制顶点数组到缓冲中供OpenGL使用
    core->glBindBuffer(GL_ARRAY_BUFFER, VBO);
    core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    // 1. 设置顶点属性指针
    core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);
    core->glEnableVertexAttribArray(0);

    core->glBindBuffer(GL_ARRAY_BUFFER, 0);
    core->glBindVertexArray(0);
    */
}

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

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

    // 2. 当我们渲染一个物体时要使用着色器程序
    core->glUseProgram(shaderProgram);
    // 3. 绘制物体
    core->glBindVertexArray(VAO);
//    core->glDrawArrays(GL_TRIANGLES, 0, 3);
    core->glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    core->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
    core->glUseProgram(0);
}
画一个矩形

为了更好的掌握上述概念,我准备了一些练习。建议在继续下一节的学习之前先做完这些练习,确保你对这些知识有比较好的理解。

  1. 添加更多顶点到数据中,使用glDrawArrays,尝试绘制两个彼此相连的三角形:
    #include "triangle.h"
    #include "ui_triangle.h"
    
    GLuint VBO, VAO, EBO;
    const char *vertexShaderSource =
            "#version 330 core
    "
            "layout(location = 0) in vec3 aPos;
    "
            "void main(){
    "
            "  gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
    "
            "}
    ";
    const char *fragmentShaderSource =
            "#version 330 core
    "
            "out vec4 FragColor;
    "
            "void main(){
    "
            "   FragColor = vec4(1.0f, 0.5f, 0.2f, 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 = 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;
        }
        shaderProgram = core->glCreateProgram();
        core->glAttachShader(shaderProgram, vertexShader);
        core->glAttachShader(shaderProgram, fragmentShader);
        core->glLinkProgram(shaderProgram);
        // check for linking errors
        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);
    
        //VAO,VBO数据部分
        float vertices[] = {
            // 第一个三角形
            0.5f, 0.5f, 0.0f,   // 右上角
            0.5f, -0.5f, 0.0f,  // 右下角
            -0.5f, 0.5f, 0.0f,  // 左上角
            // 第二个三角形
            0.5f, -0.5f, 0.0f,  // 右下角
            -0.5f, -0.5f, 0.0f, // 左下角
            -0.5f, 0.5f, 0.0f   // 左上角
        };
    
    //    core->glGenVertexArrays(1, &VAO);
    //    core->glGenBuffers(1, &VBO);
    //    core->glGenBuffers(1, &EBO);
    //    core->glBindVertexArray(VAO);
    
        // 0. 复制顶点数组到缓冲中供OpenGL使用
    //    core->glBindBuffer(GL_ARRAY_BUFFER, VBO);
    //    core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
    //    core->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    //    core->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
    //    core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);
    //    core->glEnableVertexAttribArray(0);
    
    //    core->glBindBuffer(GL_ARRAY_BUFFER, 0);
    //    core->glBindVertexArray(0);
    
        core->glGenVertexArrays(1, &VAO);//两个参数,第一个为需要创建的缓存数量。第二个为用于存储单一ID或多个ID的GLuint变量或数组的地址
        core->glGenBuffers(1, &VBO);
        core->glBindVertexArray(VAO);
    
        // 0. 复制顶点数组到缓冲中供OpenGL使用
        core->glBindBuffer(GL_ARRAY_BUFFER, VBO);
        core->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        // 1. 设置顶点属性指针
        core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);
        core->glEnableVertexAttribArray(0);
    
        core->glBindBuffer(GL_ARRAY_BUFFER, 0);
        core->glBindVertexArray(0);
    
    }
    
    void Triangle::resizeGL(int w, int h)
    {
        core->glViewport(0, 0, w, h);
    }
    
    void Triangle::paintGL()
    {
        core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        core->glClear(GL_COLOR_BUFFER_BIT);
    
        // 2. 当我们渲染一个物体时要使用着色器程序
        core->glUseProgram(shaderProgram);
        // 3. 绘制物体
        core->glBindVertexArray(VAO);
        core->glDrawArrays(GL_TRIANGLES, 0, 6);
    //    core->glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    //    core->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
        core->glUseProgram(0);
    }
    答案
  2. 创建相同的两个三角形,但对它们的数据使用不同的VAO和VBO:
    #include "triangle.h"
    #include "ui_triangle.h"
    
    GLuint VBOs[2], VAOs[2], EBO;
    const char *vertexShaderSource =
            "#version 330 core
    "
            "layout(location = 0) in vec3 aPos;
    "
            "void main(){
    "
            "  gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
    "
            "}
    ";
    const char *fragmentShaderSource =
            "#version 330 core
    "
            "out vec4 FragColor;
    "
            "void main(){
    "
            "   FragColor = vec4(1.0f, 0.5f, 0.2f, 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 = 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;
        }
        shaderProgram = core->glCreateProgram();
        core->glAttachShader(shaderProgram, vertexShader);
        core->glAttachShader(shaderProgram, fragmentShader);
        core->glLinkProgram(shaderProgram);
        // check for linking errors
        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);
    
        //VAO,VBO数据部分
        float firstTrangle[] = {
            // 第一个三角形
            -0.9f, -0.5f, 0.0f,  // left
            -0.0f, -0.5f, 0.0f,  // right
            -0.45f, 0.5f, 0.0f,  // top
        };
    
        float secondTrangle[] = {
            // 第一个三角形
            0.0f, -0.5f, 0.0f,  // left
            0.9f, -0.5f, 0.0f,  // right
            0.45f, 0.5f, 0.0f   // top
        };
    
        core->glGenVertexArrays(2, VAOs);//两个参数,第一个为需要创建的缓存数量。第二个为用于存储单一ID或多个ID的GLuint变量或数组的地址
        core->glGenBuffers(2, VBOs);
    
        core->glBindVertexArray(VAOs[0]);
        // 0. 复制顶点数组到缓冲中供OpenGL使用
        core->glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
        core->glBufferData(GL_ARRAY_BUFFER, sizeof(firstTrangle), firstTrangle, GL_STATIC_DRAW);
        // 1. 设置顶点属性指针
        core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);
        core->glEnableVertexAttribArray(0);
    
        core->glBindVertexArray(VAOs[1]);
        core->glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
        core->glBufferData(GL_ARRAY_BUFFER, sizeof(secondTrangle), secondTrangle, GL_STATIC_DRAW);
        core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);
        core->glEnableVertexAttribArray(0);
    
    }
    
    void Triangle::resizeGL(int w, int h)
    {
        core->glViewport(0, 0, w, h);
    }
    
    void Triangle::paintGL()
    {
        core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        core->glClear(GL_COLOR_BUFFER_BIT);
    
        // 2. 当我们渲染一个物体时要使用着色器程序
        core->glUseProgram(shaderProgram);
        // 3. 绘制物体
        core->glBindVertexArray(VAOs[0]);
        core->glDrawArrays(GL_TRIANGLES, 0, 3);
        core->glBindVertexArray(VAOs[1]);
        core->glDrawArrays(GL_TRIANGLES, 0, 3);
        core->glUseProgram(0);
    }
    答案
  3. 创建两个着色器程序,第二个程序使用一个不同的片段着色器,输出黄色;再次绘制这两个三角形,让其中一个输出为黄色:
    #include "triangle.h"
    #include "ui_triangle.h"
    
    GLuint VBOs[2], VAOs[2];
    const char *vertexShaderSource =
            "#version 330 core
    "
            "layout(location = 0) in vec3 aPos;
    "
            "void main(){
    "
            "  gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
    "
            "}
    ";
    const char *fragmentShaderSource[] = {
        "#version 330 core
    "
        "out vec4 FragColor;
    "
        "void main(){
    "
        "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
    "
        "}
    ",
    
        "#version 330 core
    "
        "out vec4 FragColor;
    "
        "void main(){
    "
        "   FragColor = vec4(0.0f, 0.0f, 0.2f, 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[2];
        fragmentShader[0] = core->glCreateShader(GL_FRAGMENT_SHADER);
    
        core->glShaderSource(fragmentShader[0], 1, &fragmentShaderSource[0], nullptr);
        core->glCompileShader(fragmentShader[0]);
        // check for shader compile errors
        core->glGetShaderiv(fragmentShader[0], GL_COMPILE_STATUS, &success);
        if (!success) {
            core->glGetShaderInfoLog(fragmentShader[0], 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
    " << infoLog << endl;
        }
    
        fragmentShader[1] = core->glCreateShader(GL_FRAGMENT_SHADER);
    
        core->glShaderSource(fragmentShader[1], 1, &fragmentShaderSource[1], nullptr);
        core->glCompileShader(fragmentShader[1]);
        // check for shader compile errors
        core->glGetShaderiv(fragmentShader[1], GL_COMPILE_STATUS, &success);
        if (!success) {
            core->glGetShaderInfoLog(fragmentShader[1], 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
    " << infoLog << endl;
        }
    
        shaderProgram[0] = core->glCreateProgram();
        core->glAttachShader(shaderProgram[0], vertexShader);
        core->glAttachShader(shaderProgram[0], fragmentShader[0]);
        core->glLinkProgram(shaderProgram[0]);
        // check for linking errors
        core->glGetProgramiv(shaderProgram[0], GL_LINK_STATUS, &success);
        if (!success) {
            core->glGetProgramInfoLog(shaderProgram[0], 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED
    " << infoLog << endl;
        }
    
        shaderProgram[1] = core->glCreateProgram();
        core->glAttachShader(shaderProgram[1], vertexShader);
        core->glAttachShader(shaderProgram[1], fragmentShader[1]);
        core->glLinkProgram(shaderProgram[1]);
        // check for linking errors
        core->glGetProgramiv(shaderProgram[1], GL_LINK_STATUS, &success);
        if (!success) {
            core->glGetProgramInfoLog(shaderProgram[1], 512, nullptr, infoLog);
            qDebug() << "ERROR::SHADER::PROGRAM::LINKING_FAILED
    " << infoLog << endl;
        }
    
        core->glDeleteShader(vertexShader);
        core->glDeleteShader(fragmentShader[0]);
        core->glDeleteShader(fragmentShader[1]);
    
        //VAO,VBO数据部分
        float firstTriangle[] = {
            -0.9f, -0.5f, 0.0f,  // left
            -0.0f, -0.5f, 0.0f,  // right
            -0.45f, 0.5f, 0.0f,  // top
        };
        float secondTriangle[] = {
            0.0f, -0.5f, 0.0f,  // left
            0.9f, -0.5f, 0.0f,  // right
            0.45f, 0.5f, 0.0f   // top
        };
    
    
        core->glGenVertexArrays(1, &VAOs[0]);//两个参数,第一个为需要创建的缓存数量。第二个为用于存储单一ID或多个ID的GLuint变量或数组的地址
        core->glGenBuffers(1, &VBOs[0]);
        core->glBindVertexArray(VAOs[0]);
    
        // 0. 复制顶点数组到缓冲中供OpenGL使用
        core->glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
        core->glBufferData(GL_ARRAY_BUFFER, sizeof(firstTriangle), firstTriangle, GL_STATIC_DRAW);
        // 1. 设置顶点属性指针
        core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);
        core->glEnableVertexAttribArray(0);
    
        core->glBindBuffer(GL_ARRAY_BUFFER, 0);
        core->glBindVertexArray(0);
    
        core->glGenVertexArrays(1, &VAOs[1]);//两个参数,第一个为需要创建的缓存数量。第二个为用于存储单一ID或多个ID的GLuint变量或数组的地址
        core->glGenBuffers(1, &VBOs[1]);
        core->glBindVertexArray(VAOs[1]);
    
        // 0. 复制顶点数组到缓冲中供OpenGL使用
        core->glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
        core->glBufferData(GL_ARRAY_BUFFER, sizeof(secondTriangle), secondTriangle, GL_STATIC_DRAW);
        // 1. 设置顶点属性指针
        core->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);
        core->glEnableVertexAttribArray(0);
    
        core->glBindBuffer(GL_ARRAY_BUFFER, 0);
        core->glBindVertexArray(0);
    }
    
    void Triangle::resizeGL(int w, int h)
    {
        core->glViewport(0, 0, w, h);
    }
    
    void Triangle::paintGL()
    {
        core->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        core->glClear(GL_COLOR_BUFFER_BIT);
    
        // 2. 当我们渲染一个物体时要使用着色器程序
        core->glUseProgram(shaderProgram[0]);
        // 3. 绘制物体
        core->glBindVertexArray(VAOs[0]);
        core->glDrawArrays(GL_TRIANGLES, 0, 3);
    
        core->glUseProgram(shaderProgram[1]);
        core->glBindVertexArray(VAOs[1]);
        core->glDrawArrays(GL_TRIANGLES, 0, 3);
    
        core->glUseProgram(0);
    }
    答案
原文地址:https://www.cnblogs.com/ch122633/p/12067248.html