Texture Problems/Questions

Started by CodeBunny, October 18, 2010, 11:59:58

Previous topic - Next topic

CodeBunny

I'm not sure if this should go here or in OpenGL development, since I'm not sure the problem is native to OpenGL or has to do with how Slick-Util works.

Basically, the problem is that certain images aren't being allowed translucent pixels, even though the file has semi-transparent regions. I'll be rendering a textured quad that should have smooth edges that fade out, but instead I get ugly white pixels wherever the image has slight transparency.

I'd understand the error more if this were a universal problem with all my textures. The weird thing is that other images are working fine. I'll have an animation and most of the images will work fine, but when I switch to a different animation in the same set of images, it's got the problem.

Here's an example:

This is the image when it's working fine, and it's original file (with a dark gray background):


This is another image with the problem, and it's original image:

(neither image had the background before, I placed them on a grey background so you could see that there's only black around the edges)

Basically, what is causing this and how can I stop it from happening?



Secondly, how do I get LWJGL to render these textures without smoothing them? I'd like to be able to render pixelated textures if I feel the need.

spasi

The white-pixel-border problem is related to interpolation. There a few techniques you can use to solve it, search for premultiplied-alpha for a start (e.g. http://home.comcast.net/~tom_forsyth/blog.wiki.html#[[Premultiplied%20alpha]] edit: copy/paste the whole thing).

If you want pixelated rendering, then you should use GL_NEAREST instead of GL_LINEAR for your texture magnification. This will also solve the other problem.

CodeBunny

Thanks!

Just a question, though: why does it only occur for certain images and not all of them? That's what's really confused me about this whole error.

EDIT: And how do I set GL_TEXTURE_MAG_FILTER? I can't find which method to work through, and I get an error when I try to set it directly.

spasi

That depends on the image format, how the images are saved to file and then loaded to GL, etc. There must be a difference between the two images you posted.

Fool Running

In my experience, the problems you are showing is caused by transparent pixels that do not have the same color as their neighbors.
In other words you have opaque black pixels (0.0r, 0.0g, 0.0b, 1.0a) near to transparent white pixels (1.0r, 1.0g, 1.0b, 0.0a). When OpenGL interpolates the pixels (because the textels are not directly corresponding to screen pixels) you get a semi-transparent gray pixel (0.5r, 0.5g, 0.5b, 0.5a).

To solve this problem, make sure all the transparent regions of your textures are the same color as the neighboring opaque pixels (in this case transparent black pixels (0.0r, 0.0g, 0.0b, 0.0a)).
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

kappa

as mentioned above by spasi you can use GL_NEAREST to get a pixelated look instead of a blurred one.

When doing this with slick-util you simply specify this at the time of loading the image as follows
texture = TextureLoader.getTexture("PNG", new FileInputStream("rocks.png"), GL11.GL_NEAREST);

CodeBunny

Is there a way to make a global call that achieves the same thing?

kappa

Quote from: CodeBunny on October 18, 2010, 13:33:44
Is there a way to make a global call that achieves the same thing?

No, I don't think there is but it does sound like a very useful feature. You should raise a "Request For Enhancement" over on the Slick RFE/BUGs board and it'll probably get added to slick-util.

CodeBunny

It would be nice. I'll do that.

I can probably create similar functionality without too much difficulty, but it would be good if it came out of the box.  ;)

CodeBunny

Apparently you can do this simply by calling:

public class AATest extends BasicGame {

   public AATest(String title) {
      super(title);
      // TODO Auto-generated constructor stub
   }

   public Image test;
   public boolean mode = true;
   
   public void init(GameContainer container) throws SlickException {
     test = new Image("/testdata/grass.png");
   }

   public void update(GameContainer container, int delta)
         throws SlickException {
     if(container.getInput().isKeyPressed(Input.KEY_S)){
        int target = GL11.GL_TEXTURE_2D;
        if(mode==true){
         GL11.glBindTexture(target, test.getTexture().getTextureID());
         GL11.glTexParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
           GL11.glTexParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
        }else{
         GL11.glBindTexture(target, test.getTexture().getTextureID());
          GL11.glTexParameteri(target, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
          GL11.glTexParameteri(target, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        }
        mode = !mode;
     }
   }

   public void render(GameContainer container, Graphics g)
         throws SlickException {
      test.draw(10, 10, 4.0f);
   }
   
   
   public static void main(String[] args){
      BasicGame bg = new AATest("Texture Test");
     
      try{
        AppGameContainer container = new AppGameContainer(bg);
        container.setDisplayMode(800, 600, false);
        container.start();
      }catch(SlickException se){
         
      }
   }
}