2012-02-13 144 views
0

我想呈现两个不同的对象,使用正常的glColor4f(),场景包含一个巨大的平面,均匀细分表面和一个简单的立方体在比平面小的中心,是被飞机分成一半。Opengl:透明度和深度测试问题

问题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); 

} 

调整大小的方法:对目标x类

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); 
} 

绘制方法:(平面)

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

有一件看起来很奇怪的事情是你在剔除背面。你想在你的立方体上有半透明的边,但是如果你剔除了这些背面,你将永远不会看到立方体的另一边! (或者我误解了什么?) – user1118321 2012-02-13 22:03:01

+0

糟糕,那又多了一个错误。但仍然存在颜色和深度方面的问题。输出看起来像是艺术。我无法区分远近的事物。 – 2012-02-14 16:49:34

+0

这就是它的样子 http://www.freeimagehosting.net/f9ipv – 2012-02-14 17:05:21

回答

2

1)绘图顺序是原因。

  • 深度排序的面绘图是必需的(从远到近)。如果发生相交,则必须对由交集定义的每个子面应用深度排序。 对于您的具体情况,按平面分割立方体的几何图形,然后按顺序绘制面,理论上可以完成这项工作。

    编辑:如果立方体是唯一的透明物体,渲染平面后的立方体的深度排序图(无需拆分几何)。

  • 另一种解决方案是使用着色器技术(如深度剥离)基于片段的深度排序。

2)如前所述,半透明物体的背面必须用脸部剔除来绘制。

+1

噢。有一件事我忘记了,因为你在处理透明度,深度测试是不够的。可能发生的情况是,您可能首先绘制立方体,然后绘制与其相交的平面。在这一点上,深度是不够的信息,因为你需要能够把飞机放在立方体的正面和背面之间。您仍然需要跟踪两个面的颜色和透明度,以正确地融合立方体和平面。通过深度测试,它只是说前面的立方体面比飞机更近,并且不会打扰绘制飞机。 – user1118321 2012-02-14 17:18:15