• qt opengl


    着色器:

    //#include <iostream>
    //#include "Display.h"
    //
    //int main()
    //{
    //    std::string title("LearnOpenGL");
    //    Display window(800,600, title);
    //
    //    // 渲染循环
    //    while (!window.IsClosed()) {
    //        window.Clear(0.2f, 0.3f, 0.3f, 1.0f);
    //        window.Update();
    //    }
    //    return 0;
    //}
    
    #include <glad/glad.h>
    #include <GLFW/glfw3.h>
    #include "Shader.h"
    
    #include <iostream>
    
    void framebuffer_size_callback(GLFWwindow* window, int width, int height);
    void processInput(GLFWwindow* window);
    
    // settings
    const unsigned int SCR_WIDTH = 800;
    const unsigned int SCR_HEIGHT = 600;
    
    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;
    "
    "uniform vec4 ourColor;
    "
    "void main()
    "
    "{
    "
    "   //FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
    "
    "   FragColor = ourColor;
    "
    "}
    ";
    
    int main()
    {
        // glfw: initialize and configure
        // ------------------------------
        glfwInit();
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
    #ifdef __APPLE__
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
    #endif
    
        // glfw window creation
        // --------------------
        GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
        if (window == NULL)
        {
            std::cout << "Failed to create GLFW window" << std::endl;
            glfwTerminate();
            return -1;
        }
        glfwMakeContextCurrent(window);
        glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    
        // glad: load all OpenGL function pointers
        // ---------------------------------------
        if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
        {
            std::cout << "Failed to initialize GLAD" << std::endl;
            return -1;
        }
    
    #if 0
        // build and compile our shader program
        // ------------------------------------
        // vertex shader
        int vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
        glCompileShader(vertexShader);
        // check for shader compile errors
        int success;
        char infoLog[512];
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << std::endl;
        }
        // fragment shader
        int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
        glCompileShader(fragmentShader);
        // check for shader compile errors
        glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
    " << infoLog << std::endl;
        }
        // link shaders
        int shaderProgram = glCreateProgram();
        glAttachShader(shaderProgram, vertexShader);
        glAttachShader(shaderProgram, fragmentShader);
        glLinkProgram(shaderProgram);
        // check for linking errors
        glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
        if (!success) {
            glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED
    " << infoLog << std::endl;
        }
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);
    #endif
     
        Shader ourShader("3.3.shader.vs", "3.3.shader.fs"); // you can name your shader files however you like
        // set up vertex data (and buffer(s)) and configure vertex attributes
        // ------------------------------------------------------------------
        float vertices[] = {
            // 位置                       颜色
            0.5f, -0.5f, 0.0f,  1.0f,0.0f,0.0f,
            -0.5f, -0.5f, 0.0f, 0.0f,0.1f,0.0f,
            0.0f, 0.5f, 0.0f,   0.0f,0.0f,1.0f
        };
    
        unsigned int VBO, VAO;
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
        glBindVertexArray(VAO);
    
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(0);
    
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
        glEnableVertexAttribArray(1);
    
        // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    
        // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
        // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
        glBindVertexArray(0);
    
    
        // uncomment this call to draw in wireframe polygons.
        //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    
        // render loop
        // -----------
        while (!glfwWindowShouldClose(window))
        {
            // input
            // -----
            processInput(window);
    
            // render
            // ------
            glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
    
            // 更新uniform颜色
            //float timeValue = glfwGetTime();
            //float greenValue = sin(timeValue) / 2.0f + 0.5f;
            //int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
            //glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
    
            // draw our first triangle
            //glUseProgram(shaderProgram);
            ourShader.use();
            glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
            glDrawArrays(GL_TRIANGLES, 0, 3);
            // glBindVertexArray(0); // no need to unbind it every time 
    
            // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
            // -------------------------------------------------------------------------------
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        // optional: de-allocate all resources once they've outlived their purpose:
        // ------------------------------------------------------------------------
        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
    
        // glfw: terminate, clearing all previously allocated GLFW resources.
        // ------------------------------------------------------------------
        glfwTerminate();
        return 0;
    }
    
    // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
    // ---------------------------------------------------------------------------------------------------------
    void processInput(GLFWwindow* window)
    {
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, true);
    }
    
    // glfw: whenever the window size changed (by OS or user resize) this callback function executes
    // ---------------------------------------------------------------------------------------------
    void framebuffer_size_callback(GLFWwindow* window, int width, int height)
    {
        // make sure the viewport matches the new window dimensions; note that width and 
        // height will be significantly larger than specified on retina displays.
        glViewport(0, 0, width, height);
    }
    main.cpp三角形
    #ifndef SHADER_H
    #define SHADER_H
    
    #include <glad/glad.h>
    
    #include <string>
    #include <fstream>
    #include <sstream>
    #include <iostream>
    
    class Shader
    {
    public:
        unsigned int ID;
        // constructor generates the shader on the fly
        // ------------------------------------------------------------------------
        Shader(const char* vertexPath, const char* fragmentPath)
        {
            // 1. retrieve the vertex/fragment source code from filePath
            std::string vertexCode;
            std::string fragmentCode;
            std::ifstream vShaderFile;
            std::ifstream fShaderFile;
            // ensure ifstream objects can throw exceptions:
            vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
            fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
            try
            {
                // open files
                vShaderFile.open(vertexPath);
                fShaderFile.open(fragmentPath);
                std::stringstream vShaderStream, fShaderStream;
                // read file's buffer contents into streams
                vShaderStream << vShaderFile.rdbuf();
                fShaderStream << fShaderFile.rdbuf();
                // close file handlers
                vShaderFile.close();
                fShaderFile.close();
                // convert stream into string
                vertexCode = vShaderStream.str();
                fragmentCode = fShaderStream.str();
            }
            catch (std::ifstream::failure e)
            {
                std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
            }
            const char* vShaderCode = vertexCode.c_str();
            const char* fShaderCode = fragmentCode.c_str();
            // 2. compile shaders
            unsigned int vertex, fragment;
            // vertex shader
            vertex = glCreateShader(GL_VERTEX_SHADER);
            glShaderSource(vertex, 1, &vShaderCode, NULL);
            glCompileShader(vertex);
            checkCompileErrors(vertex, "VERTEX");
            // fragment Shader
            fragment = glCreateShader(GL_FRAGMENT_SHADER);
            glShaderSource(fragment, 1, &fShaderCode, NULL);
            glCompileShader(fragment);
            checkCompileErrors(fragment, "FRAGMENT");
            // shader Program
            ID = glCreateProgram();
            glAttachShader(ID, vertex);
            glAttachShader(ID, fragment);
            glLinkProgram(ID);
            checkCompileErrors(ID, "PROGRAM");
            // delete the shaders as they're linked into our program now and no longer necessary
            glDeleteShader(vertex);
            glDeleteShader(fragment);
        }
        // activate the shader
        // ------------------------------------------------------------------------
        void use()
        {
            glUseProgram(ID);
        }
        // utility uniform functions
        // ------------------------------------------------------------------------
        void setBool(const std::string& name, bool value) const
        {
            glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
        }
        // ------------------------------------------------------------------------
        void setInt(const std::string& name, int value) const
        {
            glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
        }
        // ------------------------------------------------------------------------
        void setFloat(const std::string& name, float value) const
        {
            glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
        }
    
    private:
        // utility function for checking shader compilation/linking errors.
        // ------------------------------------------------------------------------
        void checkCompileErrors(unsigned int shader, std::string type)
        {
            int success;
            char infoLog[1024];
            if (type != "PROGRAM")
            {
                glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
                if (!success)
                {
                    glGetShaderInfoLog(shader, 1024, NULL, infoLog);
                    std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "
    " << infoLog << "
     -- --------------------------------------------------- -- " << std::endl;
                }
            }
            else
            {
                glGetProgramiv(shader, GL_LINK_STATUS, &success);
                if (!success)
                {
                    glGetProgramInfoLog(shader, 1024, NULL, infoLog);
                    std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "
    " << infoLog << "
     -- --------------------------------------------------- -- " << std::endl;
                }
            }
        }
    };
    #endif
    shader着色器

    vertex

    #version 330 core
    layout (location = 0) in vec3 aPos;
    layout (location = 1) in vec3 aColor;
    layout (location = 2) in vec3 aTexCoord;
    
    out vec3 ourColor;
    out vec2 TexCoord;
    
    void main()
    {
        gl_Position = vec4(aPos, 1.0);
        ourColor = aColor;
        TexCoord = aTexCoord;
    }

    fragment

    #version 330 core
    out vec4 FragColor;
    
    in vec3 ourColor;
    in vec2 TexCoord;
    
    uniform sampler2D ourTexture;
    
    void main()
    {
        //FragColor = vec4(ourColor, 1.0f);
        FragColor = texture(ourTexture,TexCoord);
    }

    四边形

    更多属性:

      1 #include "widget.h"
      2 #include "ui_widget.h"
      3 #include <QDebug>
      4 #include <QTime>
      5 #include <math.h>
      6 #include <sys/time.h>
      7 #include <QTimer>
      8 //#include "shader.h"
      9 
     10 //顶点着色器源码
     11 const char *vertexShaderSource = "#version 330 core
    "
     12                                  "layout (location = 0) in vec3 aPos;
    "
     13                                  "layout (location = 1) in vec3 aColor;
    "
     14                                  "out vec3 ourColor;
    "
     15                                  "void main()
    "
     16                                  "{
    "
     17                                  "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
    "
     18                                  "   ourColor = aColor;
    "
     19                                  "}";
     20 
     21 //片段着色器源码
     22 const char *fragmentShaderSource = "#version 330 core
    "
     23                                    "out vec4 FragColor;
    "
     24                                    "in vec3 ourColor;
    "
     25                                    "//uniform vec4 ourColor;
    "
     26                                    "void main()
    "
     27                                    "{
    "
     28                                    "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
    "
     29                                    "   FragColor = vec4(ourColor,1.0f);
    "
     30                                    "}
    ";
     31 
     32 Widget::Widget(QWidget *parent) :
     33     QOpenGLWidget(parent),
     34     ui(new Ui::Widget)
     35 {
     36     ui->setupUi(this);
     37 
     38     //Shader shader(":basicVertexShader.vert","./basicFragmentShader.frag");
     39 //    QTimer* timer = new QTimer(this);
     40 //    timer->start(1);
     41 //    connect(timer,&QTimer::timeout,this,&slotUpdate);
     42 
     43 }
     44 
     45 Widget::~Widget()
     46 {
     47     delete ui;
     48 }
     49 
     50 void Widget::initializeGL()
     51 {
     52     initializeOpenGLFunctions();
     53 
     54     GLuint vertexShader; // 顶点着色器
     55     vertexShader = glCreateShader(GL_VERTEX_SHADER);//创建顶点着色器
     56     glShaderSource(vertexShader,1,&vertexShaderSource,NULL);// 参数二为需要编译的着色器源码数量
     57     glCompileShader(vertexShader);
     58     createShaderError(vertexShader,GL_COMPILE_STATUS,false,"Vertex Shader compiler error");
     59 
     60     GLuint fragmentShader;// 片段着色器
     61     fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
     62     glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
     63     glCompileShader(fragmentShader);
     64     createShaderError(fragmentShader,GL_COMPILE_STATUS,false,"Fragment Shader compiler error");
     65 
     66     m_shaderProgram = glCreateProgram();
     67     glAttachShader(m_shaderProgram,vertexShader);
     68     glAttachShader(m_shaderProgram,fragmentShader);
     69     glLinkProgram(m_shaderProgram);
     70     createShaderError(m_shaderProgram,GL_LINK_STATUS,true,"Program linking failed error");
     71 
     72     glUseProgram(m_shaderProgram);//激活程序对象
     73     glDeleteShader(vertexShader);
     74     glDeleteShader(fragmentShader);
     75 
     76     int nrAttributes;
     77     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,&nrAttributes);
     78     qDebug() << nrAttributes;
     79 }
     80 
     81 void Widget::resizeGL(int w, int h)
     82 {
     83     //视口变换
     84     glViewport(0,0,(GLsizei)w,(GLsizei)h);
     85 }
     86 
     87 void Widget::paintGL()
     88 {
     89 
     90 //    glEnable(GL_DEPTH_TEST);
     91     drawTriangles();
     92     //drawRect();
     93 }
     94 
     95 void Widget::createShaderError(GLuint shader, GLuint flag, bool isProgram, const QString errMessage)
     96 {
     97     GLint success = 0;
     98     GLchar error[1024] = {0};
     99 
    100     if (isProgram){
    101         glGetProgramiv(shader,flag,&success);
    102     }
    103     else {
    104         glGetShaderiv(shader,flag,&success);
    105     }
    106 
    107     if (success == GL_FALSE){
    108         if (isProgram){
    109             glGetProgramInfoLog(shader,sizeof(error),NULL,error);
    110         }
    111         else {
    112             glGetShaderInfoLog(shader,sizeof(error),NULL,error);
    113         }
    114         qDebug() << errMessage << ": " << error;
    115     }
    116 
    117 }
    118 
    119 void Widget::drawRect()
    120 {
    121     glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    122     glClear(GL_COLOR_BUFFER_BIT);
    123 
    124     float vertices[] = {
    125         // 位置
    126         0.5f, 0.5f, 0.0f,   // 右上
    127         0.5f, -0.5f, 0.0f,  // 右下
    128         -0.5f, 0.5f, 0.0f,  // 左上
    129         -0.5f, -0.5f, 0.0f  // 左下
    130     };
    131     unsigned int indices[] = {
    132         0,1,2,//第一个三角形
    133         1,2,3// 第二个三角形
    134     };
    135 
    136 //    float timeValue = (float)clock();
    137 //    float greenValue = (sin(timeValue)/2.0f) +0.5f;
    138 //    qDebug() << greenValue;
    139 //    int vertexColorLocation = glGetUniformLocation(m_shaderProgram, "ourColor");
    140 
    141     unsigned int VBO, VAO;
    142     glGenVertexArrays(1, &VAO);
    143     glGenBuffers(1, &VBO);
    144     // 1. 绑定顶点数组对象
    145     glBindVertexArray(VAO);
    146     // 2. 把我们的顶点数组复制到一个顶点缓冲中,供OpenGL使用
    147     glBindBuffer(GL_ARRAY_BUFFER, VBO);
    148     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    149 
    150     // 3. 复制我们的索引数组到一个索引缓冲中,供OpenGL使用
    151     unsigned int EBO;
    152     glGenBuffers(1,&EBO);
    153 
    154     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
    155     glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);
    156 
    157     // 4,设置顶点指针属性
    158     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    159     glEnableVertexAttribArray(0);
    160 
    161     glBindBuffer(GL_ARRAY_BUFFER, 0);
    162 
    163     // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
    164     // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
    165     glBindVertexArray(0);
    166 
    167     glUseProgram(m_shaderProgram);
    168 //    glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
    169     glBindVertexArray(VAO);
    170     glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
    171 }
    172 
    173 void Widget::drawTriangles()
    174 {
    175     glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    176     glClear(GL_COLOR_BUFFER_BIT);
    177 
    178     float vertices[] = {
    179         // 位置                       颜色
    180         0.5f, -0.5f, 0.0f,  1.0f,0.0f,0.0f,
    181         -0.5f, -0.5f, 0.0f, 0.0f,0.1f,0.0f,
    182         0.0f, 0.5f, 0.0f,   0.0f,0.0f,1.0f
    183     };
    184 
    185     unsigned int VBO, VAO;
    186     glGenVertexArrays(1, &VAO);
    187     glGenBuffers(1, &VBO);
    188     // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
    189     glBindVertexArray(VAO);
    190 
    191     glBindBuffer(GL_ARRAY_BUFFER, VBO);
    192     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    193 
    194     /*
    195     第一个参数指定我们要配置的顶点属性。还记得我们在顶点着色器中使用layout(location = 0)定义了position顶点属性的位置值(Location)吗?它可以把顶点属性的位置值设置为0。因为我们希望把数据传递到这一个顶点属性中,所以这里我们传入0。
    196     第二个参数指定顶点属性的大小。顶点属性是一个vec3,它由3个值组成,所以大小是3。
    197     第三个参数指定数据的类型,这里是GL_FLOAT(GLSL中vec*都是由浮点数值组成的)。
    198     下个参数定义我们是否希望数据被标准化(Normalize)。如果我们设置为GL_TRUE,所有数据都会被映射到0(对于有符号型signed数据是-1)到1之间。我们把它设置为GL_FALSE。
    199     第五个参数叫做步长(Stride),它告诉我们在连续的顶点属性组之间的间隔。由于下个组位置数据在3个float之后,我们把步长设置为3 * sizeof(float)。要注意的是由于我们知道这个数组是紧密排列的(在两个顶点属性之间没有空隙)我们也可以设置为0来让OpenGL决定具体步长是多少(只有当数值是紧密排列时才可用)。一旦我们有更多的顶点属性,我们就必须更小心地定义每个顶点属性之间的间隔,我们在后面会看到更多的例子(译注: 这个参数的意思简单说就是从这个属性第二次出现的地方到整个数组0位置之间有多少字节)。
    200     最后一个参数的类型是void*,所以需要我们进行这个奇怪的强制类型转换。它表示位置数据在缓冲中起始位置的偏移量(Offset)。由于位置数据在数组的开头,所以这里是0。我们会在后面详细解释这个参数
    201     */
    202     // 位置属性
    203     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    204     glEnableVertexAttribArray(0);
    205     // 颜色属性
    206     glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE, 6 * sizeof(float), (void*)(3*sizeof(float)));
    207     glEnableVertexAttribArray(1);
    208 
    209     // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
    210     glBindBuffer(GL_ARRAY_BUFFER, 0);
    211 
    212     // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
    213     // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
    214     glBindVertexArray(0);
    215 
    216     glUseProgram(m_shaderProgram);
    217     glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
    218     glDrawArrays(GL_TRIANGLES, 0, 3);
    219 }
    widget.cpp
    #include "widget.h"
    #include "ui_widget.h"
    #include <QDebug>
    
    //顶点着色器源码
    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);
    "
                                       "}
    ";
    
    
    Widget::Widget(QWidget *parent) :
        QOpenGLWidget(parent),
        ui(new Ui::Widget)
    {
        ui->setupUi(this);
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::initializeGL()
    {
        initializeOpenGLFunctions();
    
        GLuint vertexShader; // 顶点着色器
        vertexShader = glCreateShader(GL_VERTEX_SHADER);//创建顶点着色器
        glShaderSource(vertexShader,1,&vertexShaderSource,NULL);// 参数二为需要编译的着色器源码数量
        glCompileShader(vertexShader);
        createShaderError(vertexShader,GL_COMPILE_STATUS,false,"Vertex Shader compiler error");
    
        GLuint fragmentShader;// 片段着色器
        fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
        glCompileShader(fragmentShader);
        createShaderError(fragmentShader,GL_COMPILE_STATUS,false,"Fragment Shader compiler error");
    
        m_shaderProgram = glCreateProgram();
        glAttachShader(m_shaderProgram,vertexShader);
        glAttachShader(m_shaderProgram,fragmentShader);
        glLinkProgram(m_shaderProgram);
        createShaderError(m_shaderProgram,GL_LINK_STATUS,true,"Program linking failed error");
    
        glUseProgram(m_shaderProgram);//激活程序对象
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);
    }
    
    void Widget::resizeGL(int w, int h)
    {
        //视口变换
        glViewport(0,0,(GLsizei)w,(GLsizei)h);
    }
    
    void Widget::paintGL()
    {
    
    //    glEnable(GL_DEPTH_TEST);
        //drawTriangles();
        drawRect();
    }
    
    void Widget::createShaderError(GLuint shader, GLuint flag, bool isProgram, const QString errMessage)
    {
        GLint success = 0;
        GLchar error[1024] = {0};
    
        if (isProgram){
            glGetProgramiv(shader,flag,&success);
        }
        else {
            glGetShaderiv(shader,flag,&success);
        }
    
        if (success == GL_FALSE){
            if (isProgram){
                glGetProgramInfoLog(shader,sizeof(error),NULL,error);
            }
            else {
                glGetShaderInfoLog(shader,sizeof(error),NULL,error);
            }
        }
        qDebug() << errMessage << ": " << error;
    }
    
    void Widget::drawTriangles()
    {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
    
        float vertices[] = {
            -0.5f, -0.5f, 0.0f, // left
            0.5f, -0.5f, 0.0f, // right
            0.0f,  0.5f, 0.0f  // top
        };
    
        unsigned int VBO, VAO;
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
        glBindVertexArray(VAO);
    
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(0);
    
        // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    
        // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
        // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
        glBindVertexArray(0);
    
        glUseProgram(m_shaderProgram);
        glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
    
    void Widget::drawRect()
    {
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
    
        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  // 左下
        };
        unsigned int indices[] = {
            0,1,2,//第一个三角形
            1,2,3// 第二个三角形
        };
    
        unsigned int VBO, VAO;
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        // 1. 绑定顶点数组对象
        glBindVertexArray(VAO);
        // 2. 把我们的顶点数组复制到一个顶点缓冲中,供OpenGL使用
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    
        // 3. 复制我们的索引数组到一个索引缓冲中,供OpenGL使用
        unsigned int EBO;
        glGenBuffers(1,&EBO);
    
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);
    
        // 4,设置顶点指针属性
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(0);
    
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    
        // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
        // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
        glBindVertexArray(0);
    
        glUseProgram(m_shaderProgram);
        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    //#include "widget.h"
    //#include "ui_widget.h"
    
    //Widget::Widget(QWidget *parent) :
    //    QGLWidget(parent),
    //    ui(new Ui::Widget)
    //{
    //    ui->setupUi(this);
    //}
    
    //Widget::~Widget()
    //{
    //    delete ui;
    //}
    
    //void Widget::initializeGL()
    //{
    //    //设置widget的坐标和尺寸
    //    setGeometry(300, 150, 500, 500);
    //    //设置清除时颜色
    //    glClearColor(0.0, 0.0, 0.0, 0);
    //}
    
    //void Widget::resizeGL(int w, int h)
    //{
    //    //视口变换
    //    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    //    //投影变换
    //    glMatrixMode(GL_PROJECTION);
    //    glLoadIdentity();
    //    gluPerspective(40.0,(GLdouble)w/(GLdouble)h,0.1,10000.0);
    //    //视图变换
    //    glMatrixMode(GL_MODELVIEW);
    //    glLoadIdentity();
    //    gluLookAt(0.0,0.0,15.0,0.0,0.0,0.0,0.0,1.0,0.0);
    //}
    
    //void Widget::paintGL()
    //{
    //    //清屏
    //    glClear(GL_COLOR_BUFFER_BIT);
    //    //绘制七彩三角形
    //    glBegin(GL_TRIANGLES);
    //    glColor3f(1.0,0.0,0.0);
    //    glVertex3f(-2,0,0);
    //    glColor3f(0.0,1.0,0.0);
    //    glVertex3f(2,0,0);
    //    glColor3f(0.0,0.0,1.0);
    //    glVertex3f(0,4,0);
    //    glEnd();
    //    glFlush();
    //}
    View Code
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QOpenGLWidget>
    #include <QOpenGLFunctions_3_0>
    
    namespace Ui {
    class Widget;
    }
    
    class Widget : public QOpenGLWidget,protected QOpenGLFunctions_3_0
    {
        Q_OBJECT
    
    public:
        explicit Widget(QWidget *parent = 0);
        ~Widget();
    
        void initializeGL();
        void resizeGL(int w,int h);
        void paintGL();
    private:
        void createShaderError(GLuint shader,GLuint flag,bool isProgram,const QString errMessage);
        void drawTriangles();
        void drawRect();
    private:
        GLuint m_shaderProgram;//着色器程序对象
    private:
        Ui::Widget *ui;
    };
    
    #endif // WIDGET_H
    
    
    
    
    
    
    
    
    
    //#ifndef WIDGET_H
    //#define WIDGET_H
    
    //#include <QWidget>
    //#include <QtOpenGL/qgl.h>
    //#include <GL/gl.h>
    //#include <GL/glu.h>
    //#include <QOpenGLWidget>
    //#include <QOpenGLFunctions_3_0>
    
    //namespace Ui {
    //class Widget;
    //}
    
    //class Widget : public QGLWidget
    //{
    //    Q_OBJECT
    
    //public:
    //    explicit Widget(QWidget *parent = 0);
    //    ~Widget();
    
    //    void initializeGL();
    //    void resizeGL(int w,int h);
    //    void paintGL();
    
    //private:
    //    Ui::Widget *ui;
    //};
    
    //#endif // WIDGET_H
    View Code
  • 相关阅读:
    LeetCode【21】 Merge Two Sorted Lists
    LeetCode【2】Add two numbers
    LeetCode【125】Valid Palindrome
    LeetCode【9】Palindrome Number
    LeetCode【20】Valid Parentheses
    LeetCode【1】Two Sum
    LeetCode【8】string to integer(atoi)
    LeetCode【168】Excel Sheet Column Title
    lambda表达式
    UML类图
  • 原文地址:https://www.cnblogs.com/xiangtingshen/p/12061188.html
Copyright © 2020-2023  润新知