aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-06-07 18:28:22 +0200
committerSven Gothel <[email protected]>2011-06-07 18:28:22 +0200
commitcf36398314270c2c50d55b23736e5bff8b62337d (patch)
tree53b85ce3c10a4a7a840702902a1cc4c0894a3821 /src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
parentced1a4c644483ad5bfd28ca2bb6a5ffc030b9f1d (diff)
Using GlueGen IOUtil (dropped StreamUtil, FileUtil); Public GLReadBufferUtil (screenshot etc) and GLPixelStorageModes
- Using GlueGen IOUtil, dropping StreamUtil and FileUtil - Public (util) GLReadBufferUtil for screenshots and slow r2t (AWT less), as well as GLPixelStorageModes
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
new file mode 100644
index 000000000..e5cf7d0d0
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java
@@ -0,0 +1,181 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.util;
+
+import com.jogamp.common.nio.Buffers;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.*;
+import javax.media.opengl.*;
+
+import com.jogamp.opengl.util.texture.Texture;
+import com.jogamp.opengl.util.texture.TextureData;
+import com.jogamp.opengl.util.texture.TextureIO;
+
+/**
+ * Utility to read out the current FB to TextureData, optionally writing the data back to a texture object.
+ * <p>May be used directly to write the TextureData to file (screenshot).</p>
+ */
+public class GLReadBufferUtil {
+ protected final int components, alignment;
+ protected final Texture readTexture;
+ protected final GLPixelStorageModes psm;
+
+ protected int readPixelSizeLast = 0;
+ protected ByteBuffer readPixelBuffer = null;
+ protected TextureData readTextureData = null;
+
+ /**
+ * @param alpha true for RGBA readPixels, otherwise RGB readPixels
+ * @param write2Texture true if readPixel's TextureData shall be written to a 2d Texture
+ */
+ public GLReadBufferUtil(boolean alpha, boolean write2Texture) {
+ components = alpha ? 4 : 3 ;
+ alignment = alpha ? 4 : 1 ;
+ readTexture = write2Texture ? new Texture(GL.GL_TEXTURE_2D) : null ;
+ psm = new GLPixelStorageModes();
+ }
+
+ public boolean isValid() {
+ return null!=readTextureData && null!=readPixelBuffer ;
+ }
+
+ /**
+ * @return the raw pixel ByteBuffer, filled by {@link #readPixels(GLAutoDrawable, boolean)}
+ */
+ public ByteBuffer getPixelBuffer() { return readPixelBuffer; }
+
+ /**
+ * rewind the raw pixel ByteBuffer
+ */
+ public void rewindPixelBuffer() { if( null != readPixelBuffer ) { readPixelBuffer.rewind(); } }
+
+ /**
+ * @return the resulting TextureData, filled by {@link #readPixels(GLAutoDrawable, boolean)}
+ */
+ public TextureData getTextureData() { return readTextureData; }
+
+ /**
+ * @return the Texture object filled by {@link #readPixels(GLAutoDrawable, boolean)},
+ * if this instance writes to a 2d Texture, otherwise null.
+ * @see #GLReadBufferUtil(boolean, boolean)
+ */
+ public Texture getTexture() { return readTexture; }
+
+ /**
+ * Write the TextureData filled by {@link #readPixels(GLAutoDrawable, boolean)} to file
+ */
+ public void write(File dest) {
+ try {
+ TextureIO.write(readTextureData, dest);
+ rewindPixelBuffer();
+ } catch (IOException ex) {
+ throw new RuntimeException("can not write to file: " + dest.getAbsolutePath(), ex);
+ }
+ }
+
+ /**
+ * Read the drawable's pixels to TextureData and Texture, if requested at construction
+ *
+ * @param gl the current GL object
+ * @param drawable the drawable to read from
+ * @param flip weather to flip the data vertically or not
+ *
+ * @see #GLReadBufferUtil(boolean, boolean)
+ */
+ public void readPixels(GL gl, GLDrawable drawable, boolean flip) {
+ final int textureInternalFormat, textureDataFormat;
+ final int textureDataType = GL.GL_UNSIGNED_BYTE;
+ if(4 == components) {
+ textureInternalFormat=GL.GL_RGBA;
+ textureDataFormat=GL.GL_RGBA;
+ } else {
+ textureInternalFormat=GL.GL_RGB;
+ textureDataFormat=GL.GL_RGB;
+ }
+ final int readPixelSize = drawable.getWidth() * drawable.getHeight() * components ;
+ boolean newData = false;
+ if(readPixelSize>readPixelSizeLast) {
+ readPixelBuffer = Buffers.newDirectByteBuffer(readPixelSize);
+ readPixelSizeLast = readPixelSize ;
+ try {
+ readTextureData = new TextureData(
+ gl.getGLProfile(),
+ textureInternalFormat,
+ drawable.getWidth(), drawable.getHeight(),
+ 0,
+ textureDataFormat,
+ textureDataType,
+ false, false,
+ flip,
+ readPixelBuffer,
+ null /* Flusher */);
+ newData = true;
+ } catch (Exception e) {
+ readTextureData = null;
+ readPixelBuffer = null;
+ readPixelSizeLast = 0;
+ throw new RuntimeException("can not fetch offscreen texture", e);
+ }
+ }
+ if(null!=readPixelBuffer) {
+ psm.setAlignment(gl, alignment, alignment);
+ readPixelBuffer.clear();
+ gl.glReadPixels(0, 0, drawable.getWidth(), drawable.getHeight(), textureDataFormat, textureDataType, readPixelBuffer);
+ readPixelBuffer.rewind();
+ if(null != readTexture) {
+ if(newData) {
+ readTexture.updateImage(gl, readTextureData);
+ } else {
+ readTexture.updateSubImage(gl, readTextureData, 0,
+ 0, 0, // src offset
+ 0, 0, // dst offset
+ drawable.getWidth(), drawable.getHeight());
+ }
+ readPixelBuffer.rewind();
+ }
+ psm.restore(gl);
+ }
+ }
+
+ public void dispose(GL gl) {
+ if(null != readTexture) {
+ readTexture.destroy(gl);
+ readTextureData = null;
+ }
+ if(null != readPixelBuffer) {
+ readPixelBuffer.clear();
+ readPixelBuffer = null;
+ }
+ readPixelSizeLast = 0;
+ }
+
+}
+