0

我目前正在尝试使用 JOGL 生成带纹理的多边形表面,但收到一条我不理解的错误消息。Eclipse 告诉我“java.lang.IndexOutOfBoundsException:缓冲区中需要 430233 个剩余字节,只有 428349 个”。据我所见,由 readTexture 方法生成的缓冲图像的大小不足以与 glTex2D() 方法一起使用。但是,我不确定如何解决这个问题。代码的相关部分如下,任何帮助将不胜感激。

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);

    }

该错误是由在 makeRGBTexture() 方法中调用 glTexImage2D() 生成的。

4

1 回答 1

2

默认情况下,GL 期望图像的每一行都从可被 4 整除的内存地址开始(4 字节对齐)。对于 RGBA 图像,情况总是如此(只要第一个像素正确对齐)。但是对于 RGB 图像,只有当宽度也可以被 4 整除时才会出现这种情况。请注意,这与非常旧的 GPU 的“二的幂”要求完全无关。

您的特定图像分辨率为 227x629,每行 681 个字节,因此 GL 每行需要 3 个额外字节。对于 629 行,这会产生 1887 个额外字节。如果您查看这些数字,您会发现缓冲区只有 1884 字节小。3 的差异只是因为我们不需要最后一行末尾的 3 个填充字节,因为没有下一行要开始,并且 GL 不会读取超出该数据的那一端.

所以你在这里有两个选择:将图像数据与期望的方式对齐(即,用一些额外的字节填充每一行),或者 - 从用户的角度来看更简单的方法 - 只是告诉 GL 你的数据是紧密的在指定图像数据之前通过调用打包(1 字节对齐) 。glPixelStorei(GL_UNPACK_ALIGNMENT,1)

于 2013-09-17T18:33:35.730 回答