OpenGL学习——绘制矩形

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

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

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

外注:创建VS工程配置:

project properties

*.h dir:
D:\code\OpenGL\glfw\prebuilt\include;D:\code\OpenGL\glew\prebuilt\include;

*.lib dir:
D:\code\OpenGL\glfw\prebuilt\lib;D:\code\OpenGL\glew\prebuilt\lib;

linked lib name:
opengl32.lib;libglew32d.lib;glfw3.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:\n" << 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...\n" << 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 << "\n\nfragmentShaderSrc:\n" << 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...\n" << 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\n"
        "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\n"
        "out vec4 color; "
        "void main () {"
        " color = vec4(1.0f, 0.1f, 0.1f, 1.0f);"
        "}";
    return fragmentShaderStr;
}

运行结果:

猜你喜欢

转载自www.cnblogs.com/xingchong/p/12069080.html