Opengl:透明度和深度测试问题

时间:2012-02-13 20:18:54

标签: qt opengl

我正在尝试使用普通glColor4f()渲染两个不同的对象。场景包含一个具有均匀细分曲面的巨大平面和一个小于平面的简单立方体,并被平面分成两半。

问题1:当我试图转动视图时,立方体似乎完全在飞机上方。它看起来就像埃舍尔的形象。如何正确修复深度测试?

问题2:小立方体应该是透明的并且透视类型,但透明度不起作用。

我的初始化方法。

void GWidget::initializeGL()
{
    setFormat(QGLFormat(QGL::DoubleBuffer|QGL::DepthBuffer|QGL::Rgba|QGL::DepthBuffer));


    glEnable(GL_POINT_SMOOTH);
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_POLYGON_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_COLOR_MATERIAL);

    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0.0f);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_SRC_ALPHA);

    glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);
    glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);
    glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);

    glCullFace(GL_BACK);
    glDepthFunc(GL_LEQUAL);
    glDepthMask(GL_TRUE);

    glFrontFace(GL_CCW);

        glMatrixMode(GL_MODELVIEW);
        glTranslatef(0,0,-1);
        glClearColor(0.4,0.5,0.4,0);
        glClearDepth(1.0f);
        glPushMatrix();
        glShadeModel(GL_SMOOTH);
        glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);

        glEnable(GL_MULTISAMPLE);

//        glScalef(0.1f,0.1f,0.1f);

}

调整大小的方法:

void GWidget::resizeGL(int width, int height)
{
    glViewport( 0, 0, (GLint)width, (GLint)height );
     glMatrixMode( GL_PROJECTION );
     glLoadIdentity();

     glOrtho ( -width,width,-height,height, 0.0, 200.0 );
     glPushMatrix();

     glMatrixMode( GL_MODELVIEW );
     glLoadIdentity();
     glTranslatef(0,0,-3);
     glScalef(0.7,0.7,0.7);
     glPushMatrix();
     glEnable (GL_DEPTH_TEST);
}

ObjectX类的绘制方法:(平面)

void ObjectX::GDraw(int i)
{
    qint32 count,iter;
    MeshX *dmesh;
    VertX *dvert;
    EdgeX *dedge;
    FaceX *dface;

    QList<VertX* > *vlist;


    dmesh=this->Meshes[i];
    vlist=dmesh->getVList();

     iter=0;
     int a,b;
     int c,d;
     glColor4f(0.81,0.71,0.51,1);
     glBegin(GL_QUADS);
     foreach(iter,dmesh->QFaces)
     {
            dface=dmesh->getFaceX(iter);
            a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();

            dvert=vlist->at(a);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(b);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(c);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(d);
            glVertex3fv(dvert->getV());

    }
    glEnd();
    glFlush();

    glColor4f(0.51,0.41,0.51,1);
    glBegin(GL_TRIANGLES);
    foreach(iter,dmesh->TFaces)
    {
       glBegin(GL_QUADS);
           dface=dmesh->getFaceX(iter);
           a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();

           dvert=vlist->at(a);
           glVertex3fv(dvert->getV());

           dvert=vlist->at(b);
           glVertex3fv(dvert->getV());

           dvert=vlist->at(c);
           glVertex3fv(dvert->getV());
    }
    glEnd();
    glFlush();

    iter=0;
    glLineWidth(3.0f);
    glColor4f(0.31,0.27,0.51,1.0);
    glBegin(GL_LINES);
        count=dmesh->getEListLength();
        while(iter<count)
        {
            dedge=dmesh->getEdgeX(iter);
            a=dedge->getA();b=dedge->getB();
            dvert=vlist->at(a);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(b);
            glVertex3fv(dvert->getV());
            iter++;
        }
    glEnd();
    glFlush();

    iter=0;
    glColor4f(1,1,1,1.0);
    glPointSize(3.0f);
    glBegin(GL_POINTS);

        count=dmesh->getVListLength();
        while(iter<count)
        {
            dvert=dmesh->getVertX(iter);
            glColor4fv(dvert->getColorV());
            glVertex3fv(dvert->getV());
            iter++;
        }
    glEnd();
    glFlush();

}

DomainX方法的绘制方法:(小方块)

void DomainX::drawDomain()
{
    qint32 count,iter;
    MeshX *dmesh;
    VertX *dvert;
    EdgeX *dedge;
    FaceX *dface;

    QList<VertX* > *vlist;


    dmesh=this->DMesh;
    vlist=dmesh->getVList();

     iter=0;
     int a,b;
     int c,d;
     glColor4f(0.1,0.1,0.1,0.01);
     glBegin(GL_QUADS);
     foreach(iter,dmesh->QFaces)
     {
            dface=dmesh->getFaceX(iter);
            a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();

            dvert=vlist->at(a);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(b);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(c);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(d);
            glVertex3fv(dvert->getV());

    }
    glEnd();
    glFlush();

    glColor4f(0.51,0.41,0.51,0.01);
    glBegin(GL_TRIANGLES);
    foreach(iter,dmesh->TFaces)
    {
       glBegin(GL_QUADS);
           dface=dmesh->getFaceX(iter);
           a=dface->getA();b=dface->getB();c=dface->getC();d=dface->getD();

           dvert=vlist->at(a);
           glVertex3fv(dvert->getV());

           dvert=vlist->at(b);
           glVertex3fv(dvert->getV());

           dvert=vlist->at(c);
           glVertex3fv(dvert->getV());
    }
    glEnd();
    glFlush();

    iter=0;
    glLineWidth(3.0f);
    glColor4f(0.71,0.27,0.51,1.0);
    glBegin(GL_LINES);
        count=dmesh->getEListLength();
        while(iter<count)
        {
            dedge=dmesh->getEdgeX(iter);
            a=dedge->getA();b=dedge->getB();
            dvert=vlist->at(a);
            glVertex3fv(dvert->getV());

            dvert=vlist->at(b);
            glVertex3fv(dvert->getV());
            iter++;
        }
    glEnd();
    glFlush();

    iter=0;
    glColor4f(1,1,1,1.0);
    glPointSize(3.0f);
    glBegin(GL_POINTS);

        count=dmesh->getVListLength();
        while(iter<count)
        {
            dvert=dmesh->getVertX(iter);
            glColor4f(0.3,0.7,0.6,1);
            glVertex3fv(dvert->getV());
            iter++;
        }
    glEnd();
    glFlush();


}

1 个答案:

答案 0 :(得分:2)

1)绘图顺序是原因。

  • 需要深度排序的面部绘图(从远到近)。如果发生交叉,则必须对交叉定义的每个子面应用深度排序。 对于您的具体情况,将立方体的几何体按平面分成两半然后按顺序绘制面将理论上完成工作。

    编辑:如果立方体是唯一的透明对象,则渲染平面后,立方体的深度排序图(不拆分几何图形)也可以。

  • 另一个解决方案是使用深度剥离等着色器技术进行基于片段的深度排序。

2)如上所述,必须在面部剔除的情况下绘制半透明物体的背面。