我刚学习使用OpenGL ES 2.0 for Android。我一直试图简单地在屏幕中间显示纹理,这很容易,但我似乎无法使PNG alpha正常工作。图像将以黑色背景显示,或根据我使用的设置将整个图像稍微混合为背景颜色。OpenGL ES 2.0 PNG alpha通道
我也跟着去了这一点实际的教程与透明度从来没有工作过,所以我试图在代码中工作,我已经通过各地搜索发现,并有可能刚刚错过了重要的一步。尽管我已经搜索了很多东西来解决这个问题,但我还没有看到任何有我的设置没有的东西的答案。我已经尝试了glBlendFunc的每一个组合,而不是没有运气。
我想,如果我试图在所有可能与此有关的代码粘贴,这个问题会显得很臃肿,所以我会很乐意张贴你们要求的任何代码位。我非常感谢接下来我应该尝试的任何想法。
编辑::这是我的片段着色器,这是我认为是原因。这是我从未真正找到过使用透明度的一个体面示例的唯一部分,其他所有内容都与我在其他地方看到的相符。
final String fragmentShader =
"precision mediump float; \n"
+ "varying vec2 v_Color; \n"
+ "uniform sampler2D s_baseMap; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 baseColor; \n"
+ " baseColor = texture2D(s_baseMap, v_Color); \n"
+ " gl_FragColor = baseColor; \n"
+ "} \n";
它从来不与阿尔法明确的东西,它是不使用它毕竟一个例子,但我仍然不知道很多关于片段着色器和因为它似乎“之类的”当它将图像混合到背景中工作时,我认为它以某种形式处理了alpha,并且我刚刚设置了错误的东西。
编辑::这里是 “loadTexture” 的方法。这与我试图从中学习的openGL ES 2.0书中的例子大致相同,只是一些改动似乎使图像更接近正常工作。
private int loadTexture (InputStream is)
{
int[] textureId = new int[1];
Bitmap bitmap;
bitmap = BitmapFactory.decodeStream(is);
byte[] buffer = new byte[bitmap.getWidth() * bitmap.getHeight() * 4];
for (int y = 0; y < bitmap.getHeight(); y++)
for (int x = 0; x < bitmap.getWidth(); x++)
{
int pixel = bitmap.getPixel(x, y);
buffer[(y * bitmap.getWidth() + x) * 4 + 0] = (byte)((pixel >> 16) & 0xFF);
buffer[(y * bitmap.getWidth() + x) * 4 + 1] = (byte)((pixel >> 8) & 0xFF);
buffer[(y * bitmap.getWidth() + x) * 4 + 2] = (byte)((pixel >> 0) & 0xFF);
}
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bitmap.getWidth() * bitmap.getHeight() * 4);
byteBuffer.put(buffer).position(0);
GLES20.glGenTextures (1, textureId, 0);
GLES20.glBindTexture (GLES20.GL_TEXTURE_2D, textureId[0]);
GLES20.glTexImage2D (GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap.getWidth(), bitmap.getHeight(), 0,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuffer);
GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
return textureId[0];
}
我明白的代码是干什么的,但不可否认它仍然混淆了我一下,让我可能只是缺少明显的东西,由于我缺乏知识。
我没有看到我的代码的任何其他部分看起来像他们可能会导致我遇到的问题,但编程总是充满了意想不到的(特别是在OpenGL的世界看起来),所以如果你认为别的原因我一定会为你发布。对不起,所有的烦恼!
确保在将图像加载到纹理中(而不是加载RGB图像或创建RGB纹理)时保留来自PNG的Alpha通道。当然,确保你调用'glEnable(GL_BLEND)'(除了设置正确的'glBlendFunc')。但有些代码肯定会帮助你多一点。也许只是图像加载和纹理创建代码以及您设置混合状态的代码。当然,因为你是新来者,不要忘记告诉你自己有关接受和投票功能。 –
片段着色器看起来是有效的,因为它正确地将纹理的alpha代理给了片段颜色。所以你不会发布一些你的加载和纹理创建代码。 –
您可以尝试禁用混合的'gl_FragColor = vec4(baseColor.aaa,1.0)'。这应该会给你一个alpha通道的灰度图像。 – trenki