java.awt.image.BufferedImage has a function which returns a BufferedImage which is a subimage of the original with dimensions w*h at offset x,y: public BufferedImage getSubimage(int x int y, int w, int h) Rather than creating a copy of the pixel data this function plays games with the returned images Raster and Sample model. AWTTextureIO is not correctly taking into account all of the offsets in the data reported by the buffered image, and therefore any Texture created from a BufferedImage created with a call to someImage.getSubimage( x, y, w, h) looks instead as if it were created from a BufferedImage created with a call to someImage.getSubimage( 0, 0, w, h) instead JDK 6's GIF writer seems to have the same bug, see http://bugs.sun.com/view_bug.do?bug_id=6795544 for a description of what I think is a very similar bug. I have confirmed that this problem can be worked around with a function that creates a copy of the sub-image by allocating a new BufferedImage of the correct size, and then copying the pixels into it: The code tex = AWTTextureIO.newTexture(GLProfile.getDefault(), i.getSubimage(x,y,w,h), false); displays incorrectly for x !=0, y != 0 but the code tex = AWTTextureIO.newTexture(GLProfile.getDefault(), workaround(i.getSubimage(x,y,w,h)), false); works as expected, given the function private static BufferedImage workaround(BufferedImage i) { BufferedImage d2 = new BufferedImage(i.getWidth(), i.getHeight(), i.getType()); d2.getGraphics().drawImage(i, 0, 0, null); return d2; } I will look into preparing a very short example program.
Created attachment 501 [details] Test Program for bug This is a simple test program that should reproduce the problem. A 256x256 texture is loaded, a 128x128 subimage is extracted at offset 128, 128 and used as a texture, once directly and once using the workaround in the ticket. You should see TWO green squares, but see one red and one green, the green being a product of the workaround, the red being the texture in error.
Just as a note, I was going crazy trying to reproduce this and discovered that the problem occurs when the image is a JPEG, but not when it is a PNG.
In AWTTextureIO there is a function, createFromCustom(...), which re-writes the image to a new BufferedImage exactly as the workaround above does. I think that it hits this code for PNG with alpha, but perhaps not for JPEG, explaining the difference between the two image types. (In reply to comment #2) > Just as a note, I was going crazy trying to reproduce this and discovered > that the problem occurs when the image is a JPEG, but not when it is a PNG.
(In reply to comment #3) > In AWTTextureIO there is a function, createFromCustom(...), which re-writes > the image to a new BufferedImage exactly as the workaround above does. I > think that it hits this code for PNG with alpha, but perhaps not for JPEG, > explaining the difference between the two image types. > > (In reply to comment #2) > > Just as a note, I was going crazy trying to reproduce this and discovered > > that the problem occurs when the image is a JPEG, but not when it is a PNG. Bill, can you provide a patch ? Please also note, we consider using our own PNG and JPEG decoder code as the default - hence it is used by our TextureIO class. Both are more efficient and expose better performance. The JPEG decoder is even more compliant.