2010-11-14 146 views
8

如何使用OpenGLES 1.1(iPhone)繪製紋理,但僅使用Alpha繪製某種顏色?從紋理使用alpha繪製純色

結果應該是與原始紋理完全相同的alpha蒙版,只用一個純色而不是原始的顏色。

我使用glDrawArraysglCoordPointerglVertexPointer

我認爲要做兩遍,一次是紋理,另一次是純色。我似乎無法找到glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);的反轉。

編輯:經過一些更多的環顧四周,我認爲這應該有可能實現使用glTexEnvf。這只是找到正確的論點。

+0

我想這是蟒蛇的關係,我現在有一個極大的答案。 – sharvey 2010-11-14 22:59:00

回答

8

正如所提到的,glTexEnv是要走的路。

要更換你的紋理的RGB分量,並保持其Alpha不變,你可以嘗試這樣的事情(這代碼使用紅色作爲替代色):

glColor4f(1.0f, 0.0f, 0.0f, 1.0f); 

glActiveTexture(GL_TEXTURE_0); 
glEnable(GL_TEXTURE_2D); 
glBindTexture(GL_TEXTURE_2D, spriteTexture); 

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE); 
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); 
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); 

// ... draw as usual 

這裏來了一些解釋。

使用GL_COMBINE時,您可以完全控制不同紋理階段的輸入/輸出如何組合在一起。在這種情況下,我們指定我們要用(GL_PREVIOUS)替換(GL_REPLACE)紋理階段0的RGB分量,在這種情況下,它是單一顏色(使用glColor4f設置)。

我們沒有爲alpha組件設置任何特殊的東西,因爲我們需要常規行爲。 添加以下行將不得不彷彿不包括(默認行爲)相同的效果:

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE); 
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); 
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA); 
+0

感謝您提供真正豐富的答案!我必須將'GL_TEXTURE_0'改爲'GL_TEXTURE0'來編譯,並在繪圖之後添加'glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);'以完成其餘的繪製工作。現在形狀被正確繪製,但總是使用白色作爲顏色。可能與我所做的改變有關? – sharvey 2010-12-04 20:02:43

+0

我不認爲你的改變是你的問題的原因,是的,你必須添加glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);繪圖後返回默認的紋理模式。我不清楚爲什麼你會得到白色的結果...你有沒有正確地添加glColor4f()如在示例中所述? – Ozirus 2010-12-05 00:47:09

+0

是的,glColor4f在與代碼示例中完全相同的位置被調用。 – sharvey 2010-12-05 17:13:06

2

如果您可以使用OpenGL ES 2.0,則可以使用自定義片段着色器執行此操作。如果您使用的是構建在1.1版上的框架,或者是針對不支持2.0的設備,這不會有太大的幫助。但如果你能,你這是怎麼做到這一點:

uniform lowp sampler2D sampler; // which texture unit to use 
uniform lowp vec4 solidColor; 

varying highp vec2 fragmentTexCoord; 

void main() 
{ 
    // Get the color with an alpha of zero 
    vec4 color = vec4(1,1,1,0) * solidColor; 
    // Get the alpha from the texture, zero the r,g,b components 
    vec4 alpha = vec4(0,0,0,1) * texture2D(sampler, fragmentTexCoord); 
    // their sum is the solid color with the alpha mask of the texture 
    gl_FragColor = color + alpha; 
} 

如果你能保證的SolidColor具有零阿爾法您可以跳過乘步驟。

+0

感謝您的建議。我不太確定我是否可以使用着色器。沒有辦法使用glBlendFunc的反函數(GL_ZERO,GL_ONE_MINUS_SRC_ALPHA);去做這個? – sharvey 2010-11-14 21:02:57

+0

回答說OpenGLES 1.1不支持自定義着色器:http://stackoverflow.com/questions/543948/opengl-es-1-x-shaders/544022#544022。 – sharvey 2010-11-14 21:45:54

+1

對不起,我會編輯答案,即使它對你沒有用處,也值得爲其他人做搜索。 – benzado 2010-11-15 20:07:32

0

glBlendFunc(source_factor, dest_factor)翻譯爲:

dest= source*source_factor + dest*dest_factor 

所以glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA)是:

dest= source*0 + dest*(1 - source.alpha) 

第二階段(這是不是反轉)應glBlendFunc(GL_SRC_ALPHA, GL_ONE)

dest= source*source.alpha + dest 

因爲你已經在第一遍中應用了alpha蒙版。儘管您仍然需要弄清楚如何使用alpha而不是源紋理應用常量顏色。