2010-11-15 20 views
3

我一直在玩OpenGL的整整一週或同等學歷。 二維後,我現在嘗試3D。我想重現您可以在第三個視頻http://johnnylee.net/projects/wii/中看到的3D場景。
我已經很難讓所有的東西在紋理和深度上正常工作。深度測試在OpenGL中默認顛倒了,還是我弄錯了?

我有最近2的問題,有幾分視覺上產生同樣的影響:

  • 一個與不使用3D我已經找到了2D的技術很好地融合紋理。
  • 一個對象出現在頂部上方。 就像這裏的問題暴露:Depth Buffer in OpenGL

我已經解決了這兩個問題,但我想知道如果我得到正確的事情,尤其是第二點


對於第一個,我想我已經得到了它。 我有一個圓形目標的圖像,光盤外有任何東西。它在OpenGL中很好的加載。一些(由於我的z排序問題)背後的其他目標遭受被我用來繪製它的自然方形四邊形的透明區域隱藏。

原因是紋理的每個部分都被認爲對於深度緩衝完全不透明。 使用glEnable(GL_ALPHA_TEST)以及glAlphaFunc(GL_GREATER, 0.5f)的測試使得紋理的alpha層充當每像素(布爾)不透明度指示符,並且因此使混合變得無用(因爲我的圖像具有布爾透明度)。

補充問題:順便說一下,有沒有一種方法指定alpha測試的不同來源比用於混合的alpha層?


,我已經找到了解決我的問題。 在清除顏色和深度緩衝區之前,我已將默認深度設置爲0 glClearDepth(0.0f),並且我已使用「更大」深度函數glDepthFunc(GL_GREATER)

我覺得很奇怪的是,深度是1.0,深度函數默認爲「less」GL_LESS。 我基本上反過來,以便我的對象不會顯示爲反向...

我沒見過這樣的黑客攻擊,但另一方面,我沒有看到任何對象被系統地繪製在錯誤的地方訂單,不管我給他們訂貨的順序是


OK,這裏的代碼位(剝離下來,沒有太多的希望)是現在工作,我想:

int main(int argc, char** argv) { 
     glutInit(&argc, argv); 
     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); 
     glutInitWindowSize(600, 600); // Size of the OpenGL window 
     glutCreateWindow("OpenGL - 3D Test"); // Creates OpenGL Window 
     glutDisplayFunc(display); 
     glutReshapeFunc(reshape); 

     PngImage* pi = new PngImage(); // custom class that reads well PNG with transparency 
     pi->read_from_file("target.png"); 
     GLuint texs[1]; 
     glGenTextures(1, texs); 
     target_texture = texs[0]; 
     glBindTexture(GL_TEXTURE_2D, target_texture); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
     glTexImage2D(GL_TEXTURE_2D, 0, pi->getGLInternalFormat(), pi->getWidth(), pi->getHeight(), 0, pi->getGLFormat(), GL_UNSIGNED_BYTE, pi->getTexels()); 

     glutMainLoop(); // never returns! 
     return 0; 
    } 

    void reshape(int w, int h) { 
     glViewport(0, 0, (GLsizei) w, (GLsizei) h); 
     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     gluOrtho2D(-1, 1, -1, 1); 
     gluPerspective(45.0, w/(GLdouble)h, 0.5, 10.0); 
     glMatrixMode(GL_MODELVIEW); 
     glLoadIdentity(); 
    } 

    void display(void) { 
     // The stared *** lines in this function make the (ugly?) fix for my second problem 
     glClearColor(0, 0, 0, 1.00); 
     glClearDepth(0);   // *** 
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     glShadeModel(GL_SMOOTH); 
     glEnable(GL_DEPTH_TEST); 
     glEnable(GL_DEPTH_FUNC); // *** 
     glDepthFunc(GL_GREATER); // *** 

     draw_scene(); 

     glutSwapBuffers(); 
     glutPostRedisplay(); 
    } 

    void draw_scene() { 
     glMatrixMode(GL_MODELVIEW); 
     glLoadIdentity(); 
     gluLookAt(1.5, 0, -3, 0, 0, 1, 0, 1, 0); 

     glColor4f(1.0, 1.0, 1.0, 1.0); 
     glEnable(GL_TEXTURE_2D); 
     // The following 2 lines fix the first problem 
     glEnable(GL_ALPHA_TEST);  // makes highly transparent parts 
     glAlphaFunc(GL_GREATER, 0.2f); // as not existent/not drawn 
     glBindTexture(GL_TEXTURE_2D, target_texture); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
     // Drawing a textured target 
     float x = 0, y = 0, z = 0, size = 0.2; 
     glBegin(GL_QUADS); 
     glTexCoord2f(0.0f, 0.0f); 
     glVertex3f(x-size, y-size, z); 
     glTexCoord2f(1.0f, 0.0f); 
     glVertex3f(x+size, y-size, z); 
     glTexCoord2f(1.0f, 1.0f); 
     glVertex3f(x+size, y+size, z); 
     glTexCoord2f(0.0f, 1.0f); 
     glVertex3f(x-size, y+size, z); 
     glEnd(); 
     // Drawing an textured target behind the other (but drawn after) 
     float x = 0, y = 0, z = 2, size = 0.2; 
     glBegin(GL_QUADS); 
     glTexCoord2f(0.0f, 0.0f); 
     glVertex3f(x-size, y-size, z); 
     glTexCoord2f(1.0f, 0.0f); 
     glVertex3f(x+size, y-size, z); 
     glTexCoord2f(1.0f, 1.0f); 
     glVertex3f(x+size, y+size, z); 
     glTexCoord2f(0.0f, 1.0f); 
     glVertex3f(x-size, y+size, z); 
     glEnd(); 
    } 

