1
votes

On Android using OpenGL ES 2.0 I try to perform certain performance tests using different internal texture formats. Initially I have a lot of RGBA textures (png) which I want to load and store internally in a different format with OpenGL (for example RGB and LUMINANCE). I load my textures using glTexImage2D like this:

Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),resourceId);
...
int size = bitmap.getRowBytes() * bitmap.getHeight();
ByteBuffer b = ByteBuffer.allocate(size);
bitmap.copyPixelsToBuffer(b);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap.getWidth(),    
                    bitmap.getHeight(), 0, GLES20.GL_RGBA, 
                    GLES20.GL_UNSIGNED_BYTE, b);

This works fine, however if I change the first GLES20.GL_RGBA (The internalFormat parameter) to anything else (GLES20.GL_RGB or GLES20.GL_LUMINANCE) my texture appears all black. Changing the second GLES20.GL_RGBA to the same value will display something - but obviously not correctly as the original data is RGBA.

I thought maybe it has something to with the shader code - that maybe texture2D(..) returns a different value because the internal format of the texture is different. My shader code is simply:

gl_FragColor = texture2D(texture, fragment_texture_coordinate);

I tried changing this around too, but no luck yet. So I thought maybe glTex2DImage is not at all working as I think it does (I am not an expert on this area whatsoever).

What am I doing wrong?

Edit: I overlooked this little detail on texImage2D. It appears that:

internalformat must match format. No conversion between formats is supported during texture image processing. type may be used as a hint to specify how much precision is desired, but a GL implementation may choose to store the texture array at any internal resolution it chooses.

What I gather from this, is that if you want to store your textures different from their original format you'll have to convert it yourself.

1
i tried to find the solution for few weeks ... no f..ing chance ... BitmapFactory.decodeXXXXX is premultiplying alpa groups.google.com/forum/?fromgroups#!topic/android-developers/… ... the only way is to build own loader ... i'm using jni with libpng nowSelvin
Thanks for your reply, but I don't think pre-multiplied alpha is the problem here. My images do not have any (semi) transparent pixels.Reigertje
from khronos.org/opengles/sdk/docs/man/xhtml/glTexImage2D.xml : format Specifies the format of the texel data. Must match internalformat. The following symbolic values are accepted: GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE, and GL_LUMINANCE_ALPHA. are the RGB and LUMINANCE connected if so why don't you use use A chanel as LUMINANCE?Selvin
Ah, thanks for the link. Strange I overlooked this : internalformat must match format. No conversion between formats is supported during texture image processing. type may be used as a hint to specify how much precision is desired, but a GL implementation may choose to store the texture array at any internal resolution it chooses. So basicly it is only possible to store it so if my texture is already in a RGB/Luminance format (Or converted before the GL call).Reigertje

1 Answers

0
votes

Your fragment shader must be written to agree with the format you are giving to glTexImage2D(). For GL_RGB, it should force the alpha to 1.0, like this:

vec3 Color_RGB = texture2D(sampler2d, texCoordinate);
gl_FragColor = vec4(Color_RGB, 1.0);

But, for GL_RGBA, it should look like this:

vec4 Color_RGBA = texture2D(sampler2d, texCoordinate);
gl_FragColor = Color_RGBA;

And, as has been discussed, you can only use the Android Bitmap class for textures if your PNG files have no transparency. This article explains that: http://software.intel.com/en-us/articles/porting-opengl-games-to-android-on-intel-atom-processors-part-1