zoukankan      html  css  js  c++  java
  • OpenGL学习——绘制矩形

    接下来稍微扩展一步,绘制矩形,即两个拼在一起的三角形。

    引入一个概念, EBO Element Buffer Object  元素缓冲对象,

    EBO用于存放描述“顶点绘制顺序”的对象。

    外注:创建VS工程配置:

    project properties

    *.h dir:
    D:codeOpenGLglfwprebuiltinclude;D:codeOpenGLglewprebuiltinclude;

    *.lib dir:
    D:codeOpenGLglfwprebuiltlib;D:codeOpenGLglewprebuiltlib;

    linked lib name:
    opengl32.lib;libglew32d.lib;glfw3.lib;

    加入SOIL后:

    *.h dir:
    D:codeOpenGLglfwprebuiltinclude;D:codeOpenGLglewprebuiltinclude;D:codeOpenGLsoilprebuiltinclude;

    *.lib dir:
    D:codeOpenGLglfwprebuiltlib;D:codeOpenGLglewprebuiltlib;D:codeOpenGLsoilprebuiltlib;

    linked lib name:

    opengl32.lib;libglew32d.lib;glfw3.lib;SOIL.lib;

    顶点数组对象(VAO)绑定会存储元素缓冲对象(EBO)解绑,就是说在绘制循环里只关心VAO即可。

    元素缓冲对象(EBO)的创建和绑定同顶点缓冲对象(VBO),只是绑定目标换成 GL_ELEMENT_ARRAY_BUFFER 。

    Wireframe Mode 线框模式,在绘制循环里设置,可控制画线和添充。

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // GL_FILL   set the wireframe mode 

    加入元素缓冲对象(EBO)后,绘制函数改用  glDrawElements 

    好了,上图上代码:

    main.cpp同三角形绘制。

    头文件 Rectangles.h

    // GLEW
    #define GLEW_STATIC
    #include <GL/glew.h>
    // GLFW
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include <sstream>
    
    class Rectangles{
    
    public:
        Rectangles();
    
        ~Rectangles();
    
    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;
    
    };

    实现类 Rectangles.cpp

    #include "Rectangles.h"
    
    
    
    Rectangles::Rectangles(){
    }
    
    Rectangles::~Rectangles(){
    }
    
    void Rectangles::init(){
        // x,y,z  opengl coordinates, the vertex data, three 3d point in normalized device coordinates
        GLfloat vertexs[] = {
            0.5f,   0.5f,  0.0f,  // 0-right up
            0.5f,  -0.5f,  0.0f,  // 1-right down
           -0.5f,   0.5f,  0.0f,  // 2-left up
            -0.5f, -0.5f,  0.0f,  // 3-left down
        };
        // vertex draw index array
        GLuint indexs[] = {
            0, 1, 2,
            1, 2, 3,
        };
        //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
            //define EBO, element buffer object
            GLuint EBO;
            glGenBuffers(1, &EBO);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexs), indexs, GL_STATIC_DRAW);
            //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 Rectangles::draw(){
        //use shader programs
        glUseProgram(shaderProgram);
    
        //draw the Rectangles
        glBindVertexArray(VAO);
        //glDrawArrays(GL_TRIANGLES, 0, 3);
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // GL_LINE   set the wireframe mode
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);
    }
    
    
    
    void Rectangles::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 Rectangles::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 Rectangles::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);
    }
    
    
    
    std::string Rectangles::getVertexShaderSrc(){
        std::string vertexShaderStr =
            "#version 330 core
    "
            "layout (location = 0) in vec3 pos; "
            "void main () {"
            " gl_Position = vec4(pos, 1.0);"
            "}";
        return vertexShaderStr;
    }
    
    
    std::string Rectangles::getFragmentShaderSrc(){
        std::string  fragmentShaderStr =
            "#version 330 core
    "
            "out vec4 color; "
            "void main () {"
            " color = vec4(1.0f, 0.1f, 0.1f, 1.0f);"
            "}";
        return fragmentShaderStr;
    }

    运行结果:

  • 相关阅读:
    数据挖掘实践(23):实战-- 建筑能源得分预测报告(一)
    返回闭包
    函数指针
    Rust 中的 Closure
    Moves, copies and clones in Rust
    Rust的闭包类型(Fn, FnMut, FnOne的区别)
    Clone VS Copy
    rust socket
    A simple UNIX socket listener in Rust
    【firecracker】系统启动与epoll事件循环
  • 原文地址:https://www.cnblogs.com/xingchong/p/12069080.html
Copyright © 2011-2022 走看看