2012-09-06 43 views
4

我爲我的應用程序編寫了一個基於OpenGL的矢量圖形渲染器。它需要直接渲染到幀緩衝區對象而不是屏幕。由於我在Qt中編寫應用程序,因此我使用QGLFramebufferObject,它是OpenGL幀緩衝區對象的包裝類。在QGLFramebufferObject上渲染時錯誤的alpha混合

我創建了一個最小的例子,它顯示了錯誤的結果,我也得到時渲染更復雜的東西(例如使用片段着色器設置顏色與非一個alpha值)。我只是呈現一個紅圈,清除屏幕上黑色半透明綠色的,然後同樣的FBO:

void MainWidget::initializeGL() 
{ 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glClearColor(0, 0, 0, 0); 
} 

void MainWidget::resizeGL(int w, int h) 
{ 
    glViewport(0, 0, w, h); 
} 

void MainWidget::paintGL() 
{ 
    // DRAW ON THE SCREEN 
    { 
     glClear(GL_COLOR_BUFFER_BIT); 
     glPointSize(100); 
     glEnable(GL_POINT_SMOOTH); 
     glBegin(GL_POINTS); 
     glColor4f(1, 0, 0, 1); 
     glVertex2f(-.2, 0); 
     glColor4f(0, 1, 0, .5); 
     glVertex2f(.2, 0); 
     glEnd(); 
    } 

    QGLFramebufferObject fbo(width(), height()); 
    fbo.bind(); 

    // DRAW ON THE FBO USING THE SAME CODE AND THE SAME CONTEXT 
    { 
     glClear(GL_COLOR_BUFFER_BIT); 
     glPointSize(100); 
     glEnable(GL_POINT_SMOOTH); 
     glBegin(GL_POINTS); 
     glColor4f(1, 0, 0, 1); 
     glVertex2f(-.2, 0); 
     glColor4f(0, 1, 0, .5); 
     glVertex2f(.2, 0); 
     glEnd(); 
    } 

    fbo.release(); 
    fbo.toImage().save("debug.png"); 
} 

結果看起來像這樣在屏幕上(比例400%):

enter image description here

渲染到QGLFramebufferObject看起來像這樣(也按比例400%):

enter image description here

注意,這個圖片是不是完全不透明的,所以這裏是添加了它背後棋盤相同的圖像:

enter image description here

即使在兩個圓重疊並不完全不透明的區域。反鋸齒看起來非常難看。

這是怎麼發生的?我該如何解決這個問題?

我已經嘗試過:

  • 不同的混合功能。
  • 顯式禁用QGLFramebufferObject上的深度緩衝區,模板緩衝區和採樣。我不知道如果QGLFramebufferObject默認格式添加我不想要的東西。
+0

@尼科爾布拉斯,我回滾了你的編輯,因爲它不是關於點平滑。渲染三角形時即使沒有平滑,我也會得到相同的結果。我嘗試了很多不同的最簡單的例子。繪製平滑點只是最小的一個。 – leemes

+0

對不起,我忘了glClearColor語句。它完全透明。將它添加到代碼中並不會改變任何內容。 – leemes

回答

1

嘗試以下操作:

QGLFramebufferObjectFormat fmt; 
fmt.setSamples(1); // or 4 or disable this line 
fmt.setInternalTextureFormat(GL_RGBA8); 
QGLFramebufferObject fbo(width(), height(), fmt); 

這迫使特定的像素格式,同時禁用通過使用多重採樣(否則QT總是渲染到紋理)渲染到紋理。這可能會產生不同的結果。您也可以嘗試格式。

另外,什麼是您的硬件?我的最大點大小隻有64像素(GTX 260),您正嘗試渲染100個像素點。這可能是一個問題。是否生成任何OpenGL錯誤?小問題也會發生嗎?

您也可以嘗試提示(如果可能的話在QT):

glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); 

但我不希望這能改變什麼。