主题:请问glPolygonOffset的用法?(牛仔请进!)
drasty
[专家分:0] 发布于 2011-08-13 17:05:00
请问什么是 [b]深度冲突(Z-fighting)问题[/b]?如何解决?
另外,[b]glPolygonOffset函数的用法是什么呢?什么时候用得到?[/b]我看了帮助文档
http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=/com.ibm.aix.opengl/doc/openglrf/glPolygonOffsetEXT.htm
,还是不大懂,请赐教!
最后更新于:2011-08-13 17:08:00
回复列表 (共3个回复)
沙发
eastcowboy [专家分:25370] 发布于 2011-08-13 20:44:00
一般的3D显示都通过深度缓冲区来处理遮挡问题,这样的好处就是不管绘制顺序如何,最终总能得到相同的结果。但是深度缓冲区的精度是有限的(一般是每个像素采用16bit或者24bit来表示深度),如果两次绘制到同一个像素时,深度值相差非常小,就有可能无法正确的辨别究竟哪一次绘制的深度值更小,此时深度测试(GL_DEPTH_TEST)就出错了。
参考:[url=http://en.wikipedia.org/wiki/Z-fighting]http://en.wikipedia.org/wiki/Z-fighting[/url]
测试程序:
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
g_rotate += 0.1;
glRotated(g_rotate, 0, 1, 0);
// glDisable(GL_POLYGON_OFFSET_FILL);
glColor3f(1.0f, 0.0f, 0.0f);
glRectf(-1.0f, -1.0f, 0.5f, 0.5f);
// glEnable(GL_POLYGON_OFFSET_FILL);
// glPolygonOffset(1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glRectf(-0.5f, -0.5f, 1.0f, 1.0f);
glutSwapBuffers();
glutReportErrors();
glutPostRedisplay();
}
两个矩形在旋转时,就会出现如上wiki连接中所示的那种(错误的)效果。
如果把代码中的注释都打开,就成功的避免了z-fighting。
根据IBM文档的解释:
The value of the offset is factor * DZ + bias, where DZ is a measurement of the change in z relative to the screen area of the polygon. The offset is added before the Depth Test is performed and before the value is written into the Depth Buffer.
在进行深度测试和写入深度缓冲区之前,会把深度值加上一个offset。offset的计算公式是factor * DZ + bias,其中factor和bias是由glPolygonOffset指定,DZ似乎是深度的变化值相对屏幕的比值(这个不甚了解)
注意这和直接的glTranslate偏移有一些区别。如果用glTranslate把两个矩形错开,也可以避免z-fighting,但是显示结果还是不同的。用glPolygonOffset的话,不论怎么旋转,总是红色遮住绿色;用glTranslate的话,开始是红色遮住绿色,旋转180度之后就是绿色遮住红色了。
板凳
drasty [专家分:0] 发布于 2011-08-13 22:01:00
牛仔强大!!!万分感激!!!
3 楼
drasty [专家分:0] 发布于 2011-08-13 22:30:00
[size=2][b]牛仔,谢谢您授道解惑,谢谢您的无私帮助,我现在有一个亟待解决的问题,
帖子在http://bbs.pfan.cn/post-373100.html,您能帮我看一下看看怎么解决吗?
我自己这几天一直在搞这个东东,但是没有得到满意的结果,希望牛仔能帮一把,感激不尽![/b][/size]
我来回复