2016-08-17 37 views
0

我正在使用Texture來繪製OpenGL的位圖。產生在OpenGL上顯示RGBA位圖紋理時混合是錯誤的

TextureId那樣:

 GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureIdForDrawingBitMap); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); 

而這個代碼下面我用於繪製幀:

 //Enable blend for display a RGBA bitmap 
     GLES20.glEnable(GLES20.GL_BLEND); 
     GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 

     GLES20.glUseProgram(ShaderHelper.programTexture); 
     GLES20.glEnableVertexAttribArray(ShaderHelper.a_Position_Texture); 
     GLES20.glEnableVertexAttribArray(ShaderHelper.a_texCoord_Texture); 
     GLES20.glVertexAttribPointer(ShaderHelper.a_Position_Texture, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer); 
     GLES20.glVertexAttribPointer(ShaderHelper.a_texCoord_Texture, 2, GLES20.GL_FLOAT, false, 0, uvBuffer); 

     GLES20.glUniform1f(ShaderHelper.alphaFactor_Image, alphaFactor); 
     GLES20.glUniformMatrix4fv(ShaderHelper.u_MVPMatrix_Texture, 1, false, mPVMatrix, 0); 
     GLES20.glUniform1i(ShaderHelper.u_texture_Texture, 0); 
     GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureIdForDrawingBitMap); 

     //Upload bitmap to texture 
     GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, mBitmap, 0); 

     GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, indicesBuffer); 
     GLES20.glDisableVertexAttribArray(ShaderHelper.a_Position_Texture); 
     GLES20.glDisableVertexAttribArray(ShaderHelper.a_texCoord_Texture); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); 

我需要的是繪製在一個背景的位圖(這是拉伸前)。覆蓋位圖具有RGBA格式。

當位圖只包含alpha等於0或255的顏色時,上述代碼完美工作。(如果alpha == 0,則像素透明,alpha == 1,像素不透明)。

但是,當alpha等於100(例如)時,像素顯示不正確。如果顏色的十六進制值爲0xAAFFFFFF,則顯示結果似乎爲0xAA000000。

我想也許blendFunction不僅融合了alpha chanel,還融合了RGB chanel(基於alpha chanel的價值)。

我該如何解決這個問題?我只想在OpenGL上繪製覆蓋位圖,就像我以前用Paint和Canvas所做的那樣。

===========================更新解決方案================= =======

我試圖用

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

和它的作品在我的情況。無論alpha是否等於0.0,1.0或它們之間,它都會繪製覆蓋圖紋理。唯一的剩餘點是當我想要從Fragment Shader更改Alpha通道時,結果顏色是意外的。在這種情況下,我使用:

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

它並不完全解決問題,但它對我來說沒問題。

回答

1

我想也許blendFunction不僅融合阿爾法通道,但它也融合了RGB香奈兒(於阿爾法通道的價值基礎)

正確,混合會影響到所有四個通道。如果你只混合了alpha通道,那麼你不會得到你想要的效果(文字精靈的顏色值將被寫入所有像素的白色,而不考慮字體字形的實際位置)。

我該如何解決這個問題?

如果你想要麼完全透明或完全不透明那麼答案很明顯,在α值,其要麼是0.0(透明)或(1.0)不透明,這將正常工作只能通(因爲你已經注意到)。

如果確實需要,可以將着色器中的部分值舍入爲0.0或1.0。

則可以通過擴展來設置顏色和alpha通道不同的混合:

https://www.khronos.org/registry/gles/extensions/OES/OES_blend_equation_separate.txt

...但我真的不認爲這是你想要的。

+0

感謝您的事情,我懷疑確認。我試圖使用GLES20.glBlendFunc(GLES20.GL_ONE,GLES20.GL_ONE_MINUS_SRC_ALPHA);它適用於我的情況。無論alpha是否等於0.0,1.0或它們之間,它都會繪製覆蓋圖紋理。唯一的剩餘點是當我想要從Fragment Shader更改Alpha通道時,結果顏色是意外的。無論如何,對我來說沒關係。 – Ken

+0

似乎很奇怪,這工作。這將返回(s.RGB +(d.RGB *(1-sA))的RGB顏色,所以源RGB顏色完全不會被alpha修改。輸入紋理存儲預倍,或(2)你的源字形顏色是黑色的(所以縮放值將爲零)無論如何 – solidpixel

+0

是的,我明白了這一點後閱讀https://developer.nvidia.com/content/alpha -blending-pre-or-not-pre – Ken

1

你試過:

GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_COLOR); 
+0

它沒有工作,顏色混合意外。但我嘗試了一些不同,它工作正常:) GLES20.glBlendFunc(GLES20.GL_ONE,GLES20.GL_ONE_MINUS_SRC_ALPHA); – Ken