openGL game screenshot

Started by jrdan, February 17, 2017, 05:10:51

Previous topic - Next topic

jrdan

I want to capture an openGL game's screenshot , and I can use JNA to obtain it's native handle .

how can I capture it's real-time screen?

I know the common solution is use glReadPixels to obtain it's pixels data , but first I need to use glfwMakeContextCurrent(window) ,

so how to get the openGL game's window? Then I can use glfwMakeContextCurrent and glReadPixels. or Is there exiting a better solution?

sorry to my fool English, hope I made my question clear.

Because I am a newbie here, really appreciate some one can give me some guidance.

mattparks

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

jrdan

mattparksï¼Å'thanks for your helpï¼Å'I'm familiar with your code ï¼Å'but how to get the opengl game buffer?

@param buffer The buffer to store OpenGL data into, if null a new one will be created.

jrdan

up up
I still hope to get some help!

jrdan

no one can fix this issue?

darkyellow

In what way is this a lwjgl issue?  You are asking a question about getting the context from another process which is neither lwjgl nor GLFW relevant. I'm not trying to be nasty to you but there might be better places to ask this question (best location is unknown to me though)