aboutsummaryrefslogtreecommitdiffstats
path: root/src/classes/com/sun/opengl/util/awt/gl2
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2008-06-21 02:33:51 +0000
committerSven Gothel <[email protected]>2008-06-21 02:33:51 +0000
commit006acbb9463af33a8b45aa0b3a298604eba72d82 (patch)
tree2c71662575a2c098b22c4b19b471bb5c732041c5 /src/classes/com/sun/opengl/util/awt/gl2
parentcbc45e816f4ee81031bffce19a99550681462a24 (diff)
2nd big refactoring.
Goals are orthogonal components for: - OS Windowing system - NEWT, X11, Windows, MacOsX - GL Windowing GLUE - EGL, GLX, WGL, CGL - GL profiles - core and util packages - generate all Java components from any platform All above goals are achieved. TODO: - Native compilation fix and test - Check/Fix Win32, MacOSX and the mobile devices - .. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1665 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/classes/com/sun/opengl/util/awt/gl2')
-rwxr-xr-xsrc/classes/com/sun/opengl/util/awt/gl2/GL2Screenshot.java433
1 files changed, 433 insertions, 0 deletions
diff --git a/src/classes/com/sun/opengl/util/awt/gl2/GL2Screenshot.java b/src/classes/com/sun/opengl/util/awt/gl2/GL2Screenshot.java
new file mode 100755
index 000000000..03313e2e5
--- /dev/null
+++ b/src/classes/com/sun/opengl/util/awt/gl2/GL2Screenshot.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.sun.opengl.util.awt.gl2;
+
+import java.awt.image.*;
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import javax.imageio.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+import javax.media.opengl.glu.gl2.*;
+
+import com.sun.opengl.util.io.*;
+import com.sun.opengl.util.awt.*;
+
+/** Utilities for taking screenshots of OpenGL applications. */
+
+public class GL2Screenshot {
+ private GL2Screenshot() {}
+
+ /**
+ * Takes a fast screenshot of the current OpenGL drawable to a Targa
+ * file. Requires the OpenGL context for the desired drawable to be
+ * current. Takes the screenshot from the last assigned read buffer,
+ * or the OpenGL default read buffer if none has been specified by
+ * the user (GL_FRONT for single-buffered configurations and GL_BACK
+ * for double-buffered configurations). This is the fastest
+ * mechanism for taking a screenshot of an application. Contributed
+ * by Carsten Weisse of Bytonic Software (http://bytonic.de/). <p>
+ *
+ * No alpha channel is written with this variant.
+ *
+ * @param file the file to write containing the screenshot
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ * @throws IOException if an I/O error occurred while writing the
+ * file
+ */
+ public static void writeToTargaFile(File file,
+ int width,
+ int height) throws GLException, IOException {
+ writeToTargaFile(file, width, height, false);
+ }
+
+ /**
+ * Takes a fast screenshot of the current OpenGL drawable to a Targa
+ * file. Requires the OpenGL context for the desired drawable to be
+ * current. Takes the screenshot from the last assigned read buffer,
+ * or the OpenGL default read buffer if none has been specified by
+ * the user (GL_FRONT for single-buffered configurations and GL_BACK
+ * for double-buffered configurations). This is the fastest
+ * mechanism for taking a screenshot of an application. Contributed
+ * by Carsten Weisse of Bytonic Software (http://bytonic.de/).
+ *
+ * @param file the file to write containing the screenshot
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ * @param alpha whether the alpha channel should be saved. If true,
+ * requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ * @throws IOException if an I/O error occurred while writing the
+ * file
+ */
+ public static void writeToTargaFile(File file,
+ int width,
+ int height,
+ boolean alpha) throws GLException, IOException {
+ writeToTargaFile(file, 0, 0, width, height, alpha);
+ }
+
+ /**
+ * Takes a fast screenshot of the current OpenGL drawable to a Targa
+ * file. Requires the OpenGL context for the desired drawable to be
+ * current. Takes the screenshot from the last assigned read buffer,
+ * or the OpenGL default read buffer if none has been specified by
+ * the user (GL_FRONT for single-buffered configurations and GL_BACK
+ * for double-buffered configurations). This is the fastest
+ * mechanism for taking a screenshot of an application. Contributed
+ * by Carsten Weisse of Bytonic Software (http://bytonic.de/).
+ *
+ * @param file the file to write containing the screenshot
+ * @param x the starting x coordinate of the screenshot, measured from the lower-left
+ * @param y the starting y coordinate of the screenshot, measured from the lower-left
+ * @param width the width of the desired screenshot area
+ * @param height the height of the desired screenshot area
+ * @param alpha whether the alpha channel should be saved. If true,
+ * requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ * @throws IOException if an I/O error occurred while writing the
+ * file
+ */
+ public static void writeToTargaFile(File file,
+ int x,
+ int y,
+ int width,
+ int height,
+ boolean alpha) throws GLException, IOException {
+ if (alpha) {
+ checkExtABGR();
+ }
+
+ TGAWriter writer = new TGAWriter();
+ writer.open(file, width, height, alpha);
+ ByteBuffer bgr = writer.getImageData();
+
+ GL2 gl = GLUgl2.getCurrentGL2();
+
+ // Set up pixel storage modes
+ PixelStorageModes psm = new PixelStorageModes();
+ psm.save(gl);
+
+ int readbackType = (alpha ? GL2.GL_ABGR_EXT : GL2.GL_BGR);
+
+ // read the BGR values into the image buffer
+ gl.glReadPixels(x, y, width, height, readbackType,
+ GL2.GL_UNSIGNED_BYTE, bgr);
+
+ // Restore pixel storage modes
+ psm.restore(gl);
+
+ // close the file
+ writer.close();
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to a
+ * BufferedImage. Requires the OpenGL context for the desired
+ * drawable to be current. Takes the screenshot from the last
+ * assigned read buffer, or the OpenGL default read buffer if none
+ * has been specified by the user (GL_FRONT for single-buffered
+ * configurations and GL_BACK for double-buffered configurations).
+ * Note that the scanlines of the resulting image are flipped
+ * vertically in order to correctly match the OpenGL contents, which
+ * takes time and is therefore not as fast as the Targa screenshot
+ * function. <P>
+ *
+ * No alpha channel is read back with this variant.
+ *
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ */
+ public static BufferedImage readToBufferedImage(int width,
+ int height) throws GLException {
+ return readToBufferedImage(width, height, false);
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to a
+ * BufferedImage. Requires the OpenGL context for the desired
+ * drawable to be current. Takes the screenshot from the last
+ * assigned read buffer, or the OpenGL default read buffer if none
+ * has been specified by the user (GL_FRONT for single-buffered
+ * configurations and GL_BACK for double-buffered configurations).
+ * Note that the scanlines of the resulting image are flipped
+ * vertically in order to correctly match the OpenGL contents, which
+ * takes time and is therefore not as fast as the Targa screenshot
+ * function.
+ *
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ * @param alpha whether the alpha channel should be read back. If
+ * true, requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ */
+ public static BufferedImage readToBufferedImage(int width,
+ int height,
+ boolean alpha) throws GLException {
+ return readToBufferedImage(0, 0, width, height, alpha);
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to a
+ * BufferedImage. Requires the OpenGL context for the desired
+ * drawable to be current. Takes the screenshot from the last
+ * assigned read buffer, or the OpenGL default read buffer if none
+ * has been specified by the user (GL_FRONT for single-buffered
+ * configurations and GL_BACK for double-buffered configurations).
+ * Note that the scanlines of the resulting image are flipped
+ * vertically in order to correctly match the OpenGL contents, which
+ * takes time and is therefore not as fast as the Targa screenshot
+ * function.
+ *
+ * @param x the starting x coordinate of the screenshot, measured from the lower-left
+ * @param y the starting y coordinate of the screenshot, measured from the lower-left
+ * @param width the width of the desired screenshot area
+ * @param height the height of the desired screenshot area
+ * @param alpha whether the alpha channel should be read back. If
+ * true, requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ */
+ public static BufferedImage readToBufferedImage(int x,
+ int y,
+ int width,
+ int height,
+ boolean alpha) throws GLException {
+ int bufImgType = (alpha ? BufferedImage.TYPE_4BYTE_ABGR : BufferedImage.TYPE_3BYTE_BGR);
+ int readbackType = (alpha ? GL2.GL_ABGR_EXT : GL2.GL_BGR);
+
+ if (alpha) {
+ checkExtABGR();
+ }
+
+ // Allocate necessary storage
+ BufferedImage image = new BufferedImage(width, height, bufImgType);
+
+ GL2 gl = GLUgl2.getCurrentGL2();
+
+ // Set up pixel storage modes
+ PixelStorageModes psm = new PixelStorageModes();
+ psm.save(gl);
+
+ // read the BGR values into the image
+ gl.glReadPixels(x, y, width, height, readbackType,
+ GL2.GL_UNSIGNED_BYTE,
+ ByteBuffer.wrap(((DataBufferByte) image.getRaster().getDataBuffer()).getData()));
+
+ // Restore pixel storage modes
+ psm.restore(gl);
+
+ // Must flip BufferedImage vertically for correct results
+ ImageUtil.flipImageVertically(image);
+ return image;
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to the
+ * specified file on disk using the ImageIO package. Requires the
+ * OpenGL context for the desired drawable to be current. Takes the
+ * screenshot from the last assigned read buffer, or the OpenGL
+ * default read buffer if none has been specified by the user
+ * (GL_FRONT for single-buffered configurations and GL_BACK for
+ * double-buffered configurations). This is not the fastest
+ * mechanism for taking a screenshot but may be more convenient than
+ * others for getting images for consumption by other packages. The
+ * file format is inferred from the suffix of the given file. <P>
+ *
+ * No alpha channel is saved with this variant.
+ *
+ * @param file the file to write containing the screenshot
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ *
+ * @throws IOException if an I/O error occurred or if the file could
+ * not be written to disk due to the requested file format being
+ * unsupported by ImageIO
+ */
+ public static void writeToFile(File file,
+ int width,
+ int height) throws IOException, GLException {
+ writeToFile(file, width, height, false);
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to the
+ * specified file on disk using the ImageIO package. Requires the
+ * OpenGL context for the desired drawable to be current. Takes the
+ * screenshot from the last assigned read buffer, or the OpenGL
+ * default read buffer if none has been specified by the user
+ * (GL_FRONT for single-buffered configurations and GL_BACK for
+ * double-buffered configurations). This is not the fastest
+ * mechanism for taking a screenshot but may be more convenient than
+ * others for getting images for consumption by other packages. The
+ * file format is inferred from the suffix of the given file. <P>
+ *
+ * Note that some file formats, in particular JPEG, can not handle
+ * an alpha channel properly. If the "alpha" argument is specified
+ * as true for such a file format it will be silently ignored.
+ *
+ * @param file the file to write containing the screenshot
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ * @param alpha whether an alpha channel should be saved. If true,
+ * requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ *
+ * @throws IOException if an I/O error occurred or if the file could
+ * not be written to disk due to the requested file format being
+ * unsupported by ImageIO
+ */
+ public static void writeToFile(File file,
+ int width,
+ int height,
+ boolean alpha) throws IOException, GLException {
+ writeToFile(file, 0, 0, width, height, alpha);
+ }
+
+ /**
+ * Takes a screenshot of the current OpenGL drawable to the
+ * specified file on disk using the ImageIO package. Requires the
+ * OpenGL context for the desired drawable to be current. Takes the
+ * screenshot from the last assigned read buffer, or the OpenGL
+ * default read buffer if none has been specified by the user
+ * (GL_FRONT for single-buffered configurations and GL_BACK for
+ * double-buffered configurations). This is not the fastest
+ * mechanism for taking a screenshot but may be more convenient than
+ * others for getting images for consumption by other packages. The
+ * file format is inferred from the suffix of the given file. <P>
+ *
+ * Note that some file formats, in particular JPEG, can not handle
+ * an alpha channel properly. If the "alpha" argument is specified
+ * as true for such a file format it will be silently ignored.
+ *
+ * @param file the file to write containing the screenshot
+ * @param x the starting x coordinate of the screenshot, measured from the lower-left
+ * @param y the starting y coordinate of the screenshot, measured from the lower-left
+ * @param width the width of the current drawable
+ * @param height the height of the current drawable
+ * @param alpha whether an alpha channel should be saved. If true,
+ * requires GL_EXT_abgr extension to be present.
+ *
+ * @throws GLException if an OpenGL context was not current or
+ * another OpenGL-related error occurred
+ *
+ * @throws IOException if an I/O error occurred or if the file could
+ * not be written to disk due to the requested file format being
+ * unsupported by ImageIO
+ */
+ public static void writeToFile(File file,
+ int x,
+ int y,
+ int width,
+ int height,
+ boolean alpha) throws IOException, GLException {
+ String fileSuffix = FileUtil.getFileSuffix(file);
+ if (alpha && (fileSuffix.equals("jpg") || fileSuffix.equals("jpeg"))) {
+ // JPEGs can't deal properly with alpha channels
+ alpha = false;
+ }
+
+ BufferedImage image = readToBufferedImage(x, y, width, height, alpha);
+ if (!ImageIO.write(image, fileSuffix, file)) {
+ throw new IOException("Unsupported file format " + fileSuffix);
+ }
+ }
+
+ private static int glGetInteger(GL2 gl, int pname, int[] tmp) {
+ gl.glGetIntegerv(pname, tmp, 0);
+ return tmp[0];
+ }
+
+ private static void checkExtABGR() {
+ GL2 gl = GLUgl2.getCurrentGL2();
+ if (!gl.isExtensionAvailable("GL_EXT_abgr")) {
+ throw new IllegalArgumentException("Saving alpha channel requires GL_EXT_abgr");
+ }
+ }
+
+ static class PixelStorageModes {
+ int packAlignment;
+ int packRowLength;
+ int packSkipRows;
+ int packSkipPixels;
+ int packSwapBytes;
+ int[] tmp = new int[1];
+
+ void save(GL2 gl) {
+ packAlignment = glGetInteger(gl, GL2.GL_PACK_ALIGNMENT, tmp);
+ packRowLength = glGetInteger(gl, GL2.GL_PACK_ROW_LENGTH, tmp);
+ packSkipRows = glGetInteger(gl, GL2.GL_PACK_SKIP_ROWS, tmp);
+ packSkipPixels = glGetInteger(gl, GL2.GL_PACK_SKIP_PIXELS, tmp);
+ packSwapBytes = glGetInteger(gl, GL2.GL_PACK_SWAP_BYTES, tmp);
+
+ gl.glPixelStorei(GL2.GL_PACK_ALIGNMENT, 1);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, 0);
+ }
+
+ void restore(GL2 gl) {
+ gl.glPixelStorei(GL2.GL_PACK_ALIGNMENT, packAlignment);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, packRowLength);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, packSkipRows);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, packSkipPixels);
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, packSwapBytes);
+ }
+ }
+}