2013-12-12 61 views
1

我正在渲染帶輪廓的四邊形。我通過將所需尺寸的四邊形渲染爲黑色來實現這一點,然後渲染「內部」四邊形比第一個更小。我也希望這個四邊形是透明的。OpenGL在混合時忽略對象?

我現在嘗試呈現爲這樣:

http://i39.tinypic.com/2eq993s.png

但是我有問題是因爲我基本上是呈現在彼此頂部的兩個四邊形,黑色的「主」四融合通過對較小的「內」四。我不希望發生這種情況,因爲我希望混合只能混合背景和「內部」四色。

除了爲輪廓渲染單獨的四邊形/三角形之外,還有一種方法(理想情況下不使用着色器,因爲我使用的是固定管道),以便在混合「內部」時忽略/不渲染「主」四?

相關代碼:

混合模式:

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 
glEnable(GL_BLEND); 

渲染框:

struct vertex 
{ 
    GLfloat x,y; 
}; 

void draw_box() 
{ 
    glPushMatrix(); 

    glTranslatef(-3.0f, 1.12f, 1.0f); 

    // Draw a huge black quad 
    const vertex vertices2[] = 
    { 
     { -1.0f, -1.0f }, 
     { 0.0f, 0.0f }, 
     { -1.0f, 0.0f }, 

     { -1.0f, -1.0f }, 
     { 0.0f, 0.0f }, 
     { 0.0f, -1.0f }, 

    }; 

    glVertexPointer(2, GL_FLOAT, 0, vertices2); 
    glColor4f(0.0f, 0.0f, 0.0f, 0.5f); 
    glDrawArrays(GL_TRIANGLES, 0, 6); 

    // Draw a smaller grey quad 
    const GLfloat space = 0.04f; 
    const vertex vertices3[] = 
    { 
     { -1.0f+space, -1.0f+space }, 
     { 0.0f-space, 0.0f-space }, 
     { -1.0f+space, 0.0f-space }, 

     { -1.0f+space, -1.0f+space }, 
     { 0.0f-space, 0.0f-space }, 
     { 0.0f-space, -1.0f+space }, 

    }; 

    glVertexPointer(2, GL_FLOAT, 0, vertices3); 
    glColor4f(0.5f, 0.5f, 0.5f, 0.5f); 
    glDrawArrays(GL_TRIANGLES, 0, 6); 

    glPopMatrix(); 
} 

回答

3

要做到這一點可能是邊界分割成四個梯形四邊形的最佳方式,但是既然你明確提到你不想走這條路,那麼你可以追求其他一些選擇。

下一個最好的方法可能是使用深度緩衝區:glEnable(GL_DEPTH_TEST)。首先繪製內部四邊形(啓用混合)。然後繪製外部四邊形,但使用座標使其深度大於第一個四邊形(「距離較遠」)。如果在繪製邊框時啓用了深度測試,則對於您已繪製的四邊形將會失敗,因爲這些像素的深度值較小。請注意,使用此方法時,如果在呈現這些四邊形背後的東西時寫入深度緩衝區,則可能會遇到一些問題,其中背景的部分被認爲比新的四邊形更接近。即使測試失敗,您也可以通過配置深度測試始終成功來解決此問題:glDepthFunc(GL_ALWAYS)。然而,這對於外部四元組無助。在這種情況下,下一個方法可能會有所幫助:

您可以以類似於深度緩衝區的方式使用模板緩衝區。當渲染裏面四,您設置的模板值(或至少它的一個位)爲特定值:

glEnable(GL_STENCIL_TEST); 
glStencilFunc(GL_ALWAYS, 1, GLuint(-1); 
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 

然後當你畫外四,配置模板測試只有一個片段成功不具有價值:

glStencilFunc(GL_NOT_EQUAL, 1, 1); 

從本質上講,這是版本了與上述深度緩衝做同樣的事情,但使用模板緩衝液代替。您可能需要查看glStencilFuncglStencilOp的文檔。

可能有其他方法可以實現這種行爲,但我可以想到的所有其他解決方案都涉及到使用自定義着色器,這是您所指出的不可接受的。就我個人而言,我只是將邊界分成4個四邊形。當然,它比其他方法多3個方塊,但它不需要任何額外的OpenGL功能或狀態更改。

+0

我不確定我是否理解,所以深度緩衝區將免費夾住外四邊形內部部分?這是使用這種方法會發生什麼? – paulm

+0

@paulm是的,它基本上是免費的,除非你之前根本沒有使用深度緩衝區,在這種情況下創建具有深度緩衝區的上下文將使用大約兩倍的幀緩衝區的內存,因爲每個像素需要通常情況下)對於24位深度緩衝區(最常見),3個字節的顏色數據(4個帶alpha)和(通常)3個字節,儘管16位深度緩衝區也很常見。 – bcrist

+0

我認爲這仍然會產生與現在兩個四邊形混合的結果相同的不良結果,因爲這與玻璃的效果相同? – paulm