Using alpha in textures

I had thought that the alpha channel was being used in my textures, but now that I have enabled depth testing, I can see that they are not. I have tried creating textures via

        url = c1.getResource( "com/thinkastronomy/galaxyin3d/GalacticCore.png" );
        coreTexture = TextureIO.newTexture( TextureIO.newTextureData( url, GL.GL_RGBA, GL.GL_RGBA, false, TextureIO.PNG ));

and also by the simpler

        url = c1.getResource( "com/thinkastronomy/galaxyin3d/GalacticCore.png" );
        coreTexture = TextureIO.newTexture( url, false, TextureIO.PNG ));

In neither case am I getting my transparent pixels blended as transparent.

I’m using

    gl.glEnable( GL.GL_BLEND );
    gl.glBlendFunc( GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA );

to set up blending and I’m texturing a quad.

Is there some other hidden option I need to get the alpha to work properly? It sort of looks like the alpha pixels are getting assigned the clear color, but this changes depending on what I use as the second parameter of the BlendFunc.

I suspect there is some glTexEnv*() or glTexParameter*() that I need, but it seems a pretty confusing issue and the ones I’ve tried haven’t helped.

Thanks in advance.

Bill

Well, this is slowly starting to make since to me. It looks like my alpha channel is working, but I’ve misunderstood what OpenGL will do for me. The crucial piece of information was given by “bahuman” in a separate thread. He said:

PS: the reason you have to draw the “opaque” textures first, in any order, is because they require depth testing to be enabled, and depth writing should be enabled as well.
The reason you have to draw the transparent textures afterwards, ordered by distance, is exactly because depth testing is still enabled, but depth writing should be disabled. This means openGL will no longer do (some of) the work for you.

If I draw the galactic image first and then the sprites (with alpha) afterwards, the alpha is handled pretty much correctly. I say pretty much because I don’t sort the sprites by distance and draw back to front. Therefore I do get a few overlapping sprites where the alpha isn’t totally handled correctly. To really deal with this I guess I need to truly draw in back to front order. This will probably be difficult. I will have thousands or sprites that I need to sort as the view is rotated. Does OpenGL give me any help determining the distance to a give object?

You’ll have to sort manually, but you may be surprised how quick that actually is if you’ve only got a few thousand sprites. Shove them in array and sort them (radix sort for preferance) and then bung them to GL. If that isn’t good enough then you might be able to get away with either coarse sorting (which sounds like you’re doing already) where you just sort particular chunks with respect to each other.

You might be able to get away with a different blending mode. Regular blending (for sprites and such) requires back to front, but additive - glBlendFunc(SRC_ALPHA, ONE) doesn’t require sorting and is usually acceptable for ‘glowing’ objects (such as particles or stars).

If even that isn’t good enough you could always try ‘depth peeling’ which attempts to do the whole lot on the GPU. Unfortunately this method is far from cheap and eats fillrate for breakfast.

I just found what seems like an even better solution than sorting and drawing back to front. As long as your parts of your sprites are either completely transparent or completely opaque, you can use the Alpha Test to get them to draw correctly.

       gl.glEnable( GL.GL_ALPHA_TEST );
       gl.glAlphaFunc( GL.GL_GREATER, 0.5f );

      // Do your drawing here not worrying about ordering

      gl.Disable( GL.GL_ALPHA_TEST);

This seems to solve the issue completely for me and from what I can tell performs fine with the number of sprites I have.