第一种 低效绘制圆
采用 glBegin glEnd 绘制模式,这是opengl 1.0版本中的,在高版本中已经丢弃了。循环中每次调用函数 glVertex3f 一帧调用了1000多次这个函数,CPU开销很大。另外glVertex3f 每次传输一个顶点数据到GPU,效率很低。 所以这种方式绘制效率很低。
static void drawCircle() {
float cx = 100;
float cy = 100;
float cz = 0;
float r = 80;
glColor3f(1, 1, 1);
使用360个三角形拼接一个圆
glBegin(GL_TRIANGLES);
for(int i = 0; i < 360; ++i) {
float x = (float)cos((double)i * M_PI / 180) * r + cx;
float y = (float)sin((double)i * M_PI / 180) * r + cy;
float x1 = (float)cos((double)(i + 1) * M_PI / 180) * r + cx;
float y1 = (float)sin((double)(i + 1) * M_PI / 180) * r + cy;
glVertex3f(cx, cy, cz);
glVertex3f(x, y, cz);
glVertex3f(x1, y1, cz);
}
glEnd();
}
第二种 高效绘制圆
开始准备所有顶点数据放入数组 _circle 中,然后调用函数 glVertexPointer 一次传输到GPU中。
//顶点数组数据方式绘制
static void drawCircleVPinter() {
float cx = 400;
float cy = 100;
float cz = 0;
float r = 80;
glColor3f(1, 1, 1);
for(int i = 0; i < 360; ++i) {
_circle[i * 3 + 0].x = cx;
_circle[i * 3 + 0].y = cy;
_circle[i * 3 + 0].z = cz;
_circle[i * 3 + 1].x = (float)cos((double)i * M_PI / 180) * r + cx;;
_circle[i * 3 + 1].y = (float)sin((double)i * M_PI / 180) * r + cy;;
_circle[i * 3 + 1].z = cz;
_circle[i * 3 + 2].x = (float)cos((double)(i + 1) * M_PI / 180) * r + cx;
_circle[i * 3 + 2].y = (float)sin((double)(i + 1) * M_PI / 180) * r + cy;
_circle[i * 3 + 2].z = cz;
}
glEnableClientState(GL_VERTEX_ARRAY);// 启用顶点数组
//glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
//size 表示数据是几维的
//type 数据类型
//stride 数据偏移 为0: 表示下一个数据位置是 3 * FLOAT, 不为0:表示下一个数据位置偏移是指定的大小
//pointer 要传递顶点数据的指针
glVertexPointer(3, GL_FLOAT, sizeof(float3), _circle); //该函数时一种高效的数据传递方式 把指定数组数据一次传输到GPU中
//glDrawArrays (GLenum mode, GLint first, GLsizei count);
//mode 绘制类型 三角形 等等...
//first 开始的顶点
//count 顶点个数
glDrawArrays(GL_TRIANGLES, 0, 360 * 3); //绘制
}
绘制函数:
//opengl 绘制
static void render(GLFWwindow * window) {
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
//第一种绘制方式 --- 低效绘制
drawCircle();
//第二种绘制方式 --- 高效绘制
drawCircleVPinter();
glfwSwapBuffers(window);
glfwPollEvents();
}