GL01-07:没有着色器下的图元渲染

在3.2后,图元的渲染需要使用GLSL,并开启了定点数组缓冲区。本文主要说明OpenGL2.1版本下,不使用GLSL来渲染绘制图元,主要图元包含:
  1. 点;
  2.线;
  3. 三角形;
  4. 四边形;
  5. 五边形;


关于OpenGL的版本

说明

  1. OpenGL版本默认是2.1,如果使用GLFW创建指定版本的OpenGL本身也是3以后的功能,使用GLFW指定2.1版本本身也会报段错误。

    • 默认是2.1;
    • 只能指定3.2以后的版本(本人机器是这样,可能因系统的实现存在区别);
  2. OpenGL版本变化有个比较大的变化,随着显卡硬件的性能提升,新的OpenGL要求必须使用GLSL语言进行渲染,OpenGL早期版本是支持CPU渲染的;

OpenGL版本对渲染的要求差别

代码结构

  1. GLFWwindow * contextInit();
    • 上下文初始化
  2. void loadOpenGL();
    • 加载OpenGL库
  3. GLuint bufferData();
    • 顶点数据
  4. void render();
    • 图元绘制
#include 
#include 
#include 
#include 
#include 


GLFWwindow * contextInit();         // 上下文初始化
void loadOpenGL();                  // 加载OpenGL库 
GLuint bufferData();                // 顶点数据
void render();                      // 图元绘制



int main(int argc, const char** argv) {
    GLFWwindow *win =contextInit();
    loadOpenGL();
    bufferData();
    while(!glfwWindowShouldClose(win)){

        render();
        glfwSwapBuffers(win);
        glfwWaitEvents();
    }

    glfwDestroyWindow(win);
    glfwTerminate();
    
    return 0;
}

代码实现

  1. contextInit过程实现
    • 注意其中指定OpenGL部分的代码
GLFWwindow * contextInit(){
    glfwInit();         // 初始化GLFW
    // 开启OpenGL4.1版本
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);   // 主版本  从3.2以后都支持,3.3,4.0, 4.1(本系统最高)
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);   // 副版本(可选)
    GLFWwindow *window = glfwCreateWindow(600,400,"OpenGL图元", NULL, NULL); // 创建窗体,也是创建上下文
    glfwMakeContextCurrent(window);  // 射设置当前上下文
    return window;
}

  1. loadOpenGL过程实现
void loadOpenGL(){
    glewInit();
}
  1. bufferData过程实现
    • 使用了4个点的数据
      • 创建一个缓冲区;
      • 开启了4个顶点属性数组;
GLuint bufferData(){
    float vertices[] = {
        -0.5f, -0.5f, 0.0f, // 第一个顶点  
        -0.5f,  0.5f, 0.0f, // 第二个顶点
         0.5f,  0.5f, 0.0f,  // 第三个顶点
         0.5f, -0.5f, 0.0f
    }; 
    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);  // 顶点缓冲区

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); // 指定缓冲区类型

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);  // 拷贝数据到顶点缓冲区

    // 开启顶点缓冲区与属性
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glEnableVertexAttribArray(3);
    
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    return  vertexBuffer;   // 返回是因为便于关闭与释放(这里结束应用就直接释放)
}
  1. render过程实现
    • 注意:这里的绘制效果与上面OpenGL版本指定有关
      • 在OpenGL2.1有效果,在OpenGL3.2以上没有效果。
void render(){
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f, 0.0f, 1.0f);
    glDrawArrays(GL_QUADS,0, 4);

}
  1. 完整的代码列表
#include 
#include 
#include 
#include 
#include 


GLFWwindow * contextInit();         // 上下文初始化
void loadOpenGL();                  // 加载OpenGL库 
GLuint bufferData();                // 顶点数据
void render();                      // 图元绘制



int main(int argc, const char** argv) {
    GLFWwindow *win =contextInit();
    loadOpenGL();
    bufferData();
    while(!glfwWindowShouldClose(win)){

        render();
        glfwSwapBuffers(win);
        glfwWaitEvents();
    }

    glfwDestroyWindow(win);
    glfwTerminate();
    
    return 0;
}

