2013-04-10 169 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