OpenGL单缓冲与双缓冲的区别
单缓冲,实际上就是将所有的绘图指令在窗口上执行,就是直接在窗口上绘图,这样的绘图效率是比较慢的,如果使用单缓冲,而电脑比较慢,你回到屏幕的闪烁。
双缓冲,实际上的绘图指令是在一个缓冲区完成,这里的绘图非常的快,在绘图指令完成之后,再通过交换指令把完成的图形立即显示在屏幕上,这就避免了出现绘图的不完整,同时效率很高。
一般用OpenGL绘图都是用双缓冲,单缓冲一般只用于显示单独的一副非动态的图像
OpenGL的消隐与双缓冲
在图形的旋转过程中整个图形都有一定程度的闪烁现象,显得图形的过渡极不平滑,这当然不是我们所要的效果,幸好opengl 支持双缓存,可以有效的帮助我们解决这个问题。我们知道在我们电脑中,屏幕中显示的东西都会被放在一个称为显示缓存的地方,在通常情况下我们只有一个这样的缓冲区,也就是单缓冲,在单缓冲中任何绘图的过程都会被显示在屏幕中,这也就是我们为什么会看到闪烁,而所谓双缓冲就是再这个显示的缓冲区 之外 再建立一个不显示的缓冲区,我们所有的绘图都将在这个不显示的缓冲区中进行,只有当一帧都绘制完了之后才会被拷贝到真正的现实缓冲区显示出来,这样中间过程对于最终用户就是不可见的了,那即使是速度比较慢也只会出现停顿而不会有闪烁的现象出现。
在OpenGL 中我们可以通过glut 库中的函数void glutSwapBuffers(void) 来实现从非显示缓冲区到显示缓冲区的复制,当然在使用双缓冲之前我们也要在 glutInitDisplayMode 设定参数的时候选择GLUT_DOUBLE(双缓存) 而不是之前我们用的 GLUT_SINGLE(单缓存)相信这两个参数的意思也应该很明白了。
在解决了闪烁的问题之后 我们来解决另一个问题 首先我们在窗口中画两个交叉的分别位于ZOX 和 ZOY 平面的长方形 并用不同的颜色填充它们,然后让它们旋转很快我们发现有个比较严重的问题,因为我们发现opengl显然没有空间的位置观念因为它根本不能分辨物体的前后关系,当然也不能做出适当的显示,在opengl中我们使用深度缓冲区来解决这个问题,在这个缓冲区中存放着每个象素深度信息,当有一个新的象素需要显示的时候,我们可以通过一个被称为深度测试的函数来确定它们的先后关系,要使用深度缓冲区有以下几个步骤:
- 在函数 glutInitDisplayMode(mode) 中将GLUT_DEPTH置位 表明要使用深度缓冲区
- 使用函数glEnable(GL_DEPTH_TEST) 打开深度测试函数 (函数介绍点击查看)
- void glDepthFunc(GLenum func) 函数glDepthFunc()来设置深度测试函数,深度测试函数有 GL_LESS 和 GL_LEQUAL 两者的区别在于当深度相同时是显示新的象素 还是老的象素;
- void glClearDepth(GLclampd depth) //函数来设置深度缓冲区的值,参数是背景的深度 一般都将背景深度设成最大值1
- 最后在我们使用glClear(bits) 刷新背景的同时 我们要将GL_DEPTH_BUFFER_BIT置位 表示我们在刷新背景颜色的同时 用刷新背景深度