GLFWwindow * contextInit(){
    glfwInit();         // 初始化GLFW
    // 开启OpenGL4.1版本
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);   // 主版本  从3.2以后都支持,3.3,4.0, 4.1(本系统最高)
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);   // 副版本(可选)
    GLFWwindow *window = glfwCreateWindow(600,400,"OpenGL图元", NULL, NULL); // 创建窗体,也是创建上下文
    glfwMakeContextCurrent(window);  // 射设置当前上下文
    return window;
}

void loadOpenGL(){
    glewInit();
}
GLuint bufferData(){
    float vertices[] = {
        -0.5f, -0.5f, 0.0f, // 第一个顶点  
        -0.5f,  0.5f, 0.0f, // 第二个顶点
         0.5f,  0.5f, 0.0f,  // 第三个顶点
         0.5f, -0.5f, 0.0f
    }; 
    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);  // 顶点缓冲区

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); // 指定缓冲区类型

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);  // 拷贝数据到顶点缓冲区

    // 开启顶点缓冲区与属性
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glEnableVertexAttribArray(3);
    
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    return  vertexBuffer;   // 返回是因为便于关闭与释放(这里结束应用就直接释放)
}

void render(){
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f, 0.0f, 1.0f);
    glDrawArrays(GL_QUADS,0, 4);

}
// 编译命令:g++ -omain  gl05_geometries.cpp  -lglfw -lglew -framework opengl

不同版本执行效果

  1. OpenGL2.1执行效果
    • 就是注销如下代码的效果
    // 开启OpenGL4.1版本
    // glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    // glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);   // 主版本  从3.2以后都支持,3.3,4.0, 4.1(本系统最高)
    // glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);   // 副版本(可选)
OpenGL2.1效果
  1. Open4.1执行效果
    • OpenGL4.1效果

OpenGL2与3,4版本的图元类型差别

  1. OpenGL2.1支持的图元类型

    • GL_POINTS //点
    • GL_LINES //线段
    • GL_LINE_STRIP //多段线
    • GL_LINE_LOOP //线圈
    • GL_TRIANGLES //三角形
    • GL_TRIANGLE_STRIP //三角形条带
    • GL_TRIANGLE_FAN //三角形扇
    • GL_QUADS //四边形
    • GL_QUAD_STRIP //四边形条带
    • GL_POLYGON //多边形(凸)
  2. OpenGL3.3支持的图元类型

    • GL_POINTS
    • GL_LINE_STRIP
    • GL_LINE_LOOP
    • GL_LINES
    • GL_LINE_STRIP_ADJACENCY (新增)
    • GL_LINES_ADJACENCY (新增)
    • GL_TRIANGLE_STRIP
    • GL_TRIANGLE_FAN
    • GL_TRIANGLES
    • GL_TRIANGLE_STRIP_ADJACENCY (新增)
    • GL_TRIANGLES_ADJACENCY (新增)
  3. Open4.1支持的图元类型

    • GL_POINTS
    • GL_LINE_STRIP
    • GL_LINE_LOOP
    • GL_LINES
    • GL_LINE_STRIP_ADJACENCY
    • GL_LINES_ADJACENCY
    • GL_TRIANGLE_STRIP
    • GL_TRIANGLE_FAN
    • GL_TRIANGLES
    • GL_TRIANGLE_STRIP_ADJACENCY
    • GL_TRIANGLES_ADJACENCY
    • GL_PATCHES (新增)

OpenGL图元

  • 注意:
    • 上面我们开启了4个顶点,用来绘制图元,并且使用了glColor3f函数来指定绘制图元的颜色(没有使用GLSL来渲染颜色)。
    • 只说明OpenGL2.1版本的图元

  • 点的类型只有:GL_POINTS
    • 绘制4个点;

void render(){
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    // GL_POINTS:点
    glColor3f(1.0f, 1.0f, 0.0f);
    glDrawArrays(GL_POINTS, 0, 2);  // 从0开始,绘制2个

    glColor3f(0.0f, 1.0f, 0.0f);
     glDrawArrays(GL_POINTS, 2, 2);  // 从2开始绘制两个

}

