2013-05-08 9 views
0

概述:PyOpenGL,發行使用glFrustum和glTranslate在屏幕上的3D圖形

我想創建一個類似的3D應用程序:

www.youtube.com/watch?v=h9kPI7_vhAU. 

我使用OpenCV2.2,Python2。 7和pyOpenGL。 這可以通過this background maths and code snippet其中x,y,z是觀衆眼球的位置來實現

問題(從攝像頭抓住了!):

當我做到這一點,對象(立方體),其我已經渲染沿z軸拉伸(進入屏幕),我不太確定爲什麼。它被比作從高處俯視一座非常高的摩天大樓(而不是立方體)。隨着z的位置變化,立方體的位置在z方向上變化非常迅速。 This是一個結果框架,它已被拉長!

代碼(與bigD的編輯):

def DrawGLScene(): 
    #get some parameters for calculating the FRUSTUM 
    NEAR_CLIPPING_PLANE = 0.01 
    FAR_CLIPPING_PLANE = 2 
    window = glGetIntegerv(GL_VIEWPORT) 
    WINDOW_WIDTH = window[2] 
    WINDOW_HEIGHT= window[3] 

    #do facial detection and get eye co-ordinates 
    eye = getEye() 

    #clear window 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 

    #before any projection transformation command comes these 2 lines: 
    glMatrixMode(GL_PROJECTION) 
    glLoadIdentity() 

    #transform projection to that of our eye 
    glFrustum(NEAR_CLIPPING_PLANE*(-WINDOW_WIDTH /2 - eye[0])/eye[2], 
       NEAR_CLIPPING_PLANE*(WINDOW_WIDTH /2 - eye[0])/eye[2], 
       NEAR_CLIPPING_PLANE*(-WINDOW_HEIGHT/2 - eye[1])/eye[2], 
       NEAR_CLIPPING_PLANE*(WINDOW_HEIGHT/2 - eye[1])/eye[2], 
       NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE) 

    glMatrixMode(GL_MODELVIEW) 
    glLoadIdentity() 
    glTranslatef(-eye[0],-eye[1],-eye[2]) 

    drawCube() 

    glutSwapBuffers() 

數據getEye()返回的一個例子是:

[0.25,0.37,1]如果觀衆是具有接近的左下他們的臉屏幕和爲1m遠

[-0.5,-0.1,0.5]如果觀衆是具有靠近屏幕的右上他們的臉和爲0.5m遠

繪製時,立方體具有高度,寬度,2深度一個其中心在(0,0,0)。

我會提供完整的代碼,如果任何人想要做類似的項目,並希望kickstart或認爲問題在於提供的代碼以外的地方。

回答

1

爲什麼你得到奇怪的結果的原因是因爲這一點:

glTranslatef(-eye[0],-eye[1],-eye[2]) 

此調用應作出後

glMatrixMode(GL_MODELVIEW) 
glLoadIdentity() 

由於投影矩陣已經準備好,因爲它是與你的glFrustum調用,如果你乘以一個翻譯矩陣,它不會使它成爲一個透視投影矩陣了。模型視圖矩陣必須描述所有的世界和攝像機變換。

還要記住,如果你對你的模型視圖矩陣做的唯一的轉型是一個翻譯,那麼你將永遠凝視着負Z軸。

+0

感謝您的回覆。雖然你所說的是真實的,但似乎也產生了相同的答案!我編輯了上面的代碼以包含您的建議。我絕對難住了! – user2361324 2013-05-08 10:10:09

+0

好吧,我想我發現了另一個問題: 您的glFrustum()調用似乎取決於您的眼睛的世界空間座標。看看這個圖片 http://i.iinfo.cz/r/photos/opengl/opengl_14_1.gif 的glFrustum呼叫真的只是定義了你的觀點,長寬比和限制外地多遠對象可以等到它被切斷。當看這張圖片時,將平截頭體繪製在(0,0,0)處並沿着負Z軸向下。這是在'相機空間'現在,所以世界空間中的任何座標在這裏都沒有意義,因爲一切已經通過模型視圖矩陣 – bigD 2013-05-08 10:18:53

+0

進行了轉換,您的左/右/上/下值將通過left | right = +/- near_plane * tan(0.5 * fovx) bottom | +/- near_plane * tan(0.5 * fovy) 其中fovx和fovy是水平和垂直視場。 或者您可以選擇固定的水平或垂直視場和縱橫比,並確定所有的平面 – bigD 2013-05-08 10:25:12