Reputation: 425
I'm currently trying to generate a textured polygonal surface using JOGL, and I'm getting an error message I don't understand. Eclipse tells me "java.lang.IndexOutOfBoundsException: Required 430233 remaining bytes in buffer, only had 428349". As far as I can see, the buffered image being generated by the readTexture method is not of sufficient size to use with the glTex2D() method. However, I'm not sure how to go about resolving the issue. The relevant sections of code are below, and any help would be much appreciated.
public void init(GLAutoDrawable drawable)
{
final GL2 gl = drawable.getGL().getGL2();
GLU glu = GLU.createGLU();
//Create the glu object which allows access to the GLU library\
gl.glShadeModel(GL2.GL_SMOOTH); // Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
gl.glClearDepth(1.0f); // Depth Buffer Setup
gl.glEnable(GL.GL_DEPTH_TEST); // Enables Depth Testing
gl.glDepthFunc(GL.GL_LEQUAL); // The Type Of Depth Testing To Do
gl.glEnable(GL.GL_TEXTURE_2D);
texture = genTexture(gl);
gl.glBindTexture(GL.GL_TEXTURE_2D, texture);
TextureReader.Texture texture = null;
try {
texture = TextureReader.readTexture ("/C:/Users/Alex/Desktop/boy_reaching_up_for_goalpost_stencil.png");
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
makeRGBTexture(gl, glu, texture, GL.GL_TEXTURE_2D, false);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
}
private void makeRGBTexture(GL gl, GLU glu, TextureReader.Texture img,
int target, boolean mipmapped) {
if (mipmapped) {
glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(),
img.getHeight(), GL.GL_RGB, GL.GL_UNSIGNED_BYTE, img.getPixels());
} else {
gl.glTexImage2D(target, 0, GL.GL_RGB, img.getWidth(),
img.getHeight(), 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, img.getPixels());
}
}
private int genTexture(GL gl) {
final int[] tmp = new int[1];
gl.glGenTextures(1, tmp, 0);
return tmp[0];
}
//Within the TextureReader class
public static Texture readTexture(String filename, boolean storeAlphaChannel)
throws IOException {
BufferedImage bufferedImage;
if (filename.endsWith(".bmp")) {
bufferedImage = BitmapLoader.loadBitmap(filename);
} else {
bufferedImage = readImage(filename);
}
return readPixels(bufferedImage, storeAlphaChannel);
}
The error is being generated by the call to glTexImage2D() inside the makeRGBTexture() method.
Upvotes: 0
Views: 2005
Reputation: 45342
By default, the GL expects that each line of an image starts at an memory address divisiable by 4 (4 byte alignment). With RGBA images, this is always the case (als long as the first pixel is correctly aligned). But with RGB images, this will only be the case when the width is divisable by 4, too. Note that this is totally unrelated to the "power of two" requirements of very old GPUs.
Woth your particular image resolutiion of 227x629, you get 681 bytes per line, so the GL expetcs 3 additional bytes per line. For 629 lines, this makes 1887 extra bytes. If you look at those numbers, you can see that the buffer is just 1884 bytes to small. The difference of 3 is just due to the fact that we do not need the 3 padding bytes at the end of the last line, since there is no next line to be started, and the GL won't read beyond that end of that data.
So you have two options here: align the image data to the way expect them (that is, pad every line with some extra bytes), or - the simpler approach from the user's point of view - just tell the GL that your data is tightly packed (1 byte alignment) by calling glPixelStorei
(GL_UNPACK_ALIGNMENT,1)
before you specify the image data.
Upvotes: 5