PDA

View Full Version : Issue: java.lang.IndexOutOfBoundsException



Harrogan
10-11-2010, 10:49 AM
Alright, lets go:

1. Pretty trivial class I wrote out there:



public final class Texture
{

private int[] pixels;
private int width;
private int height;

public int getHeight()
{
return height;
}


private void setHeight(int height)
{
this.height = height;
}


public int[] getPixels()
{
return pixels;
}


public ByteBuffer getPixelsAsByteBuffer()
{
ByteBuffer pixelByteBuffer = ByteBuffer.allocateDirect(pixels.length * 3).order(
ByteOrder.nativeOrder());

for(int y = 0; y [ height; ++y)
{
for(int x = 0; x [ width; ++x)
{
int currentPixel = pixels[x + (y * width)];
pixelByteBuffer.put((byte)((currentPixel ]] 16) & 0xFF));
pixelByteBuffer.put((byte)((currentPixel ]] 8) & 0xFF));
pixelByteBuffer.put((byte)(currentPixel & 0xFF));
}
}

pixelByteBuffer.rewind();

return pixelByteBuffer;
}


private void setPixels(int[] pixels)
{
this.pixels = pixels;
}


public int getWidth()
{
return width;
}


private void setWidth(int width)
{
this.width = width;
}


public void load(FileInputStream fileInputStream)
throws Exception
{
BufferedImage bufferedImage = ImageIO.read(fileInputStream);
fileInputStream.close();
setWidth(bufferedImage.getWidth());
setHeight(bufferedImage.getHeight());
setPixels(new int[width * height]);
PixelGrabber pixelGrabber = new PixelGrabber(bufferedImage,
0,
0,
width,
height,
pixels,
0,
width);
pixelGrabber.setColorModel(ColorModel.getRGBdefaul t());
pixelGrabber.grabPixels();

if((pixelGrabber.getStatus() & ImageObserver.ABORT) != 0)
{
System.err.println("image fetch aborted or errored");
setPixels(null);
}

}


public void load(String filePath)
throws Exception
{
load(new FileInputStream(filePath));
}


public void load(File file)
throws Exception
{
load(new FileInputStream(file));
}


}


2. So, its usage, again trivial:



texture = new Texture();

try
{
texture.load("resource/terrain/2.jpg");
}
catch(Exception ex)
{
System.out.println(ex);
}


3. And here (as you have probably guessed) we engage it to OpenGL:



gl.glEnable(GL.GL_TEXTURE_2D);

gl.glBindTexture(GL.GL_TEXTURE_2D,
1);
gl.glTexParameteri(GL.GL_TEXTURE_2D,
GL.GL_TEXTURE_MIN_FILTER,
GL.GL_NEAREST);
gl.glTexParameteri(GL.GL_TEXTURE_2D,
GL.GL_TEXTURE_MAG_FILTER,
GL.GL_NEAREST);


SimpleScene.java:266

gl.glTexImage2D(GL.GL_TEXTURE_2D,
0,
GL.GL_RGB,
texture.getWidth(),
texture.getHeight(),
0,
GL.GL_RGB,
GL.GL_UNSIGNED_BYTE,
texture.getPixelsAsByteBuffer());


4. Now the story:
All the above seems to be cool right? Well, I wish it was :) If I am loading a regular image (64x64, 128x128, 1024x1024 and etc.) everything works ok. If I am loading something like 1020x1020 or maybe 700x900 it MIGHT be ok, but not 100% (for instance, 1010x1010 doesnt load). Finally, if I try 129x129 or maybe 65x65 (or any other combination with numbers, which cannot be divided by 2), it fails 100%! Horrible...

5. Exception
Here I provided you with the exception thrown by glTexImage2D, you can notice that here I was trying to load 1023x1023 image, because 1023 * 1023 * 3 = 3139587 bytes, which prooves that ByteBuffer was assembled right, but in some case JOGL wants me too pass him 3142653 bytes... uhm..? And again: if I am loading a regular image (64x64, 128x128, 1024x1024 and etc.) everything works ok.



Caused by: java.lang.IndexOutOfBoundsException: Required 3142653 remaining bytes in buffer, only had 3139587
at com.jogamp.common.nio.Buffers.rangeCheckBytes(Buff ers.java:749)
at com.jogamp.opengl.impl.gl4.GL4bcImpl.glTexImage2D( GL4bcImpl.java:23826)
at javax.media.opengl.DebugGL2.glTexImage2D(DebugGL2. java:18956)
at ru.haroogan.SimpleScene.init(SimpleScene.java:266)