zoukankan      html  css  js  c++  java
  • OpenGL学习——绘制第一个三角形

    终于把三角形绘制出来了,首先一些关键概念、操作。

    Vertex Data                       顶点数据

    VBO Vertex Buffer Objects  顶点缓冲对象

    VAO Vertex Array Objects   顶点数组对象

    Vertex Attribute Pointer      顶点属性指针

    NDC Normalized Device Coordinates 标准化设备坐标

    Vertex Shader Objects        顶点着色器对象

    GLSL   OpenGL Shading Language 着色器语言

    顶点数组位置声明

    顶点着色器 in 关键字声明输入

    预定义关键字 gl_Position 顶点着色器输出

    Fragment Shader Objects    片段着色器对象

    片段着色器 out 关键字声明输出

    Shader Program                 着色器程序

    着色器程序链接顶点着色器与片段着色器

    在绘制循环里使用着色器程序、绑定顶点数组对象、告知绘制图元类型、解绑顶点数组对象。

    Graphics Pipeline:

    Vertex Data => Vertex Shader => Primitive Assembly => Geometry Shader

                                                                                           ⇩

             Alpha Test And Blending <= Fragment Shader   <= Rasterization

    就这些吧,上图、上源码:

    主函数 main.cpp

    // GLEW
    #define GLEW_STATIC
    #include <GL/glew.h>
    // GLFW
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include "Triangles.h"
    
    int main(){
        // glfw init
        glfwInit();
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
    
        //create a glfw window
        GLFWwindow *window = glfwCreateWindow(640, 360, "opengl-triangles", nullptr, nullptr);
        if (window == nullptr){
            std::cout << "create glfw window failed..." << std::endl;
            glfwTerminate();
            return -1;
        }
        glfwMakeContextCurrent(window);//set current window
    
        // glew init
        glewExperimental = GL_TRUE;
        if (glewInit() != GLEW_OK){
            std::cout << "glew init failed..." << std::endl;
            return -1;
        }
    
        //get width and height from glfw window
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        //define the glViewport
        glViewport(0, 0, width, height);
    
        Triangles triangles;
        triangles.init();
        //add the game loop
        while (!glfwWindowShouldClose(window)){
            //check event
            glfwPollEvents();
    
            //now clear window
            glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);//the gl color buffer bit
    
            //your OpenGL code logical
            triangles.draw();
    
            //swap buffer
            glfwSwapBuffers(window);
        }
    
        //the end, glfw window has been closed
        glfwTerminate();
        return 0;
    }

    头文件Triangles.h:

    // GLEW
    #define GLEW_STATIC
    #include <GL/glew.h>
    // GLFW
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include <sstream>
    
    class Triangles{
    
    public:
        Triangles();
    
        ~Triangles();
    
    public:
        void init();
    
        void draw();
    
    private:
        //create vertex shader
        void createVertexShader();
    
        //create fragment shader
        void createFragmentShader();
    
        //create shader program
        void createShaderProgram();
    
        //get vertex shader source code
        std::string getVertexShaderSrc();
    
        //get fragment shader source code
        std::string getFragmentShaderSrc();
    
    private:
        GLuint VAO;               //define VAO, vertex array object
        GLuint vertexShader;
        GLuint fragmentShader;
        GLuint shaderProgram;
    };

    实现类Triangles.cpp:

    #include "Triangles.h"
    
    Triangles::Triangles(){
    }
    
    Triangles::~Triangles(){
    }
    
    void Triangles::init(){
        // x,y,z  opengl coordinates, the vertex data, three 3d point in normalized device coordinates
        GLfloat vertexs[] = {
            -0.4f, -0.5f, 0.0f,
            0.4f, -0.5f, 0.0f,
            0.0f, 0.5f, 0.0f,
        };
        //define VAO, vertex array object
        //GLuint VAO;
        glGenVertexArrays(1, &VAO);
        glBindVertexArray(VAO); // bind vertex array object
            //define VBO, vertex buffer object
            GLuint VBO;
            glGenBuffers(1, &VBO);                                                   // gen buffer object
            glBindBuffer(GL_ARRAY_BUFFER, VBO);                                      // bind buffer to the target
            glBufferData(GL_ARRAY_BUFFER, sizeof(vertexs), vertexs, GL_STATIC_DRAW); // copy vertex data to VBO
            //set vertex attribute point
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
            glEnableVertexAttribArray(0);
        glBindVertexArray(0);//unbind vertex array object
    
        //create shader program
        this->createShaderProgram();
    }
    
    void Triangles::draw(){
        //use shader programs
        glUseProgram(shaderProgram);
    
        //draw the triangles
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glBindVertexArray(0);
    }
    
    
    
    void Triangles::createVertexShader(){
        //compile vertex shader source
        std::string vertexShaderStr = this->getVertexShaderSrc();
        const char *vertexShaderSrc = vertexShaderStr.c_str();
        std::cout << "vertexShaderSrc:
    " << vertexShaderSrc;
        //GLuint vertexShader;                                     // shader object
        vertexShader = glCreateShader(GL_VERTEX_SHADER);         // create vertex shader object
        glShaderSource(vertexShader, 1, &vertexShaderSrc, NULL); // shader source attach to shader object
        glCompileShader(vertexShader);                           // compile shader
        //compile result check
        GLint success;
        GLchar infoLog[512];
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
        if (!success){
            glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
            std::cout << "vertex shader source compile failed...
    " << infoLog << std::endl;
            std::cout << vertexShaderSrc;
        }
    }
    
    
    void Triangles::createFragmentShader(){
        //compile fragment shader source
        std::string fragmentShaderStr = this->getFragmentShaderSrc();
        const char *fragmentShaderSrc = fragmentShaderStr.c_str();
        std::cout << "
    
    fragmentShaderSrc:
    " << fragmentShaderSrc;
        //GLuint fragmentShader;
        fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, 1, &fragmentShaderSrc, NULL);
        glCompileShader(fragmentShader);
    }
    
    
    void Triangles::createShaderProgram(){
        this->createVertexShader();
        this->createFragmentShader();
        if (vertexShader == NULL || fragmentShader == NULL){
            return;
        }
        //shader program, link vertex shader object and fragment shader object
        //GLuint shaderProgram;
        shaderProgram = glCreateProgram();               // create shader program
        glAttachShader(shaderProgram, vertexShader);     // attach vertex shader
        glAttachShader(shaderProgram, fragmentShader);   // attach fragment shader
        glLinkProgram(shaderProgram);                    // linking
        //check link result
        GLint success;
        GLchar infoLog[512];
        glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
        if (!success){
            glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
            std::cout << "shader program linking failed...
    "<< infoLog << std::endl;
            return;
        }
        //delete vertex shader object and fragment shader object
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);
        //return shaderProgram;
    }
    
    
    
    std::string Triangles::getVertexShaderSrc(){
        std::stringstream ss;
        ss << "#version 330 core 
    ";
        ss << "layout (location = 0) in vec3 position;";
        ss << "void main()";
        ss << "{";
        ss << "    gl_Position = vec4(position.x, position.y, position.z, 1.0);";
        ss << "}";
        //return ss.str();
    
        std::string vertexShaderStr =
        "#version 330 core
    "
        "layout (location = 0) in vec3 pos; "
        "void main () {"
        " gl_Position = vec4(pos, 1.0);"
        "}";
        return vertexShaderStr;
    }
    
    
    std::string Triangles::getFragmentShaderSrc(){
        std::stringstream ss;
        ss << " #version 330 core  
    ";
        ss << " out vec4 color;  
    ";
        ss << " void main(){  
    ";
        ss << "        color = vec4(1.0f, 0.1f, 0.1f, 1.0f);  
    ";
        ss << " }  
    ";
        //return ss.str();
        
        
        std::string  fragmentShaderStr =
            "#version 330 core
    "
            "out vec4 color; "
            "void main () {"
            " color = vec4(1.0f, 0.1f, 0.1f, 1.0f);"
            "}";
        return fragmentShaderStr;
    }

    运行结果:

     参照:https://learnopengl-cn.readthedocs.io/zh/latest/01%20Getting%20started/04%20Hello%20Triangle/

     
  • 相关阅读:
    关于UITapGestureRecognizer的一些问题
    自定义导航栏返回按钮
    mousewheel滚轮事件 浏览器的写法
    Apache日志不记录图片文件设置方法和来源日志的配置
    redis持久化配置
    haproxy实现负载均衡
    Keepalived高可用软件的安装与配置
    Sublime text2用户自定义配置
    判断各版本的最简写法
    Ubuntu防火墙 UFW 设置
  • 原文地址:https://www.cnblogs.com/xingchong/p/12068333.html
Copyright © 2011-2022 走看看