范仁杰:9.2 OpenGL中的消隐处理

来源:百度文库 编辑:九乡新闻网 时间:2024/05/06 05:14:31
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
#include
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。这些测试可以在各种应用中减少深度缓存处理的的计算。