diff options
author | Sven Gothel <[email protected]> | 2013-05-08 22:57:17 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-05-08 22:57:17 +0200 |
commit | 0a7bf77b8c0765f8a53dc72a8edab8e0496938ff (patch) | |
tree | f7a02fad5afda28ea58f70c9fbb00edfcc2f49e9 /src/jogl/classes/com/jogamp/opengl | |
parent | e6a234edb1318bb38f6ab65d96518471d0c7fd68 (diff) |
Refactor: TextureData's PixelAttributes/PixelBufferProvider -> GLPixelBuffer/.. and enhance usage; GLJPanel: Use GLPixelBuffer* API and SingleAWTGLPixelBufferProvider if possible.
Refactor: TextureData's PixelAttributes/PixelBufferProvider -> GLPixelBuffer/.. and enhance usage
- GLPixelBuffer, GLPixelAttributes and GLPixelBufferProvider have potential for wider audience,
hence extract them to package 'com.jogamp.opengl.util'.
- Using GLPixelBuffer, shall attempt to use pack/unpack row-stride, i.e.
GL2GL3.GL_PACK_ROW_LENGTH, or GL2GL3.GL_UNPACK_ROW_LENGTH.
See GLReadBufferUtil and GLJPanel
- AWTGLPixelBuffer*: Attribute 'row-stride' allows reusing a bigger buffer than requested.
GLJPanel: Use GLPixelBuffer* API and SingleAWTGLPixelBufferProvider if possible.
- Use GLPixelBuffer API to remove redundancies
- Attempts to use SingleAWTGLPixelBufferProvider to save JVM/CPU heap space
for BuffereImage and IntBbuffer (readBack)
Added unit new test demonstrating multiple overlapping GLJPanels reusing (or not)
a singlton SingleAWTGLPixelBufferProvider.
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl')
6 files changed, 525 insertions, 231 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java new file mode 100644 index 000000000..b2e0af2b5 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/util/GLPixelBuffer.java @@ -0,0 +1,253 @@ +/** + * 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; + +import java.nio.Buffer; +import java.nio.ByteBuffer; + +import javax.media.opengl.GL; +import javax.media.opengl.GLContext; + +import com.jogamp.common.nio.Buffers; +import com.jogamp.opengl.util.texture.TextureData; + +/** + * OpenGL pixel data buffer, allowing user to provide buffers via their {@link GLPixelBufferProvider} implementation. + * <p> + * {@link GLPixelBufferProvider} produces a {@link GLPixelBuffer}. + * </p> + * <p> + * You may use {@link #defaultProvider}. + * </p> + */ +public class GLPixelBuffer { + + /** Allows user to interface with another toolkit to define {@link GLPixelAttributes} and memory buffer to produce {@link TextureData}. */ + public static interface GLPixelBufferProvider { + /** Called first to determine {@link GLPixelAttributes}. */ + GLPixelAttributes getAttributes(GL gl, int componentCount); + + /** + * Allocates a new {@link GLPixelBuffer} object. + * <p> + * Being called to gather the initial {@link GLPixelBuffer}, + * or a new replacement {@link GLPixelBuffer} if {@link GLPixelBuffer#requiresNewBuffer(GL, int, int, int)}. + * </p> + * <p> + * The minimum required {@link Buffer#remaining() remaining} byte size equals to <code>minByteSize</code>, if > 0, + * otherwise utilize {@link GLBuffers#sizeof(GL, int[], int, int, int, int, int, boolean)} + * to calculate it. + * </p> + * + * @param gl the corresponding current GL context object + * @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 minByteSize if > 0, the pre-calculated minimum byte-size for the resulting buffer, otherwise ignore. + */ + GLPixelBuffer allocate(GL gl, GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, int minByteSize); + } + /** + * Default {@link GLPixelBufferProvider} utilizing best match for {@link GLPixelAttributes} + * and {@link GLPixelBufferProvider#allocate(GL, GLPixelAttributes, int, int, int, boolean, int) allocating} a {@link ByteBuffer}. + */ + public static GLPixelBufferProvider defaultProvider = new GLPixelBufferProvider() { + + @Override + public GLPixelAttributes getAttributes(GL gl, int componentCount) { + final GLContext ctx = gl.getContext(); + final int dFormat, dType; + + if(gl.isGL2GL3() && 3 == componentCount) { + dFormat = GL.GL_RGB; + dType = GL.GL_UNSIGNED_BYTE; + } else { + dFormat = ctx.getDefaultPixelDataFormat(); + dType = ctx.getDefaultPixelDataType(); + } + return new GLPixelAttributes(componentCount, dFormat, dType); + } + + /** + * {@inheritDoc} + * <p> + * Returns an NIO {@link ByteBuffer}. + * </p> + */ + @Override + public GLPixelBuffer allocate(GL gl, GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, int minByteSize) { + if( minByteSize > 0 ) { + return new GLPixelBuffer(pixelAttributes, width, height, depth, pack, Buffers.newDirectByteBuffer(minByteSize)); + } else { + int[] tmp = { 0 }; + final int byteSize = GLBuffers.sizeof(gl, tmp, pixelAttributes.bytesPerPixel, width, height, depth, pack); + return new GLPixelBuffer(pixelAttributes, width, height, depth, pack, Buffers.newDirectByteBuffer(byteSize)); + } + } + }; + + /** Pixel attributes. */ + public static class GLPixelAttributes { + /** Undefined instance of {@link GLPixelAttributes}, having componentCount:=0, format:=0 and type:= 0. */ + public static final GLPixelAttributes UNDEF = new GLPixelAttributes(0, 0, 0); + + /** Pixel component count */ + public final int componentCount; + /** The OpenGL pixel data format */ + public final int format; + /** The OpenGL pixel data type */ + public final int type; + /** The OpenGL pixel size in bytes */ + public final int bytesPerPixel; + + /** + * Deriving {@link #componentCount} via GL <code>dataFormat</code>, i.e. {@link GLBuffers#componentCount(int)} if > 0. + * @param dataFormat GL data format + * @param dataType GL data type + */ + public GLPixelAttributes(int dataFormat, int dataType) { + this(0 < dataFormat ? GLBuffers.componentCount(dataFormat) : 0, dataFormat, dataType); + } + /** + * Using user specified source {@link #componentCount}. + * @param componentCount source component count + * @param dataFormat GL data format + * @param dataType GL data type + */ + public GLPixelAttributes(int componentCount, int dataFormat, int dataType) { + this.componentCount = componentCount; + this.format = dataFormat; + this.type = dataType; + this.bytesPerPixel = ( 0 < dataFormat && 0 < dataType ) ? GLBuffers.bytesPerPixel(dataFormat, dataType) : 0; + } + public String toString() { + return "PixelAttributes[comp "+componentCount+", fmt 0x"+Integer.toHexString(format)+", type 0x"+Integer.toHexString(type)+", bytesPerPixel "+bytesPerPixel+"]"; + } + } + + /** The {@link GLPixelAttributes}. */ + public final GLPixelAttributes pixelAttributes; + /** Width in pixels. */ + public final int width; + /** Height in pixels. */ + public final int height; + /** Depth in pixels. */ + public final int depth; + /** Data packing direction. If <code>true</code> for read mode GPU -> CPU, <code>false</code> for write mode CPU -> GPU. */ + public final boolean pack; + /** Byte size of the buffer. Actually the number of {@link Buffer#remaining()} bytes when passed in ctor. */ + public final int byteSize; + /** + * Buffer holding the pixel data. If {@link #rewind()}, it holds <code>byteSize</code> {@link Buffer#remaining()} bytes. + * <p> + * By default the {@link Buffer} is a {@link ByteBuffer}, due to {@link DefProvider#allocate(GL, GLPixelAttributes, int, int, int, boolean, int)}. + * However, other {@link GLPixelBufferProvider} may utilize different {@link Buffer} types. + * </p> + */ + public final Buffer buffer; + /** Buffer element size in bytes. */ + public final int bufferElemSize; + + public StringBuffer toString(StringBuffer sb) { + if(null == sb) { + sb = new StringBuffer(); + } + sb.append(pixelAttributes).append(", dim ").append(width).append("x").append(height).append("x").append(depth).append(", pack ").append(pack) + .append(", buffer[sz [bytes ").append(byteSize).append(", elemSize ").append(bufferElemSize).append(", ").append(buffer).append("]"); + return sb; + } + public String toString() { + return "GLPixelBuffer["+toString(null).toString()+"]"; + } + + public GLPixelBuffer(GLPixelAttributes pixelAttributes, int width, int height, int depth, boolean pack, Buffer buffer) { + this.pixelAttributes = pixelAttributes; + this.width = width; + this.height = height; + this.depth = depth; + this.pack = pack; + this.buffer = buffer; + this.byteSize = Buffers.remainingBytes(buffer); + this.bufferElemSize = Buffers.sizeOfBufferElem(buffer); + } + + public boolean isValid() { + return 0 < byteSize; + } + + public Buffer rewind() { + return buffer.rewind(); + } + + /** Returns the byte position of the {@link #buffer}. */ + public int position() { + return buffer.position() * bufferElemSize; + } + + /** Sets the byte position of the {@link #buffer}. */ + public Buffer position(int bytePos) { + return buffer.position( bytePos / bufferElemSize ); + } + + public Buffer flip() { + return buffer.flip(); + } + + public Buffer clear() { + return buffer.clear(); + } + + /** + * Returns true, if implementation requires a new buffer based on the new size + * due to pixel alignment or byte size, otherwise false. + * <p> + * It is assumed that <code>pixelAttributes</code>, <code>depth</code> and <code>pack</code> stays the same! + * </p> + * <p> + * The minimum required byte size equals to <code>minByteSize</code>, if > 0, + * otherwise utilize {@link GLBuffers#sizeof(GL, int[], int, int, int, int, int, boolean) GLBuffers.sizeof(..)} + * to calculate it. + * </p> + * @param gl the corresponding current GL context object + * @param newWidth new width in pixels + * @param newHeight new height in pixels + * @param minByteSize if > 0, the pre-calculated minimum byte-size for the resulting buffer, otherwise ignore. + * @see GLPixelBufferProvider#allocate(GL, GLPixelAttributes, int, int, int, boolean, int) + */ + public boolean requiresNewBuffer(GL gl, int newWidth, int newHeight, int minByteSize) { + return this.byteSize < minByteSize; + } + + /** Dispose resources. */ + public void dispose() { + buffer.clear(); + } +} + diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java index dc87c7ac9..602dbb095 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java +++ b/src/jogl/classes/com/jogamp/opengl/util/GLReadBufferUtil.java @@ -30,10 +30,9 @@ package com.jogamp.opengl.util; import java.io.File; import java.io.IOException; -import java.nio.Buffer; -import java.nio.ByteBuffer; import javax.media.opengl.GL; +import javax.media.opengl.GL2GL3; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLDrawable; import javax.media.opengl.GLException; @@ -41,9 +40,9 @@ import javax.media.opengl.GLException; import com.jogamp.common.nio.Buffers; import com.jogamp.opengl.util.texture.Texture; import com.jogamp.opengl.util.texture.TextureData; -import com.jogamp.opengl.util.texture.TextureData.DefPixelBufferProvider; -import com.jogamp.opengl.util.texture.TextureData.PixelAttributes; -import com.jogamp.opengl.util.texture.TextureData.PixelBufferProvider; +import com.jogamp.opengl.util.GLPixelBuffer; +import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; +import com.jogamp.opengl.util.GLPixelBuffer.GLPixelBufferProvider; import com.jogamp.opengl.util.texture.TextureIO; /** @@ -51,13 +50,12 @@ import com.jogamp.opengl.util.texture.TextureIO; * <p>May be used directly to write the TextureData to file (screenshot).</p> */ public class GLReadBufferUtil { - protected final PixelBufferProvider pixelBufferProvider; + protected final GLPixelBufferProvider pixelBufferProvider; protected final int componentCount, alignment; protected final Texture readTexture; protected final GLPixelStorageModes psm; - protected int readPixelSizeLast = 0; - protected Buffer readPixelBuffer = null; + protected GLPixelBuffer readPixelBuffer = null; protected TextureData readTextureData = null; /** @@ -65,10 +63,10 @@ public class GLReadBufferUtil { * @param write2Texture true if readPixel's TextureData shall be written to a 2d Texture */ public GLReadBufferUtil(boolean alpha, boolean write2Texture) { - this(new DefPixelBufferProvider(), alpha, write2Texture); + this(GLPixelBuffer.defaultProvider, alpha, write2Texture); } - public GLReadBufferUtil(PixelBufferProvider pixelBufferProvider, boolean alpha, boolean write2Texture) { + public GLReadBufferUtil(GLPixelBufferProvider pixelBufferProvider, boolean alpha, boolean write2Texture) { this.pixelBufferProvider = pixelBufferProvider; this.componentCount = alpha ? 4 : 3 ; this.alignment = alpha ? 4 : 1 ; @@ -76,11 +74,11 @@ public class GLReadBufferUtil { this.psm = new GLPixelStorageModes(); } - /** Returns the {@link PixelBufferProvider} used by this instance. */ - public PixelBufferProvider getPixelBufferProvider() { return pixelBufferProvider; } + /** Returns the {@link GLPixelBufferProvider} used by this instance. */ + public GLPixelBufferProvider getPixelBufferProvider() { return pixelBufferProvider; } public boolean isValid() { - return null!=readTextureData && null!=readPixelBuffer ; + return null!=readTextureData && null!=readPixelBuffer && readPixelBuffer.isValid(); } public boolean hasAlpha() { return 4 == componentCount ? true : false ; } @@ -88,14 +86,9 @@ public class GLReadBufferUtil { public GLPixelStorageModes getGLPixelStorageModes() { return psm; } /** - * Returns the raw pixel Buffer, filled by {@link #readPixels(GLAutoDrawable, boolean)}. - * <p> - * By default the {@link Buffer} is a {@link ByteBuffer}, due to {@link DefPixelBufferProvider#allocate(int, int, int)}. - * If the {@link PixelBufferProvider} has changed via {@link #setPixelBufferProvider(PixelBufferProvider)}. - * the {@link Buffer} type maybe different. - * </p> + * Returns the {@link GLPixelBuffer}, created and filled by {@link #readPixels(GLAutoDrawable, boolean)}. */ - public Buffer getPixelBuffer() { return readPixelBuffer; } + public GLPixelBuffer getPixelBuffer() { return readPixelBuffer; } /** * rewind the raw pixel ByteBuffer @@ -163,7 +156,7 @@ public class GLReadBufferUtil { if(GL.GL_NO_ERROR != glerr0) { System.err.println("Info: GLReadBufferUtil.readPixels: pre-exisiting GL error 0x"+Integer.toHexString(glerr0)); } - final PixelAttributes pixelAttribs = pixelBufferProvider.getAttributes(gl, componentCount); + final GLPixelAttributes pixelAttribs = pixelBufferProvider.getAttributes(gl, componentCount); final int internalFormat; if(gl.isGL2GL3() && 3 == componentCount) { internalFormat = GL.GL_RGB; @@ -191,13 +184,12 @@ public class GLReadBufferUtil { } final int tmp[] = new int[1]; - final int readPixelSize = GLBuffers.sizeof(gl, tmp, pixelAttribs.format, pixelAttribs.type, width, height, 1, true); + final int readPixelSize = GLBuffers.sizeof(gl, tmp, pixelAttribs.bytesPerPixel, width, height, 1, true); boolean newData = false; - if( readPixelSize > readPixelSizeLast || pixelBufferProvider.requiresNewBuffer(width, height) ) { - readPixelBuffer = pixelBufferProvider.allocate(width, height, readPixelSize); + if( null == readPixelBuffer || readPixelBuffer.requiresNewBuffer(gl, width, height, readPixelSize) ) { + readPixelBuffer = pixelBufferProvider.allocate(gl, pixelAttribs, width, height, 1, true, readPixelSize); Buffers.rangeCheckBytes(readPixelBuffer, readPixelSize); - readPixelSizeLast = readPixelSize ; try { readTextureData = new TextureData( gl.getGLProfile(), @@ -207,13 +199,12 @@ public class GLReadBufferUtil { pixelAttribs, false, false, flipVertically, - readPixelBuffer, + readPixelBuffer.buffer, null /* Flusher */); newData = true; } catch (Exception e) { readTextureData = null; readPixelBuffer = null; - readPixelSizeLast = 0; throw new RuntimeException("can not fetch offscreen texture", e); } } else { @@ -222,14 +213,17 @@ public class GLReadBufferUtil { readTextureData.setHeight(height); readTextureData.setPixelAttributes(pixelAttribs); } - boolean res = null!=readPixelBuffer; + boolean res = null!=readPixelBuffer && readPixelBuffer.isValid(); if(res) { psm.setAlignment(gl, alignment, alignment); + if(gl.isGL2GL3()) { + gl.getGL2GL3().glPixelStorei(GL2GL3.GL_PACK_ROW_LENGTH, readPixelBuffer.width); + } readPixelBuffer.clear(); try { - gl.glReadPixels(inX, inY, width, height, pixelAttribs.format, pixelAttribs.type, readPixelBuffer); + gl.glReadPixels(inX, inY, width, height, pixelAttribs.format, pixelAttribs.type, readPixelBuffer.buffer); } catch(GLException gle) { res = false; gle.printStackTrace(); } - readPixelBuffer.position( readPixelSize / Buffers.sizeOfBufferElem(readPixelBuffer) ); + readPixelBuffer.position( readPixelSize ); readPixelBuffer.flip(); final int glerr1 = gl.glGetError(); if(GL.GL_NO_ERROR != glerr1) { @@ -261,10 +255,9 @@ public class GLReadBufferUtil { readTextureData = null; } if(null != readPixelBuffer) { + readPixelBuffer.dispose(); readPixelBuffer = null; } - readPixelSizeLast = 0; - pixelBufferProvider.dispose(); } } 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); } diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java index 2f0c86255..dec1b43cf 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/TextureData.java @@ -38,14 +38,11 @@ package com.jogamp.opengl.util.texture; import java.nio.Buffer; -import java.nio.ByteBuffer; -import javax.media.opengl.GL; -import javax.media.opengl.GLContext; import javax.media.opengl.GLProfile; -import com.jogamp.common.nio.Buffers; import com.jogamp.opengl.util.GLBuffers; +import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; /** * Represents the data for an OpenGL texture. This is separated from @@ -62,97 +59,10 @@ public class TextureData { /** ColorSpace of pixel data. */ public static enum ColorSpace { RGB, YCbCr, YCCK, CMYK }; - /** Pixel data attributes. */ - public static class PixelAttributes { - /** Undefinded instance of {@link PixelAttributes}, having format:=0 and type:= 0. */ - public static final PixelAttributes UNDEF = new PixelAttributes(0, 0); - - /** The OpenGL pixel data format */ - public final int format; - /** The OpenGL pixel data type */ - public final int type; - public PixelAttributes(int dataFormat, int dataType) { - this.format = dataFormat; - this.type = dataType; - } - public String toString() { - return "PixelAttributes[fFmt 0x"+Integer.toHexString(format)+", type 0x"+Integer.toHexString(type)+"]"; - } - } - /** Allows user to interface with another toolkit to define {@link PixelAttributes} and memory buffer to produce {@link TextureData}. */ - public static interface PixelBufferProvider { - /** Called first to determine {@link PixelAttributes}. */ - PixelAttributes getAttributes(GL gl, int componentCount); - - /** - * Returns true, if implementation requires a new buffer based on the new size - * and previous aquired {@link #getAttributes(GL, int) attributes} due to pixel alignment, otherwise false. - * @see #allocate(int, int, int) - */ - boolean requiresNewBuffer(int width, int height); - - /** - * Called after {@link #getAttributes(GL, int)} to retrieve the NIO or array backed pixel {@link Buffer}. - * <p> - * Being called to gather the initial {@link Buffer}, if the existing {@link Buffer} size is not sufficient, - * or if {@link #requiresNewBuffer(int, int)} returns false. - * </p> - * <p> - * Number of components was passed via {@link #getAttributes(GL, int)}. - * </p> - * <p> - * The returned buffer must have at least <code>minByteSize</code> {@link Buffer#remaining() remaining}. - * </p> - */ - Buffer allocate(int width, int height, int minByteSize); - - /** Dispose resources. */ - void dispose(); - } - /** - * Default {@link PixelBufferProvider} utilizing best match for {@link PixelAttributes} - * and {@link #allocate(int, int, int) allocating} a {@link ByteBuffer}. - */ - public static class DefPixelBufferProvider implements PixelBufferProvider { - @Override - public PixelAttributes getAttributes(GL gl, int componentCount) { - final GLContext ctx = gl.getContext(); - final int dFormat, dType; - - if(gl.isGL2GL3() && 3 == componentCount) { - dFormat = GL.GL_RGB; - dType = GL.GL_UNSIGNED_BYTE; - } else { - dFormat = ctx.getDefaultPixelDataFormat(); - dType = ctx.getDefaultPixelDataType(); - } - return new TextureData.PixelAttributes(dFormat, dType); - } - @Override - public boolean requiresNewBuffer(int width, int height) { - return false; - } - /** - * {@inheritDoc} - * <p> - * Returns an NIO {@link ByteBuffer} of <code>minByteSize</code>. - * </p> - */ - @Override - public final Buffer allocate(int width, int height, int minByteSize) { - return Buffers.newDirectByteBuffer(minByteSize); - } - - @Override - public void dispose() { - // nop - } - } - protected int width; protected int height; private int border; - protected PixelAttributes pixelAttributes; + protected GLPixelAttributes pixelAttributes; protected int internalFormat; // perhaps inferred from pixelFormat? protected boolean mipmap; // indicates whether mipmaps should be generated // (ignored if mipmaps are supplied from the file) @@ -225,7 +135,7 @@ public class TextureData { boolean mustFlipVertically, Buffer buffer, Flusher flusher) throws IllegalArgumentException { - this(glp, internalFormat, width, height, border, new PixelAttributes(pixelFormat, pixelType), + this(glp, internalFormat, width, height, border, new GLPixelAttributes(pixelFormat, pixelType), mipmap, dataIsCompressed, mustFlipVertically, buffer, flusher); } @@ -273,7 +183,7 @@ public class TextureData { int width, int height, int border, - PixelAttributes pixelAttributes, + GLPixelAttributes pixelAttributes, boolean mipmap, boolean dataIsCompressed, boolean mustFlipVertically, @@ -348,7 +258,7 @@ public class TextureData { boolean mustFlipVertically, Buffer[] mipmapData, Flusher flusher) throws IllegalArgumentException { - this(glp, internalFormat, width, height, border, new PixelAttributes(pixelFormat, pixelType), + this(glp, internalFormat, width, height, border, new GLPixelAttributes(pixelFormat, pixelType), dataIsCompressed, mustFlipVertically, mipmapData, flusher); } @@ -395,7 +305,7 @@ public class TextureData { int width, int height, int border, - PixelAttributes pixelAttributes, + GLPixelAttributes pixelAttributes, boolean dataIsCompressed, boolean mustFlipVertically, Buffer[] mipmapData, @@ -429,7 +339,7 @@ public class TextureData { public void setColorSpace(ColorSpace cs) { pixelCS = cs; } /** Used only by subclasses */ - protected TextureData(GLProfile glp) { this.glProfile = glp; this.pixelAttributes = PixelAttributes.UNDEF; } + protected TextureData(GLProfile glp) { this.glProfile = glp; this.pixelAttributes = GLPixelAttributes.UNDEF; } /** Returns the width in pixels of the texture data. */ public int getWidth() { return width; } @@ -439,8 +349,8 @@ public class TextureData { public int getBorder() { return border; } - /** Returns the intended OpenGL {@link PixelAttributes} of the texture data, i.e. format and type. */ - public PixelAttributes getPixelAttributes() { + /** Returns the intended OpenGL {@link GLPixelAttributes} of the texture data, i.e. format and type. */ + public GLPixelAttributes getPixelAttributes() { return pixelAttributes; } /** Returns the intended OpenGL pixel format of the texture data. */ @@ -495,27 +405,27 @@ public class TextureData { /** Sets the border in pixels of the texture data. */ public void setBorder(int border) { this.border = border; } /** Sets the intended OpenGL pixel format of the texture data. */ - public void setPixelAttributes(PixelAttributes pixelAttributes) { this.pixelAttributes = pixelAttributes; } + public void setPixelAttributes(GLPixelAttributes pixelAttributes) { this.pixelAttributes = pixelAttributes; } /** - * Sets the intended OpenGL pixel format component of {@link PixelAttributes} of the texture data. + * Sets the intended OpenGL pixel format component of {@link GLPixelAttributes} of the texture data. * <p> - * Use {@link #setPixelAttributes(PixelAttributes)}, if setting format and type. + * Use {@link #setPixelAttributes(GLPixelAttributes)}, if setting format and type. * </p> */ public void setPixelFormat(int pixelFormat) { if( pixelAttributes.format != pixelFormat ) { - pixelAttributes = new PixelAttributes(pixelFormat, pixelAttributes.type); + pixelAttributes = new GLPixelAttributes(pixelFormat, pixelAttributes.type); } } /** - * Sets the intended OpenGL pixel type component of {@link PixelAttributes} of the texture data. + * Sets the intended OpenGL pixel type component of {@link GLPixelAttributes} of the texture data. * <p> - * Use {@link #setPixelAttributes(PixelAttributes)}, if setting format and type. + * Use {@link #setPixelAttributes(GLPixelAttributes)}, if setting format and type. * </p> */ public void setPixelType(int pixelType) { if( pixelAttributes.type != pixelType) { - pixelAttributes = new PixelAttributes(pixelAttributes.format, pixelType); + pixelAttributes = new GLPixelAttributes(pixelAttributes.format, pixelType); } } /** Sets the intended OpenGL internal format of the texture data. */ diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java b/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java index 7a0f00edf..d7e825c1d 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java +++ b/src/jogl/classes/com/jogamp/opengl/util/texture/awt/AWTTextureData.java @@ -66,62 +66,10 @@ import javax.media.opengl.GL2GL3; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import com.jogamp.common.nio.Buffers; +import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; import com.jogamp.opengl.util.texture.TextureData; -import com.jogamp.opengl.util.texture.TextureData.PixelBufferProvider; public class AWTTextureData extends TextureData { - public static final PixelAttributes awtPixelAttributesIntRGB = new PixelAttributes(GL.GL_BGRA, GL.GL_UNSIGNED_BYTE); - - /** - * AWT {@link PixelBufferProvider} backed by a {@link BufferedImage} of type - * {@link BufferedImage#TYPE_INT_ARGB} or {@link BufferedImage#TYPE_INT_RGB} - * and {@link #allocate(int, int, int) allocating} am array backed {@link IntBuffer}. - */ - public static final class AWTPixelBufferProviderInt implements PixelBufferProvider { - private BufferedImage image = null; - private int componentCount = 0; - - @Override - public PixelAttributes getAttributes(GL gl, int componentCount) { - this.componentCount = componentCount; - return awtPixelAttributesIntRGB; - } - @Override - public boolean requiresNewBuffer(int width, int height) { - return null == image || image.getWidth() != width || image.getHeight() != height; - } - /** - * {@inheritDoc} - * <p> - * Returns an array backed {@link IntBuffer} of size <pre>width*height*{@link Buffers#SIZEOF_INT SIZEOF_INT}</code>. - * </p> - */ - @Override - public Buffer allocate(int width, int height, int minByteSize) { - image = new BufferedImage(width, height, 4 == componentCount ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB); - final int[] readBackIntBuffer = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); - return IntBuffer.wrap( readBackIntBuffer ); - } - - @Override - public void dispose() { - if(null != image) { - image.flush(); - image = null; - } - } - - /** Returns the number source components being used as indicated at {@link #allocate(int, int, int)}. */ - public int getComponentCount() { return componentCount; } - - /** Returns the underlying {@link BufferedImage} as allocated via {@link #allocate(int, int, int)}. */ - public BufferedImage getImage() { return image; } - - /** Returns true if an underlying {@link BufferedImage} has been allocated via {@link #allocate(int, int, int)}. */ - public boolean hasImage() { return null != image; } - } - // Mechanism for lazily converting input BufferedImages with custom // ColorModels to standard ones for uploading to OpenGL, as well as // backing off from the optimizations of hoping that either @@ -198,7 +146,7 @@ public class AWTTextureData extends TextureData { } @Override - public PixelAttributes getPixelAttributes() { + public GLPixelAttributes getPixelAttributes() { validatePixelAttributes(); return super.getPixelAttributes(); } @@ -229,7 +177,7 @@ public class AWTTextureData extends TextureData { } private void createFromImage(GLProfile glp, BufferedImage image) { - pixelAttributes = PixelAttributes.UNDEF; // Determine from image + pixelAttributes = GLPixelAttributes.UNDEF; // Determine from image mustFlipVertically = true; width = image.getWidth(); @@ -259,21 +207,21 @@ public class AWTTextureData extends TextureData { if (glp.isGL2GL3()) { switch (image.getType()) { case BufferedImage.TYPE_INT_RGB: - pixelAttributes = new PixelAttributes(GL.GL_BGRA, GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV); + pixelAttributes = new GLPixelAttributes(GL.GL_BGRA, GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV); rowLength = scanlineStride; alignment = 4; expectingGL12 = true; setupLazyCustomConversion(image); break; case BufferedImage.TYPE_INT_ARGB_PRE: - pixelAttributes = new PixelAttributes(GL.GL_BGRA, GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV); + pixelAttributes = new GLPixelAttributes(GL.GL_BGRA, GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV); rowLength = scanlineStride; alignment = 4; expectingGL12 = true; setupLazyCustomConversion(image); break; case BufferedImage.TYPE_INT_BGR: - pixelAttributes = new PixelAttributes(GL.GL_RGBA, GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV); + pixelAttributes = new GLPixelAttributes(GL.GL_RGBA, GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV); rowLength = scanlineStride; alignment = 4; expectingGL12 = true; @@ -284,7 +232,7 @@ public class AWTTextureData extends TextureData { // we can pass the image data directly to OpenGL only if // we have an integral number of pixels in each scanline if ((scanlineStride % 3) == 0) { - pixelAttributes = new PixelAttributes(GL2GL3.GL_BGR, GL.GL_UNSIGNED_BYTE); + pixelAttributes = new GLPixelAttributes(GL2GL3.GL_BGR, GL.GL_UNSIGNED_BYTE); rowLength = scanlineStride / 3; alignment = 1; } else { @@ -304,7 +252,7 @@ public class AWTTextureData extends TextureData { // the necessary byte swapping (FIXME: needs more // investigation) if ((scanlineStride % 4) == 0 && glp.isGL2() && false) { - pixelAttributes = new PixelAttributes(GL2.GL_ABGR_EXT, GL.GL_UNSIGNED_BYTE); + pixelAttributes = new GLPixelAttributes(GL2.GL_ABGR_EXT, GL.GL_UNSIGNED_BYTE); rowLength = scanlineStride / 4; alignment = 4; @@ -320,26 +268,26 @@ public class AWTTextureData extends TextureData { } } case BufferedImage.TYPE_USHORT_565_RGB: - pixelAttributes = new PixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_SHORT_5_6_5); + pixelAttributes = new GLPixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_SHORT_5_6_5); rowLength = scanlineStride; alignment = 2; expectingGL12 = true; setupLazyCustomConversion(image); break; case BufferedImage.TYPE_USHORT_555_RGB: - pixelAttributes = new PixelAttributes(GL.GL_BGRA, GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV); + pixelAttributes = new GLPixelAttributes(GL.GL_BGRA, GL2GL3.GL_UNSIGNED_SHORT_1_5_5_5_REV); rowLength = scanlineStride; alignment = 2; expectingGL12 = true; setupLazyCustomConversion(image); break; case BufferedImage.TYPE_BYTE_GRAY: - pixelAttributes = new PixelAttributes(GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE); + pixelAttributes = new GLPixelAttributes(GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE); rowLength = scanlineStride; alignment = 1; break; case BufferedImage.TYPE_USHORT_GRAY: - pixelAttributes = new PixelAttributes(GL.GL_LUMINANCE, GL.GL_UNSIGNED_SHORT); + pixelAttributes = new GLPixelAttributes(GL.GL_LUMINANCE, GL.GL_UNSIGNED_SHORT); rowLength = scanlineStride; alignment = 2; break; @@ -354,11 +302,11 @@ public class AWTTextureData extends TextureData { default: java.awt.image.ColorModel cm = image.getColorModel(); if (cm.equals(rgbColorModel)) { - pixelAttributes = new PixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_BYTE); + pixelAttributes = new GLPixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_BYTE); rowLength = scanlineStride / 3; alignment = 1; } else if (cm.equals(rgbaColorModel)) { - pixelAttributes = new PixelAttributes(GL.GL_RGBA, GL.GL_UNSIGNED_BYTE); + pixelAttributes = new GLPixelAttributes(GL.GL_RGBA, GL.GL_UNSIGNED_BYTE); rowLength = scanlineStride / 4; // FIXME: correct? alignment = 4; } else { @@ -370,7 +318,7 @@ public class AWTTextureData extends TextureData { } else { switch (image.getType()) { case BufferedImage.TYPE_INT_RGB: - pixelAttributes = new PixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_BYTE); + pixelAttributes = new GLPixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_BYTE); rowLength = scanlineStride; alignment = 3; expectingGL12 = true; @@ -385,21 +333,21 @@ public class AWTTextureData extends TextureData { case BufferedImage.TYPE_4BYTE_ABGR_PRE: throw new GLException("INT_BGR n.a."); case BufferedImage.TYPE_USHORT_565_RGB: - pixelAttributes = new PixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_SHORT_5_6_5); + pixelAttributes = new GLPixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_SHORT_5_6_5); rowLength = scanlineStride; alignment = 2; expectingGL12 = true; setupLazyCustomConversion(image); break; case BufferedImage.TYPE_USHORT_555_RGB: - pixelAttributes = new PixelAttributes(GL.GL_RGBA, GL.GL_UNSIGNED_SHORT_5_5_5_1); + pixelAttributes = new GLPixelAttributes(GL.GL_RGBA, GL.GL_UNSIGNED_SHORT_5_5_5_1); rowLength = scanlineStride; alignment = 2; expectingGL12 = true; setupLazyCustomConversion(image); break; case BufferedImage.TYPE_BYTE_GRAY: - pixelAttributes = new PixelAttributes(GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE); + pixelAttributes = new GLPixelAttributes(GL.GL_LUMINANCE, GL.GL_UNSIGNED_BYTE); rowLength = scanlineStride; alignment = 1; break; @@ -416,11 +364,11 @@ public class AWTTextureData extends TextureData { default: java.awt.image.ColorModel cm = image.getColorModel(); if (cm.equals(rgbColorModel)) { - pixelAttributes = new PixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_BYTE); + pixelAttributes = new GLPixelAttributes(GL.GL_RGB, GL.GL_UNSIGNED_BYTE); rowLength = scanlineStride / 3; alignment = 1; } else if (cm.equals(rgbaColorModel)) { - pixelAttributes = new PixelAttributes(GL.GL_RGBA, GL.GL_UNSIGNED_BYTE); + pixelAttributes = new GLPixelAttributes(GL.GL_RGBA, GL.GL_UNSIGNED_BYTE); rowLength = scanlineStride / 4; // FIXME: correct? alignment = 4; } else { @@ -465,7 +413,7 @@ public class AWTTextureData extends TextureData { } else { throw new RuntimeException("Unexpected DataBuffer type?"); } - pixelAttributes = new PixelAttributes(pixelFormat, pixelType); + pixelAttributes = new GLPixelAttributes(pixelFormat, pixelType); } private void createFromCustom(BufferedImage image) { @@ -524,7 +472,7 @@ public class AWTTextureData extends TextureData { // and knowing we're in the process of doing the fallback code // path, re-infer a vanilla pixel format and type compatible with // OpenGL 1.1 - pixelAttributes = PixelAttributes.UNDEF; + pixelAttributes = GLPixelAttributes.UNDEF; setupLazyCustomConversion(imageForLazyCustomConversion); } |