回答

4

通常深度明確的值是1(有效無窮大),也因爲要模擬在那裏你看到的東西都是在他們身後的東西前面現實世界的深度通功能較少。通過清除深度緩衝區爲1,你基本上是說,應繪製所有比最大深度更近的物體。除非你真的瞭解你在做什麼,否則更改這些參數通常不是你想要做的事情。

隨着要傳遞到gluLookAt攝像機參數和您的物體的位置,沿z = 2的四將進一步從相機比z = 0的對象。你想完成什麼,這似乎不正確?

的標準方法來實現訂單正確alpha混合是使得所有不透明的物體,然後渲染透明所有對象後到前。常規/默認深度功能將始終使用。

另外請注意,你可能會從你設置你的投影矩陣的方式有些怪異的行爲。通常你會打電話給gluOrtho或gluPerspective。但不是兩個。這將把兩個不同的視角矩陣放在一起,這可能不是你想要的。

+0

我回答段落:1)我只倒置它倒置倒置!2)我正在測試兩個對象的渲染,一個在另一個之後,z = 2中的那個不應該被看到,但是在第一段的修復之前。3)我知道當我讀它時,但是我不太需要它。 4)*這是訣竅!它現在正在工作,而不必反轉深度!! *我基本上是一個2D代碼,我已經適應繪製3D,並且我排除了這條愚蠢的線。謝謝! – ofavre 2010-11-16 22:22:52

0

問題補充:由方式,是 有沒有爲alpha測試指定一個不同的 來源的平均值比用於混合的 alpha層?

是的,如果你使用着色器,你可以自己計算輸出片段的alpha值。

+0

我添加了一個鼠標選擇,使用'glRenderMode(GL_SELECT)',但是我遇到了一個問題:'ALPHA_TEST'沒有在這種模式下使用(混合禁用或不)。這篇文章http://stackoverflow.com/questions/1189891/opengl-selection-with-alpha-test#1194114似乎表示否則,雖然他沒有測試它。如果有幫助,我可以使用fglrx專有驅動程序版本2:8.723.1-0ubuntu5,在Kubuntu Lucid Lynx 10.04.1 LTS下安裝ATI Mobility Radeon HD 2600卡。 (我提到它只是爲了防萬一,因爲我注意到多邊形平滑適用於較舊的nVidia,而不是此ATI卡...) – ofavre 2010-11-16 22:33:16

+0

我不明白你想用alpha來做什麼。 – Stringer 2010-11-17 08:33:45

0

關於第二個問題:有很可能出錯了您的modelViewProjection矩陣。

我有同樣的問題(並且可以「修理」它與你的黑客)至極被我採用一個矩陣,在某種程度上古怪的錯誤造成的。我解決了它正在實現我自己的矩陣生成。

0

以標準glOrtho函數映射zNear爲-1和zFar爲1默認映射到窗口座標爲[0,1](可通過glDepthRange更改爲固定管線,不確定是否仍支持該函數)。深度測試的確適用於這些術語。 解決這個問題的方法是假設zNear距離投影平面最遠,或者自己生成矩陣,無論如何,如果您想擺脫傳統的管線,就需要使用矩陣。