在了解深度测试前我们先了解几个概念。
1、什么是深度?
深度是指该像素点在3D世界中距离摄像机位置的Z值。
2、什么是深度缓冲区
深度缓冲区是指一块内存区域,专门用来保存每个像素点在屏幕上的深度值。深度越大Z值越大
3、深度缓冲区的意义
在不使用深度测试的时候,假如我们先绘制一个近距离的物体,在绘制一个远距离的物体,远距离物体因为后绘制,就会把近距离的物体覆盖掉,有了深度缓冲区,物体绘制的顺序就不那么重要了,实际上只要存在深度缓冲区,OpenGL都会把像素的深度值写入其中,除非掉用glDepthMask(GL FALSE)来禁止写入。
所以在我们开启深度测试的时候,首先要将表面对应的像素的深入值和当前深度缓冲区中的值进行比较,如果大于深入缓冲区中的值,则丢弃这部分,否者就利用该像素对应的深度值和颜色值分别更新深度缓冲区和颜色缓冲区。这个过程就是深度测试。(深入缓冲区和颜色缓冲区是一一对应的)。深入测试的判断是以像素点为单位,并非以当前绘制的图形为单位。
如何开启深度测试?
glEnable(GL_DEPTH_TEST).
在使用中我们需要注意如果项目中需要使用深度测试,我们在绘制前要对深度缓冲区进行清除。如果不清空颜色/深度缓冲区时,会造成数据的残留,导致绘制异常。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
下面上传开启深入测试后的效果图。
当然我们在项目中也可能会遇到深度值都一样的情况,这样就会出现ZFighting 闪烁问题(即指OpenGL不能正确的判断同一平面的绘制的深度值,导致深入测试结果不可预测,显示出来的纹理交错闪烁),就需要进行如下处理多边形偏移让其深度值产生一些细微的变化,达到区分二者图形深度值的效果。
glEnable(GL_POLYGON_OFFSET_POINT) //对应GL_POINT
glEnable(GL_POLYGON_OFFSET_LINE) //对应GL_LINE
glEnable(GL_POLYGON_OFFSET_FILL) //对应GL_FILL
然后指定偏移量
void glPolygonOffet(Glfloat factor,Glfloat units);
一般来说,只需要将-1.0和-1这样简单赋值给glPolygonOffet基本就可以满足需求
关闭Polygon Offset
glDisable(GL_POLYGON_OFFSET_FILL)
如有不妥之处,敬请指出。