diff options
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/util/awt')
7 files changed, 502 insertions, 95 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..a33356067 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLPixelBuffer.java @@ -0,0 +1,248 @@ +/** + * 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.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; + +import javax.media.opengl.GL; + +import com.jogamp.common.nio.Buffers; +import com.jogamp.opengl.util.GLPixelBuffer; + +/** + * 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> + * <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); + public static final GLPixelAttributes awtPixelAttributesIntRGB3 = new GLPixelAttributes(3, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE); + + /** 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)}. + * 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) { + super(pixelAttributes, width, height, depth, pack, buffer, allowRowStride); + this.image = image; + } + + @Override + public void dispose() { + image.flush(); + 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() && height == image.getHeight() ) { + return image; + } else { + final ColorModel cm = image.getColorModel(); + final WritableRaster raster0 = image.getRaster(); + final DataBuffer dataBuffer = raster0.getDataBuffer(); + final SinglePixelPackedSampleModel sppsm0 = (SinglePixelPackedSampleModel) raster0.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 final boolean isDataBufferSource(BufferedImage imageU) { + final DataBuffer dataBuffer0 = image.getRaster().getDataBuffer(); + final DataBuffer dataBufferU = imageU.getRaster().getDataBuffer(); + return dataBufferU == dataBuffer0; + } + + @Override + 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("]"); + return sb; + } + @Override + public String toString() { + return "AWTGLPixelBuffer["+toString(null).toString()+"]"; + } + + /** + * Provider for {@link AWTGLPixelBuffer} instances. + */ + public static class AWTGLPixelBufferProvider implements GLPixelBufferProvider { + private final boolean allowRowStride; + + /** + * @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; + } + @Override + public boolean getAllowRowStride() { return allowRowStride; } + + @Override + public GLPixelAttributes getAttributes(GL gl, int componentCount) { + return 4 == componentCount ? awtPixelAttributesIntRGBA4 : awtPixelAttributesIntRGB3; + } + + /** + * {@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 implements SingletonGLPixelBufferProvider { + private AWTGLPixelBuffer singleRGBA4 = null; + private AWTGLPixelBuffer singleRGB3 = 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( 4 == pixelAttributes.componentCount ) { + if( null == singleRGBA4 || singleRGBA4.requiresNewBuffer(gl, width, height, minByteSize) ) { + singleRGBA4 = allocateImpl(pixelAttributes, width, height, depth, pack, minByteSize); + } + return singleRGBA4; + } else { + if( null == singleRGB3 || singleRGB3.requiresNewBuffer(gl, width, height, minByteSize) ) { + singleRGB3 = allocateImpl(pixelAttributes, width, height, depth, pack, minByteSize); + } + return singleRGB3; + } + } + + 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, getAllowRowStride()); + } + + /** Return the last {@link #allocate(GL, GLPixelAttributes, int, int, int, boolean, int) allocated} {@link AWTGLPixelBuffer} w/ {@link GLPixelAttributes#componentCount}. */ + @Override + public AWTGLPixelBuffer getSingleBuffer(GLPixelAttributes pixelAttributes) { + return 4 == pixelAttributes.componentCount ? singleRGBA4 : singleRGB3; + } + + /** + * 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. + */ + @Override + public AWTGLPixelBuffer initSingleton(int componentCount, int width, int height, int depth, boolean pack) { + if( 4 == componentCount ) { + if( null != singleRGBA4 ) { + return null; + } + singleRGBA4 = allocateImpl(AWTGLPixelBuffer.awtPixelAttributesIntRGBA4, width, height, depth, pack, 0); + return singleRGBA4; + } else { + if( null != singleRGB3 ) { + return null; + } + singleRGB3 = allocateImpl(AWTGLPixelBuffer.awtPixelAttributesIntRGB3, width, height, depth, pack, 0); + return singleRGB3; + } + } + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLReadBufferUtil.java b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLReadBufferUtil.java new file mode 100644 index 000000000..9490e041b --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/AWTGLReadBufferUtil.java @@ -0,0 +1,109 @@ +/** + * 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 javax.media.opengl.GL; +import javax.media.opengl.GLDrawable; +import javax.media.opengl.GLProfile; + +import com.jogamp.opengl.util.GLReadBufferUtil; + +/** + * {@link GLReadBufferUtil} specialization allowing to + * read out a frambuffer to an AWT BufferedImage + * utilizing {@link AWTPixelBufferProviderInt} for further AWT processing. + */ +public class AWTGLReadBufferUtil extends GLReadBufferUtil { + /** + * {@inheritDoc} + * + * @param alpha + */ + public AWTGLReadBufferUtil(GLProfile glp, boolean alpha) { + super(new AWTGLPixelBuffer.AWTGLPixelBufferProvider( glp.isGL2ES3() /* allowRowStride */ ), alpha, false); + } + + public AWTGLPixelBuffer getAWTGLPixelBuffer() { return (AWTGLPixelBuffer)this.getPixelBuffer(); } + + /** + * Read the drawable's pixels to TextureData and Texture, if requested at construction, + * and returns an aligned {@link BufferedImage}. + * + * @param gl the current GL context object. It's read drawable is being used as the pixel source. + * @param awtOrientation flips the data vertically if <code>true</code>. + * The context's drawable {@link GLDrawable#isGLOriented()} state + * is taken into account. + * Vertical flipping is propagated to TextureData + * and handled in a efficient manner there (TextureCoordinates and TextureIO writer). + * @see #AWTGLReadBufferUtil(GLProfile, boolean) + */ + public BufferedImage readPixelsToBufferedImage(GL gl, boolean awtOrientation) { + return readPixelsToBufferedImage(gl, 0, 0, 0, 0, awtOrientation); + } + + /** + * Read the drawable's pixels to TextureData and Texture, if requested at construction, + * and returns an aligned {@link BufferedImage}. + * + * @param gl the current GL context object. It's read drawable is being used as the pixel source. + * @param inX readPixel x offset + * @param inY readPixel y offset + * @param inWidth optional readPixel width value, used if [1 .. drawable.width], otherwise using drawable.width + * @param inHeight optional readPixel height, used if [1 .. drawable.height], otherwise using drawable.height + * @param awtOrientation flips the data vertically if <code>true</code>. + * The context's drawable {@link GLDrawable#isGLOriented()} state + * is taken into account. + * Vertical flipping is propagated to TextureData + * and handled in a efficient manner there (TextureCoordinates and TextureIO writer). + * @see #AWTGLReadBufferUtil(GLProfile, boolean) + */ + public BufferedImage readPixelsToBufferedImage(GL gl, int inX, int inY, int inWidth, int inHeight, boolean awtOrientation) { + final GLDrawable drawable = gl.getContext().getGLReadDrawable(); + final int width, height; + if( 0 >= inWidth || drawable.getWidth() < inWidth ) { + width = drawable.getWidth(); + } else { + width = inWidth; + } + if( 0 >= inHeight || drawable.getHeight() < inHeight ) { + height = drawable.getHeight(); + } else { + height= inHeight; + } + if( readPixelsImpl(drawable, gl, inX, inY, width, height, awtOrientation) ) { + final BufferedImage image = getAWTGLPixelBuffer().getAlignedImage(width, height); + if( getTextureData().getMustFlipVertically() ) { + ImageUtil.flipImageVertically(image); + } + return image; + } + return null; + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/ImageUtil.java b/src/jogl/classes/com/jogamp/opengl/util/awt/ImageUtil.java index a3139b16a..df3cc4a39 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/ImageUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/ImageUtil.java @@ -1,21 +1,21 @@ /* * 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 @@ -28,11 +28,11 @@ * 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. - * + * * Sun gratefully acknowledges that this software was originally authored * and developed by Kenneth Bradley Russell and Christopher John Kline. */ @@ -54,7 +54,7 @@ public class ImageUtil { WritableRaster raster = image.getRaster(); Object scanline1 = null; Object scanline2 = null; - + for (int i = 0; i < image.getHeight() / 2; i++) { scanline1 = raster.getDataElements(0, i, image.getWidth(), 1, scanline1); scanline2 = raster.getDataElements(0, image.getHeight() - i - 1, image.getWidth(), 1, scanline2); @@ -97,21 +97,21 @@ public class ImageUtil { if (thumbWidth > image.getWidth()) { throw new IllegalArgumentException("Thumbnail width must be greater than image width"); } - + if (thumbWidth == image.getWidth()) { return image; } - + float ratio = (float) image.getWidth() / (float) image.getHeight(); int width = image.getWidth(); BufferedImage thumb = image; - + do { width /= 2; if (width < thumbWidth) { width = thumbWidth; } - + BufferedImage temp = createCompatibleImage(width, (int) (width / ratio)); Graphics2D g2 = temp.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, @@ -120,7 +120,7 @@ public class ImageUtil { g2.dispose(); thumb = temp; } while (width != thumbWidth); - + return thumb; } diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/Overlay.java b/src/jogl/classes/com/jogamp/opengl/util/awt/Overlay.java index 73d694cd9..931f59869 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/Overlay.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/Overlay.java @@ -1,21 +1,21 @@ /* * Copyright (c) 2006 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 @@ -28,11 +28,11 @@ * 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. - * + * * Sun gratefully acknowledges that this software was originally authored * and developed by Kenneth Bradley Russell and Christopher John Kline. */ diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java b/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java index fa66673fd..f686b672a 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/Screenshot.java @@ -1,21 +1,22 @@ /* * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. - * + * Copyright (c) 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: - * + * * - 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 @@ -28,7 +29,7 @@ * 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. @@ -43,20 +44,30 @@ import java.io.IOException; import java.nio.ByteBuffer; import javax.imageio.ImageIO; +import javax.media.opengl.GL; import javax.media.opengl.GL2; +import javax.media.opengl.GL2GL3; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawable; import javax.media.opengl.GLException; -import javax.media.opengl.glu.gl2.GLUgl2; import com.jogamp.common.util.IOUtil; +import com.jogamp.opengl.GLExtensions; import com.jogamp.opengl.util.GLPixelStorageModes; import com.jogamp.opengl.util.TGAWriter; -/** Utilities for taking screenshots of OpenGL applications. */ - +/** + * Utilities for taking screenshots of OpenGL applications. + * @deprecated Please consider using {@link com.jogamp.opengl.util.GLReadBufferUtil}, + * which is AWT independent and does not require a CPU based vertical image flip + * in case drawable {@link GLDrawable#isGLOriented() is in OpenGL orientation}. + * Further more you may use {@link AWTGLReadBufferUtil} to read out + * the framebuffer into a BufferedImage for further AWT processing. + */ public class Screenshot { private Screenshot() {} - /** + /** * 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, @@ -83,7 +94,7 @@ public class Screenshot { 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, @@ -111,7 +122,7 @@ public class Screenshot { 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, @@ -148,17 +159,17 @@ public class Screenshot { writer.open(file, width, height, alpha); ByteBuffer bgr = writer.getImageData(); - GL2 gl = GLUgl2.getCurrentGL2(); + GL gl = GLContext.getCurrentGL(); // Set up pixel storage modes GLPixelStorageModes psm = new GLPixelStorageModes(); psm.setPackAlignment(gl, 1); - int readbackType = (alpha ? GL2.GL_ABGR_EXT : GL2.GL_BGR); + int readbackType = (alpha ? GL2.GL_ABGR_EXT : GL2GL3.GL_BGR); // read the BGR values into the image buffer gl.glReadPixels(x, y, width, height, readbackType, - GL2.GL_UNSIGNED_BYTE, bgr); + GL.GL_UNSIGNED_BYTE, bgr); // Restore pixel storage modes psm.restore(gl); @@ -246,7 +257,7 @@ public class Screenshot { 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); + int readbackType = (alpha ? GL2.GL_ABGR_EXT : GL2GL3.GL_BGR); if (alpha) { checkExtABGR(); @@ -255,7 +266,8 @@ public class Screenshot { // Allocate necessary storage BufferedImage image = new BufferedImage(width, height, bufImgType); - GL2 gl = GLUgl2.getCurrentGL2(); + GLContext glc = GLContext.getCurrent(); + GL gl = glc.getGL(); // Set up pixel storage modes GLPixelStorageModes psm = new GLPixelStorageModes(); @@ -263,14 +275,16 @@ public class Screenshot { // read the BGR values into the image gl.glReadPixels(x, y, width, height, readbackType, - GL2.GL_UNSIGNED_BYTE, + GL.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); + if( glc.getGLDrawable().isGLOriented() ) { + // Must flip BufferedImage vertically for correct results + ImageUtil.flipImageVertically(image); + } return image; } @@ -391,9 +405,10 @@ public class Screenshot { } private static void checkExtABGR() { - GL2 gl = GLUgl2.getCurrentGL2(); - if (!gl.isExtensionAvailable("GL_EXT_abgr")) { + GL gl = GLContext.getCurrentGL(); + + if (!gl.isExtensionAvailable(GLExtensions.EXT_abgr)) { throw new IllegalArgumentException("Saving alpha channel requires GL_EXT_abgr"); } - } + } } diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java index 622ee1b79..46dc73003 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java @@ -41,6 +41,7 @@ package com.jogamp.opengl.util.awt; import com.jogamp.common.nio.Buffers; +import com.jogamp.opengl.GLExtensions; import com.jogamp.opengl.util.*; import com.jogamp.opengl.util.packrect.*; import com.jogamp.opengl.util.texture.*; @@ -127,7 +128,12 @@ import jogamp.opengl.Debug; @author Kenneth Russell */ public class TextRenderer { - private static final boolean DEBUG = Debug.isPropertyDefined("jogl.debug.TextRenderer", true); + private static final boolean DEBUG; + + static { + Debug.initSingleton(); + DEBUG = Debug.isPropertyDefined("jogl.debug.TextRenderer", true); + } // These are occasionally useful for more in-depth debugging private static final boolean DISABLE_GLYPH_CACHE = false; @@ -153,20 +159,20 @@ public class TextRenderer { static final int kTotalBufferSizeBytesTex = kTotalBufferSizeCoordsTex * 4; static final int kSizeInBytes_OneVertices_VertexData = kCoordsPerVertVerts * 4; static final int kSizeInBytes_OneVertices_TexData = kCoordsPerVertTex * 4; - private Font font; - private boolean antialiased; - private boolean useFractionalMetrics; + private final Font font; + private final boolean antialiased; + private final boolean useFractionalMetrics; // Whether we're attempting to use automatic mipmap generation support private boolean mipmap; private RectanglePacker packer; private boolean haveMaxSize; - private RenderDelegate renderDelegate; + private final RenderDelegate renderDelegate; private TextureRenderer cachedBackingStore; private Graphics2D cachedGraphics; private FontRenderContext cachedFontRenderContext; - private Map /*<String,Rect>*/ stringLocations = new HashMap /*<String,Rect>*/(); - private GlyphProducer mGlyphProducer; + private final Map<String, Rect> stringLocations = new HashMap<String, Rect>(); + private final GlyphProducer mGlyphProducer; private int numRenderCycles; @@ -194,10 +200,10 @@ public class TextRenderer { // Debugging purposes only private boolean debugged; Pipelined_QuadRenderer mPipelinedQuadRenderer; - + //emzic: added boolean flag private boolean useVertexArrays = true; - + //emzic: added boolean flag private boolean isExtensionAvailable_GL_VERSION_1_5; private boolean checkFor_isExtensionAvailable_GL_VERSION_1_5; @@ -329,9 +335,9 @@ public class TextRenderer { is made to ensure an accurate bound. */ public Rectangle2D getBounds(CharSequence str) { // FIXME: this should be more optimized and use the glyph cache - Rect r = null; + Rect r = stringLocations.get(str); - if ((r = (Rect) stringLocations.get(str)) != null) { + if (r != null) { TextData data = (TextData) r.getUserData(); // Reconstitute the Java 2D results based on the cached values @@ -701,7 +707,7 @@ public class TextRenderer { /** * emzic: here the call to glBindBuffer crashes on certain graphicscard/driver combinations * this is why the ugly try-catch block has been added, which falls back to the old textrenderer - * + * * @param ortho * @throws GLException */ @@ -744,11 +750,12 @@ public class TextRenderer { } private void clearUnusedEntries() { - final java.util.List deadRects = new ArrayList /*<Rect>*/(); + final java.util.List<Rect> deadRects = new ArrayList<Rect>(); // Iterate through the contents of the backing store, removing // text strings that haven't been used recently packer.visit(new RectVisitor() { + @Override public void visit(Rect rect) { TextData data = (TextData) rect.getUserData(); @@ -760,8 +767,7 @@ public class TextRenderer { } }); - for (Iterator iter = deadRects.iterator(); iter.hasNext();) { - Rect r = (Rect) iter.next(); + for (Rect r : deadRects) { packer.remove(r); stringLocations.remove(((TextData) r.getUserData()).string()); @@ -800,9 +806,7 @@ public class TextRenderer { private void internal_draw3D(CharSequence str, float x, float y, float z, float scaleFactor) { - List/*<Glyph>*/ glyphs = mGlyphProducer.getGlyphs(str); - for (Iterator iter = glyphs.iterator(); iter.hasNext(); ) { - Glyph glyph = (Glyph) iter.next(); + for (Glyph glyph : mGlyphProducer.getGlyphs(str)) { float advance = glyph.draw3D(x, y, z, scaleFactor); x += advance * scaleFactor; } @@ -824,7 +828,7 @@ public class TextRenderer { } // Look up the string on the backing store - Rect rect = (Rect) stringLocations.get(curStr); + Rect rect = stringLocations.get(curStr); if (rect == null) { // Rasterize this string and place it on the backing store @@ -885,7 +889,7 @@ public class TextRenderer { data.markUsed(); Rectangle2D origRect = data.origRect(); - + // Align the leftmost point of the baseline to the (x, y, z) coordinate requested renderer.draw3DRect(x - (scaleFactor * data.origOriginX()), y - (scaleFactor * ((float) origRect.getHeight() - data.origOriginY())), z, @@ -901,18 +905,20 @@ public class TextRenderer { private void debug(GL gl) { dbgFrame = new Frame("TextRenderer Debug Output"); - GLCanvas dbgCanvas = new GLCanvas(new GLCapabilities(gl.getGLProfile()), null, - GLContext.getCurrent(), null); + GLCanvas dbgCanvas = new GLCanvas(new GLCapabilities(gl.getGLProfile())); + dbgCanvas.setSharedContext(GLContext.getCurrent()); dbgCanvas.addGLEventListener(new DebugListener(gl, dbgFrame)); dbgFrame.add(dbgCanvas); final FPSAnimator anim = new FPSAnimator(dbgCanvas, 10); dbgFrame.addWindowListener(new WindowAdapter() { + @Override public void windowClosing(WindowEvent e) { // Run this on another thread than the AWT event queue to // make sure the call to Animator.stop() completes before // exiting new Thread(new Runnable() { + @Override public void run() { anim.stop(); } @@ -1003,12 +1009,14 @@ public class TextRenderer { mCurrentIndex = 0; } + @Override public char last() { mCurrentIndex = Math.max(0, mLength - 1); return current(); } + @Override public char current() { if ((mLength == 0) || (mCurrentIndex >= mLength)) { return CharacterIterator.DONE; @@ -1017,36 +1025,43 @@ public class TextRenderer { return mSequence.charAt(mCurrentIndex); } + @Override public char next() { mCurrentIndex++; return current(); } + @Override public char previous() { mCurrentIndex = Math.max(mCurrentIndex - 1, 0); return current(); } + @Override public char setIndex(int position) { mCurrentIndex = position; return current(); } + @Override public int getBeginIndex() { return 0; } + @Override public int getEndIndex() { return mLength; } + @Override public int getIndex() { return mCurrentIndex; } + @Override public Object clone() { CharSequenceIterator iter = new CharSequenceIterator(mSequence); iter.mCurrentIndex = mCurrentIndex; @@ -1054,6 +1069,7 @@ public class TextRenderer { return iter; } + @Override public char first() { if (mLength == 0) { return CharacterIterator.DONE; @@ -1069,7 +1085,7 @@ public class TextRenderer { static class TextData { // Back-pointer to String this TextData describes, if it // represents a String rather than a single glyph - private String str; + private final String str; // If this TextData represents a single glyph, this is its // unicode ID @@ -1080,7 +1096,7 @@ public class TextRenderer { // 2D coordinate system) at which the string must be rasterized in // order to fit within the rectangle -- the leftmost point of the // baseline. - private Point origin; + private final Point origin; // This represents the pre-normalized rectangle, which fits // within the rectangle on the backing store. We keep a @@ -1088,7 +1104,7 @@ public class TextRenderer { // prevent bleeding of adjacent letters when using GL_LINEAR // filtering for rendering. The origin of this rectangle is // equivalent to the origin above. - private Rectangle2D origRect; + private final Rectangle2D origRect; private boolean used; // Whether this text was used recently @@ -1137,6 +1153,7 @@ public class TextRenderer { class Manager implements BackingStoreManager { private Graphics2D g; + @Override public Object allocateBackingStore(int w, int h) { // FIXME: should consider checking Font's attributes to see // whether we're likely to need to support a full RGBA backing @@ -1159,10 +1176,12 @@ public class TextRenderer { return renderer; } + @Override public void deleteBackingStore(Object backingStore) { ((TextureRenderer) backingStore).dispose(); } + @Override public boolean preExpand(Rect cause, int attemptNumber) { // Only try this one time; clear out potentially obsolete entries // NOTE: this heuristic and the fact that it clears the used bit @@ -1198,6 +1217,7 @@ public class TextRenderer { return false; } + @Override public boolean additionFailed(Rect cause, int attemptNumber) { // Heavy hammer -- might consider doing something different packer.clear(); @@ -1216,10 +1236,12 @@ public class TextRenderer { return false; } + @Override public boolean canCompact() { return true; } + @Override public void beginMovement(Object oldBackingStore, Object newBackingStore) { // Exit the begin / end pair if necessary if (inBeginEndPair) { @@ -1253,6 +1275,7 @@ public class TextRenderer { g = newRenderer.createGraphics(); } + @Override public void move(Object oldBackingStore, Rect oldLocation, Object newBackingStore, Rect newLocation) { TextureRenderer oldRenderer = (TextureRenderer) oldBackingStore; @@ -1274,6 +1297,7 @@ public class TextRenderer { } } + @Override public void endMovement(Object oldBackingStore, Object newBackingStore) { g.dispose(); @@ -1310,10 +1334,12 @@ public class TextRenderer { } public static class DefaultRenderDelegate implements RenderDelegate { + @Override public boolean intensityOnly() { return true; } + @Override public Rectangle2D getBounds(CharSequence str, Font font, FontRenderContext frc) { return getBounds(font.createGlyphVector(frc, @@ -1321,20 +1347,24 @@ public class TextRenderer { frc); } + @Override public Rectangle2D getBounds(String str, Font font, FontRenderContext frc) { return getBounds(font.createGlyphVector(frc, str), frc); } + @Override public Rectangle2D getBounds(GlyphVector gv, FontRenderContext frc) { return gv.getVisualBounds(); } + @Override public void drawGlyphVector(Graphics2D graphics, GlyphVector str, int x, int y) { graphics.drawGlyphVector(str, x, y); } + @Override public void draw(Graphics2D graphics, String str, int x, int y) { graphics.drawString(str, x, y); } @@ -1345,7 +1375,7 @@ public class TextRenderer { // // A temporary to prevent excessive garbage creation - private char[] singleUnicode = new char[1]; + private final char[] singleUnicode = new char[1]; /** A Glyph represents either a single unicode glyph or a substring of characters to be drawn. The reason for the dual @@ -1467,10 +1497,10 @@ public class TextRenderer { int width = (int) origRect.getWidth(); int height = (int) origRect.getHeight(); - float tx1 = xScale * (float) texturex / (float) renderer.getWidth(); + float tx1 = xScale * texturex / renderer.getWidth(); float ty1 = yScale * (1.0f - ((float) texturey / (float) renderer.getHeight())); - float tx2 = xScale * (float) (texturex + width) / (float) renderer.getWidth(); + float tx2 = xScale * (texturex + width) / renderer.getWidth(); float ty2 = yScale * (1.0f - ((float) (texturey + height) / (float) renderer.getHeight())); @@ -1555,9 +1585,9 @@ public class TextRenderer { class GlyphProducer { final int undefined = -2; FontRenderContext fontRenderContext; - List/*<Glyph>*/ glyphsOutput = new ArrayList/*<Glyph>*/(); - HashMap/*<String, GlyphVector>*/fullGlyphVectorCache = new HashMap/*<String, GlyphVector>*/(); - HashMap/*<Character, GlyphMetrics>*/glyphMetricsCache = new HashMap/*<Character, GlyphMetrics>*/(); + List<Glyph> glyphsOutput = new ArrayList<Glyph>(); + HashMap<String, GlyphVector> fullGlyphVectorCache = new HashMap<String, GlyphVector>(); + HashMap<Character, GlyphMetrics> glyphMetricsCache = new HashMap<Character, GlyphMetrics>(); // The mapping from unicode character to font-specific glyph ID int[] unicodes2Glyphs; // The mapping from glyph ID to Glyph @@ -1571,10 +1601,10 @@ public class TextRenderer { clearAllCacheEntries(); } - public List/*<Glyph>*/ getGlyphs(CharSequence inString) { + public List<Glyph> getGlyphs(CharSequence inString) { glyphsOutput.clear(); GlyphVector fullRunGlyphVector; - fullRunGlyphVector = (GlyphVector) fullGlyphVectorCache.get(inString.toString()); + fullRunGlyphVector = fullGlyphVectorCache.get(inString.toString()); if (fullRunGlyphVector == null) { iter.initFromCharSequence(inString); fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(), iter); @@ -1591,7 +1621,7 @@ public class TextRenderer { int i = 0; while (i < lengthInGlyphs) { Character letter = CharacterCache.valueOf(inString.charAt(i)); - GlyphMetrics metrics = (GlyphMetrics) glyphMetricsCache.get(letter); + GlyphMetrics metrics = glyphMetricsCache.get(letter); if (metrics == null) { metrics = fullRunGlyphVector.getGlyphMetrics(i); glyphMetricsCache.put(letter, metrics); @@ -1709,7 +1739,7 @@ public class TextRenderer { return glyph; } } - + private static class CharacterCache { private CharacterCache() { } @@ -1799,7 +1829,7 @@ public class TextRenderer { GL2 gl = GLContext.getCurrentGL().getGL2(); TextureRenderer renderer = getBackingStore(); - Texture texture = renderer.getTexture(); // triggers texture uploads. Maybe this should be more obvious? + renderer.getTexture(); // triggers texture uploads. Maybe this should be more obvious? mVertCoords.rewind(); mTexCoords.rewind(); @@ -1842,7 +1872,7 @@ public class TextRenderer { private void drawIMMEDIATE() { if (mOutstandingGlyphsVerticesPipeline > 0) { TextureRenderer renderer = getBackingStore(); - Texture texture = renderer.getTexture(); // triggers texture uploads. Maybe this should be more obvious? + renderer.getTexture(); // triggers texture uploads. Maybe this should be more obvious? GL2 gl = GLContext.getCurrentGL().getGL2(); gl.glBegin(GL2.GL_QUADS); @@ -1890,6 +1920,7 @@ public class TextRenderer { this.frame = frame; } + @Override public void display(GLAutoDrawable drawable) { GL2 gl = GLContext.getCurrentGL().getGL2(); gl.glClear(GL2.GL_DEPTH_BUFFER_BIT | GL2.GL_COLOR_BUFFER_BIT); @@ -1907,6 +1938,7 @@ public class TextRenderer { if ((frame.getWidth() != w) || (frame.getHeight() != h)) { EventQueue.invokeLater(new Runnable() { + @Override public void run() { frame.setSize(w, h); } @@ -1914,6 +1946,7 @@ public class TextRenderer { } } + @Override public void dispose(GLAutoDrawable drawable) { glu.destroy(); glu=null; @@ -1921,9 +1954,11 @@ public class TextRenderer { } // Unused methods + @Override public void init(GLAutoDrawable drawable) { } + @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { } @@ -1976,7 +2011,7 @@ public class TextRenderer { private final boolean is15Available(GL gl) { if (!checkFor_isExtensionAvailable_GL_VERSION_1_5) { - isExtensionAvailable_GL_VERSION_1_5 = gl.isExtensionAvailable("GL_VERSION_1_5"); + isExtensionAvailable_GL_VERSION_1_5 = gl.isExtensionAvailable(GLExtensions.VERSION_1_5); checkFor_isExtensionAvailable_GL_VERSION_1_5 = true; } return isExtensionAvailable_GL_VERSION_1_5; diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java index 922fc69c1..26e1eb041 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java @@ -1,22 +1,22 @@ /* * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * Copyright (c) 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: - * + * * - 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 @@ -29,11 +29,11 @@ * 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. - * + * * Sun gratefully acknowledges that this software was originally authored * and developed by Kenneth Bradley Russell and Christopher John Kline. */ @@ -407,7 +407,7 @@ public class TextureRenderer { this.a = a; gl.glColor4f(this.r, this.g, this.b, this.a); - } + } private float[] compArray; /** Changes the current color of this TextureRenderer to the @@ -437,7 +437,7 @@ public class TextureRenderer { @param screenx the on-screen x coordinate at which to draw the rectangle @param screeny the on-screen y coordinate (relative to lower left) at which to draw the rectangle - + @throws GLException If an OpenGL context is not current when this method is called */ public void drawOrthoRect(int screenx, int screeny) throws GLException { @@ -459,7 +459,7 @@ public class TextureRenderer { rectangle to draw @param width the width of the rectangle to draw @param height the height of the rectangle to draw - + @throws GLException If an OpenGL context is not current when this method is called */ public void drawOrthoRect(int screenx, int screeny, @@ -490,7 +490,7 @@ public class TextureRenderer { @param height the height in texels of the rectangle to draw @param scaleFactor the scale factor to apply (multiplicatively) to the size of the drawn rectangle - + @throws GLException If an OpenGL context is not current when this method is called */ public void draw3DRect(float x, float y, float z, @@ -518,7 +518,7 @@ public class TextureRenderer { OpenGL texture to the screen, if the application intends to draw them as a flat overlay on to the screen. Must be used if {@link #beginOrthoRendering} is used to set up the rendering stage for - this overlay. + this overlay. @throws GLException If an OpenGL context is not current when this method is called */ @@ -552,7 +552,7 @@ public class TextureRenderer { private void beginRendering(boolean ortho, int width, int height, boolean disableDepthTestForOrtho) { GL2 gl = GLContext.getCurrentGL().getGL2(); - int attribBits = + int attribBits = GL2.GL_ENABLE_BIT | GL2.GL_TEXTURE_BIT | GL2.GL_COLOR_BUFFER_BIT | (ortho ? (GL2.GL_DEPTH_BUFFER_BIT | GL2.GL_TRANSFORM_BIT) : 0); gl.glPushAttrib(attribBits); @@ -622,7 +622,7 @@ public class TextureRenderer { // Infer the internal format if not an intensity texture int internalFormat = (intensity ? GL2.GL_INTENSITY : 0); - int imageType = + int imageType = (intensity ? BufferedImage.TYPE_BYTE_GRAY : (alpha ? BufferedImage.TYPE_INT_ARGB_PRE : BufferedImage.TYPE_INT_RGB)); image = new BufferedImage(width, height, imageType); |