To make it a more complete example, let's also consider loading a texture from a BufferedImage
as well.
First let's assume:
int texture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, texture);
First we need to load an image. For this we can use ImageIO.read()
. Then we put all the pixels from the BufferedImage
into a 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);
Before we go ahead and call glGetTexImage()
lets assume that the only thing we have is the texture name (texture
). Thus we consider that we don't know the size or format of the texture. We can get all this by doing:
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);
Using that information we again create a ByteBuffer
as well as a BufferedImage
. Reading the pixels from the ByteBuffer
and placing them on the BufferedImage
.
int channels = 4;
if (format == GL_RGB)
channels = 3;
ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * channels);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
glGetTexImage(GL_TEXTURE_2D, 0, format, GL_UNSIGNED_BYTE, buffer);
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
int i = (x + y * width) * channels;
int r = buffer.get(i) & 0xFF;
int g = buffer.get(i + 1) & 0xFF;
int b = buffer.get(i + 2) & 0xFF;
int a = 255;
if (channels == 4)
a = buffer.get(i + 3) & 0xFF;
image.setRGB(x, y, (a << 24) | (r << 16) | (g << 8) | b);
}
}
Now go ahead and save that BufferedImage
to a file.
ImageIO.write(image, "PNG", new File("out.png"));
Last but not least, you can get rid of all those GL11.
prefixes, by statically importing GL11
. You do that by doing:
import static org.lwjgl.opengl.GL11.*;