2013-04-10 48 views
3

我有一些.png文件,我用作我的2D遊戲四個小精靈的紋理。使用半透明PNG的紋理和褪色他們OpenGL ES 2.0

其中一些已經有部分透明的像素,我需要能夠正確顯示它們並淡入/淡出。

起初,我畫他們具有以下混合模式:

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 

這工作正常是固體開始與紋理和我可以使用1.0F和0.0F引進透明度之間的任意值。到目前爲止這麼好,但是當我嘗試使用已經具有透明度的png時,它們將無法正確顯示(它們太暗並且具有黑色輪廓)。

我做了大量的研究,發現我需要改變這些類型的紋理的混合模式,因爲上面的那個不能正常工作,所以這就是我現在所擁有的(包括我的着色器) ......

片段着色器

String strFShader = 
"precision mediump float;" + 
"varying vec2 v_texCoords;" + 
"uniform sampler2D u_baseMap;" + 
"void main()" + 
"{" + 
"gl_FragColor = texture2D(u_baseMap, v_texCoords);" + 
"gl_FragColor.a *= "+1.0f+";"+ //** Where 1.0f is the amount to blend, with 0.0f being completely transparent and 1.0f being as per the original png file. 
"}"; 

代碼

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

GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 

GLES20.glDisable(GLES20.GL_BLEND); 

如果我在着色器中使用這個值爲1.0f的半透明紋理(如上所述),它會非常好。但是,如果我嘗試淡化它,某些顏色似乎淡出,有些顏色不在0.0f時,我只剩下原始紋理的奇色版。

如果有人能告訴我如何正確渲染這些類型的紋理,請將此函件感謝。

感謝

回答

1

我並不需要將圖像以非預乘圖像轉換到了最後,我只是讓他們在該格式,改變了線我着色器:

"gl_FragColor *= "+op+";"+ 

和二手....

GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA); 

完美的作品。

1

如果他們是太黑暗,有深色的輪廓,這似乎是由顏色通道alpha通道預乘而引起的。在這種情況下,紋理非常透明的部分顏色變暗。比方說,如果像素的alpha值爲0.9,那麼預先乘以RGB顏色將比實際顏色偏低90%。

爲了加載沒有RGB預通道的PNG圖像,我們使用第三方PNGDecoder,然後使用glTexImage2D()加載紋理。你可以得到PNGDecoder庫PNG從這裏解碼:http://twl.l33tlabs.org/#downloads

+0

嗨@keaukraine - 非常感謝評論!但是,我不太明白。爲什麼我需要下載PNGDecoder?如果沒有它,你有沒有辦法在Android中使用半透明紋理?我寧願如果可能的話不用下載任何exta文件(例如,只是改變我的代碼),我認爲這是可能的,因爲當使用surfaceview時,位圖顯示OK,而不是openGL - .....如果你能詳細說明,那就太好了 - 謝謝! – Zippy 2013-04-10 12:05:17

+1

Android'Bitmap'類總是通過alpha通道預乘倍數。這就是爲什麼我們不得不使用'PNGDecoder'。 – keaukraine 2013-04-10 12:21:16

+0

謝謝@keaukraine,你知道有什麼方法可以不使用任何第三方庫嗎?你用過這個解碼器嗎?這是否意味着將會使用3倍的內存?它看起來與我剛剛發現的手動解碼位圖的方法非常相似,但是這種方法的內存效率不高,這與內存效率相比如何?感謝您的建議。 – Zippy 2013-04-10 15:18:48