LWJGL Forum

Please login or register.

Login with username, password and session length

Author Topic: Problem with transparency in 2D [Solved]  (Read 8628 times)

Sankacoffee51

  • Newbie
  • *
  • Offline Offline
  • Posts: 4
Problem with transparency in 2D [Solved]
« 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)
Code: [Select]
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)
Code: [Select]
                           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)
Code: [Select]
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
Code: [Select]
       
        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/pic1.png
Logged

spasi

  • Administrator
  • Nerdus Imperius
  • *****
  • Offline Offline
  • Posts: 1891
Re: Problem with transparency in 2D
« Reply #1 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?
Logged

Sankacoffee51

  • Newbie
  • *
  • Offline Offline
  • Posts: 4
Re: Problem with transparency in 2D
« Reply #2 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.

Code: [Select]

        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());
        }
Logged

spasi

  • Administrator
  • Nerdus Imperius
  • *****
  • Offline Offline
  • Posts: 1891
Re: Problem with transparency in 2D
« Reply #3 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.
Logged

Sankacoffee51

  • Newbie
  • *
  • Offline Offline
  • Posts: 4
Re: Problem with transparency in 2D
« Reply #4 on: March 16, 2012, 14:29:00 »

Logged

Sankacoffee51

  • Newbie
  • *
  • Offline Offline
  • Posts: 4
Re: Problem with transparency in 2D [Solved]
« Reply #5 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!
Logged