9.2 OpenGL中的消隐处理
多边形剔除
在多边形表面模型中,一个面包括正面和反面,通常正面会被观察着看见,而反面通常看不见,这种看不见
的面,可以直接进行消隐处理,这种处理可以使用OpenGL中的多边形剔除函数:
glEnable(GL_CULL_FACE);
glCullFace (mode);
这里用GL_CULL_FACE符号常量调用glEnable函数表示开启多边形表面剔除功能。然后调用glCullFace函数指定多边形所要剔除的面,参数mode可以赋值为GL_FRONT、GL_BACK和GL_FRONT_AND_BACK,分别表示剔除多边形的前面、后面以及前后面。
剔除操作可以影响从开启剔除功能开始绘制直至调用函数:
glDisable(GL_CULL_FACE);
关闭剔除功能为止的所有多边形。
程序:多边形剔除
#include <windows.h>
#include <gl/glut.h>
void Initial()
{
glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CW);
glClearColor(1.0, 1.0, 1.0, 0.0);
}
void ChangeSize(int w, int h)
{
if(h == 0) h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho (-4.0f, 4.0f, -4.0f*h/w, 4.0f*h/w, -4.0f, 4.0f);
else
glOrtho (-4.0f*w/h, 4.0f*w/h, -4.0f, 4.0f, -4.0f, 4.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glPushMatrix();
/* 第一个茶壶使用了剔除*/
glEnable(GL_CULL_FACE);
glCullFace (GL_BACK); //剔除茶壶的后向面
glTranslatef(-2.0f, 0.0f, 0.0f);
glRotatef(180.0f, 0.0f, 1.0f, 0.0f );
GLdouble equ[4] = { -1.0f, 2.3f, 2.3f, 2.3f }; // equ中保存平面方程的系数
glClipPlane(GL_CLIP_PLANE0, equ);
//glClipPlane定义裁减平面
glEnable(GL_CLIP_PLANE0);
glutSolidTeapot(1.0);
glPopMatrix();
/* 第二个茶壶关闭了剔除操作*/
glDisable(GL_CULL_FACE);
glTranslatef(2.0f, 0.0f, 0.0f);
glRotatef(180.0f, 0.0f, 1.0f, 0.0f );
glClipPlane(GL_CLIP_PLANE0, equ);
glEnable(GL_CLIP_PLANE0);
glutSolidTeapot(1.0);
glPopMatrix();
glDisable(GL_CLIP_PLANE0);
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize(400,400);
glutCreateWindow("茶壶的剔除操作");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(Display);
Initial();
glutMainLoop();
return 0;
}
深度测试
OpenGL中的深度测试是采用深度缓存器算法,消除场景中的不可见面。在默认情况下,深度缓存中深度值的范围在0.0到1.0之间,这个范围值可以通过函数:
glDepthRange (nearNormDepth,
farNormalDepth);
将深度值的范围变为nearNormDepth到farNormalDepth之间。这里nearNormDepth和farNormalDepth可以取0.0到1.0范围内的任意值,甚至可以让nearNormDepth
>
farNormalDepth。这样,通过glDepthRange函数可以在透视投影有限观察空间中的任意区域进行深度测试。
另一个非常有用的函数是:
glClearDepth (maxDepth);
参数maxDepth可以是0.0到1.0范围内的任意值。glClearDepth用maxDepth对深度缓存进行初始化,而默认情况下,深度缓存用1.0进行初始化。由于在进行深度测试中,大
于深度缓存初始值的多边形都不会被绘制,因此glClearDepth函数可以用来加速深度测试处理。这里需要注意的是指定了深度缓存的初始化值之后,应调用:
glClear(GL_DEPTH_BUFFER_BIT);
完成深度缓存的初始化。
在深度测试中,默认情况是将需要绘制的新像素的z值与深度缓冲区中对应位置的z值进行比较,如果比深度缓存中的值小,那么用新像素的颜色值更新帧缓存中对应像素的颜色值。这种比
较测试的方式可以通过函数:
glDepthFunc(func);
进行修改。其中参数func的值可以为GL_NEVER(没有处理)、GL_ALWAYS(处理所有)、GL_LESS(小于)、GL_LEQUAL(小于等于)、GL_EQUAL(等于)、GL_GEQUAL(大于等于)、GL_GREATER(大于)或GL_NOTEQUAL(不等于),其中默认值是GL_LESS。这些测试可以在各种应用中减少深度缓存处理的的计算。
|