diff options
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/util/awt')
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java | 203 | ||||
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLReadBufferUtil.java | 25 |
2 files changed, 209 insertions, 19 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java new file mode 100644 index 000000000..2af48cefd --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java @@ -0,0 +1,203 @@ +/** + * Copyright 2013 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.awt; + +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; +import java.nio.Buffer; +import java.nio.IntBuffer; + +import javax.media.opengl.GL; +import javax.media.opengl.GL2GL3; + +import com.jogamp.common.nio.Buffers; +import com.jogamp.opengl.util.GLPixelBuffer; +import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; + +/** + * AWT {@link GLPixelBuffer} backed by an {@link BufferedImage} of type + * {@link BufferedImage#TYPE_INT_ARGB} or {@link BufferedImage#TYPE_INT_RGB}. + * <p> + * Implementation uses an array backed {@link IntBuffer}. + * </p> + * <p> + * {@link AWTGLPixelBuffer} can be produced via {@link AWTGLPixelBufferProvider}'s + * {@link AWTGLPixelBufferProvider#allocate(GL, GLPixelAttributes, int, int, int, boolean, int) allocate(..)}. + * </p> + * <p> + * See {@link AWTGLPixelBuffer#requiresNewBuffer(GL, int, int, int)} for {@link #allowRowStride} details. + * </p> + */ +public class AWTGLPixelBuffer extends GLPixelBuffer { + public static final GLPixelAttributes awtPixelAttributesIntRGB = new GLPixelAttributes(GL.GL_BGRA, GL.GL_UNSIGNED_BYTE); + + /** Allow {@link GL2GL3#GL_PACK_ROW_LENGTH}, or {@link GL2GL3#GL_UNPACK_ROW_LENGTH}. See {@link #requiresNewBuffer(GL, int, int, int)}. */ + public final boolean allowRowStride; + /** The underlying {@link BufferedImage}. */ + public final BufferedImage image; + + /** + * @param pixelAttributes the desired {@link GLPixelAttributes} + * @param width in pixels + * @param height in pixels + * @param depth in pixels + * @param pack true for read mode GPU -> CPU, otherwise false for write mode CPU -> GPU + * @param image the AWT image + * @param buffer the backing array + * @param allowRowStride If <code>true</code>, allow row-stride, otherwise not. See {@link #requiresNewBuffer(GL, int, int, int)}. + */ + public AWTGLPixelBuffer(GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, BufferedImage image, + Buffer buffer, boolean allowRowStride) { + super(pixelAttributes, width, height, depth, pack, buffer); + this.allowRowStride = allowRowStride; + this.image = image; + } + + /** + * {@inheritDoc} + * <p> + * If <code>{@link #allowRowStride} = false</code>, + * method returns <code>true</code> if the new size ≠ current size. + * </p> + * <p> + * If <code>{@link #allowRowStride} = true</code>, see {@link AWTGLPixelBufferProvider#AWTGLPixelBufferProvider(boolean)}, + * method returns <code>true</code> only if the new size > current size. Assuming user utilizes the row-stride + * when dealing w/ the data, i.e. {@link GL2GL3#GL_PACK_ROW_LENGTH}. + * </p> + */ + @Override + public boolean requiresNewBuffer(GL gl, int newWidth, int newHeight, int minByteSize) { + if( allowRowStride && gl.isGL2GL3() ) { + return width < newWidth || height < newHeight; + } else { + return width != newWidth || height != newHeight; + } + } + + @Override + public void dispose() { + image.flush(); + super.dispose(); + } + + public StringBuffer toString(StringBuffer sb) { + sb = super.toString(sb); + sb.append(", allowRowStride ").append(allowRowStride).append(", image [").append(image.getWidth()).append("x").append(image.getHeight()).append(", ").append(image.toString()).append("]"); + return sb; + } + public String toString() { + return "AWTGLPixelBuffer["+toString(null).toString()+"]"; + } + + /** + * Provider for {@link AWTGLPixelBuffer} instances. + */ + public static class AWTGLPixelBufferProvider implements GLPixelBufferProvider { + /** Allow {@link GL2GL3#GL_PACK_ROW_LENGTH}, or {@link GL2GL3#GL_UNPACK_ROW_LENGTH}. */ + public final boolean allowRowStride; + + /** + * @param allowRowStride If <code>true</code>, allow row-stride, otherwise not. See {@link AWTGLPixelBuffer#requiresNewBuffer(GL, int, int, int)}. + */ + public AWTGLPixelBufferProvider(boolean allowRowStride) { + this.allowRowStride = allowRowStride; + } + @Override + public GLPixelAttributes getAttributes(GL gl, int componentCount) { + return awtPixelAttributesIntRGB; + } + + /** + * {@inheritDoc} + * <p> + * Returns an array backed {@link IntBuffer} of size <pre>width*height*{@link Buffers#SIZEOF_INT SIZEOF_INT}</code>. + * </p> + */ + @Override + public AWTGLPixelBuffer allocate(GL gl, GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, int minByteSize) { + final BufferedImage image = new BufferedImage(width, height, 4 == pixelAttributes.componentCount ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB); + final int[] readBackIntBuffer = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); + final Buffer ibuffer = IntBuffer.wrap( readBackIntBuffer ); + return new AWTGLPixelBuffer(pixelAttributes, width, height, depth, pack, image, ibuffer, allowRowStride); + } + } + + /** + * Provider for singleton {@link AWTGLPixelBuffer} instances. + * <p> + * Provider instance holds the last {@link AWTGLPixelBuffer} instance + * {@link #allocate(GL, GLPixelAttributes, int, int, int, boolean, int) allocated}. + * A new {@link #allocate(GL, GLPixelAttributes, int, int, int, boolean, int) allocation} + * will return same instance, if a new buffer is not {@link AWTGLPixelBuffer#requiresNewBuffer(GL, int, int, int) required}. + * The latter is true if size are compatible, hence <code>allowRowStride</code> should be enabled, if possible. + * </p> + */ + public static class SingleAWTGLPixelBufferProvider extends AWTGLPixelBufferProvider { + private AWTGLPixelBuffer single = null; + + /** + * @param allowRowStride If <code>true</code>, allow row-stride, otherwise not. See {@link AWTGLPixelBuffer#requiresNewBuffer(GL, int, int, int)}. + */ + public SingleAWTGLPixelBufferProvider(boolean allowRowStride) { + super(allowRowStride); + } + + /** + * {@inheritDoc} + * <p> + * Returns an array backed {@link IntBuffer} of size <pre>width*height*{@link Buffers#SIZEOF_INT SIZEOF_INT}</code>. + * </p> + */ + @Override + public AWTGLPixelBuffer allocate(GL gl, GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, int minByteSize) { + if( null == single || single.requiresNewBuffer(gl, width, height, minByteSize) ) { + single = allocateImpl(pixelAttributes, width, height, depth, pack, minByteSize); + } + return single; + } + + private AWTGLPixelBuffer allocateImpl(GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, int minByteSize) { + final BufferedImage image = new BufferedImage(width, height, 4 == pixelAttributes.componentCount ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB); + final int[] readBackIntBuffer = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); + final Buffer ibuffer = IntBuffer.wrap( readBackIntBuffer ); + return new AWTGLPixelBuffer(pixelAttributes, width, height, depth, pack, image, ibuffer, allowRowStride); + } + + /** + * Initializes the single {@link AWTGLPixelBuffer} w/ a given size, if not yet {@link #allocate(GL, GLPixelAttributes, int, int, int, boolean, int) allocated}. + * @return the newly initialized single {@link AWTGLPixelBuffer}, or null if already allocated. + */ + public AWTGLPixelBuffer initSingleton(int width, int height, int depth, boolean pack) { + if( null != single ) { + return null; + } + single = allocateImpl(AWTGLPixelBuffer.awtPixelAttributesIntRGB, width, height, depth, pack, 0); + return single; + } + } +}
\ No newline at end of file diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLReadBufferUtil.java b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLReadBufferUtil.java index f26fec0d5..0edd53ca1 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLReadBufferUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLReadBufferUtil.java @@ -28,14 +28,11 @@ package com.jogamp.opengl.util.awt; import java.awt.image.BufferedImage; -import java.nio.Buffer; -import java.nio.IntBuffer; import javax.media.opengl.GL; -import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLProfile; import com.jogamp.opengl.util.GLReadBufferUtil; -import com.jogamp.opengl.util.texture.awt.AWTTextureData.AWTPixelBufferProviderInt; /** * {@link GLReadBufferUtil} specialization allowing to @@ -48,25 +45,15 @@ public class AWTGLReadBufferUtil extends GLReadBufferUtil { * * @param alpha */ - public AWTGLReadBufferUtil(boolean alpha) { - super(new AWTPixelBufferProviderInt(), alpha, false); + public AWTGLReadBufferUtil(GLProfile glp, boolean alpha) { + super(new AWTGLPixelBuffer.AWTGLPixelBufferProvider( glp.isGL2GL3() /* allowRowStride */ ), alpha, false); } - /** - * Returns the raw pixel Buffer, filled by {@link #readPixels(GLAutoDrawable, boolean)}. - * <p> - * Due to using {@link AWTPixelBufferProviderInt#allocate(int, int, int)}, - * returns an {@link IntBuffer} instance. - * </p> - */ - @Override - public Buffer getPixelBuffer() { return readPixelBuffer; } - - public BufferedImage getImage() { return ((AWTPixelBufferProviderInt)pixelBufferProvider).getImage(); } + public AWTGLPixelBuffer getAWTGLPixelBuffer() { return (AWTGLPixelBuffer)this.getPixelBuffer(); } public BufferedImage readPixelsToBufferedImage(GL gl, boolean awtOrientation) { if( readPixels(gl, awtOrientation) ) { - final BufferedImage image = getImage(); + final BufferedImage image = getAWTGLPixelBuffer().image; if( getTextureData().getMustFlipVertically() ) { ImageUtil.flipImageVertically(image); } @@ -78,7 +65,7 @@ public class AWTGLReadBufferUtil extends GLReadBufferUtil { final int[] ioWidth = new int[] { inWidth }; final int[] ioHeight= new int[] { inHeight }; if( readPixels(gl, inX, inY, ioWidth, ioHeight, awtOrientation) ) { - final BufferedImage image = getImage(); + final BufferedImage image = getAWTGLPixelBuffer().image; if( getTextureData().getMustFlipVertically() ) { ImageUtil.flipImageVertically(image); } |