2012-02-13 63 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