OpenGL 基础渲染(正背面剔除) - 简书
在上文案例使用了正背面剔除后,出现了新的问题。如下图所示,那我们要如何解决这个问题呢。这个问题出现的原因是,无法区分那个图层在前,OpenGL 提供了另外一种高效消除隐藏面的技术,它叫做深度测试。
![](https://img.haomeiwen.com/i2438680/71b3b4138240348b.png)
深度测试
深度
在绘制一个像素A时,有一个Z值表示它到观察者的距离,这个值其实就是深度。
当另外一个像素B需要在屏幕上的同样位置绘制时,新像素B将与已经存储的像素A的Z值进行比较。如果新像素B相对观察者更近,则覆盖原像素点A。
深度缓冲区
在OpenGL内部,这个任务是通过深度缓冲区实现的,它在显存中存储了屏幕上每个像素的深度值。深度缓冲区默认值是1.0,表示最大的深度值。深度值的范围是[0,1]之间。
-
申请深度缓冲区
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
-
清空深度缓冲区(恢复默认1.0)
glClear(GL_DEPTH_BIT)
深度测试操作
-
开启深度测试
glEnable(GL_DEPTH_TEST)
-
关闭深度测试
glDisable(GL_DEPTH_TEST)
深度测试解决隐藏面
-
监听右键弹出菜单
glutCreateMenu(ProcessMenu);
-
在弹出菜单回调中,设置是否开启深度测试
ProcessMenu
//右键菜单栏选项 void ProcessMenu(int value) { switch(value) { case 1: iDepth = !iDepth; break; } glutPostRedisplay(); }
-
在重塑函数中,判断开启深度测试
setupRC
//根据设置iDepth标记来判断是否开启深度测试 if(iDepth) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
-
下图为开启深度测试后的效果
深度测试后.png
z-fighting
虽然深度测试解决渲染问题并提供性能。但是当两个几何图形绘制到同一位置时,会导致渲染冲突。这种情况通常称为z-fighting
(Z冲突)。
多边形偏移
OpenGL 提供了一个glPolygonOffset
模式使得我们可以调节片段的深度值,使得深度值产生偏移而不实际改变3D空间中的物理位置,从而解决z-fighting
的情况。
-
启用多边形偏移(填充几何图形)
glEnable(GL_POLYGON_OFFSET_FILL)
-
启用多边形偏移(填充点)
glEnable(GL_POLYGON_OFFSET_POINT)
-
启用多边形偏移(填充线)
glEnable(GL_POLYGON_OFFSET_LINE)
-
指定偏移量
void glPolygonOffset(GLfloat factor, GLfloat units);
-
关闭多边形偏移
glDisable(GL_POLYGON_OFFSET_FILL)
应用到片段上的总偏移可以通过下面的方程式表示。其中DZ是深度值相对于多边形屏幕区域的变换量,r则是使深度缓冲区产生变换的最小值。
网友评论