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

Vertex Data                       顶点数据

VBO Vertex Buffer Objects  顶点缓冲对象

VAO Vertex Array Objects   顶点数组对象

顶点属性指针

Vertex Shader Objects        顶点着色器对象

GLSL   OpenGL Shading Language 着色器语言

顶点数组位置声明

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

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

Fragment Shader Objects    片段着色器对象

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

Shader Program                 着色器程序

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

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

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

主函数 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:\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 Triangles::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 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...\n"<< 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 \n";
    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\n"
    "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  \n";
    ss << " out vec4 color;  \n";
    ss << " void main(){  \n";
    ss << "        color = vec4(1.0f, 0.1f, 0.1f, 1.0f);  \n";
    ss << " }  \n";
    //return ss.str();


    std::string  fragmentShaderStr =
        "#version 330 core\n"
        "out vec4 color; "
        "void main () {"
        " color = vec4(1.0f, 0.1f, 0.1f, 1.0f);"
        "}";
    return fragmentShaderStr;
}
12-19 14:30