尝试使用openGL创建纹理时缓冲区大小不足

时间:2013-09-17 13:59:49

标签: java opengl textures buffer bufferedimage

我目前正在尝试使用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()调用生成的。

1 个答案:

答案 0 :(得分:1)

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

对于227x629的特定图像解析,每行得到681个字节,因此GL每行需要额外3个字节。对于629行,这使得1887个额外字节。如果查看这些数字,可以看到缓冲区只有1884字节到小。 3的差异仅仅是因为我们不需要在最后一行末尾的3个填充字节,因为没有下一行要启动,并且GL将不会读取超出该数据的那一端

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