2015-07-13 153 views
1

我有一個奇怪的問題,我猜是由qt引起的。 我使用Qt的OpenGL窗口小部件和我的重繪常規和MouseMove事件是這樣的:OpenGL重繪不同渲染結果的相同參數

void RenderGraphFrame::redraw() 
{ 
    GLdouble objX, objY, objZ; 
    GLdouble ModelViewMatrixvector[16], ProjectionViewMatrixVector[16]; 
    GLint ViewportVector[4]; 

    glGetIntegerv (GL_VIEWPORT, ViewportVector); 
    glGetDoublev (GL_MODELVIEW_MATRIX, ModelViewMatrixvector); 
    glGetDoublev (GL_PROJECTION_MATRIX, ProjectionViewMatrixVector); 

    gluUnProject(mousepositionX, mousepositionY, 0, 
       ModelViewMatrixvector, 
       ProjectionViewMatrixVector, 
       ViewportVector, 
       &objX, &objY, &objZ); 

    qDebug() << "objX: " << objX << " objY: " << objY << " objZ: " << objZ; 

    qglColor(Qt::red); 
    glBegin(GL_TRIANGLES); 
     glNormal3f(0,-1,0.707); 
     glVertex3f(objX-1,objY-1,0); 
     glVertex3f(objX+1,objY-1,0); 
     glVertex3f(objX,objY,1.2); 
    glEnd(); 
} 

void RenderGraphFrame::mouseMoveEvent (QMouseEvent *event) 
{ 
    mousepositionX = event->x(); 
    mousepositionY = event->y(); 
    redraw(); 
    return; 
} 

當我在Widget上移動鼠標,我得到的輸出的全碼流通過qDebug()所以它是確保Even觸發器和redraw()得到執行。

爲了測試,我想要一個4個三角形的方形區域被渲染,其中1個三角形跟隨着光標。

但是隻有3種形狀,第四種缺失......那至少是我在想什麼。雖然當我正在摸索時,我想象出當我在窗外跳動時,當我按下alt時,關鍵redraw()方法被再次調用,其輸出與最後一次鼠標移動完全相同,但現在第四個形狀獲得呈現(不是我想要的位置,但這可能只是我的3d邏輯中的錯誤)

這怎麼可能? 有什麼神祕的東西在小部件中導致這個問題?如果這不是我的錯,我能做些什麼qt讓我按照自己的意願去做?

編輯:

-I注意到,剛剛按下alt - 鍵,以引起期望的呈現是難以重現(Tab鍵切換到其他applicantions同時點擊不同而alt + tab菜單中的某些時間上的工作)。但什麼是可重現的是: 當我從應用程序中退出,然後再次選項卡時,重畫就像它應該那樣工作。但不是從mousemove事件中調用時。

-I刪除了不是問題的靜態形狀,所以代碼更容易閱讀。

回答

2

你的錯誤是假定OpenGL上下文在每次函數調用時處於相同的狀態。但是,Qt在渲染自己的東西時會修改很多狀態。這就是爲什麼即使您每次在代碼中執行完全相同的GL調用時都會得到不同的結果。

報價Qt文檔:

[...]當前的OpenGL上下文的狀態將被繪圖引擎進行修改,以反映其需求。應用程序不應依賴將OpenGL狀態重置爲其原始狀態,特別是當前着色器程序,OpenGL視口,紋理單元和繪圖模式。

所以,很多像綁定紋理,多邊形模式,混合,深度測試等狀態基本處於隨機狀態,每次redraw()被調用。您必須在redraw()開頭重置所有這些設置,以確保您每次都能得到相同的結果。

+0

+1迄今爲止,因爲ti聽起來符合我的邏輯。但在我接受這個之前,我希望看到一個解決方案或解釋如何實施重置。 – dhein

+0

在您的特定場景中,我會查看視口和矩陣值,看看它們是否處於理智狀態。您目前正在將它們用於未投影,但Qt可能已將它們設置爲不正確的值,您可能必須重置它們。您可以使用[apitrace](http://apitrace.github.io/)查看Qt究竟在做什麼以及需要重置哪些狀態。 –

+0

但我記錄了gluUnProject返回的值,它依賴於矩陣。所以他們的輸出在正確和不正確的行爲之間應該是不同的,不是嗎?目前在這兩種情況下gluUnProject輸出是相同的。但我會看。 – dhein

1

我通過在事件監聽器中更改redraw()updateGL()的方法調用來解決此問題。這可能是對自己的qt行爲的影響,正如Lukas Boersma在他的回答中所描述的那樣。

現在按預期運行的版本有這種實施方法:

void RenderGraphFrame::mouseMoveEvent (QMouseEvent *event) 
{ 
    mousepositionX = event->x(); 
    mousepositionY = event->y(); 
    updateGL(); 
    return; 
} 

注: updateGL()是外部函數!

相關問題