在3.2后,图元的渲染需要使用GLSL,并开启了定点数组缓冲区。本文主要说明OpenGL2.1版本下,不使用GLSL来渲染绘制图元,主要图元包含:
1. 点;
2.线;
3. 三角形;
4. 四边形;
5. 五边形;
关于OpenGL的版本
说明
-
OpenGL版本默认是2.1,如果使用GLFW创建指定版本的OpenGL本身也是3以后的功能,使用GLFW指定2.1版本本身也会报段错误。
- 默认是2.1;
- 只能指定3.2以后的版本(本人机器是这样,可能因系统的实现存在区别);
OpenGL版本变化有个比较大的变化,随着显卡硬件的性能提升,新的OpenGL要求必须使用GLSL语言进行渲染,OpenGL早期版本是支持CPU渲染的;
OpenGL版本对渲染的要求差别
代码结构
-
GLFWwindow * contextInit();
- 上下文初始化
-
void loadOpenGL();
- 加载OpenGL库
-
GLuint bufferData();
- 顶点数据
-
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;
}
代码实现
- 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;
}
- loadOpenGL过程实现
void loadOpenGL(){
glewInit();
}
- bufferData过程实现
- 使用了4个点的数据
- 创建一个缓冲区;
- 开启了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; // 返回是因为便于关闭与释放(这里结束应用就直接释放)
}
- render过程实现
- 注意:这里的绘制效果与上面OpenGL版本指定有关
- 在OpenGL2.1有效果,在OpenGL3.2以上没有效果。
- 注意:这里的绘制效果与上面OpenGL版本指定有关
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);
}
- 完整的代码列表
#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
不同版本执行效果
- 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); // 副版本(可选)
- Open4.1执行效果
-
OpenGL2与3,4版本的图元类型差别
-
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 //多边形(凸)
-
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 (新增)
-
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
- 代码
glColor3f(1.0f, 1.0f, 0.0f);
glDrawArrays(GL_LINES, 0, 4);
- 效果
-
GL_LINE_STRIP
- 代码
glColor3f(1.0f, 1.0f, 0.0f);
glDrawArrays(GL_LINE_STRIP, 0, 4);
- 效果
-
GL_LINE_LOOP
- 代码
glColor3f(1.0f, 1.0f, 0.0f);
glDrawArrays(GL_LINE_LOOP, 0, 4);
- 效果
-
三角形
- 三角形支持3种
- GL_TRIANGLES //三角形
- GL_TRIANGLE_STRIP //三角形条带
- GL_TRIANGLE_FAN //三角形扇
三角形绘制规则
GL_TRIANGLES
- 代码
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);
}
- 效果(3个点构成一个蛋饺行,6个点构成2个三角形)
-
GL_TRIANGLE_STRIP
- 代码
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);
}
- 效果(2个三角形重叠而成)
-
GL_TRIANGLE_FAN
- 代码
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);
}
- 效果(4个三角形重叠而成)
-
四边形
- 新的OpenGL不支持
- 四边形支持两种
- GL_QUADS //四边形
- GL_QUAD_STRIP //四边形条带
四边形绘制规
GL_QUADS
- 数据修改为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; // 返回是因为便于关闭与释放(这里结束应用就直接释放)
}
- 图元绘制代码
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);
}
- 效果(最后一个点没有使用)
-
GL_QUAD_STRIP
- 代码
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);
}
- 效果
- 记得按照()顺序理解绘图。
-
多边形
- 新的OpenGL不支持
- 多边形只有一个类型:
- GL_POLYGON //多边形(凸)
- 绘制代码(使用的还是是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);
}
- 效果
-