我有一个纹理ID,想检索它的数据。数据应存储在BufferedImage中以备将来使用。我正在使用Java中的LWJGL库,因此,如果有一些库特定的快捷方式,我想使用它们。

int id = ...;
IntBuffer buff = BufferUtils.createIntBuffer(1024*512*4);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
System.out.println(buff.remaining());
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, buff);
System.out.println(buff.remaining());
buff.flip();
buff.rewind();
System.out.println(buff.remaining());
// Somehow create a BufferedImage from buff here


我不知道为什么,但是第一个和buff.remaining()返回相同的值,表明没有写任何内容,不应情况。

#1 楼

为了使其更完整,我们还考虑从BufferedImage加载纹理。首先,我们假设:

我们需要加载图像。为此,我们可以使用ImageIO.read()。然后,将所有来自BufferedImage的像素放入一个ByteBuffer中。 glGetTexImage())。因此,我们认为我们不知道纹理的大小或格式。我们可以通过以下操作获得所有这些信息:

int texture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, texture);


使用该信息,我们再次创建textureByteBuffer。从BufferedImage读取像素并将其放在ByteBuffer上。

BufferedImage image = ImageIO.read(new File("image.png"));
int width = image.getWidth(), height = image.getHeight();

int[] pixels = new int[width * height];
image.getRGB(0, 0, width, height, pixels, 0, width);

ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * 4); // 4 because RGBA

for(int y = 0; y < height; ++y) {
    for(int x = 0; x < width; ++x) {
        int pixel = pixels[x + y * width];
        buffer.put((byte) ((pixel >> 16) & 0xFF));
        buffer.put((byte) ((pixel >> 8) & 0xFF));
        buffer.put((byte) (pixel & 0xFF));
        buffer.put((byte) ((pixel >> 24) & 0xFF));
    }
}

buffer.flip();

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);


现在继续将BufferedImage保存到文件中。

最后但并非最不重要的一点是,您可以通过静态导入BufferedImage来摆脱所有这些GL11.前缀。您可以这样做:

int format = glGetTexLevelParameteri(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT);
int width = glGetTexLevelParameteri(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH);
int height = glGetTexLevelParameteri(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT);