我正在学习如何在Android中使用OpenGL ES 2.0。我一直试图简单地在屏幕中央显示一张纹理,这很容易,但是我似乎无法正确地使用PNG透明度。根据我的设置,图像要么显示为黑色背景,要么整个图像会与背景颜色稍微混合。我按照实际教程进行操作,但到目前为止从未使用过透明度,因此我尝试了搜索到的代码,并可能错过了一个重要步骤。我花了很多时间搜索解决这个问题,但没有看到任何答案涉及我的设置。我尝试了各种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通道,毕竟它是来自一个不使用alpha通道的示例。但由于我对片段着色器并不了解,而且当将图像混合到背景中时似乎“有点”有效,所以我认为它以某种形式与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世界中),所以如果你认为其他原因是导致问题的根源,我也会把它们发给你。非常抱歉给你带来这么多麻烦!
glEnable(GL_BLEND)
。但是,一些代码肯定会更有帮助。也许只需要加载图像和创建纹理的代码以及设置混合状态的代码。当然,由于您是新手,请不要忘记了解有关接受和点赞功能的信息。 - Christian Raugl_FragColor = vec4(baseColor.aaa, 1.0)
。这应该会给你一个带有 alpha 通道的灰度图像。 - trenki