2D Sprite Engine

Hello all,

I’m working on a 2D sprite engine using the JOGL and I’ve come across some weird problems. I realize this is probably more of an OpenGL question, but I thought maybe some of you might have some experience with this.

Basically, what I am doing is using texture mapped quads to draw the sprites. Also, it should be noted that I am reading in a png image into the GL_RGBA format so I can have transparency.

Now, here are the two problems I have been having:

1.) For some reason, the texture mapped quad won’t even show up unless I specify a color like so:
gl.glColor4f (1.0f, 1.0f, 1.0f, 1.0f);
before drawing the quad.

2.) When I move the quad around the screen using the translate function, the very edge of the non-transparent area of the texture fades in and out.

I know I am probably making some fairly stupid mistake. Anyone have any ideas just from my general description?

Not sure what could be going on to be honest, the colour thing is fairly normal but the fading is wierd, its not just a laptop screen or something is it?

You might consider looking at the GL Impl of J2DA (http://j2da.sf.net) to see if you’re doing anything different.

Kev

Don’t know but the transparent part and so in a PNG doesn’t always work to will to my knowledge so if I need to use transparency in my textures I always use masking for better effect. You can get a good explenation at www.gametutorials.com -> OpenGL tutorials and then Masking. It’s C++, but of coarse the OpenGL is still the same.

Link:
http://www.gametutorials.com/Tutorials/opengl/OpenGL_Pg2.htm

here somewhere near the bottom: “Masking And Ortho Mode”

[quote]Don’t know but the transparent part and so in a PNG doesn’t always work to will to my knowledge
[/quote]
If with “transparent” you mean alpha transparency then PNG works perfectly for RGBA textures.
Since Java can load such PNG pictures directly they’re pretty handy for JOGL, too. :slight_smile:

hmm … have to check it out then. Come from C++ OpenGL and there you always needed the masking stuff. Good tip !

gives me some strange stuff, but I make a small mistake somewhere probably.

Do you need to use blending, and is so, which Blend function … ?

I use the TextureReader from Pepijn Van Eeckhoudt in common, as follows:


private void loadRGBAGLTextures(GL gl, int textureID, String textureName)
            throws IOException {

            int[] temp = new int[1]; // create blank 
            gl.glGenTextures(1, temp); // fill with proper gl texture id 
            texturesID[textureID] = temp[0];

            // store gl texture id in correct slot of global array.
            TextureReader.Texture texture = TextureReader.readTexture(textureName,true);

            //Create Linear Filtered Texture
            gl.glBindTexture(GL.GL_TEXTURE_2D, texturesID[textureID]);
            gl.glTexParameteri(
                  GL.GL_TEXTURE_2D,
                  GL.GL_TEXTURE_MAG_FILTER,
                  GL.GL_LINEAR);
            gl.glTexParameteri(
                  GL.GL_TEXTURE_2D,
                  GL.GL_TEXTURE_MIN_FILTER,
                  GL.GL_LINEAR);

            gl.glTexImage2D(
                  GL.GL_TEXTURE_2D,
                  0,
                  3,
                  texture.getWidth(),
                  texture.getHeight(),
                  0,
                  GL.GL_RGBA,
                  GL.GL_UNSIGNED_BYTE,
                  texture.getPixels());

      }

presume this is correct … ?

[quote]hmm … have to check it out then. Come from C++ OpenGL and there you always needed the masking stuff. Good tip !
[/quote]
Ugh, that masking example is pretty hacky, its wasting time drawing things twice when it could be done with a single texture :o

What its effectly doing is storing the RGB in one texture (with the crosshairs) and the alpha in the other (as a greyscale). If instead you stored them both in a single .png file then you could do it in one step with the right blend mode. ( GL_SRC_ALPHA and GL_ONE off the top of my head).

You do loose a slight bit of flexibility (you might want to scroll the mask one way and the image the other for example) but thats really not needed here.

veediot: Are you blending your sprite when drawing it? Sounds like normal behaviour if you are. If you want a hard edge then alpha testing may be more appropriate (although you’d have to add an alpha channel if you’ve not already got one). Whats your current blend func & state for your sprites?

Okay, here is what I am doing:

To save the png, I am using Photoshop. I have a transparent area in the image in photoshop, so I am not creating a seperate alpha channel, then I am using the save for web feature to save it as a png-24 with transparency checked (which should store an alpha channel then for the transparency, correct?) Because the transparent area does appear transparent inside my app, so I’m assuming there’s nothing wrong with the way I am handling the image. The texture is 64x64, btw.

Here is how I am initing OpenGL:


gl.glBlendFunc (GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
gl.glEnable (GL.GL_BLEND);
gl.glEnable(GL.GL_TEXTURE_2D);                        
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);                  // Black Background
gl.glColor3f( 0.0f, 0.0f, 0.0f ); 
gl.glPointSize(4.0f);

I also tried turning off blending, and enabling alpha testing in this way:


gl.glAlphaFunc(gl.GL_LESS, 1);
gl.glEnable(gl.GL_ALPHA_TEST); 

However, when I did that, only the outside edge of the non-transparent part of the image was showing up (but it was still fading in and out)

This is how I setup the texture:


  gl.glBindTexture(GL.GL_TEXTURE_2D, texture[0]);
            gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR);
            gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR);
            gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 4, imageWidth,
                           imageHeight, 0, GL.GL_RGBA,
                          GL.GL_UNSIGNED_BYTE, imageRGBA);

Notice the use of GL_RGBA here. imageRGBA is the data from the image loaded using the same method used by the “Jumping into JOGL” tutorial, using the Image toolkit.

And finally, here is how I attempt to draw a sprite:


      gl.glPushMatrix();

        gl.glTranslatef(x_loc,y_loc,0.0f);
        gl.glColor4f (1.0f, 1.0f, 1.0f, 1.0f);
        gl.glBindTexture(GL.GL_TEXTURE_2D, texture[0]);

        gl.glBegin (GL.GL_POLYGON);
        gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex2i (0, 0);
        gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex2i (63, 0);
        gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex2i (63, 63);
        gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex2i (0, 63);
        gl.glEnd();    

            gl.glPopMatrix();

That having been said, does that give anyone any more clues as to what I may be doing wrong to get this fading in and out business around the edge?

I appreciate all your help!

-veediot!

Difficult to know whats going on without seeing it.

One tip is to floor() your x_loc and y_loc values. You wont get sub pixel accuracy if your texture is not scaled anyway.

I use blending and the alpha test:
GL.glAlphaFunc(GL.GL_GREATER, 0);
But I don’t think it matters.

Any reason why you clear your backbuffer alpha to 0.5?