Issue: java.lang.IndexOutOfBoundsException (Textures)

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Issue: java.lang.IndexOutOfBoundsException (Textures)

Haroogan
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.getRGBdefault());
		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(Buffers.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)
Reply | Threaded
Open this post in threaded view
|

Re: Issue: java.lang.IndexOutOfBoundsException (Textures)

Demoscene Passivist
Administrator
Reply | Threaded
Open this post in threaded view
|

Re: Issue: java.lang.IndexOutOfBoundsException (Textures)

Haroogan
The first two references are to guys who didnt rewind their ByteBuffers... My ByteBuffer is rewinded. My problem is that I am doing everything right, but somehow JOGL wants more bytes from me on irregular size images. Also I have noticed that when I was creating ByteBuffer with alpha channel and specifing GL_RGBA in glTexImage2D like that, the problem was gone:

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

But why would I do that? What if I want to keep my ByteBuffer without alpha channel component..?
Reply | Threaded
Open this post in threaded view
|

Re: Issue: java.lang.IndexOutOfBoundsException (Textures)

Demoscene Passivist
Administrator
try changing ++y and ++x to y++ and x++ ... as far as I can see u are ignoring the 0th element/y-line ...
Reply | Threaded
Open this post in threaded view
|

Re: Issue: java.lang.IndexOutOfBoundsException (Textures)

Haroogan
You are wrong... I am actually confused that you dont know such things...