zoukankan      html  css  js  c++  java
  • 【转】OpenGL中的消隐处理

    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。这些测试可以在各种应用中减少深度缓存处理的的计算。

  • 相关阅读:
    SE Springer小组《Spring音乐播放器》软件需求说明3
    SE Springer小组之《Spring音乐播放器》可行性研究报告三、四
    软件工程学习笔记一:单元测试
    关于软件工程
    离散数学中的命题表达式计算并生成真值表
    “A + B”竟然还能这样做?
    测试程序运行时间的方法——clock()
    排序(1)———选择排序及其优化
    临时存几张图
    伊利亚特
  • 原文地址:https://www.cnblogs.com/wenshanzh/p/2580034.html
Copyright © 2011-2022 走看看