Typicly this is how I handle LWJGL 3 screenshots and saving.
/**
* Takes a screenshot of the current image of the display and saves it into the screenshots folder a png image.
*/
public static void screenshot() {
// Tries to create an image, otherwise throws an exception.
String name = Calendar.getInstance().get(Calendar.MONTH) + 1 + "." + Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "." + Calendar.getInstance().get(Calendar.HOUR) + "." + Calendar.getInstance().get(Calendar.MINUTE) + "." + (Calendar.getInstance().get(Calendar.SECOND) + 1);
File saveDirectory = new File(Framework.getRoamingFolder().getPath(), "screenshots");
if (!saveDirectory.exists()) {
try {
if (!saveDirectory.mkdir()) {
FlounderLogger.error("The screenshot directory could not be created.");
}
} catch (SecurityException e) {
FlounderLogger.error("The screenshot directory could not be created.");
FlounderLogger.exception(e);
return;
}
}
File file = new File(saveDirectory + "/" + name + ".png"); // The file to save the pixels too.
String format = "png"; // "PNG" or "JPG".
FlounderLogger.log("Taking screenshot and outputting it to " + file.getAbsolutePath());
// Tries to create image.
try {
ImageIO.write(getImage(null, null), format, file);
} catch (Exception e) {
FlounderLogger.error("Failed to take screenshot.");
FlounderLogger.exception(e);
}
}
/**
* Creates a buffered image from the OpenGL pixel buffer.
*
* @param destination The destination BufferedImage to store in, if null a new one will be created.
* @param buffer The buffer to store OpenGL data into, if null a new one will be created.
*
* @return A new buffered image containing the displays data.
*/
public static BufferedImage getImage(BufferedImage destination, ByteBuffer buffer) {
// Creates a new destination if it does not exist, or fixes a old one,
if (destination == null || buffer == null || destination.getWidth() != getWidth() || destination.getHeight() != getHeight()) {
destination = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
buffer = BufferUtils.createByteBuffer(getWidth() * getHeight() * 4);
}
// Creates a new buffer and stores the displays data into it.
glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// Transfers the data from the buffer into the image. This requires bit shifts to get the components data.
for (int x = destination.getWidth() - 1; x >= 0; x--) {
for (int y = destination.getHeight() - 1; y >= 0; y--) {
int i = (x + getWidth() * y) * 4;
destination.setRGB(x, destination.getHeight() - 1 - y, (((buffer.get(i) & 0xFF) & 0x0ff) << 16) | (((buffer.get(i + 1) & 0xFF) & 0x0ff) << 8) | ((buffer.get(i + 2) & 0xFF) & 0x0ff));
}
}
return destination;
}