LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: Sankacoffee51 on March 16, 2012, 13:22:38

Title: Problem with transparency in 2D [Solved]
Post by: Sankacoffee51 on March 16, 2012, 13:22:38
Hello the forum, I am a computer science engineer, currently working in a smartphone software company in Geneva.

I am making a small 2D game engine which I will use for game-prototype designing and testing a few ideas.

However, I am having some issues with transparency in opengl, and all the solutions I found so far don't work in my code. I use the TextureLoader class from the small space invaders game.

At first I had 32bit PNG's with an alpha channel, but there wasn't any transparent on the sprite, the animations worked fine, but i had my white square background beside the character.
Then I took off the white background and replaced it with a transparent one.
If I comment the lines GL11.GL_Enable(GL11.GL_BLEND) and GL11.glBlendFunc(GL11.GL_SRC_ALPHA,GL11.GL_ONE_MINUS_SRC_ALPHA),
my sprite is rendered as a black full square.

I then uncomment these two lines GL11.GL_Enable(GL11.GL_BLEND) and GL11.glBlendFunc(GL11.GL_SRC_ALPHA,GL11.GL_ONE_MINUS_SRC_ALPHA), and now I can't see anything of the character, he has completely disappeared.

I then tried with a 8bit png with alpha channel, the results are the same.
I tried messing (couldn't find good doc for these two functions) with GL11.glEnable(GL11.GL_ALPHA_TEST), GL11.glAlphaFunc(GL11.GL_GREATER, 0.1f) with no succes.

I also tried using GL11.glTexEnvi(GL11.GL_TEXTURE_ENV,GL11.GL_TEXTURE_ENV_MODE,GL11.GL_BLEND) but it messes with all the colors on the screen (blue gets yellow, green gets red-pink) and my png is still grey or transparent.

If I summarize a bit : my transparent png's are rendered black when blending is disabled, and rendered completely transparent when blending is enabled.

My conclusions are that only the alpha channel is being rendered(once all black, and once all transparent).
Or since the alpha channel multiplies the current pixel color, if alpha is always 0, my picture color is always the same.

There must be a logic way to avoid this, but I couldn't find any useful specific information on my problem.
If anyone has an idea on how to solve this, I'm stuck here for the moment.

I listed my OPENGL code hereunder and the Texture loading code from TextureLoader as well as a few links to my different types of png's.

OpenGL Initialisation Code:
(called once in the program)

GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glMatrixMode(GL11.GL_PROJECTION);
                       GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
GL11.glOrtho(0, width, height, 0, -1, 1);
                       GL11.glViewport(0, 0, width, height);


OpenGL Current Frame Code:
(called once each frame before drawing objects)

                           GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
                           GL11.glLoadIdentity();



OpenGL Object Draw Code:
(called x times per frame, x = number of objects to draw)
public void drawf(float x, float y, int spriteX, int spriteY) {
GL11.glPushMatrix();

// bind to the appropriate texture for this sprite
texture.bind();
               
               float divX = (texture.getImageWidth()/texWidth);
               float divY = (texture.getImageHeight()/texHeight);

               // coords of the sprite in the spritesheet
               float texBindX = spriteX*(texture.getWidth()/divX);
               float texBindY = spriteY*(texture.getHeight()/divY);
               float texBindX2 = (texture.getWidth()/divX) + spriteX*(texture.getWidth()/divX);
               float texBindY2 = (texture.getHeight()/divY) + spriteY*(texture.getHeight()/divY);

// draw a quad textured to match the sprite at right pos on screen
               float textureStartX = ((float)x-10f)/10.0f;
               float textureStartY = ((float)y-5f)/5.0f;
               float textureEndX = textureStartX + 1.0f/10f;
               float textureEndY = textureStartY + 1.0f/5f;
               
               GL11.glEnable(GL11.GL_BLEND);
               GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
         
               GL11.glBegin(GL11.GL_QUADS);
{  
                   GL11.glTexCoord2f(texBindX, texBindY);
                   GL11.glVertex2f(textureStartX, textureStartY);
                   GL11.glTexCoord2f(texBindX, texBindY2);
                   GL11.glVertex2f(textureStartX, textureEndY);
                   GL11.glTexCoord2f(texBindX2, texBindY2);
                   GL11.glVertex2f(textureEndX,textureEndY);
                   GL11.glTexCoord2f(texBindX2, texBindY);
                   GL11.glVertex2f(textureEndX,textureStartY);
}
GL11.glEnd();
GL11.glPopMatrix();
}



TextureLoader texture loading code
       
       int textureID = createTextureID();
       Texture texture = new Texture(GL11.GL_TEXTURE_2D,textureID);
       
       // bind this texture

       GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
       BufferedImage bufferedImage = loadImage(resourceName);
       texture.setWidth(bufferedImage.getWidth());
       texture.setHeight(bufferedImage.getHeight());
       
       if (bufferedImage.getColorModel().hasAlpha()) {
           srcPixelFormat = GL11.GL_RGBA;
       } else {
           srcPixelFormat = GL11.GL_RGB;
       }

       // convert that image into a byte buffer of texture data

       ByteBuffer textureBuffer = convertImageData(bufferedImage,texture);
       
       if (target == GL11.GL_TEXTURE_2D)
       {
           GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
           GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
       }

       // produce a texture from the byte buffer

       GL11.glTexImage2D(target,
                     0,
                     GL11.GL_RGBA,
                     get2Fold(bufferedImage.getWidth()),
                     get2Fold(bufferedImage.getHeight()),
                     0,
                     srcPixelFormat,
                     GL11.GL_UNSIGNED_BYTE,
                     textureBuffer );


Here are two links to the png's spritesheets

http://keupon99.is-a-geek.org/pic2.png (http://keupon99.is-a-geek.org/pic2.png)
http://keupon99.is-a-geek.org/pic1.png (http://keupon99.is-a-geek.org/pic1.png)
Title: Re: Problem with transparency in 2D
Post by: spasi on March 16, 2012, 13:59:09
Have you verified that convertImageData produces correct image data? Is it in RGBA format or something else, like BGRA?
Title: Re: Problem with transparency in 2D
Post by: Sankacoffee51 on March 16, 2012, 14:05:05
Here is the code from convertImageData that produces the image:

I did not look exactly what the functions do, but i have read the code, and it seems logical to me.
However, I am not experienced enough in png format to recognize glitches.



        glAlphaColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
                                            new int[] {8,8,8,8},
                                            true,
                                            false,
                                            ComponentColorModel.TRANSLUCENT,
                                            DataBuffer.TYPE_BYTE);
                                           
        glColorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
                                            new int[] {8,8,8,0},
                                            false,
                                            false,
                                            ComponentColorModel.OPAQUE,
                                            DataBuffer.TYPE_BYTE);

        if (bufferedImage.getColorModel().hasAlpha()) {
            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,texWidth,texHeight,4,null);
            texImage = new BufferedImage(glAlphaColorModel,raster,false,new Hashtable());
        } else {
            raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,texWidth,texHeight,3,null);
            texImage = new BufferedImage(glColorModel,raster,false,new Hashtable());
        }
Title: Re: Problem with transparency in 2D
Post by: spasi on March 16, 2012, 14:19:39
That code looks weird. At least I haven't seen anyone doing image loading this way before. Try using slick-util or some other library for loading textures.
Title: Re: Problem with transparency in 2D
Post by: Sankacoffee51 on March 16, 2012, 14:29:00
okay, I will try to find a few hours this week-end to get some testing done.
At least my opengl code is familiar to me now, after testing everything possible.¨
I'll send some feedback as soon as I have tested slick-util. I hesitated to use that directly,
but wanted something simple and plug&play I could say.

Thank you very much,       

                                                   Olivier
Title: Re: Problem with transparency in 2D [Solved]
Post by: Sankacoffee51 on March 18, 2012, 01:58:09
I tried using slick-utils and after a few minor issues, my problem is solved. Thanks for finding the problem so quickly!