线段

  • 线段有三种:
    • GL_LINES //线段(两个成对的线段,比如4个点,只能3绘制2条线段,3个点只能1条线段)
    • GL_LINE_STRIP //多段线 (连续线段,4个点绘制3条线段)
    • GL_LINE_LOOP //线圈 (封闭,4个点绘制4条线段)

GL_LINES

  1. 代码
    glColor3f(1.0f, 1.0f, 0.0f);
    glDrawArrays(GL_LINES, 0, 4);  
  1. 效果
    • GL_LINES

GL_LINE_STRIP

  1. 代码
    glColor3f(1.0f, 1.0f, 0.0f);
    glDrawArrays(GL_LINE_STRIP, 0, 4);  
  1. 效果
    • GL_LINE_STRIP

GL_LINE_LOOP

  1. 代码
    glColor3f(1.0f, 1.0f, 0.0f);
    glDrawArrays(GL_LINE_LOOP, 0, 4);  
  1. 效果
    • GL_LINE_LOOP

三角形

  • 三角形支持3种
    • GL_TRIANGLES //三角形
    • GL_TRIANGLE_STRIP //三角形条带
    • GL_TRIANGLE_FAN //三角形扇

三角形绘制规则

  • 三角形绘制规则说明

GL_TRIANGLES

  1. 代码
void render(){
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    // GL_POINTS:点
    glColor3f(1.0f, 1.0f, 0.0f);
    glDrawArrays(GL_TRIANGLES, 0, 4);  
}
  1. 效果(3个点构成一个蛋饺行,6个点构成2个三角形)
    • GL_TRIANGLES

GL_TRIANGLE_STRIP

  1. 代码
void render(){
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    // GL_POINTS:点
    glColor3f(1.0f, 1.0f, 0.0f);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);  
}
  1. 效果(2个三角形重叠而成)
    • GL_TRIANGLE_STRIP

GL_TRIANGLE_FAN

  1. 代码
void render(){
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    // GL_POINTS:点
    glColor3f(1.0f, 1.0f, 0.0f);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);  
}
  1. 效果(4个三角形重叠而成)
    • GL_TRIANGLE_FAN

四边形

  • 新的OpenGL不支持
  • 四边形支持两种
    • GL_QUADS //四边形
    • GL_QUAD_STRIP //四边形条带

四边形绘制规

  • 四边形绘制规则

GL_QUADS

  1. 数据修改为5个点
GLuint bufferData(){
    float vertices[] = {            // 5边形(顺时针:注意点的顺序)
         0.0f,  0.5f, 0.0f,         // 第一个顶点  
         0.5f,  0.0f, 0.0f,         // 第二个顶点
         0.3f, -0.5f, 0.0f,         // 第三个顶点
        -0.3f, -0.5f, 0.0f,         // 第四个顶点
        -0.5f,  0.0f, 0.0f,         // 第五个顶点
    }; 
    
    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);  // 顶点缓冲区

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); // 指定缓冲区类型

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);  // 拷贝数据到顶点缓冲区

    // 开启顶点缓冲区与属性
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glEnableVertexAttribArray(3);
    glEnableVertexAttribArray(4);
    
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    return  vertexBuffer;   // 返回是因为便于关闭与释放(这里结束应用就直接释放)
}
  1. 图元绘制代码
void render(){
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f, 1.0f, 0.0f);
    glDrawArrays(GL_QUADS, 0, 5);  
}
  1. 效果(最后一个点没有使用)
    • GL_QUADS

GL_QUAD_STRIP

  1. 代码
void render(){
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    // GL_POINTS:点
    glColor3f(1.0f, 1.0f, 0.0f);
    // glDrawArrays(GL_QUADS, 0, 5);  
    glDrawArrays(GL_QUAD_STRIP, 0, 5);  

}
  1. 效果
    • 记得按照()顺序理解绘图。
    • GL_QUAD_STRIP
  • 绘制过程(v4没有参与绘制)

多边形

  • 新的OpenGL不支持
  • 多边形只有一个类型:
    • GL_POLYGON //多边形(凸)
  1. 绘制代码(使用的还是是5个顶点的数据)
void render(){
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0f, 1.0f, 0.0f);
    glDrawArrays(GL_POLYGON, 0, 5);  

}
  1. 效果
    • GL_POLYGON

你可能感兴趣的:(GL01-07:没有着色器下的图元渲染)