Sprites & transparency

Hi everyone!!

I’m programming a little game, faking isometric view with ortho + rotate (x & y) + billboarding sprites.

To optimize the GL calls, my SpriteManager is using a Vertex Buffer to draw all the sprite on screen in a single call.
Creation Code


    spritePool = new Sprite[MAX_SPRITES];
    vertexData = new float[3*6*MAX_SPRITES]; //6 vertices por sprite
    ByteBuffer vbb = ByteBuffer.allocateDirect(vertexData.length * 4); 
    vbb.order(ByteOrder.nativeOrder());
    vertexBuffer = vbb.asFloatBuffer();

Use Code


      /*
       *    p1              p2
       *      +-----------+
       *      |           |
       *      |           |
       *      |     +     |
       *      |   px,py   |
       *      |           |
       *      +-----------+
       *     p3            p4
       *
       *     p1           p2                 p2 
       *      +-----------+                 -+
       *      |         +                  + |
       *      |       +                  +   |
       *      |     +                  +     |
       *      |   +                  +       | 
       *      | +                  +         |  
       *      +-                 +-----------+
       *     p3                  p3         p4
       *                  
       */
    GL11.glVertexPointer(3, 0, vertexBuffer);
    GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
    GL11.glDrawArrays(GL11.GL_TRIANGLES,0,totalSprites*6);
    GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);

Everything was working OK until I added textures, I checked and the textures are being loaded with the correct alpha. The sprites only draw the alpha > 0 part of the texture, but some quads are drawn with the background over sprites.

The image show a sprite drawn OK (green, transparent quad), and a sprite with the error (red, background over sprtes):

http://www.demegames.cl/images/error.png

The blending and texture calls are:


    GL11.glEnable(GL11.GL_BLEND);
    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId);  

Do I need some sorting of the triangles? or the blending call is not correct??

Are you using a Z-buffer? If you are, then you can’t use blending. The transparent parts of the sprite will still result in a depth write, making all underlying sprites not being drawn.
Either sort your sprites from back to front and use blending. If you don’t want to do that, use alpha testing instead. That will discard all fragments of the sprite that have an alpha under the threshold you decide. These fragments will not write to the depth buffer either.

Yup, when I had a similar issue it was also because of the depth buffer.

Just a question but wouldn’t help to just enable the Alpha_Test with LEQUAL function? If the sprites have alpha values of 1.0 this would work with the Z-Buffer. At least it works fpr my sprite sorting for the Slick2D Framework…

With interpolation the alpha values could be anything between 1.0 and 0.0. Where you choose to put the limit for alpha testing is just an aesthetic issue. The alpha will be ignored anyway (set to 1.0) if you aren’t using blending anyway.

I’m using zbuffer, so i added a sort before drawing the sprites

I’m also using transparency for some effects (smoke, fire), so I needed blending.

Thanks to all, with the “z-sort” now the sprites are working ok, here a screenshot

http://www.demegames.cl/images/screen.gif

Uh, if you’re sorting the sprites, why are you using a z-buffer? I mean, sorting OR z-buffer+alpha testing should be enough, unless you have other geometry (terrain, buildings) that can occlude the sprites.
If your fire uses additive blending, then you won’t have to sort it at all, just draw them all in any order. x+y = y+x. If you do want to sort your fire for more accurate blending, you can do this after drawing the sprites with alpha-testing. Just sort them, keep depth TESTING enabled, but disable depth WRITES and draw them. Sorting lists every frame isn’t going to scale well with many sprites/particles… xd
Anyway, nice screenshot!