Good enough texture loader?

Hello all,

I’m wondering if the texture loader I have is good enough for 2D games in LWJGL. It works great with 3D development, but with 2D textures with alpha values, there’s small artifacts in the image. What can I do to improve this for 2D games?

I’m converting the image data to bytes myself.

	// Loads a texture.
	public int loadTexture(String filename) {
		int ID = 0;

		try {
			BufferedImage image = ImageIO.read(getClass().getResource(filename));
			int imageW = image.getWidth();
			int imageH = image.getHeight();

			int size = imageW*imageH;
			IntBuffer data = BufferUtils.createIntBuffer(size);
			for (int y=0; y<imageH; y++) {
				for (int x=0; x<imageW; x++) {
					Color c1 = new Color(image.getRGB(x, y), true);
					Color c2 = new Color(c1.getBlue(), c1.getGreen(), c1.getRed(), c1.getAlpha());
					data.put(c2.getRGB());
				}
			}
			data.flip();

			IntBuffer buf = BufferUtils.createIntBuffer(1);
			GL11.glGenTextures(buf);
			ID = buf.get(0);
			GL11.glBindTexture(GL11.GL_TEXTURE_2D, ID);

			GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, imageW, imageH, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, data);
			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);
		} catch(Exception e) {
			e.printStackTrace();
			Sys.alert("Error", "Unable to load texture: "+filename);
			System.exit(-1);
		}

		return ID;
	}

I’m using the following blend function:

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

What exactly do you mean by “small artifacts”? A screenshot might help.

At a guess, you’re getting colour bleeding from transparent pixels into opaque pixels, possibly giving a pink or black halo aroun your sprites. If so then that’s an art problem, not a code problem.

Yeah, sorry. I guess I should have posted a screenshot. Here’s the texture:

http://www.myexh.com/~gonav341/Mario.png

And here’s a screenshot of the LWJGL alpha test I made (multiple sprites moving and rotating):

http://www.myexh.com/~gonav341/Screenshot.png

Click for the full size view.

Notice the kind of “halo” on his head?

EDIT: I found a fix for this. By adding a one pixel border around the sprite, it removes the artifacts. Looks good.

It looks like you’re drawing the texture wrapped and filtered, so the border pixels bleed from one side of the texture to the other (you see pixels from mario’s feet also above his head and vise versa). Try to draw them clamped (you can set that up by glTexParameter iirc).

The pixels from the feet bleed over to the head… and the head bleeds over to the feet.

GL12.GL_CLAMP_TO_EDGE will sort that out.

GL11.GL_CLAMP won’t do the trick if it’s implemented correctly (accordingly to the specs the borders are supposed to be blended over to the border colors of the polygon, which is like… completely useless). If OpenGL 1.2 isn’t available you can use GL_CLAMP (which will be most likely implemented incorrectly and thus yield the desired results).

Using transparent padding pixels also helps. Well, as long as you aren’t generating mipmaps, that is.

edit: one advantage of padding pixels is that you also get nicely AA-ed edges at those areas, which would usually touch the quad.

Thanks a lot guys. That worked just great.