diff options
author | Sven Gothel <[email protected]> | 2013-10-02 01:12:20 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-10-02 01:12:20 +0200 |
commit | 543c8649f43fdc43028075d7472ad553299271bf (patch) | |
tree | 01f0d9e2d94e4a9277c3318b9188fcd95b5f851d /src/jogl/classes/com/jogamp | |
parent | 00062e490f0b0cc2944a2167f2f00149c8ba352e (diff) |
GLJPanel/AWTGLPixelBuffer: Reused BufferedImage didn't account for row-stride (regression of b33bdf41cf53f37203643a8551bf5d94b42a8fab)
SingleAWTGLPixelBufferProvider w/ allowing row-stride reuses the AWTGLPixelBuffer and it's BufferedImage
even w/ different width.
This leads to distortion if using the BufferedImage unhandled.
GLJPanel also set GL_PACK_ROW_LENGTH to pixelBuffer.width, which leads to an 'out-of-bounds'
exception if ReadPixels is used w/ panelwidth and panelHeight.
++
Introduce AWTGLPixelBuffer.getAlignedImage(width, height) which returns an aligned
BufferedImage while reusing the DataBuffer.
GLJPanel fetches a new alignedImage if required.
This allows a more efficient single buffer usage as intended, w/o the need of copying data.
Diffstat (limited to 'src/jogl/classes/com/jogamp')
-rw-r--r-- | src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java | 39 |
1 files changed, 38 insertions, 1 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 index 1f5bb6acc..9d2ef6572 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java @@ -28,7 +28,11 @@ package com.jogamp.opengl.util.awt; import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; +import java.awt.image.SinglePixelPackedSampleModel; +import java.awt.image.WritableRaster; import java.nio.Buffer; import java.nio.IntBuffer; @@ -36,7 +40,6 @@ import javax.media.opengl.GL; 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 @@ -51,6 +54,10 @@ import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; * <p> * See {@link AWTGLPixelBuffer#requiresNewBuffer(GL, int, int, int)} for {@link #allowRowStride} details. * </p> + * <p> + * If using <code>allowRowStride == true</code>, user may needs to get the {@link #getAlignedImage(int, int) aligned image} + * since {@link #requiresNewBuffer(GL, int, int, int)} will allow different width in this case. + * </p> */ public class AWTGLPixelBuffer extends GLPixelBuffer { public static final GLPixelAttributes awtPixelAttributesIntRGBA4 = new GLPixelAttributes(4, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE); @@ -60,6 +67,7 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { public final BufferedImage image; /** + * * @param pixelAttributes the desired {@link GLPixelAttributes} * @param width in pixels * @param height in pixels @@ -68,6 +76,7 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { * @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)}. + * If <code>true</code>, user shall decide whether to use a {@link #getAlignedImage(int, int) width-aligned image}. */ public AWTGLPixelBuffer(GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, BufferedImage image, Buffer buffer, boolean allowRowStride) { @@ -81,6 +90,33 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { super.dispose(); } + /** + * Returns a width- and height-aligned image representation sharing data w/ {@link #image}. + * @param width + * @param height + * @return + * @throws IllegalArgumentException if requested size exceeds image size + */ + public BufferedImage getAlignedImage(int width, int height) throws IllegalArgumentException { + if( width * height > image.getWidth() * image.getHeight() ) { + throw new IllegalArgumentException("Requested size exceeds image size: "+width+"x"+height+" > "+image.getWidth()+"x"+image.getHeight()); + } + if( width == image.getWidth() ) { + if( height == image.getHeight() ) { + return image; + } + return image.getSubimage(0, 0, width, height); + } + final ColorModel cm = image.getColorModel(); + final WritableRaster raster = image.getRaster(); + final DataBuffer dataBuffer = raster.getDataBuffer(); + final SinglePixelPackedSampleModel sppsm0 = (SinglePixelPackedSampleModel) raster.getSampleModel(); + final SinglePixelPackedSampleModel sppsm1 = new SinglePixelPackedSampleModel(dataBuffer.getDataType(), + width, height, width /* scanLineStride */, sppsm0.getBitMasks()); + final WritableRaster raster1 = WritableRaster.createWritableRaster(sppsm1, dataBuffer, null); + return new BufferedImage (cm, raster1, cm.isAlphaPremultiplied(), null); + } + public StringBuilder toString(StringBuilder 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("]"); @@ -99,6 +135,7 @@ public class AWTGLPixelBuffer extends GLPixelBuffer { /** * @param allowRowStride If <code>true</code>, allow row-stride, otherwise not. * See {@link #getAllowRowStride()} and {@link AWTGLPixelBuffer#requiresNewBuffer(GL, int, int, int)}. + * If <code>true</code>, user shall decide whether to use a {@link AWTGLPixelBuffer#getAlignedImage(int, int) width-aligned image}. */ public AWTGLPixelBufferProvider(boolean allowRowStride) { this.allowRowStride = allowRowStride; |