Search code examples
androidopengl-esbitmap

Issues with GLUtils.texImage2D and Alpha in Textures


I'm successfully generating my textures using GLUtils.texImage2D, but when I use the textures generated I get problems with my alpha: they are darker than wanted.

after having checked several things I finally got the the conclusions that the problem comes from GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bmp, 0);

I created a second function that uses gl.glTexImage2D(GL10.GL_TEXTURE_2D, level, GL10.GL_RGBA, width, height, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixels2);

but it is costly in processing to create pixels2 which is a bytebuffer in which I have to recopy the bytes while changing the values from the bitmap ARGB to texture RGBA.

Has anybody noticed that ? and if so how did you solve this...

jason


Thank you for your answer, I'm already using

gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

and I'm getting this problem

my problem is that the alpha generated by GLUtils isn't the one of the texture, its darker.

the difference is like looking at a color in the sun and in the shade (if that makes any sence).

I already tried gl.gltextimage2d but the creating the buffer takes too long, unless there is a tool to convert a bitmap to a byte buffer that I don't know of...


Solution

  • The alpha channel is the poor mistreated stepchild of a huge number of programmers is all I can say... but the upload works fairly efficient if you do that:

    • Estimate your largest texture (like 1024x1024) and create an int array of that size (1024*1024) that you store in some static variable or somewhere where you can access it so that you don't need to recreate that array (allocation time is precious here)

    • then do this:

      bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
      gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, width, height, 
           0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, IntBuffer.wrap(pixels));
      

    I am sorry not having found a different solution... the original problem is, that the implementor of the GLUtils.texImage2D function has mistreated the alpha channel somehow resulting in black borders when the image is displayed larger than it is (the bilinear filter calculates the color between four pixels and when the rgb values of the pixels with transparent alphas have been mangled (like set to black), the result is, that there's some kind of a "color bleeding" happening over the transparent border that is forming there. Very ugly. Maybe it was done to improve the compression ratio as the RGB values in alpha transparent areas in PSDs contain a lot of junk that when eliminated yield a lot of room of improvement for compression algorithms)

    Edit: Sadly, this approach was only working for grey images correctly as the red and blue channel is swapped when fetching the pixels from the bitmap. At least on MY device. I am not sure how correctly this is for other devices, but in my case, this here did the trick:

    for (int i=0;i<pixels.length;i+=1) {
        int argb = pixels[i];
        pixels[i] = argb&0xff00ff00 | ((argb&0xff)<<16) | ((argb>>16)&0xff);
    }