• OpenGL 你好,三角形 练习一 二 三


    题目一要求

      添加更多顶点到数据中,使用glDrawArrays,

      尝试绘制两个彼此相连的三角形:参考解答(需要FQ)

     

    主要代码:

    完整代码:

    // OpenGLDemo.cpp: 定义控制台应用程序的入口点。
    
    #include "stdafx.h"
    #include <glad/glad.h>
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <fstream>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    void framebuffer_size_callback(GLFWwindow* window, int width, int height);
    void processInput(GLFWwindow* window);
    char* readTheFile(string strSource);
    
    const char* vertexShaderSource = readTheFile("vertexShaderSource.vert");
    const char* fragmentShaderSource = readTheFile("fragmentShaderSource.frag");
    
    class MyTriangle {
    public:
        float vertices[18] = {
            //第一个三角形
            .5f,.5f,.0f,//右上
            -.5f,.5f,.0f,//左上
            .5f,-.5f,.0f,//右下
            //第二个三角形
            -.5f,-.5f,.0f,//左下
            .5f,-.5f,.0f,//右下
            -.5f,.5f,.0f//左上
        };
    
        //生成顶点缓冲对象 ID:VBO
        unsigned int VBO;
        //生成顶点数组对象 ID:VAO
        unsigned int VAO;
    
        //储存 顶点着色器
        unsigned int vertexShader;
        //储存 片段着色器
        unsigned int fragmentShader;
        //存储 着色器程序
        unsigned int shaderProgram;
    
        void drawMyGraph(){
            vertexShaderInit();
            FragmentShaderInit();
            shaderProgramLinker();
            vertexInput();
        }
    private:
        void vertexInput() {
            glGenBuffers(1, &VBO);
            glGenVertexArrays(1, &VAO);
            // 1. 绑定VAO , VBO
            glBindVertexArray(VAO);
    
            // 2. 复制顶点数组到缓冲中供OpenGL使用
            //将缓冲对象 绑定到GL_ARRAY_BUFFER目标
            glBindBuffer(GL_ARRAY_BUFFER, VBO);
            //定义顶点数据复制到缓冲内存
            glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
            // 3. 设置顶点属性指针
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
        }
    
        void vertexShaderInit() {
            //创建一个顶点着色器对象
            vertexShader = glCreateShader(GL_VERTEX_SHADER);
            //着色器源码附着到着色器对象上
            glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
            //编译着色器对象
            glCompileShader(vertexShader);
            
            //检测着色编译是否成功
            int success;
            char infoLog[22];
            glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
            if (!success) {
                glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
                std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << std::endl;
            }
        }
    
        void FragmentShaderInit() {
            fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
            glShaderSource(fragmentShader, 1, &fragmentShaderSource,NULL);
            glCompileShader(fragmentShader);
            //检测着色编译是否成功
            int success;
            char infoLog[22];
            glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
            if (!success) {
                glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
                std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << std::endl;
            }
        }
    
        void shaderProgramLinker() {
            //创建着色器程序对象
            shaderProgram = glCreateProgram();
            //附加着色器到着色器程序
            glAttachShader(shaderProgram, vertexShader);
            glAttachShader(shaderProgram, fragmentShader);
            glLinkProgram(shaderProgram);
            int success;
            char infoLog[22];
            glGetProgramiv(shaderProgram, GL_LINK_STATUS,&success);
            if (!success) {
                glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
                std::cout << "ERROR::SHADER::LINKE_PROGRAM::COMPILATION_FAILED
    " << infoLog << std::endl;
            }
            glDeleteShader(vertexShader);
            glDeleteShader(fragmentShader);
        }
    
    };
    
    int main()
    {
        glfwInit();
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
        glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
        GLFWwindow* window = glfwCreateWindow(800, 600, "Oh!I see you!", NULL, NULL);
        if (window == NULL) {
            std::cout << "Failed to create the windows" << std::endl;
            glfwTerminate();
            return -1;
        }
        glfwMakeContextCurrent(window);
        glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    
        if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
            std::cout << "Failed to initialize GLAD" << std::endl;
            return -1;
        }
    
        MyTriangle myTriangle;
        myTriangle.drawMyGraph();
        //启用线段模式
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        while (!glfwWindowShouldClose(window)) {
    
            //输入处理
            processInput(window);
    
            //渲染指令
            glClearColor(0.2f,0.3f,0.3f,1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
    
            // 4. 当我们渲染一个物体时要使用着色器程序
            glUseProgram(myTriangle.shaderProgram);
            glBindVertexArray(myTriangle.VAO);
            // 3. 绘制物体
            glDrawArrays(GL_TRIANGLES, 0, 6);
    
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        glDeleteVertexArrays(1, &myTriangle.VAO);
        glDeleteBuffers(1, &myTriangle.VBO);
    
        glfwTerminate();
        return 0;
    }
    
    void framebuffer_size_callback(GLFWwindow* windows, int width, int height) {
        glViewport(0, 0, width, height);
    }
    
    void processInput(GLFWwindow* window) {
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
            glfwSetWindowShouldClose(window, true);
        }
    }
    
    //.frag .vert文件读取
    char* readTheFile(string strSource) {
        std::ifstream myfile(strSource);
        std::string str((std::istreambuf_iterator<char>(myfile)),
            std::istreambuf_iterator<char>());
        //str数组长度一定要 +1,
        /*原因: https://blog.csdn.net/ShiQW5696/article/details/80676290 */
        int len = str.length();
        char* result = new char[len];
        strcpy_s(result, len + 1, str.c_str());
        return result;
    }
    

     

    题目二要求

      创建相同的两个三角形,

      但对它们的数据使用不同的VAO和VBO:参考解答

      (需要FQ)

    主要代码:

    // OpenGLDemo.cpp: 定义控制台应用程序的入口点。
    
    #include "stdafx.h"
    #include <glad/glad.h>
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <fstream>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    void framebuffer_size_callback(GLFWwindow* window, int width, int height);
    void processInput(GLFWwindow* window);
    char* readTheFile(string strSource);
    
    const char* vertexShaderSource = readTheFile("vertexShaderSource.vert");
    const char* fragmentShaderSource = readTheFile("fragmentShaderSource.frag");
    
    class MyTriangle {
    public:
        float verticesFirst[9] = {
            //第一个三角形
            .5f,.5f,.0f,//右上
            -.5f,.5f,.0f,//左上
            .5f,-.5f,.0f,//右下
        };
    
        float verticesSecond[9] = {
            //第二个三角形
            -.5f,-.5f,.0f,//左下
            -.5f,.5f,.0f,//左上
            .5f,-.5f,.0f,//右下
        };
        //生成顶点缓冲对象 ID:VBO
        unsigned int VBOs[2];
        //生成顶点数组对象 ID:VAO
        unsigned int VAOs[2];
    
        //储存 顶点着色器
        unsigned int vertexShader;
        //储存 片段着色器
        unsigned int fragmentShader;
        //存储 着色器程序
        unsigned int shaderProgram;
    
        void drawMyGraph(){
            vertexShaderInit();
            FragmentShaderInit();
            shaderProgramLinker();
            vertexInput();
        }
    private:
        void vertexInput() {
            glGenBuffers(2, VBOs);
            glGenVertexArrays(2, VAOs);
            // 1. 绑定VAO , VBO
            glBindVertexArray(VAOs[0]);
    
            // 2. 复制顶点数组到缓冲中供OpenGL使用
            //将缓冲对象 绑定到GL_ARRAY_BUFFER目标
            glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
            //定义顶点数据复制到缓冲内存
            glBufferData(GL_ARRAY_BUFFER, sizeof(verticesFirst), verticesFirst, GL_STATIC_DRAW);
            // 3. 设置顶点属性指针
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
    
            glBindVertexArray(VAOs[1]);
            glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
            glBufferData(GL_ARRAY_BUFFER, sizeof(verticesSecond),
                verticesSecond, GL_STATIC_DRAW);
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
        }
    
        void vertexShaderInit() {
            //创建一个顶点着色器对象
            vertexShader = glCreateShader(GL_VERTEX_SHADER);
            //着色器源码附着到着色器对象上
            glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
            //编译着色器对象
            glCompileShader(vertexShader);
            
            //检测着色编译是否成功
            int success;
            char infoLog[22];
            glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
            if (!success) {
                glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
                std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << std::endl;
            }
        }
    
        void FragmentShaderInit() {
            fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
            glShaderSource(fragmentShader, 1, &fragmentShaderSource,NULL);
            glCompileShader(fragmentShader);
            //检测着色编译是否成功
            int success;
            char infoLog[22];
            glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
            if (!success) {
                glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
                std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << std::endl;
            }
        }
    
        void shaderProgramLinker() {
            //创建着色器程序对象
            shaderProgram = glCreateProgram();
            //附加着色器到着色器程序
            glAttachShader(shaderProgram, vertexShader);
            glAttachShader(shaderProgram, fragmentShader);
            glLinkProgram(shaderProgram);
            int success;
            char infoLog[22];
            glGetProgramiv(shaderProgram, GL_LINK_STATUS,&success);
            if (!success) {
                glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
                std::cout << "ERROR::SHADER::LINKE_PROGRAM::COMPILATION_FAILED
    " << infoLog << std::endl;
            }
            glDeleteShader(vertexShader);
            glDeleteShader(fragmentShader);
        }
    
    };
    
    int main()
    {
        glfwInit();
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
        glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
        GLFWwindow* window = glfwCreateWindow(800, 600, "Oh!I see you!", NULL, NULL);
        if (window == NULL) {
            std::cout << "Failed to create the windows" << std::endl;
            glfwTerminate();
            return -1;
        }
        glfwMakeContextCurrent(window);
        glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    
        if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
            std::cout << "Failed to initialize GLAD" << std::endl;
            return -1;
        }
    
        MyTriangle myTriangle;
        myTriangle.drawMyGraph();
        //启用线段模式
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        while (!glfwWindowShouldClose(window)) {
    
            //输入处理
            processInput(window);
    
            //渲染指令
            glClearColor(0.2f,0.3f,0.3f,1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
    
            // 4. 当我们渲染一个物体时要使用着色器程序
            glUseProgram(myTriangle.shaderProgram);
    
            glBindVertexArray(myTriangle.VAOs[0]);
            glDrawArrays(GL_TRIANGLES, 0, 3);
    
            glBindVertexArray(myTriangle.VAOs[1]);
            glDrawArrays(GL_TRIANGLES, 0, 3);
    
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        glDeleteVertexArrays(2, myTriangle.VAOs);
        glDeleteBuffers(2, myTriangle.VBOs);
    
        glfwTerminate();
        return 0;
    }
    
    void framebuffer_size_callback(GLFWwindow* windows, int width, int height) {
        glViewport(0, 0, width, height);
    }
    
    void processInput(GLFWwindow* window) {
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
            glfwSetWindowShouldClose(window, true);
        }
    }
    
    //.frag .vert文件读取
    char* readTheFile(string strSource) {
        std::ifstream myfile(strSource);
        std::string str((std::istreambuf_iterator<char>(myfile)),
            std::istreambuf_iterator<char>());
        //str数组长度一定要 +1,
        /*原因: https://blog.csdn.net/ShiQW5696/article/details/80676290 */
        int len = str.length();
        char* result = new char[len];
        strcpy_s(result, len + 1, str.c_str());
        return result;
    }
    

     

    题目三:

      创建两个着色器程序,第二个程序使用一个不同的片段着色器,输出黄色;

      再次绘制这两个三角形,让其中一个输出为黄色:参考解答

    // OpenGLDemo.cpp: 定义控制台应用程序的入口点。
    
    #include "stdafx.h"
    #include <glad/glad.h>
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <fstream>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    void framebuffer_size_callback(GLFWwindow* window, int width, int height);
    void processInput(GLFWwindow* window);
    char* readTheFile(string strSource);
    
    const char* vertexShaderSource = readTheFile("vertexShaderSource.vert");
    const char* fragmentShaderSource[2] = { 
        readTheFile("fragmentShaderSource.frag"), 
        readTheFile("fragmentShaderSource2.frag") 
    };
    
    
    class MyTriangle {
    public:
        float verticesFirst[9] = {
            //第一个三角形
            .5f,.5f,.0f,//右上
            -.5f,.5f,.0f,//左上
            .5f,-.5f,.0f,//右下
        };
    
        float verticesSecond[9] = {
            //第二个三角形
            -.5f,-.5f,.0f,//左下
            -.5f,.5f,.0f,//左上
            .5f,-.5f,.0f,//右下
        };
        //生成顶点缓冲对象 ID:VBO
        unsigned int VBOs[2];
        //生成顶点数组对象 ID:VAO
        unsigned int VAOs[2];
    
        //储存 顶点着色器
        unsigned int vertexShader;
        //储存 片段着色器
        unsigned int fragmentShader[2];
        //存储 着色器程序
        unsigned int shaderProgram[2];
    
        void drawMyGraph(){
            vertexShaderInit();
            FragmentShaderInit();
            shaderProgramLinker();
            vertexInput();
        }
    private:
        void vertexInput() {
            glGenBuffers(2, VBOs);
            glGenVertexArrays(2, VAOs);
            // 1. 绑定VAO , VBO
            glBindVertexArray(VAOs[0]);
    
            // 2. 复制顶点数组到缓冲中供OpenGL使用
            //将缓冲对象 绑定到GL_ARRAY_BUFFER目标
            glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
            //定义顶点数据复制到缓冲内存
            glBufferData(GL_ARRAY_BUFFER, sizeof(verticesFirst), verticesFirst, GL_STATIC_DRAW);
            // 3. 设置顶点属性指针
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
    
            glBindVertexArray(VAOs[1]);
            glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
            glBufferData(GL_ARRAY_BUFFER, sizeof(verticesSecond),
                verticesSecond, GL_STATIC_DRAW);
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
        }
    
        void vertexShaderInit() {
            //创建一个顶点着色器对象
            vertexShader = glCreateShader(GL_VERTEX_SHADER);
            //着色器源码附着到着色器对象上
            glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
            //编译着色器对象
            glCompileShader(vertexShader);
            
            //检测着色编译是否成功
            int success;
            char infoLog[22];
            glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
            if (!success) {
                glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
                std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << std::endl;
            }
        }
    
        void FragmentShaderInit() {
            int success;
            char infoLog[22];
            int len = sizeof(fragmentShader) / sizeof(unsigned int);
    
            for (int i = 0; i < len;i++) {
                fragmentShader[i] = glCreateShader(GL_FRAGMENT_SHADER);
                glShaderSource(fragmentShader[i], 1, &fragmentShaderSource[i], NULL);
                glCompileShader(fragmentShader[i]);
                glGetShaderiv(fragmentShader[i], GL_COMPILE_STATUS, &success);
                if (!success) {
                    glGetShaderInfoLog(fragmentShader[i], 512, NULL, infoLog);
                    std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED
    " << infoLog << std::endl;
                }
            }
        }
    
        void shaderProgramLinker() {
            int len = sizeof(shaderProgram) / sizeof(unsigned int);
    
            for (int i = 0;i < len;i++) {
                //创建着色器程序对象
                shaderProgram[i] = glCreateProgram();
                //附加着色器到着色器程序
                glAttachShader(shaderProgram[i], vertexShader);
                glAttachShader(shaderProgram[i], fragmentShader[i]);
                glLinkProgram(shaderProgram[i]);
                int success;
                char infoLog[22];
                glGetProgramiv(shaderProgram[i], GL_LINK_STATUS,&success);
                if (!success) {
                    glGetProgramInfoLog(shaderProgram[i], 512, NULL, infoLog);
                    std::cout << "ERROR::SHADER::LINKE_PROGRAM::COMPILATION_FAILED
    " << infoLog << std::endl;
                }
                glDeleteShader(vertexShader);
                glDeleteShader(fragmentShader[i]);
            }
        }
    
    };
    
    int main()
    {
        glfwInit();
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
        glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
        GLFWwindow* window = glfwCreateWindow(800, 600, "Oh!I see you!", NULL, NULL);
        if (window == NULL) {
            std::cout << "Failed to create the windows" << std::endl;
            glfwTerminate();
            return -1;
        }
        glfwMakeContextCurrent(window);
        glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    
        if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
            std::cout << "Failed to initialize GLAD" << std::endl;
            return -1;
        }
    
        MyTriangle myTriangle;
        myTriangle.drawMyGraph();
    
        while (!glfwWindowShouldClose(window)) {
    
            //输入处理
            processInput(window);
    
            //渲染指令
            glClearColor(0.2f,0.3f,0.3f,1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
    
            // 4. 当我们渲染一个物体时要使用着色器程序
            glUseProgram(myTriangle.shaderProgram[0]);
            glBindVertexArray(myTriangle.VAOs[0]);
            glDrawArrays(GL_TRIANGLES, 0, 3);
    
            glUseProgram(myTriangle.shaderProgram[1]);
            glBindVertexArray(myTriangle.VAOs[1]);
            glDrawArrays(GL_TRIANGLES, 0, 3);
    
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        glDeleteVertexArrays(2, myTriangle.VAOs);
        glDeleteBuffers(2, myTriangle.VBOs);
    
        glfwTerminate();
        return 0;
    }
    
    void framebuffer_size_callback(GLFWwindow* windows, int width, int height) {
        glViewport(0, 0, width, height);
    }
    
    void processInput(GLFWwindow* window) {
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
            glfwSetWindowShouldClose(window, true);
        }
    }
    
    //.frag .vert文件读取
    char* readTheFile(string strSource) {
        std::ifstream myfile(strSource);
        std::string str((std::istreambuf_iterator<char>(myfile)),
            std::istreambuf_iterator<char>());
        //str数组长度一定要 +1,
        /*原因: https://blog.csdn.net/ShiQW5696/article/details/80676290 */
        int len = str.length();
        char* result = new char[len];
        strcpy_s(result, len + 1, str.c_str());
        return result;
    }
    

      

  • 相关阅读:
    CSS浮动元素的水平居中
    html5移动web开发实战必读书记
    再说CSS3渐变——线性渐变
    链栈学习笔记
    用数组实现从文件搜索帐户和验证密码
    启程!
    在Application中集成Microsoft Translator服务之获取访问令牌
    在Application中集成Microsoft Translator服务之开发前准备
    Kinetic使用注意点--canvas
    Kinetic使用注意点--blob
  • 原文地址:https://www.cnblogs.com/--zz/p/9697474.html
Copyright © 2020-2023  润新知