2009-08-21 269 views
2

我有一個紋理,有一些透明透明的部分我想應用於其面部是一些不透明材質的對象(或顏色,如果更簡單),但最終的對象變得透明。我希望最終的對象是完全不透明的。渲染透明紋理

這裏是我的代碼:

首先,我設置的材料:

glDisable(GL_COLOR_MATERIAL); 
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); 
    glColor4f(0.00, 0.00, 0.00, 1.00); 
    glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); 
    glColor4f(0.80, 0.80, 0.80, 1.00); 
    glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); 
    glColor4f(0.01, 0.01, 0.01, 1.00); 
    glEnable(GL_COLOR_MATERIAL); 

然後,我設置了維也納組織

glBindTexture(GL_TEXTURE_2D, object->texture); 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 

    glBindBuffer(GL_ARRAY_BUFFER, object->object); 
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), ver_offset); 
    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), tex_offset); 
    glNormalPointer(GL_FLOAT, sizeof(Vertex), nor_offset); 

最後我拉攏的對象

glEnable(GL_BLEND); 
    glDisable(GL_DEPTH_TEST); 

    glDisable(GL_TEXTURE_2D); 
    glBlendFunc(GL_ONE, GL_ZERO); 
    glDrawArrays(GL_TRIANGLES, 0, object->num_faces); 

    glEnable(GL_TEXTURE_2D); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glDrawArrays(GL_TRIANGLES, 0, object->num_faces); 

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    glDisable(GL_BLEND); 
    glEnable(GL_DEPTH_TEST); 

我嘗試傳遞不同以glBlendFunc()的參數爲準。我已上載這裏來源:http://dpaste.com/83559/

UPDATE得到this,但我想this(或沒有紋理this)。

第二張和第三張照片是用glm生產的。我研究過這些資料,但由於我對OpenGL的瞭解有限,所以我不太瞭解。

+0

你想達到什麼目的?有一些實心像素的透明物體?或者是一些帶有透明紋理的固體物體,顯示下方的純色? – 2009-08-21 13:48:33

+0

後者:一個具有透明紋理的固體對象,顯示下方的純色? – Alexandru 2009-08-21 15:12:02

+0

感謝您的更新......並且按照我的建議,確定了您的Z-Buffering。 – Goz 2009-08-22 06:22:21

回答

3

如果你想要將兩個紋理應用到你的對象,你真的想設置兩個紋理,並使用multitexturing來實現這個樣子。你的方法正在繪製幾何圖形,這是一個巨大的性能浪費。

多重紋理將僅從兩個紋理單元進行採樣,而僅繪製一次幾何圖形。您可以使用着色器(事情應該完成的方式)或者仍然可以使用固定功能流水線(請​​參閱:http://bluevoid.com/opengl/sig00/advanced00/notes/node62.html

+0

我不同意應該使用着色器完成所有的事情。但是你已經打敗了我19秒;-) – hirschhornsalz 2009-08-21 13:58:18

+0

OpenGL 3.X已經完全淘汰FFP的部分,着色器是未來。 – 2009-08-21 14:01:12

+0

我不想紋理。我需要一種材質和一種紋理(如灰色金屬(材質)上的繪畫(紋理))。我同意兩次繪製幾何圖形是浪費時間,並且可能出現問題,所以我正在尋找替代方案。 – Alexandru 2009-08-21 15:11:04

-1

像素着色器會更簡單。否則我認爲你需要多遍渲染或多個紋理。 你可以在這裏找到全面的細節:http://www.opengl.org/resources/faq/technical/transparency.htm

+0

Pixelshaders比多紋理更簡單?當然是 – hirschhornsalz 2009-08-21 13:55:05

+0

!它取決於你的目標平臺和引擎,但是如果你想獲得像玻璃一樣的下降透明度效果或者裁剪出來,使用簡單的像素着色器要比使用固定功能管線更容易 – 2009-08-21 13:57:46

1

AFAIK混合功能採用片段顏色(與紋理顏色相反)。因此,如果您再次使用混合繪製對象,則三角形變得透明。

你想要完成的工作可以使用多紋理完成。

0

這只是一個瘋狂的猜測,因爲你沒有提供任何實際問題的截圖,但爲什麼你禁用深度測試?當然你想用標準的GL_LESS對第一遍進行深度測試,然後用GL_EQUAL進行第二次傳遞?

編輯:

glEnable(GL_BLEND); 
glEnable(GL_DEPTH_TEST); // ie do not disable 
glDepthFunc(GL_LESS); // only pass polys have a z value less than ones already in the z-buffer (ie are in front of any previous pixels) 

glDisable(GL_TEXTURE_2D); 
glBlendFunc(GL_ONE, GL_ZERO); 
glDrawArrays(GL_TRIANGLES, 0, object->num_faces); 

// for the second pass we only want to blend pixels where they occupy the same position 
// as in the previous pass. Therefore set to equal and only pixels that match the 
// previous pass will be blended together. 
glDepthFunc(GL_EQUAL); 

glEnable(GL_TEXTURE_2D); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
glDrawArrays(GL_TRIANGLES, 0, object->num_faces); 

glDisableClientState(GL_VERTEX_ARRAY); 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

glDisable(GL_BLEND); 
0

嘗試禁用混合和繪圖設置爲GL_DECAL,而不是你的GL_MODULATE質地功能的單通。這將根據紋理的alpha通道在頂點顏色和紋理顏色之間進行混合,但將Alpha通道設置爲頂點顏色。

請注意,這將忽略在紋理不透明的任何位置應用於頂點顏色的任何照明,但根據您的描述,這聽起來像預期的效果。