I just learned to work with OpenGL ES 2.0 for Android. I'm trying to just display a texture in the middle of the screen, which was simple enough, but I can't get PNG alpha to work correctly. The image will either display a black background, or the whole image will be slightly mixed with the background color, depending on the settings that I use.
The actual tutorials that I completed to get to this point never worked with transparency, so I tried working with the code I found while searching, and probably just skipped one important step. I searched quite a bit to understand this problem, though, and I did not see any answers that had something that my installation did not have. I tried every combination of glBlendFunc and that no luck.
I decided that if I try to insert all the code that might be related to this, the question will seem very bloated, so I will be happy to post any code snippets that you guys are asking. I would really appreciate any ideas on what I should try next.
EDIT :: Here is my fragment shader, which I believe is the reason. This is the only part on which I have never found a decent example for working with transparency, and everything else matches what I saw elsewhere.
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";
It never does anything explicitly with alpha, this is from an example that doesn't use it in the end, but I still don't know much about fragment shaders and because it seemed like a “kind of” work when it mixes an image in the background, I figured that he worked with alpha in one form or another, and I just had something wrong.
EDIT :: Here is the loadTexture method. This is about the same as the example from the openGL ES 2.0 book I'm trying to learn with, with some changes that seem to bring the image closer to working properly.
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]; }
I understand what the code does, but admittedly, it still baffles me, so I can just miss something obvious due to lack of knowledge.
I don’t see any other parts of my code that seem like they may cause problems that I am having, but programming is always full of surprise (especially in the OpenGL world), so if you think something else is the reason, by which I will send it for you. Sorry for all the problems!