From 581c4364345b46f66d1395c73d4b62feb0b20c32 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Mon, 7 May 2012 14:41:24 -0700 Subject: j3dcore: move Jogl-using classes into the main source folder We now assume Jogl support, keep it with the rest of the code. Signed-off-by: Harvey Harrison --- src/classes/jogl/javax/media/j3d/JoglContext.java | 166 - src/classes/jogl/javax/media/j3d/JoglDrawable.java | 49 - .../javax/media/j3d/JoglDrawingSurfaceObject.java | 79 - .../javax/media/j3d/JoglGraphicsConfiguration.java | 138 - src/classes/jogl/javax/media/j3d/JoglPipeline.java | 8631 -------------------- .../jogl/javax/media/j3d/JoglShaderObject.java | 44 - src/classes/share/javax/media/j3d/JoglContext.java | 166 + .../share/javax/media/j3d/JoglDrawable.java | 49 + .../javax/media/j3d/JoglDrawingSurfaceObject.java | 79 + .../javax/media/j3d/JoglGraphicsConfiguration.java | 138 + .../share/javax/media/j3d/JoglPipeline.java | 8631 ++++++++++++++++++++ .../share/javax/media/j3d/JoglShaderObject.java | 44 + 12 files changed, 9107 insertions(+), 9107 deletions(-) delete mode 100644 src/classes/jogl/javax/media/j3d/JoglContext.java delete mode 100755 src/classes/jogl/javax/media/j3d/JoglDrawable.java delete mode 100644 src/classes/jogl/javax/media/j3d/JoglDrawingSurfaceObject.java delete mode 100755 src/classes/jogl/javax/media/j3d/JoglGraphicsConfiguration.java delete mode 100644 src/classes/jogl/javax/media/j3d/JoglPipeline.java delete mode 100755 src/classes/jogl/javax/media/j3d/JoglShaderObject.java create mode 100644 src/classes/share/javax/media/j3d/JoglContext.java create mode 100644 src/classes/share/javax/media/j3d/JoglDrawable.java create mode 100644 src/classes/share/javax/media/j3d/JoglDrawingSurfaceObject.java create mode 100644 src/classes/share/javax/media/j3d/JoglGraphicsConfiguration.java create mode 100644 src/classes/share/javax/media/j3d/JoglPipeline.java create mode 100644 src/classes/share/javax/media/j3d/JoglShaderObject.java diff --git a/src/classes/jogl/javax/media/j3d/JoglContext.java b/src/classes/jogl/javax/media/j3d/JoglContext.java deleted file mode 100644 index a1f33c5..0000000 --- a/src/classes/jogl/javax/media/j3d/JoglContext.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * $RCSfile$ - * - * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * $Revision$ - * $Date$ - * $State$ - */ - -package javax.media.j3d; - -import java.nio.Buffer; -import java.nio.FloatBuffer; - -import javax.media.opengl.GL; -import javax.media.opengl.GLContext; - -/** - * Graphics context objects for Jogl rendering pipeline. - */ -class JoglContext implements Context { - private GLContext context; - - // Properties we need to keep track of for efficiency - private int maxTexCoordSets; - private float alphaClearValue; - private int currentTextureUnit; - private int currentCombinerUnit; - private boolean hasMultisample; - - // Needed for vertex attribute implementation - private JoglShaderObject shaderProgram; - - // Implementation of vertex attribute methods - static interface VertexAttributeImpl { - public void vertexAttrPointer(GL gl, - int index, int size, int type, int stride, Buffer pointer); - public void enableVertexAttrArray(GL gl, int index); - public void disableVertexAttrArray(GL gl, int index); - public void vertexAttr1fv(GL gl, int index, FloatBuffer buf); - public void vertexAttr2fv(GL gl, int index, FloatBuffer buf); - public void vertexAttr3fv(GL gl, int index, FloatBuffer buf); - public void vertexAttr4fv(GL gl, int index, FloatBuffer buf); - } - private VertexAttributeImpl vertexAttrImpl; - - class GLSLVertexAttributeImpl implements VertexAttributeImpl { - public void vertexAttrPointer(GL gl, - int index, int size, int type, int stride, Buffer pointer) { - gl.getGL2().glVertexAttribPointerARB(index + glslVertexAttrOffset, - size, type, false, stride, pointer); - } - - public void enableVertexAttrArray(GL gl, int index) { - gl.getGL2().glEnableVertexAttribArrayARB(index + glslVertexAttrOffset); - } - - public void disableVertexAttrArray(GL gl, int index) { - gl.getGL2().glDisableVertexAttribArrayARB(index + glslVertexAttrOffset); - } - - public void vertexAttr1fv(GL gl, int index, FloatBuffer buf) { - gl.getGL2().glVertexAttrib1fvARB(index + glslVertexAttrOffset, buf); - } - - public void vertexAttr2fv(GL gl, int index, FloatBuffer buf) { - gl.getGL2().glVertexAttrib2fvARB(index + glslVertexAttrOffset, buf); - } - - public void vertexAttr3fv(GL gl, int index, FloatBuffer buf) { - gl.getGL2().glVertexAttrib3fvARB(index + glslVertexAttrOffset, buf); - } - - public void vertexAttr4fv(GL gl, int index, FloatBuffer buf) { - gl.getGL2().glVertexAttrib4fvARB(index + glslVertexAttrOffset, buf); - } - } - - // Only used when GLSL shader library is active - private int glslVertexAttrOffset; - - JoglContext(GLContext context) { - this.context = context; - } - - GLContext getGLContext() { - return context; - } - - int getMaxTexCoordSets() { return maxTexCoordSets; } - void setMaxTexCoordSets(int val) { maxTexCoordSets = val; } - float getAlphaClearValue() { return alphaClearValue; } - void setAlphaClearValue(float val) { alphaClearValue = val; } - int getCurrentTextureUnit() { return currentTextureUnit; } - void setCurrentTextureUnit(int val) { currentTextureUnit = val; } - int getCurrentCombinerUnit() { return currentCombinerUnit; } - void setCurrentCombinerUnit(int val) { currentCombinerUnit = val; } - boolean getHasMultisample() { return hasMultisample; } - void setHasMultisample(boolean val){ hasMultisample = val; } - - void initGLSLVertexAttributeImpl() { - if (vertexAttrImpl != null) { - throw new RuntimeException("Should not initialize the vertex attribute implementation twice"); - } - vertexAttrImpl = new GLSLVertexAttributeImpl(); - } - - void vertexAttrPointer(GL gl, - int index, int size, int type, int stride, Buffer pointer) { - vertexAttrImpl.vertexAttrPointer(gl, index, size, type, stride, pointer); - } - - void enableVertexAttrArray(GL gl, int index) { - vertexAttrImpl.enableVertexAttrArray(gl, index); - } - - void disableVertexAttrArray(GL gl, int index) { - vertexAttrImpl.disableVertexAttrArray(gl, index); - } - - void vertexAttr1fv(GL gl, int index, FloatBuffer buf) { - vertexAttrImpl.vertexAttr1fv(gl, index, buf); - } - - void vertexAttr2fv(GL gl, int index, FloatBuffer buf) { - vertexAttrImpl.vertexAttr2fv(gl, index, buf); - } - - void vertexAttr3fv(GL gl, int index, FloatBuffer buf) { - vertexAttrImpl.vertexAttr3fv(gl, index, buf); - } - - void vertexAttr4fv(GL gl, int index, FloatBuffer buf) { - vertexAttrImpl.vertexAttr4fv(gl, index, buf); - } - - // Used in vertex attribute implementation - JoglShaderObject getShaderProgram() { return shaderProgram; } - void setShaderProgram(JoglShaderObject object) { shaderProgram = object; } - - // Only used when GLSL shaders are in use - int getGLSLVertexAttrOffset() { return glslVertexAttrOffset; } - void setGLSLVertexAttrOffset(int offset) { glslVertexAttrOffset = offset; } -} diff --git a/src/classes/jogl/javax/media/j3d/JoglDrawable.java b/src/classes/jogl/javax/media/j3d/JoglDrawable.java deleted file mode 100755 index 7adabcb..0000000 --- a/src/classes/jogl/javax/media/j3d/JoglDrawable.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * $RCSfile$ - * - * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * $Revision$ - * $Date$ - * $State$ - */ - -package javax.media.j3d; - -import javax.media.opengl.GLDrawable; - -/** - * Drawable class for the Jogl rendering pipeline. - */ -class JoglDrawable implements Drawable { - private GLDrawable drawable; - - JoglDrawable(GLDrawable drawable) { - this.drawable = drawable; - } - - GLDrawable getGLDrawable() { - return drawable; - } -} diff --git a/src/classes/jogl/javax/media/j3d/JoglDrawingSurfaceObject.java b/src/classes/jogl/javax/media/j3d/JoglDrawingSurfaceObject.java deleted file mode 100644 index 439213e..0000000 --- a/src/classes/jogl/javax/media/j3d/JoglDrawingSurfaceObject.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * $RCSfile$ - * - * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * $Revision$ - * $Date$ - * $State$ - */ - -package javax.media.j3d; - -/** - * The DrawingSurfaceObject class is used to manage native drawing surface - */ -class JoglDrawingSurfaceObject extends DrawingSurfaceObject { - - JoglDrawingSurfaceObject(Canvas3D cv) { - super(cv); - - // System.err.println("JoglDrawingSurfaceObject constructed"); - } - - synchronized boolean renderLock() { - // System.err.println("JoglDrawingSurfaceObject.renderLock()"); - gotDsiLock = true; - return true; - } - - synchronized void unLock() { - // System.err.println("JoglDrawingSurfaceObject.unLock()"); - gotDsiLock = false; - } - - synchronized void getDrawingSurfaceObjectInfo() { - // FIXME: we don't have all of the information we need here to - // create a GLDrawable for the Canvas3D, so for now, do nothing - - // FIXME: this mechanism is much too complicated - - /* - System.err.println("JoglDrawingSurfaceObject.getDrawingSurfaceObjectInfo()"); - - if (canvas.drawable == null) { - System.err.println( - "JoglDrawingSurfaceObject.getDrawingSurfaceObjectInfo: window = " - + canvas.drawable); - - // TODO: replace with a real JoglDrawable - canvas.drawable = new JoglDrawable(); - } - */ - } - - synchronized void invalidate() { - System.err.println("JoglDrawingSurfaceObject.invalidate()"); - } -} diff --git a/src/classes/jogl/javax/media/j3d/JoglGraphicsConfiguration.java b/src/classes/jogl/javax/media/j3d/JoglGraphicsConfiguration.java deleted file mode 100755 index 1f5989e..0000000 --- a/src/classes/jogl/javax/media/j3d/JoglGraphicsConfiguration.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * $RCSfile$ - * - * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * $Revision$ - * $Date$ - * $State$ - */ - -package javax.media.j3d; - -import java.awt.AWTException; -import java.awt.DisplayMode; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.ImageCapabilities; -import java.awt.Rectangle; -import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; -import java.awt.image.ColorModel; -import java.awt.image.VolatileImage; - -import com.jogamp.nativewindow.awt.AWTGraphicsDevice; -import javax.media.opengl.GLCapabilities; - -/** - * Class implementing the GraphicsConfiguration API, but not a "real" - * GraphicsConfiguration object. Wraps a GLCapabilities object and - * supports either immediate or deferred pixel format / visual - * selection depending on which platform we are running. - */ - -class JoglGraphicsConfiguration extends GraphicsConfiguration { - private GLCapabilities caps; - private int chosenIndex; - private GraphicsDevice device; - private AWTGraphicsDevice awtGraphicsDevice; - // Needed for Screen3D - private int width; - private int height; - - JoglGraphicsConfiguration(GLCapabilities caps, int chosenIndex, GraphicsDevice device) { - super(); - this.caps = caps; - this.chosenIndex = chosenIndex; - this.device = device; - //FIXME unit id? - this.awtGraphicsDevice = new AWTGraphicsDevice(this.device, 0); - DisplayMode m = device.getDisplayMode(); - width = m.getWidth(); - height = m.getHeight(); - } - - GLCapabilities getGLCapabilities() { - return caps; - } - - int getChosenIndex() { - return chosenIndex; - } - - public BufferedImage createCompatibleImage(int width, int height) { - throw new RuntimeException("Unimplemented"); - } - - public BufferedImage createCompatibleImage(int width, int height, - int transparency) { - throw new RuntimeException("Unimplemented"); - } - - public VolatileImage createCompatibleVolatileImage(int width, int height) { - throw new RuntimeException("Unimplemented"); - } - - public VolatileImage createCompatibleVolatileImage(int width, int height, int transparency) { - throw new RuntimeException("Unimplemented"); - } - - public VolatileImage createCompatibleVolatileImage(int width, int height, - ImageCapabilities caps) throws AWTException { - throw new RuntimeException("Unimplemented"); - } - - public VolatileImage createCompatibleVolatileImage(int width, int height, - ImageCapabilities caps, int transparency) throws AWTException { - throw new RuntimeException("Unimplemented"); - } - - public Rectangle getBounds() { - return new Rectangle(0, 0, width, height); - } - - public ColorModel getColorModel() { - throw new RuntimeException("Unimplemented"); - } - - public ColorModel getColorModel(int transparency) { - throw new RuntimeException("Unimplemented"); - } - - public AffineTransform getDefaultTransform() { - throw new RuntimeException("Unimplemented"); - } - - public GraphicsDevice getDevice() { - return device; - } - - public AWTGraphicsDevice getAwtGraphicsDevice() { - return awtGraphicsDevice; - } - - public AffineTransform getNormalizingTransform() { - throw new RuntimeException("Unimplemented"); - } -} diff --git a/src/classes/jogl/javax/media/j3d/JoglPipeline.java b/src/classes/jogl/javax/media/j3d/JoglPipeline.java deleted file mode 100644 index d3e3a8d..0000000 --- a/src/classes/jogl/javax/media/j3d/JoglPipeline.java +++ /dev/null @@ -1,8631 +0,0 @@ -/* - * $RCSfile$ - * - * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * $Revision$ - * $Date$ - * $State$ - */ - -package javax.media.j3d; - -import java.awt.BorderLayout; -import java.awt.Canvas; -import java.awt.DisplayMode; -import java.awt.EventQueue; -import java.awt.Frame; -import java.awt.GraphicsConfigTemplate; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Method; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.DoubleBuffer; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.StringTokenizer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration; -import com.jogamp.nativewindow.awt.AWTGraphicsDevice; -import com.jogamp.nativewindow.awt.AWTGraphicsScreen; -import javax.media.nativewindow.AbstractGraphicsConfiguration; -import javax.media.nativewindow.CapabilitiesChooser; -import javax.media.nativewindow.CapabilitiesImmutable; -import javax.media.nativewindow.GraphicsConfigurationFactory; -import javax.media.nativewindow.NativeWindow; -import javax.media.nativewindow.NativeWindowFactory; -import javax.media.opengl.DefaultGLCapabilitiesChooser; -import javax.media.opengl.GL; -import javax.media.opengl.GL2; -import javax.media.opengl.GLCapabilities; -import javax.media.opengl.GLCapabilitiesChooser; -import javax.media.opengl.GLContext; -import javax.media.opengl.GLDrawable; -import javax.media.opengl.GLDrawableFactory; -import javax.media.opengl.GLException; -import javax.media.opengl.GLPbuffer; -import javax.media.opengl.GLProfile; -import javax.media.opengl.Threading; -import javax.media.opengl.glu.GLU; - -import com.jogamp.common.nio.Buffers; - -/** - * Concrete implementation of Pipeline class for the JOGL rendering - * pipeline. - */ -class JoglPipeline extends Pipeline { - // Currently prints for entry points not yet implemented - private static final boolean DEBUG = true; - // Currently prints for entry points already implemented - private static final boolean VERBOSE = false; - // Debugging output for graphics configuration selection - private static final boolean DEBUG_CONFIG = false; - // Prints extra debugging information - private static final boolean EXTRA_DEBUGGING = false; - // Number of milliseconds to wait for windows to pop up on screen - private static final int WAIT_TIME = 1000; - // Configurable constant just in case we want to change this later - private static final int MIN_FRAME_SIZE = 1; - - /** - * Constructor for singleton JoglPipeline instance - */ - protected JoglPipeline() { - } - - /** - * Initialize the pipeline - */ - void initialize(Pipeline.Type pipelineType) { - super.initialize(pipelineType); - - assert pipelineType == Pipeline.Type.JOGL; - - // Java3D maintains strict control over which threads perform OpenGL work - Threading.disableSingleThreading(); - - // TODO: finish this with any other needed initialization - } - - /** - * Returns true if the GLSL library is loaded and available. Note that this - * does not necessarily mean that GLSL is supported by the graphics card. - */ - boolean isGLSLLibraryAvailable() { - return true; - } - - - // --------------------------------------------------------------------- - - // - // GeometryArrayRetained methods - // - - // used for GeometryArrays by Copy or interleaved - void execute(Context ctx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, - boolean useAlpha, - boolean ignoreVertexColors, - int startVIndex, int vcount, int vformat, - int texCoordSetCount, int[] texCoordSetMap, - int texCoordSetMapLen, - int[] texUnitOffset, - int numActiveTexUnitState, - int vertexAttrCount, int[] vertexAttrSizes, - float[] varray, float[] carray, int cDirty) { - if (VERBOSE) System.err.println("JoglPipeline.execute()"); - - executeGeometryArray(ctx, geo, geo_type, isNonUniformScale, useAlpha, - ignoreVertexColors, startVIndex, vcount, vformat, - texCoordSetCount, texCoordSetMap, texCoordSetMapLen, - texUnitOffset, numActiveTexUnitState, - vertexAttrCount, vertexAttrSizes, - varray, null, carray, cDirty); - } - - // used by GeometryArray by Reference with java arrays - void executeVA(Context ctx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, - boolean ignoreVertexColors, - int vcount, - int vformat, - int vdefined, - int initialCoordIndex, float[] vfcoords, double[] vdcoords, - int initialColorIndex, float[] cfdata, byte[] cbdata, - int initialNormalIndex, float[] ndata, - int vertexAttrCount, int[] vertexAttrSizes, - int[] vertexAttrIndices, float[][] vertexAttrData, - int texCoordMapLength, - int[] texcoordoffset, - int numActiveTexUnitState, - int[] texIndex, int texstride, Object[] texCoords, - int cdirty) { - if (VERBOSE) System.err.println("JoglPipeline.executeVA()"); - - boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); - boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); - boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); - boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); - boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); - boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); - boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); - - FloatBuffer fverts = null; - DoubleBuffer dverts = null; - FloatBuffer fclrs = null; - ByteBuffer bclrs = null; - FloatBuffer[] texCoordBufs = null; - FloatBuffer norms = null; - FloatBuffer[] vertexAttrBufs = null; - - // Get vertex attribute arrays - if (vattrDefined) { - vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData); - } - - // get texture arrays - if (textureDefined) { - texCoordBufs = getTexCoordSetBuffer(texCoords); - } - - // get coordinate array - if (floatCoordDefined) { - fverts = getVertexArrayBuffer(vfcoords); - } else if (doubleCoordDefined) { - dverts = getVertexArrayBuffer(vdcoords); - } - - // get color array - if (floatColorsDefined) { - fclrs = getColorArrayBuffer(cfdata); - } else if (byteColorsDefined) { - bclrs = getColorArrayBuffer(cbdata); - } - - // get normal array - if (normalsDefined) { - norms = getNormalArrayBuffer(ndata); - } - - int[] sarray = null; - int[] start_array = null; - int strip_len = 0; - if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { - sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts; - strip_len = sarray.length; - start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices; - } - - executeGeometryArrayVA(ctx, geo, geo_type, - isNonUniformScale, ignoreVertexColors, - vcount, vformat, vdefined, - initialCoordIndex, fverts, dverts, - initialColorIndex, fclrs, bclrs, - initialNormalIndex, norms, - vertexAttrCount, vertexAttrSizes, - vertexAttrIndices, vertexAttrBufs, - texCoordMapLength, - texcoordoffset, numActiveTexUnitState, - texIndex, texstride, texCoordBufs, cdirty, - sarray, strip_len, start_array); - } - - // used by GeometryArray by Reference with NIO buffer - void executeVABuffer(Context ctx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, - boolean ignoreVertexColors, - int vcount, - int vformat, - int vdefined, - int initialCoordIndex, - Object vcoords, - int initialColorIndex, - Object cdataBuffer, - float[] cfdata, byte[] cbdata, - int initialNormalIndex, Object ndata, - int vertexAttrCount, int[] vertexAttrSizes, - int[] vertexAttrIndices, Object[] vertexAttrData, - int texCoordMapLength, - int[] texcoordoffset, - int numActiveTexUnitState, - int[] texIndex, int texstride, Object[] texCoords, - int cdirty) { - if (VERBOSE) System.err.println("JoglPipeline.executeVABuffer()"); - - boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); - boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); - boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); - boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); - boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); - boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); - boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); - - FloatBuffer fverts = null; - DoubleBuffer dverts = null; - FloatBuffer fclrs = null; - ByteBuffer bclrs = null; - FloatBuffer[] texCoordBufs = null; - FloatBuffer norms = null; - FloatBuffer[] vertexAttrBufs = null; - - // Get vertex attribute arrays - if (vattrDefined) { - vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData); - } - - // get texture arrays - if (textureDefined) { - texCoordBufs = new FloatBuffer[texCoords.length]; - for (int i = 0; i < texCoords.length; i++) { - texCoordBufs[i] = (FloatBuffer) texCoords[i]; - } - } - - // get coordinate array - if (floatCoordDefined) { - fverts = (FloatBuffer) vcoords; - } else if (doubleCoordDefined) { - dverts = (DoubleBuffer) vcoords; - } - - if (fverts == null && dverts == null) { - return; - } - - // get color array - if (floatColorsDefined) { - if (cfdata != null) - fclrs = getColorArrayBuffer(cfdata); - else - fclrs = (FloatBuffer) cdataBuffer; - } else if (byteColorsDefined) { - if (cbdata != null) - bclrs = getColorArrayBuffer(cbdata); - else - bclrs = (ByteBuffer) cdataBuffer; - } - - // get normal array - if (normalsDefined) { - norms = (FloatBuffer) ndata; - } - - int[] sarray = null; - int[] start_array = null; - int strip_len = 0; - if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { - sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts; - strip_len = sarray.length; - start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices; - } - - executeGeometryArrayVA(ctx, geo, geo_type, - isNonUniformScale, ignoreVertexColors, - vcount, vformat, vdefined, - initialCoordIndex, fverts, dverts, - initialColorIndex, fclrs, bclrs, - initialNormalIndex, norms, - vertexAttrCount, vertexAttrSizes, - vertexAttrIndices, vertexAttrBufs, - texCoordMapLength, - texcoordoffset, numActiveTexUnitState, - texIndex, texstride, texCoordBufs, cdirty, - sarray, strip_len, start_array); - } - - // used by GeometryArray by Reference in interleaved format with NIO buffer - void executeInterleavedBuffer(Context ctx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, - boolean useAlpha, - boolean ignoreVertexColors, - int startVIndex, int vcount, int vformat, - int texCoordSetCount, int[] texCoordSetMap, - int texCoordSetMapLen, - int[] texUnitOffset, - int numActiveTexUnit, - Object varray, float[] cdata, int cdirty) { - if (VERBOSE) System.err.println("JoglPipeline.executeInterleavedBuffer()"); - - executeGeometryArray(ctx, geo, geo_type, - isNonUniformScale, useAlpha, ignoreVertexColors, - startVIndex, vcount, vformat, - texCoordSetCount, texCoordSetMap, texCoordSetMapLen, - texUnitOffset, numActiveTexUnit, 0, null, - null, (Buffer) varray, cdata, cdirty); - } - - void setVertexFormat(Context ctx, GeometryArrayRetained geo, - int vformat, boolean useAlpha, boolean ignoreVertexColors) { - if (VERBOSE) System.err.println("JoglPipeline.setVertexFormat()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - // Enable and disable the appropriate pointers - if ((vformat & GeometryArray.NORMALS) != 0) { - gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); - } else { - gl.glDisableClientState(GL2.GL_NORMAL_ARRAY); - } - if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) { - gl.glEnableClientState(GL2.GL_COLOR_ARRAY); - } else { - gl.glDisableClientState(GL2.GL_COLOR_ARRAY); - } - -// FIXME: SUN_global_alpha -// if (gl.isExtensionAvailable("GL_SUN_global_alpha")) { -// if (useAlpha) { -// gl.glEnable(GL.GL_GLOBAL_ALPHA_SUN); -// } else { -// gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN); -// } -// } - - if ((vformat & GeometryArray.COORDINATES) != 0) { - gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); - } else { - gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); - } - } - - void disableGlobalAlpha(Context ctx, GeometryArrayRetained geo, int vformat, - boolean useAlpha, boolean ignoreVertexColors) { - if (VERBOSE) System.err.println("JoglPipeline.disableGlobalAlpha()"); -// FIXME: SUN_global_alpha -// GL gl = context(ctx).getGL(); - -// if (gl.isExtensionAvailable("GL_SUN_global_alpha")) { -// if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) { -// if (useAlpha) { -// gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN); -// } -// } -// } - } - - // used for GeometryArrays - void buildGA(Context ctx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, boolean updateAlpha, - float alpha, - boolean ignoreVertexColors, - int startVIndex, - int vcount, int vformat, - int texCoordSetCount, int[] texCoordSetMap, - int texCoordSetMapLen, int[] texCoordSetMapOffset, - int vertexAttrCount, int[] vertexAttrSizes, - double[] xform, double[] nxform, - float[] varray) { - if (VERBOSE) System.err.println("JoglPipeline.buildGA()"); - JoglContext jctx = (JoglContext) ctx; - GL2 gl = context(ctx).getGL().getGL2(); - FloatBuffer verts = null; - int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0; - int texStride = 0; - int vAttrOff = 0; - if ((vformat & GeometryArray.COORDINATES) != 0) { - stride += 3; - } - if ((vformat & GeometryArray.NORMALS) != 0) { - stride += 3; - coordoff += 3; - } - - if ((vformat & GeometryArray.COLOR) != 0) { - if ((vformat & GeometryArray.BY_REFERENCE) != 0) { - if ((vformat & GeometryArray.WITH_ALPHA) != 0) { - stride += 4; - normoff += 4; - coordoff += 4; - } else { - stride += 3; - normoff += 3; - coordoff += 3; - } - } else { - stride += 4; - normoff += 4; - coordoff += 4; - } - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { - texStride = 2 * texCoordSetCount; - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { - texStride = 3 * texCoordSetCount; - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { - texStride = 4 * texCoordSetCount; - } - stride += texStride; - normoff += texStride; - coloroff += texStride; - coordoff += texStride; - } - - int vAttrStride = 0; - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - for (int i = 0; i < vertexAttrCount; i++) { - vAttrStride += vertexAttrSizes[i]; - } - stride += vAttrStride; - normoff += vAttrStride; - coloroff += vAttrStride; - coordoff += vAttrStride; - texCoordoff += vAttrStride; - } - - int bstride = stride * Buffers.SIZEOF_FLOAT; - // Start sending down from the startVIndex - int initialOffset = startVIndex * stride; - normoff += initialOffset; - coloroff += initialOffset; - coordoff += initialOffset; - texCoordoff += initialOffset; - vAttrOff += initialOffset; - - // process alpha for geometryArray without alpha - boolean useAlpha = false; - if (updateAlpha && !ignoreVertexColors) { - useAlpha = true; - } - - if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { - int[] sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts; - - int primType = 0; - switch (geo_type) { - case GeometryRetained.GEO_TYPE_TRI_STRIP_SET : - primType = GL.GL_TRIANGLE_STRIP; - break; - case GeometryRetained.GEO_TYPE_TRI_FAN_SET : - primType = GL.GL_TRIANGLE_FAN; - break; - case GeometryRetained.GEO_TYPE_LINE_STRIP_SET : - primType = GL.GL_LINE_STRIP; - break; - } - - if (ignoreVertexColors) { - vformat &= ~GeometryArray.COLOR; - } - - for (int i = 0; i < sarray.length; i++) { - gl.glBegin(primType); - for (int j = 0; j < sarray[i]; j++) { - if ((vformat & GeometryArray.NORMALS) != 0) { - if (nxform != null) { - float nx = (float) (nxform[0] * varray[normoff] + - nxform[1] * varray[normoff+1] + - nxform[2] * varray[normoff+2]); - float ny = (float) (nxform[4] * varray[normoff] + - nxform[5] * varray[normoff+1] + - nxform[6] * varray[normoff+2]); - float nz = (float) (nxform[8] * varray[normoff] + - nxform[9] * varray[normoff+1] + - nxform[10] * varray[normoff+2]); - gl.glNormal3f(nx, ny, nz); - } else { - gl.glNormal3f(varray[normoff], varray[normoff+1], varray[normoff+2]); - } - } - if ((vformat & GeometryArray.COLOR) != 0) { - if (useAlpha) { - gl.glColor4f(varray[coloroff], - varray[coloroff+1], - varray[coloroff+2], - varray[coloroff+3] * alpha); - } else { - if ((vformat & GeometryArray.WITH_ALPHA) != 0) { // alpha is present - gl.glColor4f(varray[coloroff], - varray[coloroff+1], - varray[coloroff+2], - varray[coloroff+3]); - } else { - gl.glColor3f(varray[coloroff], - varray[coloroff+1], - varray[coloroff+2]); - } - } - } - - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - int vaOff = vAttrOff; - if (verts == null) { - verts = FloatBuffer.wrap(varray); - } - for (int vaIdx = 0; vaIdx < vertexAttrCount; vaIdx++) { - switch (vertexAttrSizes[vaIdx]) { - case 1: - verts.position(vaOff); - jctx.vertexAttr1fv(gl, vaIdx, verts); - break; - case 2: - verts.position(vaOff); - jctx.vertexAttr2fv(gl, vaIdx, verts); - break; - case 3: - verts.position(vaOff); - jctx.vertexAttr3fv(gl, vaIdx, verts); - break; - case 4: - verts.position(vaOff); - jctx.vertexAttr4fv(gl, vaIdx, verts); - break; - } - - vaOff += vertexAttrSizes[vaIdx]; - } - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - if (texCoordSetMapLen > 0) { - if (gl.isExtensionAvailable("GL_VERSION_1_3")) { - if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { - for (int k = 0; k < texCoordSetMapLen; k++) { - if (texCoordSetMapOffset[k] != -1) { - int off = texCoordoff + texCoordSetMapOffset[k]; - gl.glMultiTexCoord2f(GL.GL_TEXTURE0 + k, - varray[off], - varray[off + 1]); - } - } - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { - for (int k = 0; k < texCoordSetMapLen; k++) { - if (texCoordSetMapOffset[k] != -1) { - int off = texCoordoff + texCoordSetMapOffset[k]; - gl.glMultiTexCoord3f(GL.GL_TEXTURE0 + k, - varray[off], - varray[off + 1], - varray[off + 2]); - } - } - } else { - for (int k = 0; k < texCoordSetMapLen; k++) { - if (texCoordSetMapOffset[k] != -1) { - int off = texCoordoff + texCoordSetMapOffset[k]; - gl.glMultiTexCoord4f(GL.GL_TEXTURE0 + k, - varray[off], - varray[off + 1], - varray[off + 2], - varray[off + 3]); - } - } - } - } else { // no multitexture - if (texCoordSetMapOffset[0] != -1) { - int off = texCoordoff + texCoordSetMapOffset[0]; - if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { - gl.glTexCoord2f(varray[off], varray[off + 1]); - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { - gl.glTexCoord3f(varray[off], varray[off + 1], varray[off + 2]); - } else { - gl.glTexCoord4f(varray[off], varray[off + 1], varray[off + 2], varray[off + 3]); - } - } - } // no multitexture - } - // texCoordSetMapLen can't be 0 if texture coordinates - // is to be specified - } - - if ((vformat & GeometryArray.COORDINATES) != 0) { - if (xform != null) { - // transform the vertex data with the static transform - float w = (float) (xform[12] * varray[coordoff] + - xform[13] * varray[coordoff+1] + - xform[14] * varray[coordoff+2] + - xform[15]); - float winv = 1.0f/w; - float vx = (float) (xform[0] * varray[coordoff] + - xform[1] * varray[coordoff+1] + - xform[2] * varray[coordoff+2] + - xform[3]) * winv; - float vy = (float) (xform[4] * varray[coordoff] + - xform[5] * varray[coordoff+1] + - xform[6] * varray[coordoff+2] + - xform[7]) * winv; - float vz = (float) (xform[8] * varray[coordoff] + - xform[9] * varray[coordoff+1] + - xform[10] * varray[coordoff+2] + - xform[11]) * winv; - gl.glVertex3f(vx, vy, vz); - } else { - gl.glVertex3f(varray[coordoff], varray[coordoff + 1], varray[coordoff + 2]); - } - } - normoff += stride; - coloroff += stride; - coordoff += stride; - texCoordoff += stride; - vAttrOff += stride; - } - gl.glEnd(); - } - } else if ((geo_type == GeometryRetained.GEO_TYPE_QUAD_SET) || - (geo_type == GeometryRetained.GEO_TYPE_TRI_SET) || - (geo_type == GeometryRetained.GEO_TYPE_POINT_SET) || - (geo_type == GeometryRetained.GEO_TYPE_LINE_SET)) { - int primType = 0; - switch (geo_type) { - case GeometryRetained.GEO_TYPE_QUAD_SET : - primType = GL2.GL_QUADS; - break; - case GeometryRetained.GEO_TYPE_TRI_SET : - primType = GL.GL_TRIANGLES; - break; - case GeometryRetained.GEO_TYPE_POINT_SET : - primType = GL.GL_POINTS; - break; - case GeometryRetained.GEO_TYPE_LINE_SET : - primType = GL.GL_LINES; - break; - } - - if (ignoreVertexColors) { - vformat &= ~GeometryArray.COLOR; - } - - gl.glBegin(primType); - for (int j = 0; j < vcount; j++) { - if ((vformat & GeometryArray.NORMALS) != 0) { - if (nxform != null) { - float nx = (float) (nxform[0] * varray[normoff] + - nxform[1] * varray[normoff+1] + - nxform[2] * varray[normoff+2]); - float ny = (float) (nxform[4] * varray[normoff] + - nxform[5] * varray[normoff+1] + - nxform[6] * varray[normoff+2]); - float nz = (float) (nxform[8] * varray[normoff] + - nxform[9] * varray[normoff+1] + - nxform[10] * varray[normoff+2]); - gl.glNormal3f(nx, ny, nz); - } else { - gl.glNormal3f(varray[normoff], varray[normoff + 1], varray[normoff + 2]); - } - } - if ((vformat & GeometryArray.COLOR) != 0) { - if (useAlpha) { - float cr, cg, cb, ca; - if ((vformat & GeometryArray.WITH_ALPHA) != 0) { - cr = varray[coloroff]; - cg = varray[coloroff + 1]; - cb = varray[coloroff + 2]; - ca = varray[coloroff + 3] * alpha; - } else { - cr = varray[coloroff]; - cg = varray[coloroff + 1]; - cb = varray[coloroff + 2]; - ca = alpha; - } - gl.glColor4f(cr, cg, cb, ca); - } else { - if ((vformat & GeometryArray.WITH_ALPHA) != 0) { // alpha is present - gl.glColor4f(varray[coloroff], - varray[coloroff + 1], - varray[coloroff + 2], - varray[coloroff + 3]); - } else { - gl.glColor3f(varray[coloroff], - varray[coloroff + 1], - varray[coloroff + 2]); - } - } - } - - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - int vaOff = vAttrOff; - if (verts == null) { - verts = FloatBuffer.wrap(varray); - } - for (int vaIdx = 0; vaIdx < vertexAttrCount; vaIdx++) { - switch (vertexAttrSizes[vaIdx]) { - case 1: - verts.position(vaOff); - jctx.vertexAttr1fv(gl, vaIdx, verts); - break; - case 2: - verts.position(vaOff); - jctx.vertexAttr2fv(gl, vaIdx, verts); - break; - case 3: - verts.position(vaOff); - jctx.vertexAttr3fv(gl, vaIdx, verts); - break; - case 4: - verts.position(vaOff); - jctx.vertexAttr4fv(gl, vaIdx, verts); - break; - } - - vaOff += vertexAttrSizes[vaIdx]; - } - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - if (texCoordSetMapLen > 0) { - if (gl.isExtensionAvailable("GL_VERSION_1_3")) { - if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { - for (int k = 0; k < texCoordSetMapLen; k++) { - if (texCoordSetMapOffset[k] != -1) { - int off = texCoordoff + texCoordSetMapOffset[k]; - gl.glMultiTexCoord2f(GL.GL_TEXTURE0 + k, - varray[off], - varray[off + 1]); - } - } - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { - for (int k = 0; k < texCoordSetMapLen; k++) { - if (texCoordSetMapOffset[k] != -1) { - int off = texCoordoff + texCoordSetMapOffset[k]; - gl.glMultiTexCoord3f(GL.GL_TEXTURE0 + k, - varray[off], - varray[off + 1], - varray[off + 2]); - } - } - } else { - for (int k = 0; k < texCoordSetMapLen; k++) { - if (texCoordSetMapOffset[k] != -1) { - int off = texCoordoff + texCoordSetMapOffset[k]; - gl.glMultiTexCoord4f(GL.GL_TEXTURE0 + k, - varray[off], - varray[off + 1], - varray[off + 2], - varray[off + 3]); - } - } - } - } else { // no multitexture - if (texCoordSetMapOffset[0] != -1) { - int off = texCoordoff + texCoordSetMapOffset[0]; - if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { - gl.glTexCoord2f(varray[off], varray[off + 1]); - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { - gl.glTexCoord3f(varray[off], varray[off + 1], varray[off + 2]); - } else { - gl.glTexCoord4f(varray[off], varray[off + 1], varray[off + 2], varray[off + 3]); - } - } - } // no multitexture - } - // texCoordSetMapLen can't be 0 if texture coordinates is - // to be specified - } - - if ((vformat & GeometryArray.COORDINATES) != 0) { - if (xform != null) { - // transform the vertex data with the static transform - float w = (float) (xform[12] * varray[coordoff] + - xform[13] * varray[coordoff+1] + - xform[14] * varray[coordoff+2] + - xform[15]); - float winv = 1.0f/w; - float vx = (float) (xform[0] * varray[coordoff] + - xform[1] * varray[coordoff+1] + - xform[2] * varray[coordoff+2] + - xform[3]) * winv; - float vy = (float) (xform[4] * varray[coordoff] + - xform[5] * varray[coordoff+1] + - xform[6] * varray[coordoff+2] + - xform[7]) * winv; - float vz = (float) (xform[8] * varray[coordoff] + - xform[9] * varray[coordoff+1] + - xform[10] * varray[coordoff+2] + - xform[11]) * winv; - gl.glVertex3f(vx, vy, vz); - } else { - gl.glVertex3f(varray[coordoff], varray[coordoff + 1], varray[coordoff + 2]); - } - } - normoff += stride; - coloroff += stride; - coordoff += stride; - texCoordoff += stride; - vAttrOff += stride; - } - gl.glEnd(); - } - } - - // used to Build Dlist GeometryArray by Reference with java arrays - void buildGAForByRef(Context ctx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, boolean updateAlpha, - float alpha, - boolean ignoreVertexColors, - int vcount, - int vformat, - int vdefined, - int initialCoordIndex, float[] vfcoords, double[] vdcoords, - int initialColorIndex, float[] cfdata, byte[] cbdata, - int initialNormalIndex, float[] ndata, - int vertexAttrCount, int[] vertexAttrSizes, - int[] vertexAttrIndices, float[][] vertexAttrData, - int texCoordMapLength, - int[] tcoordsetmap, - int[] texIndices, int texStride, Object[] texCoords, - double[] xform, double[] nxform) { - if (VERBOSE) System.err.println("JoglPipeline.buildGAForByRef()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); - boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); - boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); - boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); - boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); - boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); - boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); - - FloatBuffer fverts = null; - DoubleBuffer dverts = null; - FloatBuffer fclrs = null; - ByteBuffer bclrs = null; - FloatBuffer[] texCoordBufs = null; - FloatBuffer norms = null; - FloatBuffer[] vertexAttrBufs = null; - - // Get vertex attribute arrays - if (vattrDefined) { - vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData); - } - - // get texture arrays - if (textureDefined) { - texCoordBufs = getTexCoordSetBuffer(texCoords); - } - - // process alpha for geometryArray without alpha - boolean useAlpha = false; - if (updateAlpha && !ignoreVertexColors) { - useAlpha = true; - } - - int[] sarray = null; - int[] start_array = null; - int strip_len = 0; - if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { - sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts; - strip_len = sarray.length; - start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices; - } - - if (ignoreVertexColors) { - vformat &= ~GeometryArray.COLOR; - floatColorsDefined = false; - byteColorsDefined = false; - } - - // get coordinate array - if (floatCoordDefined) { - gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); - fverts = getVertexArrayBuffer(vfcoords, (xform == null)); - if (xform != null) { - // Must copy in and transform data - for (int i = initialCoordIndex; i < vcount * 3; i += 3) { - fverts.put(i , (float) (xform[0] * vfcoords[i] + - xform[1] * vfcoords[i+1] + - xform[2] * vfcoords[i+2])); - fverts.put(i+1, (float) (xform[4] * vfcoords[i] + - xform[5] * vfcoords[i+1] + - xform[6] * vfcoords[i+2])); - fverts.put(i+2, (float) (xform[8] * vfcoords[i] + - xform[9] * vfcoords[i+1] + - xform[10] * vfcoords[i+2])); - } - } - } else if (doubleCoordDefined) { - gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); - dverts = getVertexArrayBuffer(vdcoords, (xform == null)); - if (xform != null) { - // Must copy in and transform data - for (int i = initialCoordIndex; i < vcount * 3; i += 3) { - dverts.put(i , (xform[0] * vdcoords[i] + - xform[1] * vdcoords[i+1] + - xform[2] * vdcoords[i+2])); - dverts.put(i+1, (xform[4] * vdcoords[i] + - xform[5] * vdcoords[i+1] + - xform[6] * vdcoords[i+2])); - dverts.put(i+2, (xform[8] * vdcoords[i] + - xform[9] * vdcoords[i+1] + - xform[10] * vdcoords[i+2])); - } - } - } else { - gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); - } - - // get color array - if (floatColorsDefined) { - gl.glEnableClientState(GL2.GL_COLOR_ARRAY); - fclrs = getColorArrayBuffer(cfdata, !useAlpha); - if (useAlpha) { - // Must copy in and modify color data - if ((vformat & GeometryArray.WITH_ALPHA) != 0) { - for (int i = initialColorIndex; i < vcount * 4; i += 4) { - fclrs.put(i , cfdata[i]); - fclrs.put(i+1, cfdata[i+1]); - fclrs.put(i+2, cfdata[i+2]); - fclrs.put(i+3, alpha * cfdata[i+3]); - } - } else { - int k = 0; - for (int i = initialColorIndex; i < vcount * 4; i += 4) { - fclrs.put(i , cfdata[k++]); - fclrs.put(i+1, cfdata[k++]); - fclrs.put(i+2, cfdata[k++]); - fclrs.put(i+3, alpha); - } - } - vformat |= GeometryArray.WITH_ALPHA; - } - } else if (byteColorsDefined) { - gl.glEnableClientState(GL2.GL_COLOR_ARRAY); - bclrs = getColorArrayBuffer(cbdata, !useAlpha); - if (useAlpha) { - // Must copy in and modify color data - if ((vformat & GeometryArray.WITH_ALPHA) != 0) { - for (int i = initialColorIndex; i < vcount * 4; i += 4) { - bclrs.put(i , cbdata[i]); - bclrs.put(i+1, cbdata[i+1]); - bclrs.put(i+2, cbdata[i+2]); - bclrs.put(i+3, (byte) (alpha * (int) (cbdata[i+3] & 0xFF))); - } - } else { - int k = 0; - for (int i = initialColorIndex; i < vcount * 4; i += 4) { - bclrs.put(i , cbdata[k++]); - bclrs.put(i+1, cbdata[k++]); - bclrs.put(i+2, cbdata[k++]); - bclrs.put(i+3, (byte) (alpha * 255.0f)); - } - } - vformat |= GeometryArray.WITH_ALPHA; - } - } else { - gl.glDisableClientState(GL2.GL_COLOR_ARRAY); - } - - // get normal array - if (normalsDefined) { - gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); - norms = getNormalArrayBuffer(ndata, (nxform == null)); - if (nxform != null) { - // Must copy in and transform data - for (int i = initialNormalIndex; i < vcount * 3; i += 3) { - norms.put(i , (float) (nxform[0] * ndata[i] + - nxform[1] * ndata[i+1] + - nxform[2] * ndata[i+2])); - norms.put(i+1, (float) (nxform[4] * ndata[i] + - nxform[5] * ndata[i+1] + - nxform[6] * ndata[i+2])); - norms.put(i+2, (float) (nxform[8] * ndata[i] + - nxform[9] * ndata[i+1] + - nxform[10] * ndata[i+2])); - } - } - } else { - gl.glDisableClientState(GL2.GL_NORMAL_ARRAY); - } - - executeGeometryArrayVA(ctx, geo, geo_type, - isNonUniformScale, ignoreVertexColors, - vcount, vformat, vdefined, - initialCoordIndex, fverts, dverts, - initialColorIndex, fclrs, bclrs, - initialNormalIndex, norms, - vertexAttrCount, vertexAttrSizes, - vertexAttrIndices, vertexAttrBufs, - texCoordMapLength, - tcoordsetmap, texCoordMapLength, - texIndices, texStride, texCoordBufs, 0, - sarray, strip_len, start_array); - } - - //---------------------------------------------------------------------- - // Private helper methods for GeometryArrayRetained - // - - private void - testForInterleavedArrays(int vformat, - boolean[] useInterleavedArrays, - int[] iaFormat) { - if (VERBOSE) System.err.println("JoglPipeline.testForInterleavedArrays()"); - useInterleavedArrays[0] = true; - switch (vformat) { - case GeometryArray.COORDINATES : - iaFormat[0] = GL2.GL_V3F; break; - case (GeometryArray.COORDINATES | GeometryArray.NORMALS) : - iaFormat[0] = GL2.GL_N3F_V3F; break; - case (GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2) : - iaFormat[0] = GL2.GL_T2F_V3F; break; - case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR) : - case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR | GeometryArray.WITH_ALPHA) : - iaFormat[0] = GL2.GL_C4F_N3F_V3F; break; - case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.TEXTURE_COORDINATE_2) : - iaFormat[0] = GL2.GL_T2F_N3F_V3F; break; - case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR | GeometryArray.TEXTURE_COORDINATE_2): - case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR | GeometryArray.WITH_ALPHA | GeometryArray.TEXTURE_COORDINATE_2): - iaFormat[0] = GL2.GL_T2F_C4F_N3F_V3F; break; - default: - useInterleavedArrays[0] = false; break; - } - } - - private void - enableTexCoordPointer(GL2 gl, - int texUnit, - int texSize, - int texDataType, - int stride, - Buffer pointer) { - if (VERBOSE) System.err.println("JoglPipeline.enableTexCoordPointer()"); - clientActiveTextureUnit(gl, texUnit); - gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY); - gl.glTexCoordPointer(texSize, texDataType, stride, pointer); - } - - private void disableTexCoordPointer(GL2 gl, int texUnit) { - if (VERBOSE) System.err.println("JoglPipeline.disableTexCoordPointer()"); - clientActiveTextureUnit(gl, texUnit); - gl.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY); - } - - private void clientActiveTextureUnit(GL2 gl, int texUnit) { - if (VERBOSE) System.err.println("JoglPipeline.clientActiveTextureUnit()"); - if (gl.isExtensionAvailable("GL_VERSION_1_3")) { - gl.glClientActiveTexture(texUnit + GL.GL_TEXTURE0); - } - } - - - private void - executeTexture(int texCoordSetMapLen, - int texSize, int bstride, int texCoordoff, - int[] texCoordSetMapOffset, - int numActiveTexUnit, - FloatBuffer verts, GL2 gl) { - if (VERBOSE) System.err.println("JoglPipeline.executeTexture()"); - int tus = 0; /* texture unit state index */ - - for (int i = 0; i < numActiveTexUnit; i++) { - - tus = i; - - /* - * it's possible thattexture unit state index (tus) - * is greater than the texCoordSetMapOffsetLen, in this - * case, just disable TexCoordPointer. - */ - if ((tus < texCoordSetMapLen) && - (texCoordSetMapOffset[tus] != -1)) { - if (EXTRA_DEBUGGING) { - System.err.println(" texCoord position " + i + ": " + (texCoordoff + texCoordSetMapOffset[tus])); - } - verts.position(texCoordoff + texCoordSetMapOffset[tus]); - enableTexCoordPointer(gl, i, - texSize, GL.GL_FLOAT, bstride, - verts); - } else { - disableTexCoordPointer(gl, i); - } - } - } - - private void resetTexture(GL2 gl, JoglContext ctx) { - if (VERBOSE) System.err.println("JoglPipeline.resetTexture()"); - /* Disable texture coordinate arrays for all texture units */ - for (int i = 0; i < ctx.getMaxTexCoordSets(); i++) { - disableTexCoordPointer(gl, i); - } - /* Reset client active texture unit to 0 */ - clientActiveTextureUnit(gl, 0); - } - - private void - executeGeometryArray(Context absCtx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, - boolean useAlpha, - boolean ignoreVertexColors, - int startVIndex, int vcount, int vformat, - int texCoordSetCount, int[] texCoordSetMap, - int texCoordSetMapLen, - int[] texCoordSetMapOffset, - int numActiveTexUnitState, - int vertexAttrCount, int[] vertexAttrSizes, - float[] varray, Buffer varrayBuffer, - float[] carray, int cDirty) { - if (VERBOSE) System.err.println("JoglPipeline.executeGeometryArray()"); - JoglContext ctx = (JoglContext) absCtx; - GLContext context = context(ctx); - GL2 gl = context.getGL().getGL2(); - - boolean useInterleavedArrays; - int iaFormat = 0; - int primType = 0; - int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0; - int texSize = 0, texStride = 0; - int vAttrOff = 0; - int vAttrStride = 0; - int bstride = 0, cbstride = 0; - FloatBuffer verts = null; - FloatBuffer clrs = null; - int[] sarray = null; - int[] start_array = null; - - if (EXTRA_DEBUGGING) { - System.err.println("Vertex format: " + getVertexDescription(vformat)); - System.err.println("Geometry type: " + getGeometryDescription(geo_type)); - if (carray != null) { - System.err.println(" Separate color array"); - } else { - System.err.println(" Colors (if any) interleaved"); - } - } - - if ((vformat & GeometryArray.COORDINATES) != 0) { - stride += 3; - } - if ((vformat & GeometryArray.NORMALS) != 0) { - stride += 3; - coordoff += 3; - } - if ((vformat & GeometryArray.COLOR) != 0) { - if ((vformat & GeometryArray.WITH_ALPHA) != 0 ) { - stride += 4; - normoff += 4; - coordoff += 4; - } else { /* Handle the case of executeInterleaved 3f */ - stride += 3; - normoff += 3; - coordoff += 3; - } - } - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - if (EXTRA_DEBUGGING) { - System.err.println(" Number of tex coord sets: " + texCoordSetCount); - } - if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { - texSize = 2; - texStride = 2 * texCoordSetCount; - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { - texSize = 3; - texStride = 3 * texCoordSetCount; - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { - texSize = 4; - texStride = 4 * texCoordSetCount; - } - stride += texStride; - normoff += texStride; - coloroff += texStride; - coordoff += texStride; - } - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - for (int i = 0; i < vertexAttrCount; i++) { - vAttrStride += vertexAttrSizes[i]; - } - stride += vAttrStride; - normoff += vAttrStride; - coloroff += vAttrStride; - coordoff += vAttrStride; - texCoordoff += vAttrStride; - } - - bstride = stride * Buffers.SIZEOF_FLOAT; - - if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { - sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts; - start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices; - } - - // We have to copy if the data isn't specified using NIO - if (varray != null) { - verts = getVertexArrayBuffer(varray); - } else if (varrayBuffer != null) { - verts = (FloatBuffer) varrayBuffer; - } else { - // This should never happen - throw new AssertionError("Unable to get vertex pointer"); - } - - // using byRef interleaved array and has a separate pointer, then .. - int cstride = stride; - if (carray != null) { - clrs = getColorArrayBuffer(carray); - cstride = 4; - } else { - // FIXME: need to "auto-slice" this buffer later - clrs = verts; - } - - cbstride = cstride * Buffers.SIZEOF_FLOAT; - - // Enable normalize for non-uniform scale (which rescale can't handle) - if (isNonUniformScale) { - gl.glEnable(GL2.GL_NORMALIZE); - } - - int startVertex = stride * startVIndex; - int startClrs = cstride * startVIndex; - if (clrs == verts) { - startClrs += coloroff; - } - - /*** Handle non-indexed strip GeometryArray first *******/ - if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { - if (ignoreVertexColors || (carray != null) || - ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || - (texCoordSetCount > 1)))) { - useInterleavedArrays = false; - } else { - boolean[] tmp = new boolean[1]; - int[] tmp2 = new int[1]; - testForInterleavedArrays(vformat, tmp, tmp2); - useInterleavedArrays = tmp[0]; - iaFormat = tmp2[0]; - } - if (useInterleavedArrays) { - verts.position(startVertex); - gl.glInterleavedArrays(iaFormat, bstride, verts); - } else { - if ((vformat & GeometryArray.NORMALS) != 0) { - verts.position(startVertex + normoff); - gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); - } - if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) { - if (EXTRA_DEBUGGING) { - System.err.println(" Doing colors"); - } - clrs.position(startClrs); - if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) { - gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs); - } else { - gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs); - } - } - if ((vformat & GeometryArray.COORDINATES) != 0) { - verts.position(startVertex + coordoff); - gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - executeTexture(texCoordSetMapLen, - texSize, bstride, texCoordoff, - texCoordSetMapOffset, - numActiveTexUnitState, - verts, gl); - } - - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - int vAttrOffset = startVertex + vAttrOff; - for (int i = 0; i < vertexAttrCount; i++) { - ctx.enableVertexAttrArray(gl, i); - verts.position(vAttrOffset); - ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], - GL.GL_FLOAT, bstride, verts); - vAttrOffset += vertexAttrSizes[i]; - } - } - } - - switch (geo_type) { - case GeometryRetained.GEO_TYPE_TRI_STRIP_SET: - primType = GL.GL_TRIANGLE_STRIP; - break; - case GeometryRetained.GEO_TYPE_TRI_FAN_SET: - primType = GL.GL_TRIANGLE_FAN; - break; - case GeometryRetained.GEO_TYPE_LINE_STRIP_SET: - primType = GL.GL_LINE_STRIP; - break; - } - - if (gl.isExtensionAvailable("GL_EXT_multi_draw_arrays")) { - gl.glMultiDrawArrays(primType, start_array, 0, sarray, 0, sarray.length); - } else { - for (int i = 0; i < sarray.length; i++) { - gl.glDrawArrays(primType, start_array[i], sarray[i]); - } - } - } else if ((geo_type == GeometryRetained.GEO_TYPE_QUAD_SET) || - (geo_type == GeometryRetained.GEO_TYPE_TRI_SET) || - (geo_type == GeometryRetained.GEO_TYPE_POINT_SET) || - (geo_type == GeometryRetained.GEO_TYPE_LINE_SET)) { - /******* Handle non-indexed non-striped GeometryArray now *****/ - if (ignoreVertexColors || (carray != null) || - ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || - (texCoordSetCount > 1)))) { - useInterleavedArrays = false; - } else { - boolean[] tmp = new boolean[1]; - int[] tmp2 = new int[1]; - testForInterleavedArrays(vformat, tmp, tmp2); - useInterleavedArrays = tmp[0]; - iaFormat = tmp2[0]; - } - - if (useInterleavedArrays) { - verts.position(startVertex); - gl.glInterleavedArrays(iaFormat, bstride, verts); - } else { - if (EXTRA_DEBUGGING) { - System.err.println(" startVertex: " + startVertex); - System.err.println(" stride: " + stride); - System.err.println(" bstride: " + bstride); - System.err.println(" normoff: " + normoff); - System.err.println(" coloroff: " + coloroff); - System.err.println(" coordoff: " + coordoff); - System.err.println(" texCoordoff: " + texCoordoff); - } - if ((vformat & GeometryArray.NORMALS) != 0) { - verts.position(startVertex + normoff); - gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); - } - if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) { - clrs.position(startClrs); - if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) { - gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs); - } else { - gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs); - } - } - if ((vformat & GeometryArray.COORDINATES) != 0) { - verts.position(startVertex + coordoff); - gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - executeTexture(texCoordSetMapLen, - texSize, bstride, texCoordoff, - texCoordSetMapOffset, - numActiveTexUnitState, - verts, gl); - } - - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - int vAttrOffset = startVertex + vAttrOff; - for (int i = 0; i < vertexAttrCount; i++) { - ctx.enableVertexAttrArray(gl, i); - verts.position(vAttrOffset); - ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], - GL.GL_FLOAT, bstride, verts); - vAttrOffset += vertexAttrSizes[i]; - } - } - } - switch (geo_type){ - case GeometryRetained.GEO_TYPE_QUAD_SET : gl.glDrawArrays(GL2.GL_QUADS, 0, vcount); break; - case GeometryRetained.GEO_TYPE_TRI_SET : gl.glDrawArrays(GL.GL_TRIANGLES, 0, vcount); break; - case GeometryRetained.GEO_TYPE_POINT_SET: gl.glDrawArrays(GL.GL_POINTS, 0, vcount); break; - case GeometryRetained.GEO_TYPE_LINE_SET : gl.glDrawArrays(GL.GL_LINES, 0, vcount); break; - } - } - - /* clean up if we turned on normalize */ - if (isNonUniformScale) { - gl.glDisable(GL2.GL_NORMALIZE); - } - - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - resetVertexAttrs(gl, ctx, vertexAttrCount); - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - resetTexture(gl, ctx); - } - } - - - // glLockArrays() is invoked only for indexed geometry, and the - // vertexCount is guarenteed to be >= 0. - private void lockArray(GL2 gl, int vertexCount) { - if (gl.isExtensionAvailable("GL_EXT_compiled_vertex_array")) { - gl.glLockArraysEXT(0, vertexCount); - } - } - - private void unlockArray(GL2 gl) { - if (gl.isExtensionAvailable("GL_EXT_compiled_vertex_array")) { - gl.glUnlockArraysEXT(); - } - } - - private void - executeGeometryArrayVA(Context absCtx, - GeometryArrayRetained geo, - int geo_type, - boolean isNonUniformScale, - boolean ignoreVertexColors, - int vcount, - int vformat, - int vdefined, - int initialCoordIndex, FloatBuffer fverts, DoubleBuffer dverts, - int initialColorIndex, FloatBuffer fclrs, ByteBuffer bclrs, - int initialNormalIndex, FloatBuffer norms, - int vertexAttrCount, int[] vertexAttrSizes, - int[] vertexAttrIndices, FloatBuffer[] vertexAttrData, - int texCoordMapLength, - int[] texCoordSetMap, - int numActiveTexUnit, - int[] texindices, int texStride, FloatBuffer[] texCoords, - int cdirty, - int[] sarray, - int strip_len, - int[] start_array) { - JoglContext ctx = (JoglContext) absCtx; - GLContext context = context(ctx); - GL2 gl = context.getGL().getGL2(); - - boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); - boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); - boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); - boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); - boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); - boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); - boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); - - // Enable normalize for non-uniform scale (which rescale can't handle) - if (isNonUniformScale) { - gl.glEnable(GL2.GL_NORMALIZE); - } - - int coordoff = 3 * initialCoordIndex; - // Define the data pointers - if (floatCoordDefined) { - fverts.position(coordoff); - gl.glVertexPointer(3, GL.GL_FLOAT, 0, fverts); - } else if (doubleCoordDefined){ - dverts.position(coordoff); - gl.glVertexPointer(3, GL2.GL_DOUBLE, 0, dverts); - } - - if (floatColorsDefined) { - int coloroff; - int sz; - if ((vformat & GeometryArray.WITH_ALPHA) != 0) { - coloroff = 4 * initialColorIndex; - sz = 4; - } else { - coloroff = 3 * initialColorIndex; - sz = 3; - } - fclrs.position(coloroff); - gl.glColorPointer(sz, GL.GL_FLOAT, 0, fclrs); - } else if (byteColorsDefined) { - int coloroff; - int sz; - if ((vformat & GeometryArray.WITH_ALPHA) != 0) { - coloroff = 4 * initialColorIndex; - sz = 4; - } else { - coloroff = 3 * initialColorIndex; - sz = 3; - } - bclrs.position(coloroff); - gl.glColorPointer(sz, GL.GL_UNSIGNED_BYTE, 0, bclrs); - } - if (normalsDefined) { - int normoff = 3 * initialNormalIndex; - norms.position(normoff); - gl.glNormalPointer(GL.GL_FLOAT, 0, norms); - } - - if (vattrDefined) { - for (int i = 0; i < vertexAttrCount; i++) { - FloatBuffer vertexAttrs = vertexAttrData[i]; - int sz = vertexAttrSizes[i]; - int initIdx = vertexAttrIndices[i]; - ctx.enableVertexAttrArray(gl, i); - vertexAttrs.position(initIdx * sz); - ctx.vertexAttrPointer(gl, i, sz, GL.GL_FLOAT, 0, vertexAttrs); - } - } - - if (textureDefined) { - int texSet = 0; - for (int i = 0; i < numActiveTexUnit; i++) { - if (( i < texCoordMapLength) && - ((texSet = texCoordSetMap[i]) != -1)) { - FloatBuffer buf = texCoords[texSet]; - buf.position(texStride * texindices[texSet]); - enableTexCoordPointer(gl, i, texStride, - GL.GL_FLOAT, 0, buf); - } else { - disableTexCoordPointer(gl, i); - } - } - - // Reset client active texture unit to 0 - clientActiveTextureUnit(gl, 0); - } - - if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { - int primType = 0; - switch (geo_type) { - case GeometryRetained.GEO_TYPE_TRI_STRIP_SET: - primType = GL.GL_TRIANGLE_STRIP; - break; - case GeometryRetained.GEO_TYPE_TRI_FAN_SET: - primType = GL.GL_TRIANGLE_FAN; - break; - case GeometryRetained.GEO_TYPE_LINE_STRIP_SET: - primType = GL.GL_LINE_STRIP; - break; - } - if (gl.isExtensionAvailable("GL_EXT_multi_draw_arrays")) { - gl.glMultiDrawArrays(primType, start_array, 0, sarray, 0, strip_len); - } else if (gl.isExtensionAvailable("GL_VERSION_1_4")) { - gl.glMultiDrawArrays(primType, start_array, 0, sarray, 0, strip_len); - } else { - for (int i = 0; i < strip_len; i++) { - gl.glDrawArrays(primType, start_array[i], sarray[i]); - } - } - } else { - switch (geo_type){ - case GeometryRetained.GEO_TYPE_QUAD_SET : gl.glDrawArrays(GL2.GL_QUADS, 0, vcount); break; - case GeometryRetained.GEO_TYPE_TRI_SET : gl.glDrawArrays(GL.GL_TRIANGLES, 0, vcount); break; - case GeometryRetained.GEO_TYPE_POINT_SET : gl.glDrawArrays(GL.GL_POINTS, 0, vcount); break; - case GeometryRetained.GEO_TYPE_LINE_SET : gl.glDrawArrays(GL.GL_LINES, 0, vcount); break; - } - } - - // clean up if we turned on normalize - if (isNonUniformScale) { - gl.glDisable(GL2.GL_NORMALIZE); - } - - if (vattrDefined) { - resetVertexAttrs(gl, ctx, vertexAttrCount); - } - - if (textureDefined) { - resetTexture(gl, ctx); - } - } - - private String getVertexDescription(int vformat) { - String res = ""; - if ((vformat & GeometryArray.COORDINATES) != 0) res += "COORDINATES "; - if ((vformat & GeometryArray.NORMALS) != 0) res += "NORMALS "; - if ((vformat & GeometryArray.COLOR) != 0) res += "COLOR "; - if ((vformat & GeometryArray.WITH_ALPHA) != 0) res += "(WITH_ALPHA) "; - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) res += "TEXTURE_COORDINATE "; - if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) res += "(2) "; - if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) res += "(3) "; - if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) res += "(4) "; - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) res += "VERTEX_ATTRIBUTES "; - return res; - } - - private String getGeometryDescription(int geo_type) { - switch (geo_type) { - case GeometryRetained.GEO_TYPE_TRI_STRIP_SET : return "GEO_TYPE_TRI_STRIP_SET"; - case GeometryRetained.GEO_TYPE_TRI_FAN_SET : return "GEO_TYPE_TRI_FAN_SET"; - case GeometryRetained.GEO_TYPE_LINE_STRIP_SET: return "GEO_TYPE_LINE_STRIP_SET"; - case GeometryRetained.GEO_TYPE_QUAD_SET : return "GEO_TYPE_QUAD_SET"; - case GeometryRetained.GEO_TYPE_TRI_SET : return "GEO_TYPE_TRI_SET"; - case GeometryRetained.GEO_TYPE_POINT_SET : return "GEO_TYPE_POINT_SET"; - case GeometryRetained.GEO_TYPE_LINE_SET : return "GEO_TYPE_LINE_SET"; - default: return "(unknown " + geo_type + ")"; - } - } - - private void resetVertexAttrs(GL gl, JoglContext ctx, int vertexAttrCount) { - // Disable specified vertex attr arrays - for (int i = 0; i < vertexAttrCount; i++) { - ctx.disableVertexAttrArray(gl, i); - } - } - - - // --------------------------------------------------------------------- - - // - // IndexedGeometryArrayRetained methods - // - - // by-copy or interleaved, by reference, Java arrays - void executeIndexedGeometry(Context ctx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, - boolean useAlpha, - boolean ignoreVertexColors, - int initialIndexIndex, - int indexCount, - int vertexCount, int vformat, - int vertexAttrCount, int[] vertexAttrSizes, - int texCoordSetCount, int[] texCoordSetMap, - int texCoordSetMapLen, - int[] texCoordSetOffset, - int numActiveTexUnitState, - float[] varray, float[] carray, - int cdirty, - int[] indexCoord) { - if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometry()"); - - executeIndexedGeometryArray(ctx, geo, geo_type, - isNonUniformScale, useAlpha, ignoreVertexColors, - initialIndexIndex, indexCount, - vertexCount, vformat, - vertexAttrCount, vertexAttrSizes, - texCoordSetCount, texCoordSetMap, texCoordSetMapLen, - texCoordSetOffset, - numActiveTexUnitState, - varray, null, carray, - cdirty, indexCoord); - } - - // interleaved, by reference, nio buffer - void executeIndexedGeometryBuffer(Context ctx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, - boolean useAlpha, - boolean ignoreVertexColors, - int initialIndexIndex, - int indexCount, - int vertexCount, int vformat, - int texCoordSetCount, int[] texCoordSetMap, - int texCoordSetMapLen, - int[] texCoordSetOffset, - int numActiveTexUnitState, - Object vdata, float[] carray, - int cDirty, - int[] indexCoord) { - if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometryBuffer()"); - - executeIndexedGeometryArray(ctx, geo, geo_type, - isNonUniformScale, useAlpha, ignoreVertexColors, - initialIndexIndex, indexCount, vertexCount, vformat, - 0, null, - texCoordSetCount, texCoordSetMap, texCoordSetMapLen, texCoordSetOffset, - numActiveTexUnitState, - null, (FloatBuffer) vdata, carray, - cDirty, indexCoord); - } - - // non interleaved, by reference, Java arrays - void executeIndexedGeometryVA(Context ctx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, - boolean ignoreVertexColors, - int initialIndexIndex, - int validIndexCount, - int vertexCount, - int vformat, - int vdefined, - float[] vfcoords, double[] vdcoords, - float[] cfdata, byte[] cbdata, - float[] ndata, - int vertexAttrCount, int[] vertexAttrSizes, - float[][] vertexAttrData, - int texCoordMapLength, - int[] texcoordoffset, - int numActiveTexUnitState, - int texStride, Object[] texCoords, - int cdirty, - int[] indexCoord) { - if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometryVA()"); - - boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); - boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); - boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); - boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); - boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); - boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); - boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); - - FloatBuffer fverts = null; - DoubleBuffer dverts = null; - FloatBuffer fclrs = null; - ByteBuffer bclrs = null; - FloatBuffer[] texCoordBufs = null; - FloatBuffer norms = null; - FloatBuffer[] vertexAttrBufs = null; - - // Get vertex attribute arrays - if (vattrDefined) { - vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData); - } - - // get texture arrays - if (textureDefined) { - texCoordBufs = getTexCoordSetBuffer(texCoords); - } - - int[] sarray = null; - int strip_len = 0; - if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { - sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts; - strip_len = sarray.length; - } - - // get coordinate array - if (floatCoordDefined) { - fverts = getVertexArrayBuffer(vfcoords); - } else if (doubleCoordDefined) { - dverts = getVertexArrayBuffer(vdcoords); - } - - // get color array - if (floatColorsDefined) { - fclrs = getColorArrayBuffer(cfdata); - } else if (byteColorsDefined) { - bclrs = getColorArrayBuffer(cbdata); - } - - // get normal array - if (normalsDefined) { - norms = getNormalArrayBuffer(ndata); - } - - executeIndexedGeometryArrayVA(ctx, geo, geo_type, - isNonUniformScale, ignoreVertexColors, - initialIndexIndex, validIndexCount, vertexCount, - vformat, vdefined, - fverts, dverts, - fclrs, bclrs, - norms, - vertexAttrCount, vertexAttrSizes, vertexAttrBufs, - texCoordMapLength, texcoordoffset, - numActiveTexUnitState, - texStride, texCoordBufs, - cdirty, indexCoord, - sarray, strip_len); - } - - // non interleaved, by reference, nio buffer - void executeIndexedGeometryVABuffer(Context ctx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, - boolean ignoreVertexColors, - int initialIndexIndex, - int validIndexCount, - int vertexCount, - int vformat, - int vdefined, - Object vcoords, - Object cdataBuffer, - float[] cfdata, byte[] cbdata, - Object ndata, - int vertexAttrCount, int[] vertexAttrSizes, - Object[] vertexAttrData, - int texCoordMapLength, - int[] texcoordoffset, - int numActiveTexUnitState, - int texStride, Object[] texCoords, - int cdirty, - int[] indexCoord) { - if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometryVABuffer()"); - - boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); - boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); - boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); - boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); - boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); - boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); - boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); - - FloatBuffer fverts = null; - DoubleBuffer dverts = null; - FloatBuffer fclrs = null; - ByteBuffer bclrs = null; - FloatBuffer[] texCoordBufs = null; - FloatBuffer norms = null; - FloatBuffer[] vertexAttrBufs = null; - - // Get vertex attribute arrays - if (vattrDefined) { - vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData); - } - - // get texture arrays - if (textureDefined) { - texCoordBufs = new FloatBuffer[texCoords.length]; - for (int i = 0; i < texCoords.length; i++) { - texCoordBufs[i] = (FloatBuffer) texCoords[i]; - } - } - - // get coordinate array - if (floatCoordDefined) { - fverts = (FloatBuffer) vcoords; - } else if (doubleCoordDefined) { - dverts = (DoubleBuffer) vcoords; - } - - if (fverts == null && dverts == null) { - return; - } - - int[] sarray = null; - int strip_len = 0; - if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { - sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts; - strip_len = sarray.length; - } - - // get color array - if (floatColorsDefined) { - if (cfdata != null) - fclrs = getColorArrayBuffer(cfdata); - else - fclrs = (FloatBuffer) cdataBuffer; - } else if (byteColorsDefined) { - if (cbdata != null) - bclrs = getColorArrayBuffer(cbdata); - else - bclrs = (ByteBuffer) cdataBuffer; - } - - // get normal array - if (normalsDefined) { - norms = (FloatBuffer) ndata; - } - - executeIndexedGeometryArrayVA(ctx, geo, geo_type, - isNonUniformScale, ignoreVertexColors, - initialIndexIndex, validIndexCount, vertexCount, - vformat, vdefined, - fverts, dverts, - fclrs, bclrs, - norms, - vertexAttrCount, vertexAttrSizes, vertexAttrBufs, - texCoordMapLength, texcoordoffset, - numActiveTexUnitState, - texStride, texCoordBufs, - cdirty, indexCoord, - sarray, strip_len); - } - - // by-copy geometry - void buildIndexedGeometry(Context absCtx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, boolean updateAlpha, - float alpha, - boolean ignoreVertexColors, - int initialIndexIndex, - int validIndexCount, - int vertexCount, - int vformat, - int vertexAttrCount, int[] vertexAttrSizes, - int texCoordSetCount, int[] texCoordSetMap, - int texCoordSetMapLen, - int[] texCoordSetMapOffset, - double[] xform, double[] nxform, - float[] varray, int[] indexCoord) { - if (VERBOSE) System.err.println("JoglPipeline.buildIndexedGeometry()"); - - JoglContext ctx = (JoglContext) absCtx; - GL2 gl = context(ctx).getGL().getGL2(); - - boolean useInterleavedArrays; - int iaFormat = 0; - int primType = 0; - int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0; - int texSize = 0, texStride = 0; - int vAttrOff = 0; - int vAttrStride = 0; - int bstride = 0, cbstride = 0; - FloatBuffer verts = null; - FloatBuffer clrs = null; - int[] sarray = null; - int strip_len = 0; - boolean useAlpha = false; - - if ((vformat & GeometryArray.COORDINATES) != 0) { - gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); - stride += 3; - } else { - gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); - } - - if ((vformat & GeometryArray.NORMALS) != 0) { - gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); - stride += 3; - coordoff += 3; - } else { - gl.glDisableClientState(GL2.GL_NORMAL_ARRAY); - } - - if ((vformat & GeometryArray.COLOR) != 0) { - gl.glEnableClientState(GL2.GL_COLOR_ARRAY); - stride += 4; - normoff += 4; - coordoff += 4; - } else { - gl.glDisableClientState(GL2.GL_COLOR_ARRAY); - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { - texSize = 2; - texStride = 2 * texCoordSetCount; - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { - texSize = 3; - texStride = 3 * texCoordSetCount; - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { - texSize = 4; - texStride = 4 * texCoordSetCount; - } - stride += texStride; - normoff += texStride; - coloroff += texStride; - coordoff += texStride; - } - - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - for (int i = 0; i < vertexAttrCount; i++) { - vAttrStride += vertexAttrSizes[i]; - } - stride += vAttrStride; - normoff += vAttrStride; - coloroff += vAttrStride; - coordoff += vAttrStride; - texCoordoff += vAttrStride; - } - - bstride = stride * Buffers.SIZEOF_FLOAT; - - // process alpha for geometryArray without alpha - if (updateAlpha && !ignoreVertexColors) { - useAlpha = true; - } - - if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { - sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts; - strip_len = sarray.length; - } - - // Copy data into NIO array - verts = getVertexArrayBuffer(varray); - - // Apply normal transform if necessary - if ((vformat & GeometryArray.NORMALS) != 0 && nxform != null) { - int off = normoff; - for (int i = 0; i < vertexCount * 3; i+=3) { - verts.put(off , (float) (nxform[0] * varray[off] + - nxform[1] * varray[off+1] + - nxform[2] * varray[off+2])); - verts.put(off+1, (float) (nxform[4] * varray[off] + - nxform[5] * varray[off+1] + - nxform[6] * varray[off+2])); - verts.put(off+2, (float) (nxform[8] * varray[off] + - nxform[9] * varray[off+1] + - nxform[10] * varray[off+2])); - off += stride; - } - } - - // Apply coordinate transform if necessary - if ((vformat & GeometryArray.COORDINATES) != 0 && xform != null) { - int off = coordoff; - for (int i = 0; i < vertexCount * 3; i+=3) { - verts.put(off , (float) (xform[0] * varray[off] + - xform[1] * varray[off+1] + - xform[2] * varray[off+2])); - verts.put(off+1, (float) (xform[4] * varray[off] + - xform[5] * varray[off+1] + - xform[6] * varray[off+2])); - verts.put(off+2, (float) (xform[8] * varray[off] + - xform[9] * varray[off+1] + - xform[10] * varray[off+2])); - off += stride; - } - } - - if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { - // Note we can use interleaved arrays even if we have a - // non-null xform since we use the same data layout unlike the - // C code - if (ignoreVertexColors || - (((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) && ((texCoordSetMapLen > 1) || - (texCoordSetCount > 1)))) { - useInterleavedArrays = false; - } else { - boolean[] tmp = new boolean[1]; - int[] tmp2 = new int[1]; - testForInterleavedArrays(vformat, tmp, tmp2); - useInterleavedArrays = tmp[0]; - iaFormat = tmp2[0]; - } - - if (useInterleavedArrays) { - verts.position(0); - gl.glInterleavedArrays(iaFormat, bstride, verts); - } else { - if ((vformat & GeometryArray.NORMALS) != 0) { - verts.position(normoff); - gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); - } - if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) { - verts.position(coloroff); - if (((vformat & GeometryArray.WITH_ALPHA) != 0) || useAlpha) { - gl.glColorPointer(4, GL.GL_FLOAT, bstride, verts); - } else { - gl.glColorPointer(3, GL.GL_FLOAT, bstride, verts); - } - } - if ((vformat & GeometryArray.COORDINATES) != 0) { - verts.position(coordoff); - gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); - } - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - executeTexture(texCoordSetMapLen, - texSize, bstride, texCoordoff, - texCoordSetMapOffset, - texCoordSetMapLen, - verts, gl); - } - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - int vAttrOffset = vAttrOff; - for (int i = 0; i < vertexAttrCount; i++) { - ctx.enableVertexAttrArray(gl, i); - verts.position(vAttrOffset); - ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], - GL.GL_FLOAT, bstride, verts); - vAttrOffset += vertexAttrSizes[i]; - } - } - } - - switch (geo_type) { - case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET: - primType = GL.GL_TRIANGLE_STRIP; - break; - case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET: - primType = GL.GL_TRIANGLE_FAN; - break; - case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET: - primType = GL.GL_LINE_STRIP; - break; - } - - lockArray(gl, vertexCount); - - // Note: using MultiDrawElements is probably more expensive than - // not in this case due to the need to allocate more temporary - // direct buffers and slice up the incoming indices array - int offset = initialIndexIndex; - IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord); - for (int i = 0; i < strip_len; i++) { - indicesBuffer.position(offset); - int count = sarray[i]; - gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT, indicesBuffer); - offset += count; - } - } else if ((geo_type == GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET) || - (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_SET) || - (geo_type == GeometryRetained.GEO_TYPE_INDEXED_POINT_SET) || - (geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_SET)) { - // Note we can use interleaved arrays even if we have a - // non-null xform since we use the same data layout unlike the - // C code - if (ignoreVertexColors || - (((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) && ((texCoordSetMapLen > 1) || - (texCoordSetCount > 1)))) { - useInterleavedArrays = false; - } else { - boolean[] tmp = new boolean[1]; - int[] tmp2 = new int[1]; - testForInterleavedArrays(vformat, tmp, tmp2); - useInterleavedArrays = tmp[0]; - iaFormat = tmp2[0]; - } - - if (useInterleavedArrays) { - verts.position(0); - gl.glInterleavedArrays(iaFormat, bstride, verts); - } else { - if ((vformat & GeometryArray.NORMALS) != 0) { - verts.position(normoff); - gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); - } - - if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) { - verts.position(coloroff); - if (((vformat & GeometryArray.WITH_ALPHA) != 0) || useAlpha) { - gl.glColorPointer(4, GL.GL_FLOAT, bstride, verts); - } else { - gl.glColorPointer(3, GL.GL_FLOAT, bstride, verts); - } - } - if ((vformat & GeometryArray.COORDINATES) != 0) { - verts.position(coordoff); - gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); - } - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - executeTexture(texCoordSetMapLen, - texSize, bstride, texCoordoff, - texCoordSetMapOffset, - texCoordSetMapLen, - verts, gl); - } - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - int vAttrOffset = vAttrOff; - for (int i = 0; i < vertexAttrCount; i++) { - ctx.enableVertexAttrArray(gl, i); - verts.position(vAttrOffset); - ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], - GL.GL_FLOAT, bstride, verts); - vAttrOffset += vertexAttrSizes[i]; - } - } - - switch (geo_type) { - case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET : - primType = GL2.GL_QUADS; - break; - case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET : - primType = GL.GL_TRIANGLES; - break; - case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET : - primType = GL.GL_POINTS; - break; - case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET : - primType = GL.GL_LINES; - break; - } - - lockArray(gl, vertexCount); - - IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord); - indicesBuffer.position(initialIndexIndex); - gl.glDrawElements(primType, validIndexCount, GL.GL_UNSIGNED_INT, indicesBuffer); - } - } - - unlockArray(gl); - - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - resetVertexAttrs(gl, ctx, vertexAttrCount); - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - resetTexture(gl, ctx); - } - } - - - //---------------------------------------------------------------------- - // - // Helper routines for IndexedGeometryArrayRetained - // - - private void executeIndexedGeometryArray(Context absCtx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, - boolean useAlpha, - boolean ignoreVertexColors, - int initialIndexIndex, - int indexCount, - int vertexCount, int vformat, - int vertexAttrCount, int[] vertexAttrSizes, - int texCoordSetCount, int[] texCoordSetMap, - int texCoordSetMapLen, - int[] texCoordSetOffset, - int numActiveTexUnitState, - float[] varray, FloatBuffer vdata, float[] carray, - int cDirty, - int[] indexCoord) { - JoglContext ctx = (JoglContext) absCtx; - GL2 gl = context(ctx).getGL().getGL2(); - - boolean useInterleavedArrays; - int iaFormat = 0; - int primType = 0; - int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0; - int texSize = 0, texStride = 0; - int vAttrOff = 0; - int vAttrStride = 0; - int bstride = 0, cbstride = 0; - FloatBuffer verts = null; - FloatBuffer clrs = null; - int[] sarray = null; - int strip_len = 0; - - if ((vformat & GeometryArray.COORDINATES) != 0) { - stride += 3; - } - if ((vformat & GeometryArray.NORMALS) != 0) { - stride += 3; - coordoff += 3; - } - - if ((vformat & GeometryArray.COLOR) != 0) { - if ((vformat & GeometryArray.WITH_ALPHA) != 0) { - stride += 4; - normoff += 4; - coordoff += 4; - } else { // Handle the case of executeInterleaved 3f - stride += 3; - normoff += 3; - coordoff += 3; - } - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { - texSize = 2; - texStride = 2 * texCoordSetCount; - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { - texSize = 3; - texStride = 3 * texCoordSetCount; - } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { - texSize = 4; - texStride = 4 * texCoordSetCount; - } - stride += texStride; - normoff += texStride; - coloroff += texStride; - coordoff += texStride; - } - - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - for (int i = 0; i < vertexAttrCount; i++) { - vAttrStride += vertexAttrSizes[i]; - } - stride += vAttrStride; - normoff += vAttrStride; - coloroff += vAttrStride; - coordoff += vAttrStride; - texCoordoff += vAttrStride; - } - - bstride = stride * Buffers.SIZEOF_FLOAT; - - if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { - sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts; - strip_len = sarray.length; - } - - // We have to copy if the data isn't specified using NIO - if (varray != null) { - verts = getVertexArrayBuffer(varray); - } else if (vdata != null) { - verts = vdata; - } else { - // This should never happen - throw new AssertionError("Unable to get vertex pointer"); - } - - // using byRef interleaved array and has a separate pointer, then .. - int cstride = stride; - if (carray != null) { - clrs = getColorArrayBuffer(carray); - cstride = 4; - } else { - // FIXME: need to "auto-slice" this buffer later - clrs = verts; - } - - cbstride = cstride * Buffers.SIZEOF_FLOAT; - - // Enable normalize for non-uniform scale (which rescale can't handle) - if (isNonUniformScale) { - gl.glEnable(GL2.GL_NORMALIZE); - } - - /*** Handle non-indexed strip GeometryArray first *******/ - if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { - if (ignoreVertexColors || (carray != null) || - ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || - (texCoordSetCount > 1)))) { - useInterleavedArrays = false; - } else { - boolean[] tmp = new boolean[1]; - int[] tmp2 = new int[1]; - testForInterleavedArrays(vformat, tmp, tmp2); - useInterleavedArrays = tmp[0]; - iaFormat = tmp2[0]; - } - if (useInterleavedArrays) { - verts.position(0); - gl.glInterleavedArrays(iaFormat, bstride, verts); - } else { - if ((vformat & GeometryArray.NORMALS) != 0) { - verts.position(normoff); - gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); - } - if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) { - if (clrs == verts) { - clrs.position(coloroff); - } - if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) { - gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs); - } else { - gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs); - } - } - if ((vformat & GeometryArray.COORDINATES) != 0) { - verts.position(coordoff); - gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - /* XXXX: texCoordoff == 0 ???*/ - executeTexture(texCoordSetMapLen, - texSize, bstride, texCoordoff, - texCoordSetOffset, - numActiveTexUnitState, - verts, gl); - } - - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - int vAttrOffset = vAttrOff; - for (int i = 0; i < vertexAttrCount; i++) { - ctx.enableVertexAttrArray(gl, i); - verts.position(vAttrOffset); - ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], - GL.GL_FLOAT, bstride, verts); - vAttrOffset += vertexAttrSizes[i]; - } - } - } - - switch (geo_type) { - case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET: - primType = GL.GL_TRIANGLE_STRIP; - break; - case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET: - primType = GL.GL_TRIANGLE_FAN; - break; - case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET: - primType = GL.GL_LINE_STRIP; - break; - } - - lockArray(gl, vertexCount); - - // Note: using MultiDrawElements is probably more expensive than - // not in this case due to the need to allocate more temporary - // direct buffers and slice up the incoming indices array - int offset = initialIndexIndex; - IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord); - for (int i = 0; i < strip_len; i++) { - indicesBuffer.position(offset); - int count = sarray[i]; - gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT, indicesBuffer); - offset += count; - } - } else if ((geo_type == GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET) || - (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_SET) || - (geo_type == GeometryRetained.GEO_TYPE_INDEXED_POINT_SET) || - (geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_SET)) { - /******* Handle non-indexed non-striped GeometryArray now *****/ - if (ignoreVertexColors || (carray != null) || - ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || - (texCoordSetCount > 1)))) { - useInterleavedArrays = false; - } else { - boolean[] tmp = new boolean[1]; - int[] tmp2 = new int[1]; - testForInterleavedArrays(vformat, tmp, tmp2); - useInterleavedArrays = tmp[0]; - iaFormat = tmp2[0]; - } - - if (useInterleavedArrays) { - verts.position(0); - gl.glInterleavedArrays(iaFormat, bstride, verts); - } else { - if ((vformat & GeometryArray.NORMALS) != 0) { - verts.position(normoff); - gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); - } - - if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) { - if (clrs == verts) { - clrs.position(coloroff); - } - if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) { - gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs); - } else { - gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs); - } - } - if ((vformat & GeometryArray.COORDINATES) != 0) { - verts.position(coordoff); - gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - /* XXXX: texCoordoff == 0 ???*/ - executeTexture(texCoordSetMapLen, - texSize, bstride, texCoordoff, - texCoordSetOffset, - numActiveTexUnitState, - verts, gl); - } - - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - int vAttrOffset = vAttrOff; - for (int i = 0; i < vertexAttrCount; i++) { - ctx.enableVertexAttrArray(gl, i); - verts.position(vAttrOffset); - ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], - GL.GL_FLOAT, bstride, verts); - vAttrOffset += vertexAttrSizes[i]; - } - } - } - - lockArray(gl, vertexCount); - IntBuffer buf = IntBuffer.wrap(indexCoord); - buf.position(initialIndexIndex); - switch (geo_type){ - case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET : gl.glDrawElements(GL2.GL_QUADS, indexCount, GL.GL_UNSIGNED_INT, buf); break; - case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET : gl.glDrawElements(GL.GL_TRIANGLES, indexCount, GL.GL_UNSIGNED_INT, buf); break; - case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET: gl.glDrawElements(GL.GL_POINTS, indexCount, GL.GL_UNSIGNED_INT, buf); break; - case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET : gl.glDrawElements(GL.GL_LINES, indexCount, GL.GL_UNSIGNED_INT, buf); break; - } - } - - unlockArray(gl); - - if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { - resetVertexAttrs(gl, ctx, vertexAttrCount); - } - - if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { - resetTexture(gl, ctx); - } - - // clean up if we turned on normalize - if (isNonUniformScale) { - gl.glDisable(GL2.GL_NORMALIZE); - } - } - - - private void executeIndexedGeometryArrayVA(Context absCtx, - GeometryArrayRetained geo, int geo_type, - boolean isNonUniformScale, - boolean ignoreVertexColors, - int initialIndexIndex, - int validIndexCount, - int vertexCount, int vformat, int vdefined, - FloatBuffer fverts, DoubleBuffer dverts, - FloatBuffer fclrs, ByteBuffer bclrs, - FloatBuffer norms, - int vertexAttrCount, int[] vertexAttrSizes, FloatBuffer[] vertexAttrBufs, - int texCoordSetCount, int[] texCoordSetMap, - int numActiveTexUnitState, - int texStride, - FloatBuffer[] texCoords, - int cDirty, int[] indexCoord, int[] sarray, int strip_len) { - JoglContext ctx = (JoglContext) absCtx; - GL2 gl = context(ctx).getGL().getGL2(); - - boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); - boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); - boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); - boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); - boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); - boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); - boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); - - // Enable normalize for non-uniform scale (which rescale can't handle) - if (isNonUniformScale) { - gl.glEnable(GL2.GL_NORMALIZE); - } - - // Define the data pointers - if (floatCoordDefined) { - fverts.position(0); - gl.glVertexPointer(3, GL.GL_FLOAT, 0, fverts); - } else if (doubleCoordDefined){ - dverts.position(0); - gl.glVertexPointer(3, GL2.GL_DOUBLE, 0, dverts); - } - if (floatColorsDefined) { - fclrs.position(0); - if ((vformat & GeometryArray.WITH_ALPHA) != 0) { - gl.glColorPointer(4, GL.GL_FLOAT, 0, fclrs); - } else { - gl.glColorPointer(3, GL.GL_FLOAT, 0, fclrs); - } - } else if (byteColorsDefined) { - bclrs.position(0); - if ((vformat & GeometryArray.WITH_ALPHA) != 0) { - gl.glColorPointer(4, GL.GL_UNSIGNED_BYTE, 0, bclrs); - } else { - gl.glColorPointer(3, GL.GL_UNSIGNED_BYTE, 0, bclrs); - } - } - if (normalsDefined) { - norms.position(0); - gl.glNormalPointer(GL.GL_FLOAT, 0, norms); - } - - if (vattrDefined) { - for (int i = 0; i < vertexAttrCount; i++) { - FloatBuffer vertexAttrs = vertexAttrBufs[i]; - int sz = vertexAttrSizes[i]; - ctx.enableVertexAttrArray(gl, i); - vertexAttrs.position(0); - ctx.vertexAttrPointer(gl, i, sz, GL.GL_FLOAT, 0, vertexAttrs); - } - } - - if (textureDefined) { - int texSet = 0; - for (int i = 0; i < numActiveTexUnitState; i++) { - if ((i < texCoordSetCount) && - ((texSet = texCoordSetMap[i]) != -1)) { - FloatBuffer buf = texCoords[texSet]; - buf.position(0); - enableTexCoordPointer(gl, i, texStride, - GL.GL_FLOAT, 0, buf); - } else { - disableTexCoordPointer(gl, i); - } - } - - // Reset client active texture unit to 0 - clientActiveTextureUnit(gl, 0); - } - - lockArray(gl, vertexCount); - - if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || - geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { - int primType = 0; - switch (geo_type) { - case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET: - primType = GL.GL_TRIANGLE_STRIP; - break; - case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET: - primType = GL.GL_TRIANGLE_FAN; - break; - case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET: - primType = GL.GL_LINE_STRIP; - break; - } - - // Note: using MultiDrawElements is probably more expensive than - // not in this case due to the need to allocate more temporary - // direct buffers and slice up the incoming indices array - int offset = initialIndexIndex; - IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord); - for (int i = 0; i < strip_len; i++) { - indicesBuffer.position(offset); - int count = sarray[i]; - gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT, indicesBuffer); - offset += count; - } - } else { - IntBuffer buf = IntBuffer.wrap(indexCoord); - buf.position(initialIndexIndex); - switch (geo_type){ - case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET : gl.glDrawElements(GL2.GL_QUADS, validIndexCount, GL.GL_UNSIGNED_INT, buf); break; - case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET : gl.glDrawElements(GL.GL_TRIANGLES, validIndexCount, GL.GL_UNSIGNED_INT, buf); break; - case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET: gl.glDrawElements(GL.GL_POINTS, validIndexCount, GL.GL_UNSIGNED_INT, buf); break; - case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET : gl.glDrawElements(GL.GL_LINES, validIndexCount, GL.GL_UNSIGNED_INT, buf); break; - } - } - - unlockArray(gl); - - // clean up if we turned on normalize - if (isNonUniformScale) { - gl.glDisable(GL2.GL_NORMALIZE); - } - - if (vattrDefined) { - resetVertexAttrs(gl, ctx, vertexAttrCount); - } - - if (textureDefined) { - resetTexture(gl, ctx); - } - } - - - // --------------------------------------------------------------------- - - // - // GraphicsContext3D methods - // - - // Native method for readRaster - void readRaster(Context ctx, - int type, int xSrcOffset, int ySrcOffset, - int width, int height, int hCanvas, - int imageDataType, - int imageFormat, - Object imageBuffer, - int depthFormat, - Object depthBuffer) { - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, width); - gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1); - int yAdjusted = hCanvas - height - ySrcOffset; - - if ((type & Raster.RASTER_COLOR) != 0) { - int oglFormat = 0; - if(imageDataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) { - - switch (imageFormat) { - case ImageComponentRetained.TYPE_BYTE_BGR: - oglFormat = GL2.GL_BGR; - break; - case ImageComponentRetained.TYPE_BYTE_RGB: - oglFormat = GL.GL_RGB; - break; - case ImageComponentRetained.TYPE_BYTE_ABGR: - if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here! - oglFormat = GL2.GL_ABGR_EXT; - } else { - assert false; - return; - } - break; - case ImageComponentRetained.TYPE_BYTE_RGBA: - // all RGB types are stored as RGBA - oglFormat = GL.GL_RGBA; - break; - case ImageComponentRetained.TYPE_BYTE_LA: - // all LA types are stored as LA8 - oglFormat = GL.GL_LUMINANCE_ALPHA; - break; - case ImageComponentRetained.TYPE_BYTE_GRAY: - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_INT_BGR: - case ImageComponentRetained.TYPE_INT_RGB: - case ImageComponentRetained.TYPE_INT_ARGB: - default: - assert false; - return; - } - - gl.glReadPixels(xSrcOffset, yAdjusted, width, height, - oglFormat, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[]) imageBuffer)); - - - } else if(imageDataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) { - int intType = GL2.GL_UNSIGNED_INT_8_8_8_8; - boolean forceAlphaToOne = false; - - switch (imageFormat) { - /* GL_BGR */ - case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ - oglFormat = GL.GL_RGBA; - intType = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - forceAlphaToOne = true; - break; - case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ - forceAlphaToOne = true; - /* Fall through to next case */ - case ImageComponentRetained.TYPE_INT_ARGB: - oglFormat = GL2.GL_BGRA; - intType = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - break; - /* This method only supports 3 and 4 components formats and INT types. */ - case ImageComponentRetained.TYPE_BYTE_LA: - case ImageComponentRetained.TYPE_BYTE_GRAY: - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_BYTE_BGR: - case ImageComponentRetained.TYPE_BYTE_RGB: - case ImageComponentRetained.TYPE_BYTE_RGBA: - case ImageComponentRetained.TYPE_BYTE_ABGR: - default: - assert false; - return; - } - - /* Force Alpha to 1.0 if needed */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); - } - - gl.glReadPixels(xSrcOffset, yAdjusted, width, height, - oglFormat, intType, IntBuffer.wrap((int[]) imageBuffer)); - - /* Restore Alpha scale and bias */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); - } - - } else { - assert false; - } - } - - if ((type & Raster.RASTER_DEPTH) != 0) { - - if (depthFormat == DepthComponentRetained.DEPTH_COMPONENT_TYPE_INT) { - // yOffset is adjusted for OpenGL - Y upward - gl.glReadPixels(xSrcOffset, yAdjusted, width, height, - GL2.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT, IntBuffer.wrap((int[]) depthBuffer)); - } else { - // DEPTH_COMPONENT_TYPE_FLOAT - // yOffset is adjusted for OpenGL - Y upward - gl.glReadPixels(xSrcOffset, yAdjusted, width, height, - GL2.GL_DEPTH_COMPONENT, GL.GL_FLOAT, FloatBuffer.wrap((float[]) depthBuffer)); - } - } - - } - - // --------------------------------------------------------------------- - - // - // GLSLShaderProgramRetained methods - // - - // ShaderAttributeValue methods - - ShaderError setGLSLUniform1i(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1i()"); - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform1iARB(unbox(uniformLocation), value); - return null; - } - - ShaderError setGLSLUniform1f(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - float value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1f()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform1fARB(unbox(uniformLocation), value); - return null; - } - - ShaderError setGLSLUniform2i(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2i()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform2iARB(unbox(uniformLocation), value[0], value[1]); - return null; - } - - ShaderError setGLSLUniform2f(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - float[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2f()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform2fARB(unbox(uniformLocation), value[0], value[1]); - return null; - } - - ShaderError setGLSLUniform3i(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3i()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform3iARB(unbox(uniformLocation), value[0], value[1], value[2]); - return null; - } - - ShaderError setGLSLUniform3f(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - float[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3f()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform3fARB(unbox(uniformLocation), value[0], value[1], value[2]); - return null; - } - - ShaderError setGLSLUniform4i(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4i()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform4iARB(unbox(uniformLocation), value[0], value[1], value[2], value[3]); - return null; - } - - ShaderError setGLSLUniform4f(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - float[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4f()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform4fARB(unbox(uniformLocation), value[0], value[1], value[2], value[3]); - return null; - } - - ShaderError setGLSLUniformMatrix3f(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - float[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix3f()"); - - // Load attribute - // transpose is true : each matrix is supplied in row major order - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniformMatrix3fvARB(unbox(uniformLocation), 1, true, value, 0); - return null; - } - - ShaderError setGLSLUniformMatrix4f(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - float[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix4f()"); - - // Load attribute - // transpose is true : each matrix is supplied in row major order - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniformMatrix4fvARB(unbox(uniformLocation), 1, true, value, 0); - return null; - } - - // ShaderAttributeArray methods - - ShaderError setGLSLUniform1iArray(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int numElements, - int[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1iArray()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform1ivARB(unbox(uniformLocation), numElements, value, 0); - return null; - } - - ShaderError setGLSLUniform1fArray(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int numElements, - float[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1fArray()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform1fvARB(unbox(uniformLocation), numElements, value, 0); - return null; - } - - ShaderError setGLSLUniform2iArray(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int numElements, - int[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2iArray()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform2ivARB(unbox(uniformLocation), numElements, value, 0); - return null; - } - - ShaderError setGLSLUniform2fArray(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int numElements, - float[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2fArray()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform2fvARB(unbox(uniformLocation), numElements, value, 0); - return null; - } - - ShaderError setGLSLUniform3iArray(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int numElements, - int[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3iArray()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform3ivARB(unbox(uniformLocation), numElements, value, 0); - return null; - } - - ShaderError setGLSLUniform3fArray(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int numElements, - float[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3fArray()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform3fvARB(unbox(uniformLocation), numElements, value, 0); - return null; - } - - ShaderError setGLSLUniform4iArray(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int numElements, - int[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4iArray()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform4ivARB(unbox(uniformLocation), numElements, value, 0); - return null; - } - - ShaderError setGLSLUniform4fArray(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int numElements, - float[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4fArray()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniform4fvARB(unbox(uniformLocation), numElements, value, 0); - return null; - } - - ShaderError setGLSLUniformMatrix3fArray(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int numElements, - float[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix3fArray()"); - - // Load attribute - // transpose is true : each matrix is supplied in row major order - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniformMatrix3fvARB(unbox(uniformLocation), numElements, true, value, 0); - return null; - } - - ShaderError setGLSLUniformMatrix4fArray(Context ctx, - ShaderProgramId shaderProgramId, - ShaderAttrLoc uniformLocation, - int numElements, - float[] value) { - if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix4fArray()"); - - // Load attribute - // transpose is true : each matrix is supplied in row major order - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUniformMatrix4fvARB(unbox(uniformLocation), numElements, true, value, 0); - return null; - } - - // interfaces for shader compilation, etc. - ShaderError createGLSLShader(Context ctx, int shaderType, ShaderId[] shaderId) { - if (VERBOSE) System.err.println("JoglPipeline.createGLSLShader()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - int shaderHandle = 0; - if (shaderType == Shader.SHADER_TYPE_VERTEX) { - shaderHandle = gl.glCreateShaderObjectARB(GL2.GL_VERTEX_SHADER); - } else if (shaderType == Shader.SHADER_TYPE_FRAGMENT) { - shaderHandle = gl.glCreateShaderObjectARB(GL2.GL_FRAGMENT_SHADER); - } - - if (shaderHandle == 0) { - return new ShaderError(ShaderError.COMPILE_ERROR, - "Unable to create native shader object"); - } - - shaderId[0] = new JoglShaderObject(shaderHandle); - return null; - } - ShaderError destroyGLSLShader(Context ctx, ShaderId shaderId) { - if (VERBOSE) System.err.println("JoglPipeline.destroyGLSLShader()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glDeleteObjectARB(unbox(shaderId)); - return null; - } - ShaderError compileGLSLShader(Context ctx, ShaderId shaderId, String program) { - if (VERBOSE) System.err.println("JoglPipeline.compileGLSLShader()"); - - int id = unbox(shaderId); - if (id == 0) { - throw new AssertionError("shaderId == 0"); - } - - if (program == null) { - throw new AssertionError("shader program string is null"); - } - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glShaderSourceARB(id, 1, new String[] { program }, null, 0); - gl.glCompileShaderARB(id); - int[] status = new int[1]; - gl.glGetObjectParameterivARB(id, GL2.GL_OBJECT_COMPILE_STATUS_ARB, status, 0); - if (status[0] == 0) { - String detailMsg = getInfoLog(gl, id); - ShaderError res = new ShaderError(ShaderError.COMPILE_ERROR, - "GLSL shader compile error"); - res.setDetailMessage(detailMsg); - return res; - } - return null; - } - - ShaderError createGLSLShaderProgram(Context ctx, ShaderProgramId[] shaderProgramId) { - if (VERBOSE) System.err.println("JoglPipeline.createGLSLShaderProgram()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - int shaderProgramHandle = gl.glCreateProgramObjectARB(); - if (shaderProgramHandle == 0) { - return new ShaderError(ShaderError.LINK_ERROR, - "Unable to create native shader program object"); - } - shaderProgramId[0] = new JoglShaderObject(shaderProgramHandle); - return null; - } - ShaderError destroyGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId) { - if (VERBOSE) System.err.println("JoglPipeline.destroyGLSLShaderProgram()"); - GL2 gl = context(ctx).getGL().getGL2(); - gl.glDeleteObjectARB(unbox(shaderProgramId)); - return null; - } - ShaderError linkGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId, - ShaderId[] shaderIds) { - if (VERBOSE) System.err.println("JoglPipeline.linkGLSLShaderProgram()"); - - GL2 gl = context(ctx).getGL().getGL2(); - int id = unbox(shaderProgramId); - for (int i = 0; i < shaderIds.length; i++) { - gl.glAttachObjectARB(id, unbox(shaderIds[i])); - } - gl.glLinkProgramARB(id); - int[] status = new int[1]; - gl.glGetObjectParameterivARB(id, GL2.GL_OBJECT_LINK_STATUS_ARB, status, 0); - if (status[0] == 0) { - String detailMsg = getInfoLog(gl, id); - ShaderError res = new ShaderError(ShaderError.LINK_ERROR, - "GLSL shader program link error"); - res.setDetailMessage(detailMsg); - return res; - } - return null; - } - ShaderError bindGLSLVertexAttrName(Context ctx, ShaderProgramId shaderProgramId, - String attrName, int attrIndex) { - if (VERBOSE) System.err.println("JoglPipeline.bindGLSLVertexAttrName()"); - - JoglContext jctx = (JoglContext) ctx; - GL2 gl = context(ctx).getGL().getGL2(); - gl.glBindAttribLocation(unbox(shaderProgramId), - attrIndex + VirtualUniverse.mc.glslVertexAttrOffset, - attrName); - return null; - } - void lookupGLSLShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId, - int numAttrNames, String[] attrNames, ShaderAttrLoc[] locArr, - int[] typeArr, int[] sizeArr, boolean[] isArrayArr) { - if (VERBOSE) System.err.println("JoglPipeline.lookupGLSLShaderAttrNames()"); - - // set the loc, type, and size arrays to out-of-bound values - for (int i = 0; i < attrNames.length; i++) { - locArr[i] = null; - typeArr[i] = -1; - sizeArr[i] = -1; - } - - // Loop through the list of active uniform variables, one at a - // time, searching for a match in the attrNames array. - // - // NOTE: Since attrNames isn't sorted, and we don't have a - // hashtable of names to index locations, we will do a - // brute-force, linear search of the array. This leads to an - // O(n^2) algorithm (actually O(n*m) where n is attrNames.length - // and m is the number of uniform variables), but since we expect - // N to be small, we will not optimize this at this time. - int id = unbox(shaderProgramId); - int[] tmp = new int[1]; - int[] tmp2 = new int[1]; - int[] tmp3 = new int[1]; - GL2 gl = context(ctx).getGL().getGL2(); - gl.glGetObjectParameterivARB(id, - GL2.GL_OBJECT_ACTIVE_UNIFORMS_ARB, - tmp, 0); - int numActiveUniforms = tmp[0]; - gl.glGetObjectParameterivARB(id, - GL2.GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, - tmp, 0); - int maxStrLen = tmp[0]; - byte[] nameBuf = new byte[maxStrLen]; - - for (int i = 0; i < numActiveUniforms; i++) { - gl.glGetActiveUniformARB(id, i, maxStrLen, tmp3, 0, - tmp, 0, - tmp2, 0, - nameBuf, 0); - int size = tmp[0]; - int type = tmp2[0]; - String name = null; - try { - // TODO KCR : Shouldn't this use the default locale? - name = new String(nameBuf, 0, tmp3[0], "US-ASCII"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - - // Issue 247 - we need to workaround an ATI bug where they erroneously - // report individual elements of arrays rather than the array itself - if (name.length() >= 3 && name.endsWith("]")) { - if (name.endsWith("[0]")) { - name = name.substring(0, name.length() - 3); - } else { - // Ignore this name - continue; - } - } - - // Now try to find the name - for (int j = 0; j < numAttrNames; j++) { - if (name.equals(attrNames[j])) { - sizeArr[j] = size; - isArrayArr[j] = (size > 1); - typeArr[j] = glslToJ3dType(type); - break; - } - } - } - - // Now lookup the location of each name in the attrNames array - for (int i = 0; i < numAttrNames; i++) { - // Get uniform attribute location - int loc = gl.glGetUniformLocationARB(id, attrNames[i]); - locArr[i] = new JoglShaderObject(loc); - } - } - - ShaderError useGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId) { - if (VERBOSE) System.err.println("JoglPipeline.useGLSLShaderProgram()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glUseProgramObjectARB(unbox(shaderProgramId)); - ((JoglContext) ctx).setShaderProgram((JoglShaderObject) shaderProgramId); - return null; - } - - //---------------------------------------------------------------------- - // Helper methods for above shader routines - // - private int unbox(ShaderAttrLoc loc) { - if (loc == null) - return 0; - return ((JoglShaderObject) loc).getValue(); - } - - private int unbox(ShaderProgramId id) { - if (id == null) - return 0; - return ((JoglShaderObject) id).getValue(); - } - - private int unbox(ShaderId id) { - if (id == null) - return 0; - return ((JoglShaderObject) id).getValue(); - } - - private String getInfoLog(GL2 gl, int id) { - int[] infoLogLength = new int[1]; - gl.glGetObjectParameterivARB(id, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, infoLogLength, 0); - if (infoLogLength[0] > 0) { - byte[] storage = new byte[infoLogLength[0]]; - int[] len = new int[1]; - gl.glGetInfoLogARB(id, infoLogLength[0], len, 0, storage, 0); - try { - // TODO KCR : Shouldn't this use the default locale? - return new String(storage, 0, len[0], "US-ASCII"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - return null; - } - - private int glslToJ3dType(int type) { - switch (type) { - case GL2.GL_BOOL_ARB: - case GL2.GL_INT: - case GL2.GL_SAMPLER_2D_ARB: - case GL2.GL_SAMPLER_3D_ARB: - case GL2.GL_SAMPLER_CUBE_ARB: - return ShaderAttributeObjectRetained.TYPE_INTEGER; - - case GL.GL_FLOAT: - return ShaderAttributeObjectRetained.TYPE_FLOAT; - - case GL2.GL_INT_VEC2_ARB: - case GL2.GL_BOOL_VEC2_ARB: - return ShaderAttributeObjectRetained.TYPE_TUPLE2I; - - case GL2.GL_FLOAT_VEC2_ARB: - return ShaderAttributeObjectRetained.TYPE_TUPLE2F; - - case GL2.GL_INT_VEC3_ARB: - case GL2.GL_BOOL_VEC3_ARB: - return ShaderAttributeObjectRetained.TYPE_TUPLE3I; - - case GL2.GL_FLOAT_VEC3_ARB: - return ShaderAttributeObjectRetained.TYPE_TUPLE3F; - - case GL2.GL_INT_VEC4_ARB: - case GL2.GL_BOOL_VEC4_ARB: - return ShaderAttributeObjectRetained.TYPE_TUPLE4I; - - case GL2.GL_FLOAT_VEC4_ARB: - return ShaderAttributeObjectRetained.TYPE_TUPLE4F; - - // case GL.GL_FLOAT_MAT2_ARB: - - case GL2.GL_FLOAT_MAT3_ARB: - return ShaderAttributeObjectRetained.TYPE_MATRIX3F; - - case GL2.GL_FLOAT_MAT4_ARB: - return ShaderAttributeObjectRetained.TYPE_MATRIX4F; - - // Java 3D does not support the following sampler types: - // - // case GL.GL_SAMPLER_1D_ARB: - // case GL.GL_SAMPLER_1D_SHADOW_ARB: - // case GL.GL_SAMPLER_2D_SHADOW_ARB: - // case GL.GL_SAMPLER_2D_RECT_ARB: - // case GL.GL_SAMPLER_2D_RECT_SHADOW_ARB: - } - - return -1; - } - - // --------------------------------------------------------------------- - - // - // Renderer methods - // - - void cleanupRenderer() { - // Nothing to do - } - - - // --------------------------------------------------------------------- - - // - // ColoringAttributesRetained methods - // - - void updateColoringAttributes(Context ctx, - float dRed, float dGreen, float dBlue, - float red, float green, float blue, - float alpha, - boolean lightEnable, - int shadeModel) { - if (VERBOSE) System.err.println("JoglPipeline.updateColoringAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - float cr, cg, cb; - - if (lightEnable) { - cr = dRed; cg = dGreen; cb = dBlue; - } else { - cr = red; cg = green; cb = blue; - } - gl.glColor4f(cr, cg, cb, alpha); - if (shadeModel == ColoringAttributes.SHADE_FLAT) { - gl.glShadeModel(GL2.GL_FLAT); - } else { - gl.glShadeModel(GL2.GL_SMOOTH); - } - } - - - // --------------------------------------------------------------------- - - // - // DirectionalLightRetained methods - // - - private static final float[] black = new float[4]; - void updateDirectionalLight(Context ctx, - int lightSlot, float red, float green, - float blue, float dirx, float diry, float dirz) { - if (VERBOSE) System.err.println("JoglPipeline.updateDirectionalLight()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - int lightNum = GL2.GL_LIGHT0 + lightSlot; - float[] values = new float[4]; - - values[0] = red; - values[1] = green; - values[2] = blue; - values[3] = 1.0f; - gl.glLightfv(lightNum, GL2.GL_DIFFUSE, values, 0); - gl.glLightfv(lightNum, GL2.GL_SPECULAR, values, 0); - values[0] = -dirx; - values[1] = -diry; - values[2] = -dirz; - values[3] = 0.0f; - gl.glLightfv(lightNum, GL2.GL_POSITION, values, 0); - gl.glLightfv(lightNum, GL2.GL_AMBIENT, black, 0); - gl.glLightf(lightNum, GL2.GL_CONSTANT_ATTENUATION, 1.0f); - gl.glLightf(lightNum, GL2.GL_LINEAR_ATTENUATION, 0.0f); - gl.glLightf(lightNum, GL2.GL_QUADRATIC_ATTENUATION, 0.0f); - gl.glLightf(lightNum, GL2.GL_SPOT_EXPONENT, 0.0f); - gl.glLightf(lightNum, GL2.GL_SPOT_CUTOFF, 180.0f); - } - - - // --------------------------------------------------------------------- - - // - // PointLightRetained methods - // - - void updatePointLight(Context ctx, - int lightSlot, float red, float green, - float blue, float attenx, float atteny, float attenz, - float posx, float posy, float posz) { - if (VERBOSE) System.err.println("JoglPipeline.updatePointLight()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - int lightNum = GL2.GL_LIGHT0 + lightSlot; - float[] values = new float[4]; - - values[0] = red; - values[1] = green; - values[2] = blue; - values[3] = 1.0f; - gl.glLightfv(lightNum, GL2.GL_DIFFUSE, values, 0); - gl.glLightfv(lightNum, GL2.GL_SPECULAR, values, 0); - gl.glLightfv(lightNum, GL2.GL_AMBIENT, black, 0); - values[0] = posx; - values[1] = posy; - values[2] = posz; - gl.glLightfv(lightNum, GL2.GL_POSITION, values, 0); - gl.glLightf(lightNum, GL2.GL_CONSTANT_ATTENUATION, attenx); - gl.glLightf(lightNum, GL2.GL_LINEAR_ATTENUATION, atteny); - gl.glLightf(lightNum, GL2.GL_QUADRATIC_ATTENUATION, attenz); - gl.glLightf(lightNum, GL2.GL_SPOT_EXPONENT, 0.0f); - gl.glLightf(lightNum, GL2.GL_SPOT_CUTOFF, 180.0f); - } - - - // --------------------------------------------------------------------- - - // - // SpotLightRetained methods - // - - void updateSpotLight(Context ctx, - int lightSlot, float red, float green, - float blue, float attenx, float atteny, float attenz, - float posx, float posy, float posz, float spreadAngle, - float concentration, float dirx, float diry, - float dirz) { - if (VERBOSE) System.err.println("JoglPipeline.updateSpotLight()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - int lightNum = GL2.GL_LIGHT0 + lightSlot; - float[] values = new float[4]; - - values[0] = red; - values[1] = green; - values[2] = blue; - values[3] = 1.0f; - gl.glLightfv(lightNum, GL2.GL_DIFFUSE, values, 0); - gl.glLightfv(lightNum, GL2.GL_SPECULAR, values, 0); - gl.glLightfv(lightNum, GL2.GL_AMBIENT, black, 0); - values[0] = posx; - values[1] = posy; - values[2] = posz; - gl.glLightfv(lightNum, GL2.GL_POSITION, values, 0); - gl.glLightf(lightNum, GL2.GL_CONSTANT_ATTENUATION, attenx); - gl.glLightf(lightNum, GL2.GL_LINEAR_ATTENUATION, atteny); - gl.glLightf(lightNum, GL2.GL_QUADRATIC_ATTENUATION, attenz); - values[0] = dirx; - values[1] = diry; - values[2] = dirz; - gl.glLightfv(lightNum, GL2.GL_SPOT_DIRECTION, values, 0); - gl.glLightf(lightNum, GL2.GL_SPOT_EXPONENT, concentration); - gl.glLightf(lightNum, GL2.GL_SPOT_CUTOFF, (float) (spreadAngle * 180.0f / Math.PI)); - } - - - // --------------------------------------------------------------------- - - // - // ExponentialFogRetained methods - // - - void updateExponentialFog(Context ctx, - float red, float green, float blue, - float density) { - if (VERBOSE) System.err.println("JoglPipeline.updateExponentialFog()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - float[] color = new float[3]; - color[0] = red; - color[1] = green; - color[2] = blue; - gl.glFogi(GL2.GL_FOG_MODE, GL2.GL_EXP); - gl.glFogfv(GL2.GL_FOG_COLOR, color, 0); - gl.glFogf(GL2.GL_FOG_DENSITY, density); - gl.glEnable(GL2.GL_FOG); - } - - - // --------------------------------------------------------------------- - - // - // LinearFogRetained methods - // - - void updateLinearFog(Context ctx, - float red, float green, float blue, - double fdist, double bdist) { - if (VERBOSE) System.err.println("JoglPipeline.updateLinearFog()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - float[] color = new float[3]; - color[0] = red; - color[1] = green; - color[2] = blue; - gl.glFogi(GL2.GL_FOG_MODE, GL.GL_LINEAR); - gl.glFogfv(GL2.GL_FOG_COLOR, color, 0); - gl.glFogf(GL2.GL_FOG_START, (float) fdist); - gl.glFogf(GL2.GL_FOG_END, (float) bdist); - gl.glEnable(GL2.GL_FOG); - } - - - // --------------------------------------------------------------------- - - // - // LineAttributesRetained methods - // - - void updateLineAttributes(Context ctx, - float lineWidth, int linePattern, - int linePatternMask, - int linePatternScaleFactor, - boolean lineAntialiasing) { - if (VERBOSE) System.err.println("JoglPipeline.updateLineAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glLineWidth(lineWidth); - - if (linePattern == LineAttributes.PATTERN_SOLID) { - gl.glDisable(GL2.GL_LINE_STIPPLE); - } else { - if (linePattern == LineAttributes.PATTERN_DASH) { // dashed lines - gl.glLineStipple(1, (short) 0x00ff); - } else if (linePattern == LineAttributes.PATTERN_DOT) { // dotted lines - gl.glLineStipple(1, (short) 0x0101); - } else if (linePattern == LineAttributes.PATTERN_DASH_DOT) { // dash-dotted lines - gl.glLineStipple(1, (short) 0x087f); - } else if (linePattern == LineAttributes.PATTERN_USER_DEFINED) { // user-defined mask - gl.glLineStipple(linePatternScaleFactor, (short) linePatternMask); - } - gl.glEnable(GL2.GL_LINE_STIPPLE); - } - - /* XXXX: Polygon Mode check, blend enable */ - if (lineAntialiasing) { - gl.glEnable(GL.GL_LINE_SMOOTH); - } else { - gl.glDisable(GL.GL_LINE_SMOOTH); - } - } - - - // --------------------------------------------------------------------- - - // - // MaterialRetained methods - // - - void updateMaterial(Context ctx, - float red, float green, float blue, float alpha, - float aRed, float aGreen, float aBlue, - float eRed, float eGreen, float eBlue, - float dRed, float dGreen, float dBlue, - float sRed, float sGreen, float sBlue, - float shininess, int colorTarget, boolean lightEnable) { - if (VERBOSE) System.err.println("JoglPipeline.updateMaterial()"); - - float[] color = new float[4]; - - GL2 gl = context(ctx).getGL().getGL2(); - - gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL2.GL_SHININESS, shininess); - switch (colorTarget) { - case Material.DIFFUSE: - gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE); - break; - case Material.AMBIENT: - gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT); - break; - case Material.EMISSIVE: - gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_EMISSION); - break; - case Material.SPECULAR: - gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_SPECULAR); - break; - case Material.AMBIENT_AND_DIFFUSE: - gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT_AND_DIFFUSE); - break; - } - - color[0] = eRed; color[1] = eGreen; color[2] = eBlue; - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_EMISSION, color, 0); - - color[0] = aRed; color[1] = aGreen; color[2] = aBlue; - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT, color, 0); - - color[0] = sRed; color[1] = sGreen; color[2] = sBlue; - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, color, 0); - - float cr, cg, cb; - - if (lightEnable) { - color[0] = dRed; color[1] = dGreen; color[2] = dBlue; - } else { - color[0] = red; color[1] = green; color[2] = blue; - } - color[3] = alpha; - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE, color, 0); - gl.glColor4f(color[0], color[1], color[2], color[3]); - - if (lightEnable) { - gl.glEnable(GL2.GL_LIGHTING); - } else { - gl.glDisable(GL2.GL_LIGHTING); - } - } - - - // --------------------------------------------------------------------- - - // - // ModelClipRetained methods - // - - void updateModelClip(Context ctx, int planeNum, boolean enableFlag, - double A, double B, double C, double D) { - if (VERBOSE) System.err.println("JoglPipeline.updateModelClip()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - double[] equation = new double[4]; - int pl = GL2.GL_CLIP_PLANE0 + planeNum; - - // OpenGL clip planes are opposite to J3d clip planes - if (enableFlag) { - equation[0] = -A; - equation[1] = -B; - equation[2] = -C; - equation[3] = -D; - gl.glClipPlane(pl, DoubleBuffer.wrap(equation)); - gl.glEnable(pl); - } else { - gl.glDisable(pl); - } - } - - - // --------------------------------------------------------------------- - - // - // PointAttributesRetained methods - // - - void updatePointAttributes(Context ctx, float pointSize, boolean pointAntialiasing) { - if (VERBOSE) System.err.println("JoglPipeline.updatePointAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glPointSize(pointSize); - - // XXXX: Polygon Mode check, blend enable - if (pointAntialiasing) { - gl.glEnable(GL2.GL_POINT_SMOOTH); - } else { - gl.glDisable(GL2.GL_POINT_SMOOTH); - } - } - - - // --------------------------------------------------------------------- - - // - // PolygonAttributesRetained methods - // - - void updatePolygonAttributes(Context ctx, - int polygonMode, int cullFace, - boolean backFaceNormalFlip, - float polygonOffset, - float polygonOffsetFactor) { - if (VERBOSE) System.err.println("JoglPipeline.updatePolygonAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - if (cullFace == PolygonAttributes.CULL_NONE) { - gl.glDisable(GL.GL_CULL_FACE); - } else { - if (cullFace == PolygonAttributes.CULL_BACK) { - gl.glCullFace(GL.GL_BACK); - } else { - gl.glCullFace(GL.GL_FRONT); - } - gl.glEnable(GL.GL_CULL_FACE); - } - - if (backFaceNormalFlip && (cullFace != PolygonAttributes.CULL_BACK)) { - gl.glLightModeli(GL2.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_TRUE); - } else { - gl.glLightModeli(GL2.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_FALSE); - } - - if (polygonMode == PolygonAttributes.POLYGON_POINT) { - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_POINT); - } else if (polygonMode == PolygonAttributes.POLYGON_LINE) { - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_LINE); - } else { - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL); - } - - gl.glPolygonOffset(polygonOffsetFactor, polygonOffset); - - if ((polygonOffsetFactor != 0.0) || (polygonOffset != 0.0)) { - switch (polygonMode) { - case PolygonAttributes.POLYGON_POINT: - gl.glEnable(GL2.GL_POLYGON_OFFSET_POINT); - gl.glDisable(GL2.GL_POLYGON_OFFSET_LINE); - gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); - break; - case PolygonAttributes.POLYGON_LINE: - gl.glEnable(GL2.GL_POLYGON_OFFSET_LINE); - gl.glDisable(GL2.GL_POLYGON_OFFSET_POINT); - gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); - break; - case PolygonAttributes.POLYGON_FILL: - gl.glEnable(GL.GL_POLYGON_OFFSET_FILL); - gl.glDisable(GL2.GL_POLYGON_OFFSET_POINT); - gl.glDisable(GL2.GL_POLYGON_OFFSET_LINE); - break; - } - } else { - gl.glDisable(GL2.GL_POLYGON_OFFSET_POINT); - gl.glDisable(GL2.GL_POLYGON_OFFSET_LINE); - gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); - } - } - - - // --------------------------------------------------------------------- - - // - // RenderingAttributesRetained methods - // - - void updateRenderingAttributes(Context ctx, - boolean depthBufferWriteEnableOverride, - boolean depthBufferEnableOverride, - boolean depthBufferEnable, - boolean depthBufferWriteEnable, - int depthTestFunction, - float alphaTestValue, int alphaTestFunction, - boolean ignoreVertexColors, - boolean rasterOpEnable, int rasterOp, - boolean userStencilAvailable, boolean stencilEnable, - int stencilFailOp, int stencilZFailOp, int stencilZPassOp, - int stencilFunction, int stencilReferenceValue, - int stencilCompareMask, int stencilWriteMask ) { - if (VERBOSE) System.err.println("JoglPipeline.updateRenderingAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - if (!depthBufferEnableOverride) { - if (depthBufferEnable) { - gl.glEnable(GL.GL_DEPTH_TEST); - gl.glDepthFunc(getFunctionValue(depthTestFunction)); - } else { - gl.glDisable(GL.GL_DEPTH_TEST); - } - } - - if (!depthBufferWriteEnableOverride) { - if (depthBufferWriteEnable) { - gl.glDepthMask(true); - } else { - gl.glDepthMask(false); - } - } - - if (alphaTestFunction == RenderingAttributes.ALWAYS) { - gl.glDisable(GL2.GL_ALPHA_TEST); - } else { - gl.glEnable(GL2.GL_ALPHA_TEST); - gl.glAlphaFunc(getFunctionValue(alphaTestFunction), alphaTestValue); - } - - if (ignoreVertexColors) { - gl.glDisable(GL2.GL_COLOR_MATERIAL); - } else { - gl.glEnable(GL2.GL_COLOR_MATERIAL); - } - - if (rasterOpEnable) { - gl.glEnable(GL.GL_COLOR_LOGIC_OP); - switch (rasterOp) { - case RenderingAttributes.ROP_CLEAR: - gl.glLogicOp(GL.GL_CLEAR); - break; - case RenderingAttributes.ROP_AND: - gl.glLogicOp(GL.GL_AND); - break; - case RenderingAttributes.ROP_AND_REVERSE: - gl.glLogicOp(GL.GL_AND_REVERSE); - break; - case RenderingAttributes.ROP_COPY: - gl.glLogicOp(GL.GL_COPY); - break; - case RenderingAttributes.ROP_AND_INVERTED: - gl.glLogicOp(GL.GL_AND_INVERTED); - break; - case RenderingAttributes.ROP_NOOP: - gl.glLogicOp(GL.GL_NOOP); - break; - case RenderingAttributes.ROP_XOR: - gl.glLogicOp(GL.GL_XOR); - break; - case RenderingAttributes.ROP_OR: - gl.glLogicOp(GL.GL_OR); - break; - case RenderingAttributes.ROP_NOR: - gl.glLogicOp(GL.GL_NOR); - break; - case RenderingAttributes.ROP_EQUIV: - gl.glLogicOp(GL.GL_EQUIV); - break; - case RenderingAttributes.ROP_INVERT: - gl.glLogicOp(GL.GL_INVERT); - break; - case RenderingAttributes.ROP_OR_REVERSE: - gl.glLogicOp(GL.GL_OR_REVERSE); - break; - case RenderingAttributes.ROP_COPY_INVERTED: - gl.glLogicOp(GL.GL_COPY_INVERTED); - break; - case RenderingAttributes.ROP_OR_INVERTED: - gl.glLogicOp(GL.GL_OR_INVERTED); - break; - case RenderingAttributes.ROP_NAND: - gl.glLogicOp(GL.GL_NAND); - break; - case RenderingAttributes.ROP_SET: - gl.glLogicOp(GL.GL_SET); - break; - } - } else { - gl.glDisable(GL.GL_COLOR_LOGIC_OP); - } - - if (userStencilAvailable) { - if (stencilEnable) { - gl.glEnable(GL.GL_STENCIL_TEST); - - gl.glStencilOp(getStencilOpValue(stencilFailOp), - getStencilOpValue(stencilZFailOp), - getStencilOpValue(stencilZPassOp)); - - gl.glStencilFunc(getFunctionValue(stencilFunction), - stencilReferenceValue, stencilCompareMask); - - gl.glStencilMask(stencilWriteMask); - - } else { - gl.glDisable(GL.GL_STENCIL_TEST); - } - } - } - - private int getFunctionValue(int func) { - switch (func) { - case RenderingAttributes.ALWAYS: - func = GL.GL_ALWAYS; - break; - case RenderingAttributes.NEVER: - func = GL.GL_NEVER; - break; - case RenderingAttributes.EQUAL: - func = GL.GL_EQUAL; - break; - case RenderingAttributes.NOT_EQUAL: - func = GL.GL_NOTEQUAL; - break; - case RenderingAttributes.LESS: - func = GL.GL_LESS; - break; - case RenderingAttributes.LESS_OR_EQUAL: - func = GL.GL_LEQUAL; - break; - case RenderingAttributes.GREATER: - func = GL.GL_GREATER; - break; - case RenderingAttributes.GREATER_OR_EQUAL: - func = GL.GL_GEQUAL; - break; - } - - return func; - } - - private int getStencilOpValue(int op) { - switch (op) { - case RenderingAttributes.STENCIL_KEEP: - op = GL.GL_KEEP; - break; - case RenderingAttributes.STENCIL_ZERO: - op = GL.GL_ZERO; - break; - case RenderingAttributes.STENCIL_REPLACE: - op = GL.GL_REPLACE; - break; - case RenderingAttributes.STENCIL_INCR: - op = GL.GL_INCR; - break; - case RenderingAttributes.STENCIL_DECR: - op = GL.GL_DECR; - break; - case RenderingAttributes.STENCIL_INVERT: - op = GL.GL_INVERT; - break; - } - - return op; - } - - - // --------------------------------------------------------------------- - - // - // TexCoordGenerationRetained methods - // - - /** - * This method updates the native context: - * trans contains eyeTovworld transform in d3d - * trans contains vworldToEye transform in ogl - */ - void updateTexCoordGeneration(Context ctx, - boolean enable, int genMode, int format, - float planeSx, float planeSy, float planeSz, float planeSw, - float planeTx, float planeTy, float planeTz, float planeTw, - float planeRx, float planeRy, float planeRz, float planeRw, - float planeQx, float planeQy, float planeQz, float planeQw, - double[] vworldToEc) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexCoordGeneration()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - float[] planeS = new float[4]; - float[] planeT = new float[4]; - float[] planeR = new float[4]; - float[] planeQ = new float[4]; - - if (enable) { - gl.glEnable(GL2.GL_TEXTURE_GEN_S); - gl.glEnable(GL2.GL_TEXTURE_GEN_T); - if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { - gl.glEnable(GL2.GL_TEXTURE_GEN_R); - gl.glDisable(GL2.GL_TEXTURE_GEN_Q); - } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { - gl.glEnable(GL2.GL_TEXTURE_GEN_R); - gl.glEnable(GL2.GL_TEXTURE_GEN_Q); - } else { - gl.glDisable(GL2.GL_TEXTURE_GEN_R); - gl.glDisable(GL2.GL_TEXTURE_GEN_Q); - } - - if (genMode != TexCoordGeneration.SPHERE_MAP) { - planeS[0] = planeSx; planeS[1] = planeSy; - planeS[2] = planeSz; planeS[3] = planeSw; - planeT[0] = planeTx; planeT[1] = planeTy; - planeT[2] = planeTz; planeT[3] = planeTw; - if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { - planeR[0] = planeRx; planeR[1] = planeRy; - planeR[2] = planeRz; planeR[3] = planeRw; - } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { - planeR[0] = planeRx; planeR[1] = planeRy; - planeR[2] = planeRz; planeR[3] = planeRw; - planeQ[0] = planeQx; planeQ[1] = planeQy; - planeQ[2] = planeQz; planeQ[3] = planeQw; - } - } - - switch (genMode) { - case TexCoordGeneration.OBJECT_LINEAR: - gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_OBJECT_LINEAR); - gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_OBJECT_LINEAR); - gl.glTexGenfv(GL2.GL_S, GL2.GL_OBJECT_PLANE, planeS, 0); - gl.glTexGenfv(GL2.GL_T, GL2.GL_OBJECT_PLANE, planeT, 0); - - if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { - gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_OBJECT_LINEAR); - gl.glTexGenfv(GL2.GL_R, GL2.GL_OBJECT_PLANE, planeR, 0); - } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { - gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_OBJECT_LINEAR); - gl.glTexGenfv(GL2.GL_R, GL2.GL_OBJECT_PLANE, planeR, 0); - gl.glTexGeni(GL2.GL_Q, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_OBJECT_LINEAR); - gl.glTexGenfv(GL2.GL_Q, GL2.GL_OBJECT_PLANE, planeQ, 0); - } - break; - case TexCoordGeneration.EYE_LINEAR: - - gl.glMatrixMode(GL2.GL_MODELVIEW); - gl.glPushMatrix(); - - if (gl.isExtensionAvailable("GL_VERSION_1_3")) { - gl.glLoadTransposeMatrixd(vworldToEc, 0); - } else { - double[] v = new double[16]; - copyTranspose(vworldToEc, v); - gl.glLoadMatrixd(v, 0); - } - - gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_EYE_LINEAR); - gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_EYE_LINEAR); - gl.glTexGenfv(GL2.GL_S, GL2.GL_EYE_PLANE, planeS, 0); - gl.glTexGenfv(GL2.GL_T, GL2.GL_EYE_PLANE, planeT, 0); - - if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { - gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_EYE_LINEAR); - gl.glTexGenfv(GL2.GL_R, GL2.GL_EYE_PLANE, planeR, 0); - } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { - gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_EYE_LINEAR); - gl.glTexGenfv(GL2.GL_R, GL2.GL_EYE_PLANE, planeR, 0); - gl.glTexGeni(GL2.GL_Q, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_EYE_LINEAR); - gl.glTexGenfv(GL2.GL_Q, GL2.GL_EYE_PLANE, planeQ, 0); - } - gl.glPopMatrix(); - break; - case TexCoordGeneration.SPHERE_MAP: - gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); - gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); - if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { - gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); - } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { - gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); - gl.glTexGeni(GL2.GL_Q, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); - } - - break; - case TexCoordGeneration.NORMAL_MAP: - gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP); - gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP); - if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { - gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP); - } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { - gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP); - gl.glTexGeni(GL2.GL_Q, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP); - } - break; - case TexCoordGeneration.REFLECTION_MAP: - gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_REFLECTION_MAP); - gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_REFLECTION_MAP); - if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { - gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_REFLECTION_MAP); - } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { - gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_REFLECTION_MAP); - gl.glTexGeni(GL2.GL_Q, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_REFLECTION_MAP); - } - break; - } - } else { - gl.glDisable(GL2.GL_TEXTURE_GEN_S); - gl.glDisable(GL2.GL_TEXTURE_GEN_T); - gl.glDisable(GL2.GL_TEXTURE_GEN_R); - gl.glDisable(GL2.GL_TEXTURE_GEN_Q); - } - } - - - // --------------------------------------------------------------------- - - // - // TransparencyAttributesRetained methods - // - - private static final int screen_door[][] = { - /* 0 / 16 */ - { - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - }, - /* 1 / 16 */ - { - 0x00000000, 0x22222222, 0x00000000, 0x00000000, - 0x00000000, 0x22222222, 0x00000000, 0x00000000, - 0x00000000, 0x22222222, 0x00000000, 0x00000000, - 0x00000000, 0x22222222, 0x00000000, 0x00000000, - 0x00000000, 0x22222222, 0x00000000, 0x00000000, - 0x00000000, 0x22222222, 0x00000000, 0x00000000, - 0x00000000, 0x22222222, 0x00000000, 0x00000000, - 0x00000000, 0x22222222, 0x00000000, 0x00000000, - }, - /* 2 / 16 */ - { - 0x00000000, 0x22222222, 0x00000000, 0x88888888, - 0x00000000, 0x22222222, 0x00000000, 0x88888888, - 0x00000000, 0x22222222, 0x00000000, 0x88888888, - 0x00000000, 0x22222222, 0x00000000, 0x88888888, - 0x00000000, 0x22222222, 0x00000000, 0x88888888, - 0x00000000, 0x22222222, 0x00000000, 0x88888888, - 0x00000000, 0x22222222, 0x00000000, 0x88888888, - 0x00000000, 0x22222222, 0x00000000, 0x88888888, - }, - /* 3 / 16 */ - { - 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, - }, - /* 4 / 16 */ - { - 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - }, - /* 5 / 16 */ - { - 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, - }, - /* 6 / 16 */ - { - 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - }, - /* 7 / 16 */ - { - 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, - }, - /* 8 / 16 */ - { - 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - }, - /* 9 / 16 */ - { - 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, - }, - /* 10 / 16 */ - { - 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - }, - /* 11 / 16 */ - { - 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, - }, - /* 12 / 16 */ - { - 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, - }, - /* 13 / 16 */ - { - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, - }, - /* 14 / 16 */ - { - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, - }, - /* 15 / 16 */ - { - 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, - 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, - }, - /* 16 / 16 */ - { - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, - }, - }; - private static final ByteBuffer[] screen_door_table = new ByteBuffer[screen_door.length]; - static { - int eachLen = screen_door[0].length * Buffers.SIZEOF_INT; - ByteBuffer buf = Buffers.newDirectByteBuffer(screen_door.length * eachLen); - IntBuffer intBuf = buf.asIntBuffer(); - for (int i = 0; i < screen_door.length; i++) { - intBuf.put(screen_door[i]); - } - buf.rewind(); - for (int i = 0; i < screen_door.length; i++) { - buf.position(i * eachLen); - buf.limit((i+1) * eachLen); - screen_door_table[i] = buf.slice(); - } - } - - private static final int[] blendFunctionTable = new int[TransparencyAttributes.MAX_BLEND_FUNC_TABLE_SIZE]; - static { - blendFunctionTable[TransparencyAttributes.BLEND_ZERO] = GL.GL_ZERO; - blendFunctionTable[TransparencyAttributes.BLEND_ONE] = GL.GL_ONE; - blendFunctionTable[TransparencyAttributes.BLEND_SRC_ALPHA] = GL.GL_SRC_ALPHA; - blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_SRC_ALPHA] = GL.GL_ONE_MINUS_SRC_ALPHA; - blendFunctionTable[TransparencyAttributes.BLEND_DST_COLOR] = GL.GL_DST_COLOR; - blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_DST_COLOR] = GL.GL_ONE_MINUS_DST_COLOR; - blendFunctionTable[TransparencyAttributes.BLEND_SRC_COLOR] = GL.GL_SRC_COLOR; - blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_SRC_COLOR] = GL.GL_ONE_MINUS_SRC_COLOR; - blendFunctionTable[TransparencyAttributes.BLEND_CONSTANT_COLOR] = GL2.GL_CONSTANT_COLOR; - } - - void updateTransparencyAttributes(Context ctx, - float alpha, int geometryType, - int polygonMode, - boolean lineAA, boolean pointAA, - int transparencyMode, - int srcBlendFunction, - int dstBlendFunction) { - if (VERBOSE) System.err.println("JoglPipeline.updateTransparencyAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - if (transparencyMode != TransparencyAttributes.SCREEN_DOOR) { - gl.glDisable(GL2.GL_POLYGON_STIPPLE); - } else { - gl.glEnable(GL2.GL_POLYGON_STIPPLE); - gl.glPolygonStipple(screen_door_table[(int)(alpha * 16)]); - } - - if ((transparencyMode < TransparencyAttributes.SCREEN_DOOR) || - ((((geometryType & RenderMolecule.LINE) != 0) || - (polygonMode == PolygonAttributes.POLYGON_LINE)) - && lineAA) || - ((((geometryType & RenderMolecule.POINT) != 0) || - (polygonMode == PolygonAttributes.POLYGON_POINT)) - && pointAA)) { - gl.glEnable(GL.GL_BLEND); - // valid range of blendFunction 0..3 is already verified in shared code. - gl.glBlendFunc(blendFunctionTable[srcBlendFunction], blendFunctionTable[dstBlendFunction]); - } else { - gl.glDisable(GL.GL_BLEND); - } - } - - - // --------------------------------------------------------------------- - - // - // TextureAttributesRetained methods - // - - void updateTextureAttributes(Context ctx, - double[] transform, boolean isIdentity, int textureMode, - int perspCorrectionMode, - float textureBlendColorRed, - float textureBlendColorGreen, - float textureBlendColorBlue, - float textureBlendColorAlpha, - int textureFormat) { - if (VERBOSE) System.err.println("JoglPipeline.updateTextureAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, - (perspCorrectionMode == TextureAttributes.NICEST) ? GL.GL_NICEST : GL.GL_FASTEST); - - // set OGL texture matrix - gl.glPushAttrib(GL2.GL_TRANSFORM_BIT); - gl.glMatrixMode(GL.GL_TEXTURE); - - if (isIdentity) { - gl.glLoadIdentity(); - } else if (gl.isExtensionAvailable("GL_VERSION_1_3")) { - gl.glLoadTransposeMatrixd(transform, 0); - } else { - double[] mx = new double[16]; - copyTranspose(transform, mx); - gl.glLoadMatrixd(mx, 0); - } - - gl.glPopAttrib(); - - // set texture color - float[] color = new float[4]; - color[0] = textureBlendColorRed; - color[1] = textureBlendColorGreen; - color[2] = textureBlendColorBlue; - color[3] = textureBlendColorAlpha; - gl.glTexEnvfv(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_COLOR, color, 0); - - // set texture environment mode - - switch (textureMode) { - case TextureAttributes.MODULATE: - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE); - break; - case TextureAttributes.DECAL: - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_DECAL); - break; - case TextureAttributes.BLEND: - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_BLEND); - break; - case TextureAttributes.REPLACE: - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); - break; - case TextureAttributes.COMBINE: - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_COMBINE); - break; - } -// FIXME: GL_SGI_texture_color_table -// if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) { -// gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI); -// } - } - - void updateRegisterCombiners(Context absCtx, - double[] transform, boolean isIdentity, int textureMode, - int perspCorrectionMode, - float textureBlendColorRed, - float textureBlendColorGreen, - float textureBlendColorBlue, - float textureBlendColorAlpha, - int textureFormat, - int combineRgbMode, int combineAlphaMode, - int[] combineRgbSrc, int[] combineAlphaSrc, - int[] combineRgbFcn, int[] combineAlphaFcn, - int combineRgbScale, int combineAlphaScale) { -// FIXME: GL_NV_register_combiners -// if (VERBOSE) System.err.println("JoglPipeline.updateRegisterCombiners()"); -// -// JoglContext ctx = (JoglContext) absCtx; -// GL2 gl = context(ctx).getGL().getGL2(); -// -// if (perspCorrectionMode == TextureAttributes.NICEST) { -// gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); -// } else { -// gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_FASTEST); -// } -// -// // set OGL texture matrix -// gl.glPushAttrib(GL2.GL_TRANSFORM_BIT); -// gl.glMatrixMode(GL.GL_TEXTURE); -// -// if (isIdentity) { -// gl.glLoadIdentity(); -// } else if (gl.isExtensionAvailable("GL_VERSION_1_3")) { -// gl.glLoadTransposeMatrixd(transform, 0); -// } else { -// double[] mx = new double[16]; -// copyTranspose(transform, mx); -// gl.glLoadMatrixd(mx, 0); -// } -// -// gl.glPopAttrib(); -// -// // set texture color -// float[] color = new float[4]; -// color[0] = textureBlendColorRed; -// color[1] = textureBlendColorGreen; -// color[2] = textureBlendColorBlue; -// color[3] = textureBlendColorAlpha; -// gl.glTexEnvfv(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_COLOR, color, 0); -// -// // set texture environment mode -// gl.glEnable(GL.GL_REGISTER_COMBINERS_NV); -// int textureUnit = ctx.getCurrentTextureUnit(); -// int combinerUnit = ctx.getCurrentCombinerUnit(); -// int fragment; -// if (combinerUnit == GL.GL_COMBINER0_NV) { -// fragment = GL.GL_PRIMARY_COLOR_NV; -// } else { -// fragment = GL.GL_SPARE0_NV; -// } -// -// switch (textureMode) { -// case TextureAttributes.MODULATE: -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_A_NV, fragment, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_B_NV, textureUnit, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_VARIABLE_A_NV, fragment, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); -// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_VARIABLE_B_NV, textureUnit, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); -// -// gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB, -// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, -// GL.GL_NONE, GL.GL_NONE, false, false, false); -// gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, -// GL.GL_NONE, GL.GL_NONE, false, false, false); -// break; -// -// case TextureAttributes.DECAL: -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_A_NV, fragment, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_B_NV, textureUnit, -// GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA); -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_C_NV, textureUnit, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_D_NV, textureUnit, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); -// -// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_VARIABLE_A_NV, fragment, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); -// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_VARIABLE_B_NV, GL.GL_ZERO, -// GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA); -// -// gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB, -// GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, GL.GL_SPARE0_NV, -// GL.GL_NONE, GL.GL_NONE, false, false, false); -// gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, -// GL.GL_NONE, GL.GL_NONE, false, false, false); -// break; -// -// case TextureAttributes.BLEND: -// gl.glCombinerParameterfvNV(GL.GL_CONSTANT_COLOR0_NV, color, 0); -// -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_A_NV, fragment, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_B_NV, textureUnit, -// GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_C_NV, GL.GL_CONSTANT_COLOR0_NV, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_D_NV, textureUnit, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// -// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_VARIABLE_A_NV, fragment, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); -// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_VARIABLE_B_NV, textureUnit, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); -// -// gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB, -// GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, GL.GL_SPARE0_NV, -// GL.GL_NONE, GL.GL_NONE, false, false, false); -// gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, -// GL.GL_NONE, GL.GL_NONE, false, false, false); -// break; -// -// case TextureAttributes.REPLACE: -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_A_NV, textureUnit, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_B_NV, GL.GL_ZERO, -// GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); -// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_VARIABLE_A_NV, textureUnit, -// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); -// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_VARIABLE_B_NV, GL.GL_ZERO, -// GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA); -// -// gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB, -// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, -// GL.GL_NONE, GL.GL_NONE, false, false, false); -// gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, -// GL.GL_NONE, GL.GL_NONE, false, false, false); -// break; -// -// case TextureAttributes.COMBINE: -// if (combineRgbMode == TextureAttributes.COMBINE_DOT3) { -// int color1 = getCombinerArg(gl, combineRgbSrc[0], textureUnit, combinerUnit); -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_A_NV, color1, -// GL.GL_EXPAND_NORMAL_NV, GL.GL_RGB); -// int color2 = getCombinerArg(gl, combineRgbSrc[1], textureUnit, combinerUnit); -// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, -// GL.GL_VARIABLE_B_NV, color2, -// GL.GL_EXPAND_NORMAL_NV, GL.GL_RGB); -// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_VARIABLE_A_NV, GL.GL_ZERO, -// GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA); -// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_VARIABLE_B_NV, GL.GL_ZERO, -// GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA); -// -// gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB, -// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, -// GL.GL_NONE/*SCALE_BY_FOUR_NV*/, GL.GL_NONE, true, -// false, false); -// gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA, -// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, -// GL.GL_NONE, GL.GL_NONE, false, -// false, false); -// } -// break; -// } -// -// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_A_NV, -// GL.GL_SPARE0_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_B_NV, -// GL.GL_ZERO, GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); -// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_C_NV, -// GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_D_NV, -// GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_E_NV, -// GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_F_NV, -// GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); -// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_G_NV, -// GL.GL_SPARE0_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); -// -// if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) -// gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI); - // GL_SGI_texture_color_table - } - - void updateTextureColorTable(Context ctx, int numComponents, - int colorTableSize, - int[] textureColorTable) { -// FIXME: GL_SGI_texture_color_table -// if (VERBOSE) System.err.println("JoglPipeline.updateTextureColorTable()"); -// -// GL gl = context(ctx).getGL(); -// if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) { -// if (numComponents == 3) { -// gl.glColorTable(GL.GL_TEXTURE_COLOR_TABLE_SGI, GL.GL_RGB, -// colorTableSize, GL.GL_RGB, GL2.GL_INT, IntBuffer.wrap(textureColorTable)); -// } else { -// gl.glColorTable(GL.GL_TEXTURE_COLOR_TABLE_SGI, GL.GL_RGBA, -// colorTableSize, GL.GL_RGBA, GL2.GL_INT, IntBuffer.wrap(textureColorTable)); -// } -// gl.glEnable(GL.GL_TEXTURE_COLOR_TABLE_SGI); -// } - } - - void updateCombiner(Context ctx, - int combineRgbMode, int combineAlphaMode, - int[] combineRgbSrc, int[] combineAlphaSrc, - int[] combineRgbFcn, int[] combineAlphaFcn, - int combineRgbScale, int combineAlphaScale) { - if (VERBOSE) System.err.println("JoglPipeline.updateCombiner()"); - - GL2 gl = context(ctx).getGL().getGL2(); - int[] GLrgbMode = new int[1]; - int[] GLalphaMode = new int[1]; - getGLCombineMode(gl, combineRgbMode, combineAlphaMode, - GLrgbMode, GLalphaMode); - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_COMBINE_RGB, GLrgbMode[0]); - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_COMBINE_ALPHA, GLalphaMode[0]); - - int nargs; - if (combineRgbMode == TextureAttributes.COMBINE_REPLACE) { - nargs = 1; - } else if (combineRgbMode == TextureAttributes.COMBINE_INTERPOLATE) { - nargs = 3; - } else { - nargs = 2; - } - - for (int i = 0; i < nargs; i++) { - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, _gl_combineRgbSrcIndex[i], - _gl_combineSrc[combineRgbSrc[i]]); - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, _gl_combineRgbOpIndex[i], - _gl_combineFcn[combineRgbFcn[i]]); - } - - if (combineAlphaMode == TextureAttributes.COMBINE_REPLACE) { - nargs = 1; - } else if (combineAlphaMode == TextureAttributes.COMBINE_INTERPOLATE) { - nargs = 3; - } else { - nargs = 2; - } - - for (int i = 0; i < nargs; i++) { - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, _gl_combineAlphaSrcIndex[i], - _gl_combineSrc[combineAlphaSrc[i]]); - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, _gl_combineAlphaOpIndex[i], - _gl_combineFcn[combineAlphaFcn[i]]); - } - - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_RGB_SCALE, combineRgbScale); - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_ALPHA_SCALE, combineAlphaScale); - } - - // Helper routines for above - - private void getGLCombineMode(GL gl, int combineRgbMode, int combineAlphaMode, - int[] GLrgbMode, int[] GLalphaMode) { - switch (combineRgbMode) { - case TextureAttributes.COMBINE_REPLACE: - GLrgbMode[0] = GL.GL_REPLACE; - break; - case TextureAttributes.COMBINE_MODULATE: - GLrgbMode[0] = GL2.GL_MODULATE; - break; - case TextureAttributes.COMBINE_ADD: - GLrgbMode[0] = GL2.GL_ADD; - break; - case TextureAttributes.COMBINE_ADD_SIGNED: - GLrgbMode[0] = GL2.GL_ADD_SIGNED; - break; - case TextureAttributes.COMBINE_SUBTRACT: - GLrgbMode[0] = GL2.GL_SUBTRACT; - break; - case TextureAttributes.COMBINE_INTERPOLATE: - GLrgbMode[0] = GL2.GL_INTERPOLATE; - break; - case TextureAttributes.COMBINE_DOT3: - GLrgbMode[0] = GL2.GL_DOT3_RGB; - break; - default: - break; - } - - switch (combineAlphaMode) { - case TextureAttributes.COMBINE_REPLACE: - GLalphaMode[0] = GL.GL_REPLACE; - break; - case TextureAttributes.COMBINE_MODULATE: - GLalphaMode[0] = GL2.GL_MODULATE; - break; - case TextureAttributes.COMBINE_ADD: - GLalphaMode[0] = GL2.GL_ADD; - break; - case TextureAttributes.COMBINE_ADD_SIGNED: - GLalphaMode[0] = GL2.GL_ADD_SIGNED; - break; - case TextureAttributes.COMBINE_SUBTRACT: - GLalphaMode[0] = GL2.GL_SUBTRACT; - break; - case TextureAttributes.COMBINE_INTERPOLATE: - GLalphaMode[0] = GL2.GL_INTERPOLATE; - break; - case TextureAttributes.COMBINE_DOT3: - // dot3 will only make sense for alpha if rgb is also - // doing dot3. So if rgb is not doing dot3, fallback to replace - if (combineRgbMode == TextureAttributes.COMBINE_DOT3) { - GLrgbMode[0] = GL2.GL_DOT3_RGBA; - } else { - GLalphaMode[0] = GL.GL_REPLACE; - } - break; - default: - break; - } - } - - // mapping from java enum to gl enum - private static final int[] _gl_combineRgbSrcIndex = { - GL2.GL_SOURCE0_RGB, - GL2.GL_SOURCE1_RGB, - GL2.GL_SOURCE2_RGB, - }; - - private static final int[] _gl_combineAlphaSrcIndex = { - GL2.GL_SOURCE0_ALPHA, - GL2.GL_SOURCE1_ALPHA, - GL2.GL_SOURCE2_ALPHA, - }; - - private static final int[] _gl_combineRgbOpIndex = { - GL2.GL_OPERAND0_RGB, - GL2.GL_OPERAND1_RGB, - GL2.GL_OPERAND2_RGB, - }; - - private static final int[] _gl_combineAlphaOpIndex = { - GL2.GL_OPERAND0_ALPHA, - GL2.GL_OPERAND1_ALPHA, - GL2.GL_OPERAND2_ALPHA, - }; - - private static final int[] _gl_combineSrc = { - GL2.GL_PRIMARY_COLOR, // TextureAttributes.COMBINE_OBJECT_COLOR - GL.GL_TEXTURE, // TextureAttributes.COMBINE_TEXTURE - GL2.GL_CONSTANT, // TextureAttributes.COMBINE_CONSTANT_COLOR - GL2.GL_PREVIOUS, // TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE - }; - - private static final int[] _gl_combineFcn = { - GL.GL_SRC_COLOR, // TextureAttributes.COMBINE_SRC_COLOR - GL.GL_ONE_MINUS_SRC_COLOR, // TextureAttributes.COMBINE_ONE_MINUS_SRC_COLOR - GL.GL_SRC_ALPHA, // TextureAttributes.COMBINE_SRC_ALPHA - GL.GL_ONE_MINUS_SRC_ALPHA, // TextureAttributes.COMBINE_ONE_MINUS_SRC_ALPHA - }; - -// FIXME: GL_NV_register_combiners -// private int getCombinerArg(GL gl, int arg, int textureUnit, int combUnit) { -// int comb = 0; -// -// switch (arg) { -// case TextureAttributes.COMBINE_OBJECT_COLOR: -// if (combUnit == GL.GL_COMBINER0_NV) { -// comb = GL.GL_PRIMARY_COLOR_NV; -// } else { -// comb = GL.GL_SPARE0_NV; -// } -// break; -// case TextureAttributes.COMBINE_TEXTURE_COLOR: -// comb = textureUnit; -// break; -// case TextureAttributes.COMBINE_CONSTANT_COLOR: -// comb = GL.GL_CONSTANT_COLOR0_NV; -// break; -// case TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE: -// comb = textureUnit -1; -// break; -// } -// -// return comb; -// } - - - // --------------------------------------------------------------------- - - // - // TextureUnitStateRetained methods - // - - void updateTextureUnitState(Context ctx, int index, boolean enable) { - if (VERBOSE) System.err.println("JoglPipeline.updateTextureUnitState()"); - - GL2 gl = context(ctx).getGL().getGL2(); - JoglContext jctx = (JoglContext) ctx; - - if (index >= 0 && gl.isExtensionAvailable("GL_VERSION_1_3")) { - gl.glActiveTexture(index + GL.GL_TEXTURE0); - gl.glClientActiveTexture(GL.GL_TEXTURE0 + index); -// FIXME: GL_NV_register_combiners -// if (gl.isExtensionAvailable("GL_NV_register_combiners")) { -// jctx.setCurrentTextureUnit(index + GL.GL_TEXTURE0); -// jctx.setCurrentCombinerUnit(index + GL.GL_COMBINER0_NV); -// gl.glCombinerParameteriNV(GL.GL_NUM_GENERAL_COMBINERS_NV, index + 1); -// } - } - - if (!enable) { - // if not enabled, then don't enable any tex mapping - gl.glDisable(GL2.GL_TEXTURE_1D); - gl.glDisable(GL.GL_TEXTURE_2D); - gl.glDisable(GL2.GL_TEXTURE_3D); - gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); - } - - // if it is enabled, the enable flag will be taken care of - // in the bindTexture call - } - - - // --------------------------------------------------------------------- - - // - // TextureRetained methods - // Texture2DRetained methods - // - - void bindTexture2D(Context ctx, int objectId, boolean enable) { - if (VERBOSE) System.err.println("JoglPipeline.bindTexture2D(objectId=" + objectId + ",enable=" + enable + ")"); - - GL gl = context(ctx).getGL(); - gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); - gl.glDisable(GL2.GL_TEXTURE_3D); - - if (!enable) { - gl.glDisable(GL.GL_TEXTURE_2D); - } else { - gl.glBindTexture(GL.GL_TEXTURE_2D, objectId); - gl.glEnable(GL.GL_TEXTURE_2D); - } - } - - void updateTexture2DImage(Context ctx, - int numLevels, int level, - int textureFormat, int imageFormat, - int width, int height, - int boundaryWidth, - int dataType, Object data, boolean useAutoMipMap) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DImage(width=" + width + ",height=" + height + ",level=" + level + ")"); - - updateTexture2DImage(ctx, GL.GL_TEXTURE_2D, - numLevels, level, textureFormat, imageFormat, - width, height, boundaryWidth, dataType, data, useAutoMipMap); - } - - void updateTexture2DSubImage(Context ctx, - int level, int xoffset, int yoffset, - int textureFormat, int imageFormat, - int imgXOffset, int imgYOffset, - int tilew, int width, int height, - int dataType, Object data, boolean useAutoMipMap) { - - /* Note: useAutoMipMap is not use for SubImage in the jogl pipe */ - - if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DSubImage()"); - - updateTexture2DSubImage(ctx, GL.GL_TEXTURE_2D, - level, xoffset, yoffset, - textureFormat, imageFormat, - imgXOffset, imgYOffset, tilew, width, height, - dataType, data); - } - - void updateTexture2DLodRange(Context ctx, - int baseLevel, int maximumLevel, - float minimumLOD, float maximumLOD) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DLodRange()"); - - updateTextureLodRange(ctx, GL.GL_TEXTURE_2D, - baseLevel, maximumLevel, - minimumLOD, maximumLOD); - } - - void updateTexture2DLodOffset(Context ctx, - float lodOffsetS, float lodOffsetT, - float lodOffsetR) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DLodOffset()"); - - updateTextureLodOffset(ctx, GL.GL_TEXTURE_2D, - lodOffsetS, lodOffsetT, lodOffsetR); - } - - void updateTexture2DBoundary(Context ctx, - int boundaryModeS, int boundaryModeT, - float boundaryRed, float boundaryGreen, - float boundaryBlue, float boundaryAlpha) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DBoundary()"); - - updateTextureBoundary(ctx, GL.GL_TEXTURE_2D, - boundaryModeS, boundaryModeT, -1, - boundaryRed, boundaryGreen, - boundaryBlue, boundaryAlpha); - } - - void updateTexture2DFilterModes(Context ctx, - int minFilter, int magFilter) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DFilterModes()"); - - updateTextureFilterModes(ctx, GL.GL_TEXTURE_2D, minFilter, magFilter); - } - - void updateTexture2DSharpenFunc(Context ctx, - int numSharpenTextureFuncPts, - float[] sharpenTextureFuncPts) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DSharpenFunc()"); - - updateTextureSharpenFunc(ctx, GL.GL_TEXTURE_2D, - numSharpenTextureFuncPts, sharpenTextureFuncPts); - } - - void updateTexture2DFilter4Func(Context ctx, - int numFilter4FuncPts, - float[] filter4FuncPts) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DFilter4Func()"); - - updateTextureFilter4Func(ctx, GL.GL_TEXTURE_2D, - numFilter4FuncPts, filter4FuncPts); - } - - void updateTexture2DAnisotropicFilter(Context ctx, float degree) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DAnisotropicFilter()"); - - updateTextureAnisotropicFilter(ctx, GL.GL_TEXTURE_2D, degree); - } - - private void updateTextureLodRange(Context ctx, - int target, - int baseLevel, int maximumLevel, - float minimumLOD, float maximumLOD) { - GL gl = context(ctx).getGL(); - // checking of the availability of the extension is already done - // in the shared code - gl.glTexParameteri(target, GL2.GL_TEXTURE_BASE_LEVEL, baseLevel); - gl.glTexParameteri(target, GL2.GL_TEXTURE_MAX_LEVEL, maximumLevel); - gl.glTexParameterf(target, GL2.GL_TEXTURE_MIN_LOD, minimumLOD); - gl.glTexParameterf(target, GL2.GL_TEXTURE_MAX_LOD, maximumLOD); - } - - private void updateTextureLodOffset(Context ctx, - int target, - float lodOffsetS, float lodOffsetT, - float lodOffsetR) { -// FIXME: GL_SGIX_texture_lod_bias -// GL gl = context(ctx).getGL(); - // checking of the availability of the extension is already done - // in the shared code -// gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_S_SGIX, lodOffsetS); -// gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_T_SGIX, lodOffsetT); -// gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_R_SGIX, lodOffsetR); - } - - private void updateTextureAnisotropicFilter(Context ctx, int target, float degree) { - GL gl = context(ctx).getGL(); - // checking of the availability of anisotropic filter functionality - // is already done in the shared code - gl.glTexParameterf(target, - GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, - degree); - } - - // --------------------------------------------------------------------- - - // - // Texture3DRetained methods - // - - void bindTexture3D(Context ctx, int objectId, boolean enable) { - if (VERBOSE) System.err.println("JoglPipeline.bindTexture3D()"); - - GL gl = context(ctx).getGL(); - // textureCubeMap will take precedure over 3D Texture - gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); - - if (!enable) { - gl.glDisable(GL2.GL_TEXTURE_3D); - } else { - gl.glBindTexture(GL2.GL_TEXTURE_3D, objectId); - gl.glEnable(GL2.GL_TEXTURE_3D); - } - } - - void updateTexture3DImage(Context ctx, - int numLevels, int level, - int textureFormat, int imageFormat, - int width, int height, int depth, - int boundaryWidth, - int dataType, Object data, boolean useAutoMipMap) { - - if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DImage()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - int format = 0; - int internalFormat = 0; - int type = GL2.GL_UNSIGNED_INT_8_8_8_8; - boolean forceAlphaToOne = false; - - switch (textureFormat) { - case Texture.INTENSITY: - internalFormat = GL2.GL_INTENSITY; - break; - case Texture.LUMINANCE: - internalFormat = GL.GL_LUMINANCE; - break; - case Texture.ALPHA: - internalFormat = GL.GL_ALPHA; - break; - case Texture.LUMINANCE_ALPHA: - internalFormat = GL.GL_LUMINANCE_ALPHA; - break; - case Texture.RGB: - internalFormat = GL.GL_RGB; - break; - case Texture.RGBA: - internalFormat = GL.GL_RGBA; - break; - default: - assert false; - return; - } - - if (useAutoMipMap) { - gl.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_GENERATE_MIPMAP, GL.GL_TRUE); - } - else { - gl.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_GENERATE_MIPMAP, GL.GL_FALSE); - } - - if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) || - (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) { - - switch (imageFormat) { - case ImageComponentRetained.TYPE_BYTE_BGR: - format = GL2.GL_BGR; - break; - case ImageComponentRetained.TYPE_BYTE_RGB: - format = GL.GL_RGB; - break; - case ImageComponentRetained.TYPE_BYTE_ABGR: - if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here! - format = GL2.GL_ABGR_EXT; - } else { - assert false; - return; - } - break; - case ImageComponentRetained.TYPE_BYTE_RGBA: - // all RGB types are stored as RGBA - format = GL.GL_RGBA; - break; - case ImageComponentRetained.TYPE_BYTE_LA: - // all LA types are stored as LA8 - format = GL.GL_LUMINANCE_ALPHA; - break; - case ImageComponentRetained.TYPE_BYTE_GRAY: - if (internalFormat == GL.GL_ALPHA) { - format = GL.GL_ALPHA; - } else { - format = GL.GL_LUMINANCE; - } - break; - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_INT_BGR: - case ImageComponentRetained.TYPE_INT_RGB: - case ImageComponentRetained.TYPE_INT_ARGB: - default: - assert false; - return; - } - - if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) { - - gl.glTexImage3D(GL2.GL_TEXTURE_3D, - level, internalFormat, - width, height, depth, boundaryWidth, - format, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[]) data)); - } - else { - gl.glTexImage3D(GL2.GL_TEXTURE_3D, - level, internalFormat, - width, height, depth, boundaryWidth, - format, GL.GL_UNSIGNED_BYTE, (ByteBuffer) data); - } - - } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) || - (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) { - - switch (imageFormat) { - /* GL_BGR */ - case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ - format = GL.GL_RGBA; - type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - forceAlphaToOne = true; - break; - case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ - forceAlphaToOne = true; - /* Fall through to next case */ - case ImageComponentRetained.TYPE_INT_ARGB: - format = GL2.GL_BGRA; - type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - break; - /* This method only supports 3 and 4 components formats and INT types. */ - case ImageComponentRetained.TYPE_BYTE_LA: - case ImageComponentRetained.TYPE_BYTE_GRAY: - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_BYTE_BGR: - case ImageComponentRetained.TYPE_BYTE_RGB: - case ImageComponentRetained.TYPE_BYTE_RGBA: - case ImageComponentRetained.TYPE_BYTE_ABGR: - default: - assert false; - return; - } - - /* Force Alpha to 1.0 if needed */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); - } - - if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) { - gl.glTexImage3D(GL2.GL_TEXTURE_3D, - level, internalFormat, - width, height, depth, boundaryWidth, - format, type, IntBuffer.wrap((int[]) data)); - } else { - gl.glTexImage3D(GL2.GL_TEXTURE_3D, - level, internalFormat, - width, height, depth, boundaryWidth, - format, type, (Buffer) data); - } - - /* Restore Alpha scale and bias */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); - } - } else { - assert false; - } - } - - void updateTexture3DSubImage(Context ctx, - int level, - int xoffset, int yoffset, int zoffset, - int textureFormat, int imageFormat, - int imgXOffset, int imgYOffset, int imgZOffset, - int tilew, int tileh, - int width, int height, int depth, - int dataType, Object data, boolean useAutoMipMap) { - - /* Note: useAutoMipMap is not use for SubImage in the jogl pipe */ - - if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DSubImage()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - int format = 0; - int internalFormat = 0; - int type = GL2.GL_UNSIGNED_INT_8_8_8_8; - int numBytes = 0; - boolean forceAlphaToOne = false; - boolean pixelStore = false; - - if (imgXOffset > 0 || (width < tilew)) { - pixelStore = true; - gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, tilew); - } - - switch (textureFormat) { - case Texture.INTENSITY: - internalFormat = GL2.GL_INTENSITY; - break; - case Texture.LUMINANCE: - internalFormat = GL.GL_LUMINANCE; - break; - case Texture.ALPHA: - internalFormat = GL.GL_ALPHA; - break; - case Texture.LUMINANCE_ALPHA: - internalFormat = GL.GL_LUMINANCE_ALPHA; - break; - case Texture.RGB: - internalFormat = GL.GL_RGB; - break; - case Texture.RGBA: - internalFormat = GL.GL_RGBA; - break; - default: - assert false; - } - - if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) || - (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) { - - switch (imageFormat) { - case ImageComponentRetained.TYPE_BYTE_BGR: - format = GL2.GL_BGR; - numBytes = 3; - break; - case ImageComponentRetained.TYPE_BYTE_RGB: - format = GL.GL_RGB; - numBytes = 3; - break; - case ImageComponentRetained.TYPE_BYTE_ABGR: - if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here! - format = GL2.GL_ABGR_EXT; - numBytes = 4; - } else { - assert false; - return; - } - break; - case ImageComponentRetained.TYPE_BYTE_RGBA: - // all RGB types are stored as RGBA - format = GL.GL_RGBA; - numBytes = 4; - break; - case ImageComponentRetained.TYPE_BYTE_LA: - // all LA types are stored as LA8 - format = GL.GL_LUMINANCE_ALPHA; - numBytes = 2; - break; - case ImageComponentRetained.TYPE_BYTE_GRAY: - if (internalFormat == GL.GL_ALPHA) { - format = GL.GL_ALPHA; - numBytes = 1; - } else { - format = GL.GL_LUMINANCE; - numBytes = 1; - } - break; - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_INT_BGR: - case ImageComponentRetained.TYPE_INT_RGB: - case ImageComponentRetained.TYPE_INT_ARGB: - default: - assert false; - return; - } - - ByteBuffer buf = null; - if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) { - buf = ByteBuffer.wrap((byte[]) data); - } - else { - buf = (ByteBuffer) data; - } - - int offset = (tilew * tileh * imgZOffset + - tilew * imgYOffset + imgXOffset) * numBytes; - buf.position(offset); - gl.glTexSubImage3D(GL2.GL_TEXTURE_3D, - level, xoffset, yoffset, zoffset, - width, height, depth, - format, GL.GL_UNSIGNED_BYTE, - buf); - - } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) || - (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) { - - switch (imageFormat) { - /* GL_BGR */ - case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ - format = GL.GL_RGBA; - type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - forceAlphaToOne = true; - break; - case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ - forceAlphaToOne = true; - /* Fall through to next case */ - case ImageComponentRetained.TYPE_INT_ARGB: - format = GL2.GL_BGRA; - type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - break; - /* This method only supports 3 and 4 components formats and INT types. */ - case ImageComponentRetained.TYPE_BYTE_LA: - case ImageComponentRetained.TYPE_BYTE_GRAY: - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_BYTE_BGR: - case ImageComponentRetained.TYPE_BYTE_RGB: - case ImageComponentRetained.TYPE_BYTE_RGBA: - case ImageComponentRetained.TYPE_BYTE_ABGR: - default: - assert false; - return; - } - - /* Force Alpha to 1.0 if needed */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); - } - - IntBuffer buf = null; - if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) { - buf = IntBuffer.wrap((int[]) data); - } - else { - buf = (IntBuffer) data; - } - - int offset = tilew * tileh * imgZOffset + - tilew * imgYOffset + imgXOffset; - buf.position(offset); - gl.glTexSubImage3D(GL2.GL_TEXTURE_3D, - level, xoffset, yoffset, zoffset, - width, height, depth, - format, type, - buf); - - /* Restore Alpha scale and bias */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); - } - } else { - assert false; - return; - } - - if (pixelStore) { - gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, 0); - } - - } - - - void updateTexture3DLodRange(Context ctx, - int baseLevel, int maximumLevel, - float minimumLod, float maximumLod) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DLodRange()"); - - updateTextureLodRange(ctx, GL2.GL_TEXTURE_3D, - baseLevel, maximumLevel, - minimumLod, maximumLod); - } - - void updateTexture3DLodOffset(Context ctx, - float lodOffsetS, float lodOffsetT, - float lodOffsetR) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DLodOffset()"); - - updateTextureLodOffset(ctx, GL2.GL_TEXTURE_3D, - lodOffsetS, lodOffsetT, lodOffsetR); - } - - void updateTexture3DBoundary(Context ctx, - int boundaryModeS, int boundaryModeT, - int boundaryModeR, float boundaryRed, - float boundaryGreen, float boundaryBlue, - float boundaryAlpha) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DBoundary()"); - - updateTextureBoundary(ctx, GL.GL_TEXTURE_2D, - boundaryModeS, boundaryModeT, boundaryModeR, - boundaryRed, boundaryGreen, - boundaryBlue, boundaryAlpha); - } - - void updateTexture3DFilterModes(Context ctx, - int minFilter, int magFilter) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DFilterModes()"); - - updateTextureFilterModes(ctx, GL2.GL_TEXTURE_3D, - minFilter, magFilter); - } - - void updateTexture3DSharpenFunc(Context ctx, - int numSharpenTextureFuncPts, - float[] sharpenTextureFuncPts) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DSharpenFunc()"); - - updateTextureSharpenFunc(ctx, GL2.GL_TEXTURE_3D, - numSharpenTextureFuncPts, sharpenTextureFuncPts); - } - - void updateTexture3DFilter4Func(Context ctx, - int numFilter4FuncPts, - float[] filter4FuncPts) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DFilter4Func()"); - - updateTextureFilter4Func(ctx, GL2.GL_TEXTURE_3D, - numFilter4FuncPts, filter4FuncPts); - } - - void updateTexture3DAnisotropicFilter(Context ctx, float degree) { - if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DAnisotropicFilter()"); - - updateTextureAnisotropicFilter(ctx, GL2.GL_TEXTURE_3D, degree); - } - - - // --------------------------------------------------------------------- - - // - // TextureCubeMapRetained methods - // - - void bindTextureCubeMap(Context ctx, int objectId, boolean enable) { - if (VERBOSE) System.err.println("JoglPipeline.bindTextureCubeMap()"); - - GL gl = context(ctx).getGL(); - // TextureCubeMap will take precedure over 3D Texture so - // there is no need to disable 3D Texture here. - if (!enable) { - gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); - } else { - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, objectId); - gl.glEnable(GL.GL_TEXTURE_CUBE_MAP); - } - } - - void updateTextureCubeMapImage(Context ctx, - int face, int numLevels, int level, - int textureFormat, int imageFormat, - int width, int height, - int boundaryWidth, - int dataType, Object data, boolean useAutoMipMap) { - if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapImage()"); - - updateTexture2DImage(ctx, _gl_textureCubeMapFace[face], - numLevels, level, textureFormat, imageFormat, - width, height, boundaryWidth, dataType, data, useAutoMipMap); - } - - void updateTextureCubeMapSubImage(Context ctx, - int face, int level, int xoffset, int yoffset, - int textureFormat,int imageFormat, - int imgXOffset, int imgYOffset, - int tilew, int width, int height, - int dataType, Object data, boolean useAutoMipMap) { - - /* Note: useAutoMipMap is not use for SubImage in the jogl pipe */ - - if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapSubImage()"); - - updateTexture2DSubImage(ctx, _gl_textureCubeMapFace[face], - level, xoffset, yoffset, textureFormat, - imageFormat, imgXOffset, imgYOffset, tilew, - width, height, dataType, data); - } - - void updateTextureCubeMapLodRange(Context ctx, - int baseLevel, int maximumLevel, - float minimumLod, float maximumLod) { - if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapLodRange()"); - - updateTextureLodRange(ctx, - GL.GL_TEXTURE_CUBE_MAP, - baseLevel, maximumLevel, - minimumLod, maximumLod); - } - - void updateTextureCubeMapLodOffset(Context ctx, - float lodOffsetS, float lodOffsetT, - float lodOffsetR) { - if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapLodOffset()"); - - updateTextureLodOffset(ctx, - GL.GL_TEXTURE_CUBE_MAP, - lodOffsetS, lodOffsetT, lodOffsetR); - } - - void updateTextureCubeMapBoundary(Context ctx, - int boundaryModeS, int boundaryModeT, - float boundaryRed, float boundaryGreen, - float boundaryBlue, float boundaryAlpha) { - if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapBoundary()"); - - updateTextureBoundary(ctx, - GL.GL_TEXTURE_CUBE_MAP, - boundaryModeS, boundaryModeT, -1, - boundaryRed, boundaryGreen, - boundaryBlue, boundaryAlpha); - } - - void updateTextureCubeMapFilterModes(Context ctx, - int minFilter, int magFilter) { - if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapFilterModes()"); - - updateTextureFilterModes(ctx, - GL.GL_TEXTURE_CUBE_MAP, - minFilter, magFilter); - } - - void updateTextureCubeMapSharpenFunc(Context ctx, - int numSharpenTextureFuncPts, - float[] sharpenTextureFuncPts) { - if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapSharpenFunc()"); - - updateTextureSharpenFunc(ctx, - GL.GL_TEXTURE_CUBE_MAP, - numSharpenTextureFuncPts, sharpenTextureFuncPts); - } - - void updateTextureCubeMapFilter4Func(Context ctx, - int numFilter4FuncPts, - float[] filter4FuncPts) { - if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapFilter4Func()"); - - updateTextureFilter4Func(ctx, - GL.GL_TEXTURE_CUBE_MAP, - numFilter4FuncPts, filter4FuncPts); - } - - void updateTextureCubeMapAnisotropicFilter(Context ctx, float degree) { - if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapAnisotropicFilter()"); - - updateTextureAnisotropicFilter(ctx, - GL.GL_TEXTURE_CUBE_MAP, - degree); - } - - //---------------------------------------------------------------------- - // - // Helper routines for above texture methods - // - - private void updateTexture2DImage(Context ctx, - int target, - int numLevels, - int level, - int textureFormat, - int imageFormat, - int width, - int height, - int boundaryWidth, - int dataType, - Object data, - boolean useAutoMipMap) { - GL2 gl = context(ctx).getGL().getGL2(); - - int format = 0, internalFormat = 0; - int type = GL2.GL_UNSIGNED_INT_8_8_8_8; - boolean forceAlphaToOne = false; - - switch (textureFormat) { - case Texture.INTENSITY: - internalFormat = GL2.GL_INTENSITY; - break; - case Texture.LUMINANCE: - internalFormat = GL.GL_LUMINANCE; - break; - case Texture.ALPHA: - internalFormat = GL.GL_ALPHA; - break; - case Texture.LUMINANCE_ALPHA: - internalFormat = GL.GL_LUMINANCE_ALPHA; - break; - case Texture.RGB: - internalFormat = GL.GL_RGB; - break; - case Texture.RGBA: - internalFormat = GL.GL_RGBA; - break; - default: - assert false; - } - - if (useAutoMipMap) { - gl.glTexParameteri(target, GL2.GL_GENERATE_MIPMAP, GL.GL_TRUE); - } - else { - gl.glTexParameteri(target, GL2.GL_GENERATE_MIPMAP, GL.GL_FALSE); - } - - if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) || - (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) { - - switch (imageFormat) { - case ImageComponentRetained.TYPE_BYTE_BGR: - format = GL2.GL_BGR; - break; - case ImageComponentRetained.TYPE_BYTE_RGB: - format = GL.GL_RGB; - break; - case ImageComponentRetained.TYPE_BYTE_ABGR: - if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here! - format = GL2.GL_ABGR_EXT; - } else { - assert false; - return; - } - break; - case ImageComponentRetained.TYPE_BYTE_RGBA: - // all RGB types are stored as RGBA - format = GL.GL_RGBA; - break; - case ImageComponentRetained.TYPE_BYTE_LA: - // all LA types are stored as LA8 - format = GL.GL_LUMINANCE_ALPHA; - break; - case ImageComponentRetained.TYPE_BYTE_GRAY: - if (internalFormat == GL.GL_ALPHA) { - format = GL.GL_ALPHA; - } else { - format = GL.GL_LUMINANCE; - } - break; - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_INT_BGR: - case ImageComponentRetained.TYPE_INT_RGB: - case ImageComponentRetained.TYPE_INT_ARGB: - default: - assert false; - return; - } - - if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) { - - gl.glTexImage2D(target, level, internalFormat, - width, height, boundaryWidth, - format, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[])data)); - } else { - gl.glTexImage2D(target, level, internalFormat, - width, height, boundaryWidth, - format, GL.GL_UNSIGNED_BYTE, (Buffer) data); - } - - } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) || - (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) { - - switch (imageFormat) { - /* GL_BGR */ - case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ - format = GL.GL_RGBA; - type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - forceAlphaToOne = true; - break; - case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ - forceAlphaToOne = true; - /* Fall through to next case */ - case ImageComponentRetained.TYPE_INT_ARGB: - format = GL2.GL_BGRA; - type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - break; - /* This method only supports 3 and 4 components formats and INT types. */ - case ImageComponentRetained.TYPE_BYTE_LA: - case ImageComponentRetained.TYPE_BYTE_GRAY: - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_BYTE_BGR: - case ImageComponentRetained.TYPE_BYTE_RGB: - case ImageComponentRetained.TYPE_BYTE_RGBA: - case ImageComponentRetained.TYPE_BYTE_ABGR: - default: - assert false; - return; - } - - /* Force Alpha to 1.0 if needed */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); - } - - if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) { - gl.glTexImage2D(target, level, internalFormat, - width, height, boundaryWidth, - format, type, IntBuffer.wrap((int[])data)); - } else { - gl.glTexImage2D(target, level, internalFormat, - width, height, boundaryWidth, - format, type, (Buffer) data); - } - - /* Restore Alpha scale and bias */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); - } - } else { - assert false; - } - } - - private void updateTexture2DSubImage(Context ctx, - int target, - int level, int xoffset, int yoffset, - int textureFormat, int imageFormat, - int imgXOffset, int imgYOffset, - int tilew, int width, int height, - int dataType, Object data) { - GL2 gl = context(ctx).getGL().getGL2(); - - int format = 0, internalFormat=0; - int numBytes = 0; - int type = GL2.GL_UNSIGNED_INT_8_8_8_8; - boolean forceAlphaToOne = false; - boolean pixelStore = false; - - if (imgXOffset > 0 || (width < tilew)) { - pixelStore = true; - gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, tilew); - } - - switch (textureFormat) { - case Texture.INTENSITY: - internalFormat = GL2.GL_INTENSITY; - break; - case Texture.LUMINANCE: - internalFormat = GL.GL_LUMINANCE; - break; - case Texture.ALPHA: - internalFormat = GL.GL_ALPHA; - break; - case Texture.LUMINANCE_ALPHA: - internalFormat = GL.GL_LUMINANCE_ALPHA; - break; - case Texture.RGB: - internalFormat = GL.GL_RGB; - break; - case Texture.RGBA: - internalFormat = GL.GL_RGBA; - break; - default: - assert false; - } - - if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) || - (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) { - - switch (imageFormat) { - case ImageComponentRetained.TYPE_BYTE_BGR: - format = GL2.GL_BGR; - numBytes = 3; - break; - case ImageComponentRetained.TYPE_BYTE_RGB: - format = GL.GL_RGB; - numBytes = 3; - break; - case ImageComponentRetained.TYPE_BYTE_ABGR: - if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here! - format = GL2.GL_ABGR_EXT; - numBytes = 4; - } else { - assert false; - return; - } - break; - case ImageComponentRetained.TYPE_BYTE_RGBA: - // all RGB types are stored as RGBA - format = GL.GL_RGBA; - numBytes = 4; - break; - case ImageComponentRetained.TYPE_BYTE_LA: - // all LA types are stored as LA8 - format = GL.GL_LUMINANCE_ALPHA; - numBytes = 2; - break; - case ImageComponentRetained.TYPE_BYTE_GRAY: - if (internalFormat == GL.GL_ALPHA) { - format = GL.GL_ALPHA; - numBytes = 1; - } else { - format = GL.GL_LUMINANCE; - numBytes = 1; - } - break; - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_INT_BGR: - case ImageComponentRetained.TYPE_INT_RGB: - case ImageComponentRetained.TYPE_INT_ARGB: - default: - assert false; - return; - } - - ByteBuffer buf = null; - if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) { - buf = ByteBuffer.wrap((byte[]) data); - } - else { - buf = (ByteBuffer) data; - } - - // offset by the imageOffset - buf.position((tilew * imgYOffset + imgXOffset) * numBytes); - gl.glTexSubImage2D(target, level, xoffset, yoffset, width, height, - format, GL.GL_UNSIGNED_BYTE, buf); - - } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) || - (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) { - - switch (imageFormat) { - /* GL_BGR */ - case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ - format = GL.GL_RGBA; - type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - forceAlphaToOne = true; - break; - case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ - forceAlphaToOne = true; - /* Fall through to next case */ - case ImageComponentRetained.TYPE_INT_ARGB: - format = GL2.GL_BGRA; - type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - break; - /* This method only supports 3 and 4 components formats and INT types. */ - case ImageComponentRetained.TYPE_BYTE_LA: - case ImageComponentRetained.TYPE_BYTE_GRAY: - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_BYTE_BGR: - case ImageComponentRetained.TYPE_BYTE_RGB: - case ImageComponentRetained.TYPE_BYTE_RGBA: - case ImageComponentRetained.TYPE_BYTE_ABGR: - default: - assert false; - return; - } - /* Force Alpha to 1.0 if needed */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); - } - - IntBuffer buf = null; - if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) { - buf = IntBuffer.wrap((int[]) data); - } - else { - buf = (IntBuffer) data; - } - - // offset by the imageOffset - buf.position(tilew * imgYOffset + imgXOffset); - gl.glTexSubImage2D(target, level, xoffset, yoffset, width, height, - format, type, buf); - - /* Restore Alpha scale and bias */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); - } - } else { - assert false; - return; - } - - if (pixelStore) { - gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, 0); - } - - } - - void updateTextureFilterModes(Context ctx, - int target, - int minFilter, - int magFilter) { - GL gl = context(ctx).getGL(); - - if (EXTRA_DEBUGGING) { - System.err.println("minFilter: " + getFilterName(minFilter) + - " magFilter: " + getFilterName(magFilter)); - } - - // FIXME: unclear whether we really need to set up the enum values - // in the JoglContext as is done in the native code depending on - // extension availability; maybe this is the defined fallback - // behavior of the various Java3D modes - - // set texture min filter - switch (minFilter) { - case Texture.FASTEST: - case Texture.BASE_LEVEL_POINT: - gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); - break; - case Texture.BASE_LEVEL_LINEAR: - gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); - break; - case Texture.MULTI_LEVEL_POINT: - gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, - GL.GL_NEAREST_MIPMAP_NEAREST); - break; - case Texture.NICEST: - case Texture.MULTI_LEVEL_LINEAR: - gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, - GL.GL_LINEAR_MIPMAP_LINEAR); - break; - case Texture.FILTER4: -// We should never get here as we've disabled the FILTER4 feature -// gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, -// GL.GL_FILTER4_SGIS); - break; - } - - // set texture mag filter - switch (magFilter) { - case Texture.FASTEST: - case Texture.BASE_LEVEL_POINT: - gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); - break; - case Texture.NICEST: - case Texture.BASE_LEVEL_LINEAR: - gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); - break; - case Texture.LINEAR_SHARPEN: -// We should never get here as we've disabled the TEXTURE_SHARPEN feature -// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, -// GL.GL_LINEAR_SHARPEN_SGIS); - break; - case Texture.LINEAR_SHARPEN_RGB: -// We should never get here as we've disabled the TEXTURE_SHARPEN feature -// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, -// GL.GL_LINEAR_SHARPEN_COLOR_SGIS); - break; - case Texture.LINEAR_SHARPEN_ALPHA: -// We should never get here as we've disabled the TEXTURE_SHARPEN feature -// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, -// GL.GL_LINEAR_SHARPEN_ALPHA_SGIS); - break; - case Texture2D.LINEAR_DETAIL: -// We should never get here as we've disabled the TEXTURE_DETAIL feature -// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, -// GL.GL_LINEAR_DETAIL_SGIS); - break; - case Texture2D.LINEAR_DETAIL_RGB: -// We should never get here as we've disabled the TEXTURE_DETAIL feature -// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, -// GL.GL_LINEAR_DETAIL_COLOR_SGIS); - break; - case Texture2D.LINEAR_DETAIL_ALPHA: -// We should never get here as we've disabled the TEXTURE_DETAIL feature -// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, -// GL.GL_LINEAR_DETAIL_ALPHA_SGIS); - break; - case Texture.FILTER4: -// We should never get here as we've disabled the FILTER4 feature -// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, -// GL.GL_FILTER4_SGIS); - break; - } - } - - void updateTextureBoundary(Context ctx, - int target, - int boundaryModeS, - int boundaryModeT, - int boundaryModeR, - float boundaryRed, - float boundaryGreen, - float boundaryBlue, - float boundaryAlpha) { - GL gl = context(ctx).getGL(); - - // set texture wrap parameter - switch (boundaryModeS) { - case Texture.WRAP: - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT); - break; - case Texture.CLAMP: - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP); - break; - case Texture.CLAMP_TO_EDGE: - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, - GL.GL_CLAMP_TO_EDGE); - break; - case Texture.CLAMP_TO_BOUNDARY: - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, - GL2.GL_CLAMP_TO_BORDER); - break; - } - - switch (boundaryModeT) { - case Texture.WRAP: - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT); - break; - case Texture.CLAMP: - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP); - break; - case Texture.CLAMP_TO_EDGE: - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, - GL.GL_CLAMP_TO_EDGE); - break; - case Texture.CLAMP_TO_BOUNDARY: - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, - GL2.GL_CLAMP_TO_BORDER); - break; - } - - // applies to Texture3D only - if (boundaryModeR != -1) { - switch (boundaryModeR) { - case Texture.WRAP: - gl.glTexParameteri(target, - GL2.GL_TEXTURE_WRAP_R, GL.GL_REPEAT); - break; - - case Texture.CLAMP: - gl.glTexParameteri(target, - GL2.GL_TEXTURE_WRAP_R, GL2.GL_CLAMP); - break; - case Texture.CLAMP_TO_EDGE: - gl.glTexParameteri(target, - GL2.GL_TEXTURE_WRAP_R, - GL.GL_CLAMP_TO_EDGE); - break; - case Texture.CLAMP_TO_BOUNDARY: - gl.glTexParameteri(target, - GL2.GL_TEXTURE_WRAP_R, - GL2.GL_CLAMP_TO_BORDER); - break; - } - } - - if (boundaryModeS == Texture.CLAMP || - boundaryModeT == Texture.CLAMP || - boundaryModeR == Texture.CLAMP) { - // set texture border color - float[] color = new float[4]; - color[0] = boundaryRed; - color[1] = boundaryGreen; - color[2] = boundaryBlue; - color[3] = boundaryAlpha; - gl.glTexParameterfv(target, GL2.GL_TEXTURE_BORDER_COLOR, color, 0); - } - } - - private static final String getFilterName(int filter) { - switch (filter) { - case Texture.FASTEST: - return "Texture.FASTEST"; - case Texture.NICEST: - return "Texture.NICEST"; - case Texture.BASE_LEVEL_POINT: - return "Texture.BASE_LEVEL_POINT"; - case Texture.BASE_LEVEL_LINEAR: - return "Texture.BASE_LEVEL_LINEAR"; - case Texture.MULTI_LEVEL_POINT: - return "Texture.MULTI_LEVEL_POINT"; - case Texture.MULTI_LEVEL_LINEAR: - return "Texture.MULTI_LEVEL_LINEAR"; - case Texture.FILTER4: - return "Texture.FILTER4"; - case Texture.LINEAR_SHARPEN: - return "Texture.LINEAR_SHARPEN"; - case Texture.LINEAR_SHARPEN_RGB: - return "Texture.LINEAR_SHARPEN_RGB"; - case Texture.LINEAR_SHARPEN_ALPHA: - return "Texture.LINEAR_SHARPEN_ALPHA"; - case Texture2D.LINEAR_DETAIL: - return "Texture.LINEAR_DETAIL"; - case Texture2D.LINEAR_DETAIL_RGB: - return "Texture.LINEAR_DETAIL_RGB"; - case Texture2D.LINEAR_DETAIL_ALPHA: - return "Texture.LINEAR_DETAIL_ALPHA"; - default: - return "(unknown)"; - } - } - - private void updateTextureSharpenFunc(Context ctx, - int target, - int numPts, - float[] pts) { - // checking of the availability of sharpen texture functionality - // is already done in shared code -// FIXME: GL_SGIS_sharpen_texture -// GL gl = context(ctx).getGL(); -// gl.glSharpenTexFuncSGIS(target, numPts, pts, 0); - } - - private void updateTextureFilter4Func(Context ctx, - int target, - int numPts, - float[] pts) { - // checking of the availability of filter4 functionality - // is already done in shared code -// FIXME: GL_SGIS_texture_filter4 -// GL gl = context(ctx).getGL(); -// gl.glTexFilterFuncSGIS(target, GL.GL_FILTER4_SGIS, -// numPts, pts, 0); - } - - // mapping from java enum to gl enum - private static final int[] _gl_textureCubeMapFace = { - GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, - GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, - GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, - }; - - // --------------------------------------------------------------------- - - // - // MasterControl methods - // - - // Method to return the AWT object - long getAWT() { - if (VERBOSE) System.err.println("JoglPipeline.getAWT()"); - - // FIXME: probably completely unneeded in this implementation, - // but should probably remove this dependence in the shared code - return 0; - } - - // Method to initialize the native J3D library - boolean initializeJ3D(boolean disableXinerama) { - // Dummy method in JOGL pipeline - return true; - } - - // Maximum lights supported by the native API - int getMaximumLights() { - if (VERBOSE) System.err.println("JoglPipeline.getMaximumLights()"); - - // FIXME: this isn't quite what the NativePipeline returns but - // is probably close enough - return 8; - } - - - // --------------------------------------------------------------------- - - // - // Canvas3D methods - native wrappers - // - - // This is the native method for creating the underlying graphics context. - Context createNewContext(Canvas3D cv, long display, Drawable drawable, - long fbConfig, Context shareCtx, boolean isSharedCtx, - boolean offScreen, - boolean glslLibraryAvailable) { - if (VERBOSE) System.err.println("JoglPipeline.createNewContext()"); - GLDrawable draw = null; - GLCapabilitiesChooser indexChooser = null; - JoglGraphicsConfiguration config = (JoglGraphicsConfiguration) cv.graphicsConfiguration; - if (config.getChosenIndex() >= 0) { - indexChooser = new IndexCapabilitiesChooser(config.getChosenIndex()); - } - if (cv.drawable == null) { - AWTGraphicsScreen awtGraphicsScreen = new AWTGraphicsScreen(config.getAwtGraphicsDevice()); - GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(config.getAwtGraphicsDevice()); - AWTGraphicsConfiguration awtGraphicsConfiguration = (AWTGraphicsConfiguration)factory.chooseGraphicsConfiguration(config.getGLCapabilities(), - config.getGLCapabilities(), - indexChooser, awtGraphicsScreen); - NativeWindow nativeWindow = NativeWindowFactory.getNativeWindow(cv, awtGraphicsConfiguration); - draw = GLDrawableFactory.getFactory(getDefaultProfile()).createGLDrawable(nativeWindow); - cv.drawable = new JoglDrawable(draw); - } else { - draw = drawable(cv.drawable); - } - - // FIXME: assuming that this only gets called after addNotify has been called - draw.setRealized(true); - GLContext context = draw.createContext(context(shareCtx)); - - // Apparently we are supposed to make the context current at - // this point and set up a bunch of properties - - // Work around for some low end graphics driver bug, such as Intel Chipset. - // Issue 324 : Lockup Java3D program and throw exception using JOGL renderer - boolean failed = false; - int failCount = 0; - int MAX_FAIL_COUNT = 5; - do { - failed = false; - int res = context.makeCurrent(); - if (res == GLContext.CONTEXT_NOT_CURRENT) { - // System.err.println("makeCurrent fail : " + failCount); - failed = true; - ++failCount; - try { - Thread.sleep(100); - } catch (InterruptedException e) { - } - } - } while (failed && (failCount < MAX_FAIL_COUNT)); - if (failCount == MAX_FAIL_COUNT) { - throw new IllegalRenderingStateException("Unable to make new context current after " + failCount + "tries"); - } - - GL2 gl = context.getGL().getGL2(); - JoglContext ctx = new JoglContext(context); - - try { - if (!getPropertiesFromCurrentContext(ctx)) { - throw new IllegalRenderingStateException("Unable to fetch properties from current OpenGL context"); - } - - if(!isSharedCtx){ - // Set up fields in Canvas3D - setupCanvasProperties(cv, ctx, gl, glslLibraryAvailable); - } - - // Enable rescale normal - gl.glEnable(GL2.GL_RESCALE_NORMAL); - - gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE); - gl.glDepthFunc(GL.GL_LEQUAL); - gl.glEnable(GL2.GL_COLOR_MATERIAL); - gl.glReadBuffer(GL.GL_FRONT); - - // Issue 417: JOGL: Mip-mapped NPOT textures rendered incorrectly - // Java 3D images are aligned to 1 byte - gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); - - // Workaround for issue 400: Enable separate specular by default - gl.glLightModeli(GL2.GL_LIGHT_MODEL_COLOR_CONTROL, GL2.GL_SEPARATE_SPECULAR_COLOR); - } finally { - context.release(); - } - - return ctx; - } - - private GLProfile getDefaultProfile() { - return GLProfile.getMaxFixedFunc(true); - } - - void createQueryContext(Canvas3D cv, long display, Drawable drawable, - long fbConfig, boolean offScreen, int width, int height, - boolean glslLibraryAvailable) { - if (VERBOSE) System.err.println("JoglPipeline.createQueryContext()"); - - // FIXME: for now, ignoring the "offscreen" flag -- unclear how - // to create an offscreen buffer at this point -- very likely - // need Canvas3D.offScreenBufferInfo promoted to an Object -- - // this logic will need to be revisited to make sure we capture - // all of the functionality of the NativePipeline - - Frame f = new Frame(); - f.setUndecorated(true); - f.setLayout(new BorderLayout()); - GLCapabilities caps = new GLCapabilities(getDefaultProfile()); - ContextQuerier querier = new ContextQuerier(cv, glslLibraryAvailable); - // FIXME: should know what GraphicsDevice on which to create - // this Canvas / Frame, and this should probably be known from - // the incoming "display" parameter - - JoglGraphicsConfiguration joglGraphicsConfiguration = (JoglGraphicsConfiguration) cv.graphicsConfiguration; - AWTGraphicsDevice awtGraphicsDevice = joglGraphicsConfiguration.getAwtGraphicsDevice(); - AWTGraphicsConfiguration awtGraphicsConfiguration = createAwtGraphicsConfiguration(caps, querier, awtGraphicsDevice/*null*/); - - QueryCanvas canvas = new QueryCanvas(awtGraphicsConfiguration, querier); - f.add(canvas, BorderLayout.CENTER); - f.setSize(MIN_FRAME_SIZE, MIN_FRAME_SIZE); - f.setVisible(true); - canvas.doQuery(); - // Attempt to wait for the frame to become visible, but don't block the EDT - if (!EventQueue.isDispatchThread()) { - synchronized(querier) { - if (!querier.done()) { - try { - querier.wait(WAIT_TIME); - } catch (InterruptedException e) { - } - } - } - } - - disposeOnEDT(f); - } - - // This is the native for creating an offscreen buffer - Drawable createOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, int width, int height) { - if (VERBOSE) System.err.println("JoglPipeline.createOffScreenBuffer()"); - - // Note 1: when this is called, the incoming Context argument is - // null because (obviously) no drawable or context has been - // created for the Canvas3D yet. - - // Note 2: we ignore the global j3d.usePbuffer flag; JOGL - // doesn't expose pixmap/bitmap surfaces in its public API. - - // First pick up the JoglGraphicsConfiguration and from there - // the GLCapabilities from the Canvas3D - JoglGraphicsConfiguration jcfg = (JoglGraphicsConfiguration) cv.graphicsConfiguration; - // Note that we ignore any chosen index from a prior call to getBestConfiguration(); - // those only enumerate the on-screen visuals, and we need to find one which is - // pbuffer capable - GLCapabilities caps = jcfg.getGLCapabilities(); - - //FIXME use the real AWTGraphicsDevice - GLPbuffer pbuffer = GLDrawableFactory.getFactory(getDefaultProfile()).createGLPbuffer(GLDrawableFactory.getDesktopFactory().getDefaultDevice() ,caps, null,width, height, GLContext.getCurrent()); - - return new JoglDrawable(pbuffer); - } - - void destroyOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, Drawable drawable) { - if (VERBOSE) System.err.println("JoglPipeline.destroyOffScreenBuffer()"); - - JoglDrawable jdraw = (JoglDrawable) drawable; - GLPbuffer pbuffer = (GLPbuffer) jdraw.getGLDrawable(); - pbuffer.destroy(); - } - - // This is the native for reading the image from the offscreen buffer - void readOffScreenBuffer(Canvas3D cv, Context ctx, int format, int dataType, Object data, int width, int height) { - if (VERBOSE) System.err.println("JoglPipeline.readOffScreenBuffer()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, width); - gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1); - - int type = 0; - if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) || - (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) { - - switch (format) { - // GL_BGR - case ImageComponentRetained.TYPE_BYTE_BGR: - type = GL2.GL_BGR; - break; - case ImageComponentRetained.TYPE_BYTE_RGB: - type = GL.GL_RGB; - break; - // GL_ABGR_EXT - case ImageComponentRetained.TYPE_BYTE_ABGR: - if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If false, should never come here! - type = GL2.GL_ABGR_EXT; - } else { - assert false; - return; - } - break; - case ImageComponentRetained.TYPE_BYTE_RGBA: - type = GL.GL_RGBA; - break; - - /* This method only supports 3 and 4 components formats and BYTE types. */ - case ImageComponentRetained.TYPE_BYTE_LA: - case ImageComponentRetained.TYPE_BYTE_GRAY: - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_INT_BGR: - case ImageComponentRetained.TYPE_INT_RGB: - case ImageComponentRetained.TYPE_INT_ARGB: - default: - throw new AssertionError("illegal format " + format); - } - - gl.glReadPixels(0, 0, width, height, type, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[]) data)); - - } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) || - (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) { - - int intType = GL2.GL_UNSIGNED_INT_8_8_8_8; - boolean forceAlphaToOne = false; - - switch (format) { - /* GL_BGR */ - case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ - type = GL.GL_RGBA; - intType = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - forceAlphaToOne = true; - break; - case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ - forceAlphaToOne = true; - /* Fall through to next case */ - case ImageComponentRetained.TYPE_INT_ARGB: - type = GL2.GL_BGRA; - intType = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; - break; - /* This method only supports 3 and 4 components formats and BYTE types. */ - case ImageComponentRetained.TYPE_BYTE_LA: - case ImageComponentRetained.TYPE_BYTE_GRAY: - case ImageComponentRetained.TYPE_USHORT_GRAY: - case ImageComponentRetained.TYPE_BYTE_BGR: - case ImageComponentRetained.TYPE_BYTE_RGB: - case ImageComponentRetained.TYPE_BYTE_RGBA: - case ImageComponentRetained.TYPE_BYTE_ABGR: - default: - throw new AssertionError("illegal format " + format); - } - - /* Force Alpha to 1.0 if needed */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); - } - - gl.glReadPixels(0, 0, width, height, type, intType, IntBuffer.wrap((int[]) data)); - - /* Restore Alpha scale and bias */ - if(forceAlphaToOne) { - gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); - gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); - } - - } else { - throw new AssertionError("illegal image data type " + dataType); - - } - } - - // The native method for swapBuffers - int swapBuffers(Canvas3D cv, Context ctx, long dpy, Drawable drawable) { - if (VERBOSE) System.err.println("JoglPipeline.swapBuffers()"); - GLDrawable draw = drawable(drawable); - draw.swapBuffers(); - return 0; - } - - // native method for setting Material when no material is present - void updateMaterialColor(Context ctx, float r, float g, float b, float a) { - if (VERBOSE) System.err.println("JoglPipeline.updateMaterialColor()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glColor4f(r, g, b, a); - gl.glDisable(GL2.GL_LIGHTING); - } - - void destroyContext(long display, Drawable drawable, Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.destroyContext()"); - GLDrawable draw = drawable(drawable); - GLContext context = context(ctx); - if (GLContext.getCurrent() == context) { - context.release(); - } - context.destroy(); - // FIXME: assuming this is the right point at which to make this call - draw.setRealized(false); - } - - // This is the native method for doing accumulation. - void accum(Context ctx, float value) { - if (VERBOSE) System.err.println("JoglPipeline.accum()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glReadBuffer(GL.GL_BACK); - gl.glAccum(GL2.GL_ACCUM, value); - gl.glReadBuffer(GL.GL_FRONT); - } - - // This is the native method for doing accumulation return. - void accumReturn(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.accumReturn()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glAccum(GL2.GL_RETURN, 1.0f); - } - - // This is the native method for clearing the accumulation buffer. - void clearAccum(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.clearAccum()"); - - GL gl = context(ctx).getGL(); - gl.glClear(GL2.GL_ACCUM_BUFFER_BIT); - } - - // This is the native method for getting the number of lights the underlying - // native library can support. - int getNumCtxLights(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.getNumCtxLights()"); - - GL gl = context(ctx).getGL(); - int[] res = new int[1]; - gl.glGetIntegerv(GL2.GL_MAX_LIGHTS, res, 0); - return res[0]; - } - - // Native method for decal 1st child setup - boolean decal1stChildSetup(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.decal1stChildSetup()"); - - GL gl = context(ctx).getGL(); - gl.glEnable(GL.GL_STENCIL_TEST); - gl.glClearStencil(0x0); - gl.glClear(GL.GL_STENCIL_BUFFER_BIT); - gl.glStencilFunc(GL.GL_ALWAYS, 0x1, 0x1); - gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_REPLACE); - if (gl.glIsEnabled(GL.GL_DEPTH_TEST)) - return true; - else - return false; - } - - // Native method for decal nth child setup - void decalNthChildSetup(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.decalNthChildSetup()"); - - GL gl = context(ctx).getGL(); - gl.glDisable(GL.GL_DEPTH_TEST); - gl.glStencilFunc(GL.GL_EQUAL, 0x1, 0x1); - gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); - } - - // Native method for decal reset - void decalReset(Context ctx, boolean depthBufferEnable) { - if (VERBOSE) System.err.println("JoglPipeline.decalReset()"); - - GL gl = context(ctx).getGL(); - gl.glDisable(GL.GL_STENCIL_TEST); - if (depthBufferEnable) - gl.glEnable(GL.GL_DEPTH_TEST); - } - - // Native method for eye lighting - void ctxUpdateEyeLightingEnable(Context ctx, boolean localEyeLightingEnable) { - if (VERBOSE) System.err.println("JoglPipeline.ctxUpdateEyeLightingEnable()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - if (localEyeLightingEnable) { - gl.glLightModeli(GL2.GL_LIGHT_MODEL_LOCAL_VIEWER, GL.GL_TRUE); - } else { - gl.glLightModeli(GL2.GL_LIGHT_MODEL_LOCAL_VIEWER, GL.GL_FALSE); - } - } - - // The following three methods are used in multi-pass case - - // native method for setting blend color - void setBlendColor(Context ctx, float red, float green, - float blue, float alpha) { - if (VERBOSE) System.err.println("JoglPipeline.setBlendColor()"); - - GL2 gl = context(ctx).getGL().getGL2(); - if (gl.isExtensionAvailable("GL_ARB_imaging")) { - gl.glBlendColor(red, green, blue, alpha); - } - } - - // native method for setting blend func - void setBlendFunc(Context ctx, int srcBlendFunction, int dstBlendFunction) { - if (VERBOSE) System.err.println("JoglPipeline.setBlendFunc()"); - - GL gl = context(ctx).getGL(); - gl.glEnable(GL.GL_BLEND); - gl.glBlendFunc(blendFunctionTable[srcBlendFunction], - blendFunctionTable[dstBlendFunction]); - } - - // native method for setting fog enable flag - void setFogEnableFlag(Context ctx, boolean enable) { - if (VERBOSE) System.err.println("JoglPipeline.setFogEnableFlag()"); - - GL gl = context(ctx).getGL(); - - if (enable) - gl.glEnable(GL2.GL_FOG); - else - gl.glDisable(GL2.GL_FOG); - } - - // Setup the full scene antialising in D3D and ogl when GL_ARB_multisamle supported - void setFullSceneAntialiasing(Context absCtx, boolean enable) { - if (VERBOSE) System.err.println("JoglPipeline.setFullSceneAntialiasing()"); - - JoglContext ctx = (JoglContext) absCtx; - GL gl = context(ctx).getGL(); - if (ctx.getHasMultisample() && !VirtualUniverse.mc.implicitAntialiasing) { - if (enable) { - gl.glEnable(GL.GL_MULTISAMPLE); - } else { - gl.glDisable(GL.GL_MULTISAMPLE); - } - } - } - - void setGlobalAlpha(Context ctx, float alpha) { - if (VERBOSE) System.err.println("JoglPipeline.setGlobalAlpha()"); -// FIXME: SUN_global_alpha -// GL gl = context(ctx).getGL(); -// if (gl.isExtensionAvailable("GL_SUN_global_alpha")) { -// gl.glEnable(GL.GL_GLOBAL_ALPHA_SUN); -// gl.glGlobalAlphaFactorfSUN(alpha); -// } - } - - // Native method to update separate specular color control - void updateSeparateSpecularColorEnable(Context ctx, boolean enable) { - if (VERBOSE) System.err.println("JoglPipeline.updateSeparateSpecularColorEnable()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - if (enable) { - gl.glLightModeli(GL2.GL_LIGHT_MODEL_COLOR_CONTROL, GL2.GL_SEPARATE_SPECULAR_COLOR); - } else { - gl.glLightModeli(GL2.GL_LIGHT_MODEL_COLOR_CONTROL, GL2.GL_SINGLE_COLOR); - } - } - - // True under Solaris, - // False under windows when display mode <= 8 bit - boolean validGraphicsMode() { - if (VERBOSE) System.err.println("JoglPipeline.validGraphicsMode()"); - - // FIXME: believe this should do exactly what the native code - // used to, but not 100% sure (also in theory should only run - // this code on the Windows platform? What about Mac OS X?) - DisplayMode currentMode = - GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode(); - // Note: on X11 platforms, a bit depth < 0 simply indicates that - // multiple visuals are supported on the current display mode - - if (VERBOSE) System.err.println(" Returning " + (currentMode.getBitDepth() < 0 || - currentMode.getBitDepth() > 8)); - - return (currentMode.getBitDepth() < 0 || - currentMode.getBitDepth() > 8); - } - - // native method for setting light enables - void setLightEnables(Context ctx, long enableMask, int maxLights) { - if (VERBOSE) System.err.println("JoglPipeline.setLightEnables()"); - - GL gl = context(ctx).getGL(); - - for (int i = 0; i < maxLights; i++) { - if ((enableMask & (1 << i)) != 0) { - gl.glEnable(GL2.GL_LIGHT0 + i); - } else { - gl.glDisable(GL2.GL_LIGHT0 + i); - } - } - } - - // native method for setting scene ambient - void setSceneAmbient(Context ctx, float red, float green, float blue) { - if (VERBOSE) System.err.println("JoglPipeline.setSceneAmbient()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - float[] color = new float[4]; - color[0] = red; - color[1] = green; - color[2] = blue; - color[3] = 1.0f; - gl.glLightModelfv(GL2.GL_LIGHT_MODEL_AMBIENT, color, 0); - } - - // native method for disabling fog - void disableFog(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.disableFog()"); - - GL gl = context(ctx).getGL(); - gl.glDisable(GL2.GL_FOG); - } - - // native method for disabling modelClip - void disableModelClip(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.disableModelClip()"); - - GL gl = context(ctx).getGL(); - - gl.glDisable(GL2.GL_CLIP_PLANE0); - gl.glDisable(GL2.GL_CLIP_PLANE1); - gl.glDisable(GL2.GL_CLIP_PLANE2); - gl.glDisable(GL2.GL_CLIP_PLANE3); - gl.glDisable(GL2.GL_CLIP_PLANE4); - gl.glDisable(GL2.GL_CLIP_PLANE5); - } - - // native method for setting default RenderingAttributes - void resetRenderingAttributes(Context ctx, - boolean depthBufferWriteEnableOverride, - boolean depthBufferEnableOverride) { - if (VERBOSE) System.err.println("JoglPipeline.resetRenderingAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - if (!depthBufferWriteEnableOverride) { - gl.glDepthMask(true); - } - if (!depthBufferEnableOverride) { - gl.glEnable(GL.GL_DEPTH_TEST); - } - gl.glAlphaFunc(GL.GL_ALWAYS, 0.0f); - gl.glDepthFunc(GL.GL_LEQUAL); - gl.glEnable(GL2.GL_COLOR_MATERIAL); - gl.glDisable(GL.GL_COLOR_LOGIC_OP); - } - - // native method for setting default texture - void resetTextureNative(Context ctx, int texUnitIndex) { - if (VERBOSE) System.err.println("JoglPipeline.resetTextureNative()"); - - GL2 gl = context(ctx).getGL().getGL2(); - if (texUnitIndex >= 0 && - gl.isExtensionAvailable("GL_VERSION_1_3")) { - gl.glActiveTexture(texUnitIndex + GL.GL_TEXTURE0); - gl.glClientActiveTexture(texUnitIndex + GL.GL_TEXTURE0); - } - - gl.glDisable(GL2.GL_TEXTURE_1D); - gl.glDisable(GL.GL_TEXTURE_2D); - gl.glDisable(GL2.GL_TEXTURE_3D); - gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); - } - - // native method for activating a particular texture unit - void activeTextureUnit(Context ctx, int texUnitIndex) { - if (VERBOSE) System.err.println("JoglPipeline.activeTextureUnit()"); - - GL2 gl = context(ctx).getGL().getGL2(); - if (gl.isExtensionAvailable("GL_VERSION_1_3")) { - gl.glActiveTexture(texUnitIndex + GL.GL_TEXTURE0); - gl.glClientActiveTexture(texUnitIndex + GL.GL_TEXTURE0); - } - } - - // native method for setting default TexCoordGeneration - void resetTexCoordGeneration(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.resetTexCoordGeneration()"); - - GL gl = context(ctx).getGL(); - gl.glDisable(GL2.GL_TEXTURE_GEN_S); - gl.glDisable(GL2.GL_TEXTURE_GEN_T); - gl.glDisable(GL2.GL_TEXTURE_GEN_R); - gl.glDisable(GL2.GL_TEXTURE_GEN_Q); - } - - // native method for setting default TextureAttributes - void resetTextureAttributes(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.resetTextureAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - float[] color = new float[4]; - - gl.glPushAttrib(GL2.GL_TRANSFORM_BIT); - gl.glMatrixMode(GL.GL_TEXTURE); - gl.glLoadIdentity(); - gl.glPopAttrib(); - gl.glTexEnvfv(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_COLOR, color, 0); - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); - gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); - -// FIXME: GL_NV_register_combiners -// if (gl.isExtensionAvailable("GL_NV_register_combiners")) { -// gl.glDisable(GL.GL_REGISTER_COMBINERS_NV); -// } - -// FIXME: GL_SGI_texture_color_table -// if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) { -// gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI); -// } - } - - // native method for setting default PolygonAttributes - void resetPolygonAttributes(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.resetPolygonAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - gl.glCullFace(GL.GL_BACK); - gl.glEnable(GL.GL_CULL_FACE); - - gl.glLightModeli(GL2.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_FALSE); - - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL); - - gl.glPolygonOffset(0.0f, 0.0f); - gl.glDisable(GL2.GL_POLYGON_OFFSET_POINT); - gl.glDisable(GL2.GL_POLYGON_OFFSET_LINE); - gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); - } - - // native method for setting default LineAttributes - void resetLineAttributes(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.resetLineAttributes()"); - - GL gl = context(ctx).getGL(); - gl.glLineWidth(1.0f); - gl.glDisable(GL2.GL_LINE_STIPPLE); - - // XXXX: Polygon Mode check, blend enable - gl.glDisable(GL.GL_LINE_SMOOTH); - } - - // native method for setting default PointAttributes - void resetPointAttributes(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.resetPointAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glPointSize(1.0f); - - // XXXX: Polygon Mode check, blend enable - gl.glDisable(GL2.GL_POINT_SMOOTH); - } - - // native method for setting default TransparencyAttributes - void resetTransparency(Context ctx, int geometryType, - int polygonMode, boolean lineAA, - boolean pointAA) { - if (VERBOSE) System.err.println("JoglPipeline.resetTransparency()"); - - GL gl = context(ctx).getGL(); - - if (((((geometryType & RenderMolecule.LINE) != 0) || - (polygonMode == PolygonAttributes.POLYGON_LINE)) - && lineAA) || - ((((geometryType & RenderMolecule.POINT) != 0) || - (polygonMode == PolygonAttributes.POLYGON_POINT)) - && pointAA)) { - gl.glEnable(GL.GL_BLEND); - gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); - } else { - gl.glDisable(GL.GL_BLEND); - } - gl.glDisable(GL2.GL_POLYGON_STIPPLE); - } - - // native method for setting default ColoringAttributes - void resetColoringAttributes(Context ctx, - float r, float g, - float b, float a, - boolean enableLight) { - if (VERBOSE) System.err.println("JoglPipeline.resetColoringAttributes()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - if (!enableLight) { - gl.glColor4f(r, g, b, a); - } - gl.glShadeModel(GL2.GL_SMOOTH); - } - - /** - * This native method makes sure that the rendering for this canvas - * gets done now. - */ - void syncRender(Context ctx, boolean wait) { - if (VERBOSE) System.err.println("JoglPipeline.syncRender()"); - - GL gl = context(ctx).getGL(); - - if (wait) - gl.glFinish(); - else - gl.glFlush(); - } - - // The native method that sets this ctx to be the current one - boolean useCtx(Context ctx, long display, Drawable drawable) { - if (VERBOSE) System.err.println("JoglPipeline.useCtx()"); - GLContext context = context(ctx); - int res = context.makeCurrent(); - return (res != GLContext.CONTEXT_NOT_CURRENT); - } - - // Optionally release the context. Returns true if the context was released. - boolean releaseCtx(Context ctx, long dpy) { - if (VERBOSE) System.err.println("JoglPipeline.releaseCtx()"); - GLContext context = context(ctx); - context.release(); - return true; - } - - void clear(Context ctx, float r, float g, float b, boolean clearStencil) { - if (VERBOSE) System.err.println("JoglPipeline.clear()"); - - JoglContext jctx = (JoglContext) ctx; - GLContext context = context(ctx); - GL2 gl = context.getGL().getGL2(); - - // OBSOLETE CLEAR CODE - /* - gl.glClearColor(r, g, b, jctx.getAlphaClearValue()); - gl.glClear(GL.GL_COLOR_BUFFER_BIT); - - // Java 3D always clears the Z-buffer - gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT); - gl.glDepthMask(true); - gl.glClear(GL.GL_DEPTH_BUFFER_BIT); - gl.glPopAttrib(); - - // Issue 239 - clear stencil if specified - if (clearStencil) { - gl.glPushAttrib(GL.GL_STENCIL_BUFFER_BIT); - gl.glClearStencil(0); - gl.glStencilMask(~0); - gl.glClear(GL.GL_STENCIL_BUFFER_BIT); - gl.glPopAttrib(); - } - */ - - // Mask of which buffers to clear, this always includes color & depth - int clearMask = GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT; - - // Issue 239 - clear stencil if specified - if (clearStencil) { - gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT); - - gl.glClearStencil(0); - gl.glStencilMask(~0); - clearMask |= GL.GL_STENCIL_BUFFER_BIT; - } else { - gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT); - } - - gl.glDepthMask(true); - gl.glClearColor(r, g, b, jctx.getAlphaClearValue()); - gl.glClear(clearMask); - gl.glPopAttrib(); - - } - - void textureFillBackground(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV, - float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, boolean useBilinearFilter) { - if (VERBOSE) System.err.println("JoglPipeline.textureFillBackground()"); - - GLContext context = context(ctx); - GL2 gl = context.getGL().getGL2(); - - // Temporarily disable fragment and most 3D operations - gl.glPushAttrib(GL2.GL_ENABLE_BIT | GL2.GL_TEXTURE_BIT | GL2.GL_POLYGON_BIT); - - disableAttribFor2D(gl); - gl.glDepthMask(false); - gl.glEnable(GL.GL_TEXTURE_2D); - - /* Setup filter mode if needed */ - if(useBilinearFilter) { - // System.err.println("JoglPipeline - Background : use bilinear filter\n"); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); - } - - // reset the polygon mode - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL); - - gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); - - // load identity modelview and projection matrix - gl.glMatrixMode(GL2.GL_PROJECTION); - gl.glLoadIdentity(); - gl.glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); - gl.glMatrixMode(GL2.GL_MODELVIEW); - gl.glLoadIdentity(); - gl.glMatrixMode(GL.GL_TEXTURE); - gl.glPushMatrix(); - gl.glLoadIdentity(); - - gl.glBegin(GL2.GL_QUADS); - gl.glTexCoord2f(texMinU, texMinV); gl.glVertex2f(mapMinX,mapMinY); - gl.glTexCoord2f(texMaxU, texMinV); gl.glVertex2f(mapMaxX,mapMinY); - gl.glTexCoord2f(texMaxU, texMaxV); gl.glVertex2f(mapMaxX,mapMaxY); - gl.glTexCoord2f(texMinU, texMaxV); gl.glVertex2f(mapMinX,mapMaxY); - gl.glEnd(); - - // Restore texture Matrix transform - gl.glPopMatrix(); - - gl.glMatrixMode(GL2.GL_MODELVIEW); - // Restore attributes - gl.glPopAttrib(); - - } - - void textureFillRaster(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV, - float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, float mapZ, float alpha, - boolean useBilinearFilter) { - - if (VERBOSE) System.err.println("JoglPipeline.textureFillRaster()"); - - GLContext context = context(ctx); - GL2 gl = context.getGL().getGL2(); - - // Temporarily disable fragment and most 3D operations - gl.glPushAttrib(GL2.GL_ENABLE_BIT | GL2.GL_TEXTURE_BIT | GL2.GL_POLYGON_BIT | - GL2.GL_CURRENT_BIT ); - - disableAttribForRaster(gl); - - /* Setup filter mode if needed */ - if(useBilinearFilter) { - // System.err.println("JoglPipeline - Raster : use bilinear filter\n"); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); - } - - gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE); - gl.glColor4f(1.0f, 1.0f, 1.0f, alpha); - - // reset the polygon mode - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL); - - gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); - - // load identity modelview and projection matrix - gl.glMatrixMode(GL2.GL_MODELVIEW); - gl.glPushMatrix(); - gl.glLoadIdentity(); - gl.glMatrixMode(GL2.GL_PROJECTION); - gl.glPushMatrix(); - gl.glLoadIdentity(); - gl.glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0); - - gl.glBegin(GL2.GL_QUADS); - gl.glTexCoord2f(texMinU, texMinV); gl.glVertex3f(mapMinX,mapMinY, mapZ); - gl.glTexCoord2f(texMaxU, texMinV); gl.glVertex3f(mapMaxX,mapMinY, mapZ); - gl.glTexCoord2f(texMaxU, texMaxV); gl.glVertex3f(mapMaxX,mapMaxY, mapZ); - gl.glTexCoord2f(texMinU, texMaxV); gl.glVertex3f(mapMinX,mapMaxY, mapZ); - gl.glEnd(); - - // Restore matrices - gl.glPopMatrix(); - gl.glMatrixMode(GL2.GL_MODELVIEW); - gl.glPopMatrix(); - // Restore attributes - gl.glPopAttrib(); - - } - - void executeRasterDepth(Context ctx, float posX, float posY, float posZ, - int srcOffsetX, int srcOffsetY, int rasterWidth, int rasterHeight, - int depthWidth, int depthHeight, int depthFormat, Object depthData) { - if (VERBOSE) System.err.println("JoglPipeline.executeRasterDepth()"); - GLContext context = context(ctx); - GL2 gl = context.getGL().getGL2(); - - - gl.glRasterPos3f(posX, posY, posZ); - - int[] drawBuf = new int[1]; - gl.glGetIntegerv(GL2.GL_DRAW_BUFFER, drawBuf, 0); - /* disable draw buffer */ - gl.glDrawBuffer(GL.GL_NONE); - - /* - * raster position is upper left corner, default for Java3D - * ImageComponent currently has the data reverse in Y - */ - gl.glPixelZoom(1.0f, -1.0f); - gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, depthWidth); - if (srcOffsetX >= 0) { - gl.glPixelStorei(GL2.GL_UNPACK_SKIP_PIXELS, srcOffsetX); - if (srcOffsetX + rasterWidth > depthWidth) { - rasterWidth = depthWidth - srcOffsetX; - } - } else { - rasterWidth += srcOffsetX; - if (rasterWidth > depthWidth) { - rasterWidth = depthWidth; - } - } - if (srcOffsetY >= 0) { - gl.glPixelStorei(GL2.GL_UNPACK_SKIP_ROWS, srcOffsetY); - if (srcOffsetY + rasterHeight > depthHeight) { - rasterHeight = depthHeight - srcOffsetY; - } - } else { - rasterHeight += srcOffsetY; - if (rasterHeight > depthHeight) { - rasterHeight = depthHeight; - } - } - - - if (depthFormat == DepthComponentRetained.DEPTH_COMPONENT_TYPE_INT) { - gl.glDrawPixels(rasterWidth, rasterHeight, GL2.GL_DEPTH_COMPONENT, - GL.GL_UNSIGNED_INT, IntBuffer.wrap((int[]) depthData)); - } else { /* DepthComponentRetained.DEPTH_COMPONENT_TYPE_FLOAT */ - gl.glDrawPixels(rasterWidth, rasterHeight, GL2.GL_DEPTH_COMPONENT, - GL.GL_FLOAT, FloatBuffer.wrap((float[]) depthData)); - } - - /* re-enable draw buffer */ - gl.glDrawBuffer(drawBuf[0]); - - gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, 0); - gl.glPixelStorei(GL2.GL_UNPACK_SKIP_PIXELS, 0); - gl.glPixelStorei(GL2.GL_UNPACK_SKIP_ROWS, 0); - - } - - // The native method for setting the ModelView matrix. - void setModelViewMatrix(Context ctx, double[] viewMatrix, double[] modelMatrix) { - if (VERBOSE) System.err.println("JoglPipeline.setModelViewMatrix()"); - GLContext context = context(ctx); - GL2 gl = context.getGL().getGL2(); - - gl.glMatrixMode(GL2.GL_MODELVIEW); - - if (gl.isExtensionAvailable("GL_VERSION_1_3")) { - gl.glLoadTransposeMatrixd(viewMatrix, 0); - gl.glMultTransposeMatrixd(modelMatrix, 0); - } else { - double[] v = new double[16]; - double[] m = new double[16]; - copyTranspose(viewMatrix, v); - copyTranspose(modelMatrix, m); - gl.glLoadMatrixd(v, 0); - gl.glMultMatrixd(m, 0); - } - } - - // The native method for setting the Projection matrix. - void setProjectionMatrix(Context ctx, double[] projMatrix) { - if (VERBOSE) System.err.println("JoglPipeline.setProjectionMatrix()"); - GLContext context = context(ctx); - GL2 gl = context.getGL().getGL2(); - - gl.glMatrixMode(GL2.GL_PROJECTION); - - if (gl.isExtensionAvailable("GL_VERSION_1_3")) { - // Invert the Z value in clipping coordinates because OpenGL uses - // left-handed clipping coordinates, while Java3D defines right-handed - // coordinates everywhere. - projMatrix[8] *= -1.0; - projMatrix[9] *= -1.0; - projMatrix[10] *= -1.0; - projMatrix[11] *= -1.0; - gl.glLoadTransposeMatrixd(projMatrix, 0); - projMatrix[8] *= -1.0; - projMatrix[9] *= -1.0; - projMatrix[10] *= -1.0; - projMatrix[11] *= -1.0; - } else { - double[] p = new double[16]; - copyTranspose(projMatrix, p); - // Invert the Z value in clipping coordinates because OpenGL uses - // left-handed clipping coordinates, while Java3D defines right-handed - // coordinates everywhere. - p[2] *= -1.0; - p[6] *= -1.0; - p[10] *= -1.0; - p[14] *= -1.0; - gl.glLoadMatrixd(p, 0); - } - } - - // The native method for setting the Viewport. - void setViewport(Context ctx, int x, int y, int width, int height) { - if (VERBOSE) System.err.println("JoglPipeline.setViewport()"); - GL gl = context(ctx).getGL(); - gl.glViewport(x, y, width, height); - } - - // used for display Lists - void newDisplayList(Context ctx, int displayListId) { - if (VERBOSE) System.err.println("JoglPipeline.newDisplayList()"); - if (displayListId <= 0) { - System.err.println("JAVA 3D ERROR : glNewList(" + displayListId + ") -- IGNORED"); - } - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glNewList(displayListId, GL2.GL_COMPILE); - } - - void endDisplayList(Context ctx) { - if (VERBOSE) System.err.println("JoglPipeline.endDisplayList()"); - GL2 gl = context(ctx).getGL().getGL2(); - gl.glEndList(); - } - - int numInvalidLists = 0; - void callDisplayList(Context ctx, int id, boolean isNonUniformScale) { - if (VERBOSE) System.err.println("JoglPipeline.callDisplayList()"); - if (id <= 0) { - if (numInvalidLists < 3) { - ++numInvalidLists; - System.err.println("JAVA 3D ERROR : glCallList(" + id + ") -- IGNORED"); - } else if (numInvalidLists == 3) { - ++numInvalidLists; - System.err.println("JAVA 3D : further glCallList error messages discarded"); - } - return; - } - - GL2 gl = context(ctx).getGL().getGL2(); - // Set normalization if non-uniform scale - if (isNonUniformScale) { - gl.glEnable(GL2.GL_NORMALIZE); - } - - gl.glCallList(id); - - // Turn normalization back off - if (isNonUniformScale) { - gl.glDisable(GL2.GL_NORMALIZE); - } - } - - void freeDisplayList(Context ctx, int id) { - if (VERBOSE) System.err.println("JoglPipeline.freeDisplayList()"); - if (id <= 0) { - System.err.println("JAVA 3D ERROR : glDeleteLists(" + id + ",1) -- IGNORED"); - } - - GL2 gl = context(ctx).getGL().getGL2(); - gl.glDeleteLists(id, 1); - } - void freeTexture(Context ctx, int id) { - if (VERBOSE) System.err.println("JoglPipeline.freeTexture()"); - - GL gl = context(ctx).getGL(); - - if (id > 0) { - int[] tmp = new int[1]; - tmp[0] = id; - gl.glDeleteTextures(1, tmp, 0); - } else { - System.err.println("tried to delete tex with texid <= 0"); - } - } - - - void texturemapping(Context ctx, - int px, int py, - int minX, int minY, int maxX, int maxY, - int texWidth, int texHeight, - int rasWidth, - int format, int objectId, - byte[] imageYdown, - int winWidth, int winHeight) { - if (VERBOSE) System.err.println("JoglPipeline.texturemapping()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - int glType = GL.GL_RGBA; - - // Temporarily disable fragment and most 3D operations - gl.glPushAttrib(GL2.GL_ENABLE_BIT | GL2.GL_TEXTURE_BIT | GL.GL_DEPTH_BUFFER_BIT | GL2.GL_POLYGON_BIT); - disableAttribFor2D(gl); - - // Reset the polygon mode - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL); - - gl.glDepthMask(false); - gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); - gl.glBindTexture(GL.GL_TEXTURE_2D, objectId); - // set up texture parameter - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT); - - gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); - gl.glEnable(GL.GL_BLEND); - gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); - - gl.glEnable(GL.GL_TEXTURE_2D); - - // loaded identity modelview and projection matrix - gl.glMatrixMode(GL2.GL_PROJECTION); - gl.glLoadIdentity(); - - gl.glOrtho(0.0, winWidth, 0.0, winHeight, 0.0, 0.0); - - gl.glMatrixMode(GL2.GL_MODELVIEW); - gl.glLoadIdentity(); - - if (gl.isExtensionAvailable("GL_EXT_abgr")) { - glType = GL2.GL_ABGR_EXT; - } else { - switch (format) { - case ImageComponentRetained.TYPE_BYTE_RGBA: - glType = GL.GL_RGBA; - break; - case ImageComponentRetained.TYPE_BYTE_RGB: - glType = GL.GL_RGB; - break; - } - } - gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, rasWidth); - gl.glPixelStorei(GL2.GL_UNPACK_SKIP_PIXELS, minX); - gl.glPixelStorei(GL2.GL_UNPACK_SKIP_ROWS, minY); - gl.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, minX, minY, - maxX - minX, maxY - minY, - glType, GL.GL_UNSIGNED_BYTE, - ByteBuffer.wrap(imageYdown)); - gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, 0); - gl.glPixelStorei(GL2.GL_UNPACK_SKIP_PIXELS, 0); - gl.glPixelStorei(GL2.GL_UNPACK_SKIP_ROWS, 0); - - float texMinU = (float) minX/ (float) texWidth; - float texMinV = (float) minY/ (float) texHeight; - float texMaxU = (float) maxX/ (float) texWidth; - float texMaxV = (float) maxY/ (float) texHeight; - float halfWidth = (float)winWidth/2.0f; - float halfHeight = (float)winHeight/2.0f; - - float mapMinX = (float) (((px + minX)- halfWidth)/halfWidth); - float mapMinY = (float) ((halfHeight - (py + maxY))/halfHeight); - float mapMaxX = (float) ((px + maxX - halfWidth)/halfWidth); - float mapMaxY = (float) ((halfHeight - (py + minY))/halfHeight); - - gl.glBegin(GL2.GL_QUADS); - - gl.glTexCoord2f(texMinU, texMaxV); gl.glVertex2f(mapMinX,mapMinY); - gl.glTexCoord2f(texMaxU, texMaxV); gl.glVertex2f(mapMaxX,mapMinY); - gl.glTexCoord2f(texMaxU, texMinV); gl.glVertex2f(mapMaxX,mapMaxY); - gl.glTexCoord2f(texMinU, texMinV); gl.glVertex2f(mapMinX,mapMaxY); - gl.glEnd(); - - // Java 3D always clears the Z-buffer - gl.glDepthMask(true); - gl.glClear(GL.GL_DEPTH_BUFFER_BIT); - gl.glPopAttrib(); - } - - boolean initTexturemapping(Context ctx, int texWidth, - int texHeight, int objectId) { - if (VERBOSE) System.err.println("JoglPipeline.initTexturemapping()"); - - GL2 gl = context(ctx).getGL().getGL2(); - - int glType = (gl.isExtensionAvailable("GL_EXT_abgr") ? GL2.GL_ABGR_EXT : GL.GL_RGBA); - - gl.glBindTexture(GL.GL_TEXTURE_2D, objectId); - - gl.glTexImage2D(GL2.GL_PROXY_TEXTURE_2D, 0, GL.GL_RGBA, texWidth, - texHeight, 0, glType, GL.GL_UNSIGNED_BYTE, null); - - int[] width = new int[1]; - gl.glGetTexLevelParameteriv(GL2.GL_PROXY_TEXTURE_2D, 0, - GL2.GL_TEXTURE_WIDTH, width, 0); - - if (width[0] <= 0) { - return false; - } - - // init texture size only without filling the pixels - gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, texWidth, - texHeight, 0, glType, GL.GL_UNSIGNED_BYTE, null); - - return true; - } - - - // Set internal render mode to one of FIELD_ALL, FIELD_LEFT or - // FIELD_RIGHT. Note that it is up to the caller to ensure that - // stereo is available before setting the mode to FIELD_LEFT or - // FIELD_RIGHT. The boolean isTRUE for double buffered mode, FALSE - // foe single buffering. - void setRenderMode(Context ctx, int mode, boolean doubleBuffer) { - if (VERBOSE) System.err.println("JoglPipeline.setRenderMode()"); - - GL2 gl = context(ctx).getGL().getGL2(); - int drawBuf = 0; - if (doubleBuffer) { - drawBuf = GL.GL_BACK; - switch (mode) { - case Canvas3D.FIELD_LEFT: - drawBuf = GL2.GL_BACK_LEFT; - break; - case Canvas3D.FIELD_RIGHT: - drawBuf = GL2.GL_BACK_RIGHT; - break; - case Canvas3D.FIELD_ALL: - drawBuf = GL.GL_BACK; - break; - } - } else { - drawBuf = GL.GL_FRONT; - switch (mode) { - case Canvas3D.FIELD_LEFT: - drawBuf = GL2.GL_FRONT_LEFT; - break; - case Canvas3D.FIELD_RIGHT: - drawBuf = GL2.GL_FRONT_RIGHT; - break; - case Canvas3D.FIELD_ALL: - drawBuf = GL.GL_FRONT; - break; - } - } - - gl.glDrawBuffer(drawBuf); - } - - // Set glDepthMask. - void setDepthBufferWriteEnable(Context ctx, boolean mode) { - if (VERBOSE) System.err.println("JoglPipeline.setDepthBufferWriteEnable()"); - - GL gl = context(ctx).getGL(); - if (mode) { - gl.glDepthMask(true); - } else { - gl.glDepthMask(false); - } - } - - //---------------------------------------------------------------------- - // Helper private functions for Canvas3D - // - - private boolean getPropertiesFromCurrentContext(JoglContext ctx) { - GL gl = GLU.getCurrentGL(); - // FIXME: this is a heavily abridged set of the stuff in Canvas3D.c; - // probably need to pull much more in - int[] tmp = new int[1]; - gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_UNITS, tmp, 0); - ctx.setMaxTexCoordSets(tmp[0]); - if (VirtualUniverse.mc.transparentOffScreen) { - ctx.setAlphaClearValue(0.0f); - } else { - ctx.setAlphaClearValue(1.0f); - } - if (gl.isExtensionAvailable("GL_ARB_vertex_shader")) { - gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_COORDS_ARB, tmp, 0); - ctx.setMaxTexCoordSets(tmp[0]); - } - return true; - } - - private int[] extractVersionInfo(String versionString) { - StringTokenizer tok = new StringTokenizer(versionString, ". "); - int major = Integer.valueOf(tok.nextToken()).intValue(); - int minor = Integer.valueOf(tok.nextToken()).intValue(); - - // See if there's vendor-specific information which might - // imply a more recent OpenGL version - tok = new StringTokenizer(versionString, " "); - if (tok.hasMoreTokens()) { - tok.nextToken(); - if (tok.hasMoreTokens()) { - Pattern p = Pattern.compile("\\D*(\\d+)\\.(\\d+)\\.?(\\d*).*"); - Matcher m = p.matcher(tok.nextToken()); - if (m.matches()) { - int altMajor = Integer.valueOf(m.group(1)).intValue(); - int altMinor = Integer.valueOf(m.group(2)).intValue(); - // Avoid possibly confusing situations by requiring - // major version to match - if (altMajor == major && - altMinor > minor) { - minor = altMinor; - } - } - } - } - return new int[] { major, minor }; - } - -// FIXME: GL_SGI_texture_color_table -// private int getTextureColorTableSize(GL gl) { -// if (!gl.isExtensionAvailable("GL_ARB_imaging")) { -// return 0; -// } -// -// gl.glColorTable(GL.GL_PROXY_TEXTURE_COLOR_TABLE_SGI, GL.GL_RGBA, 256, GL.GL_RGB, -// GL2.GL_INT, null); -// int[] tmp = new int[1]; -// gl.glGetColorTableParameteriv(GL.GL_PROXY_TEXTURE_COLOR_TABLE_SGI, -// GL2.GL_COLOR_TABLE_WIDTH, tmp, 0); -// return tmp[0]; -// } - - - private void checkTextureExtensions(Canvas3D cv, - JoglContext ctx, - GL gl, - boolean gl13) { - if (gl13) { - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_MULTI_TEXTURE; - cv.multiTexAccelerated = true; - int[] tmp = new int[1]; - gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_UNITS, tmp, 0); - cv.maxTextureUnits = tmp[0]; - cv.maxTexCoordSets = cv.maxTextureUnits; - if (gl.isExtensionAvailable("GL_ARB_vertex_shader")) { - gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_COORDS_ARB, tmp, 0); - cv.maxTexCoordSets = tmp[0]; - } - } -// FIXME: GL_SGI_texture_color_table -// if (gl.isExtensionAvailable("GL_SGI_texture_color_table") || -// gl.isExtensionAvailable("GL_ARB_imaging")) { -// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COLOR_TABLE; -// -// // get texture color table size -// // need to check later -// cv.textureColorTableSize = getTextureColorTableSize(gl); -// if (cv.textureColorTableSize <= 0) { -// cv.textureExtendedFeatures &= ~Canvas3D.TEXTURE_COLOR_TABLE; -// } -// if (cv.textureColorTableSize > 256) { -// cv.textureColorTableSize = 256; -// } -// } - - if (gl.isExtensionAvailable("GL_ARB_texture_env_combine")) { - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE; - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE_SUBTRACT; - } else if (gl.isExtensionAvailable("GL_EXT_texture_env_combine")) { - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE; - } - -// FIXME: GL_NV_register_combiners -// if (gl.isExtensionAvailable("GL_NV_register_combiners")) { -// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_REGISTER_COMBINERS; -// } - - if (gl.isExtensionAvailable("GL_ARB_texture_env_dot3") || - gl.isExtensionAvailable("GL_EXT_texture_env_dot3")) { - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE_DOT3; - } - - if (gl13) { - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_CUBE_MAP; - } - -// FIXME: GL_SGIS_sharpen_texture -// if (gl.isExtensionAvailable("GL_SGIS_sharpen_texture")) { -// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_SHARPEN; -// } - -// FIXME: GL_SGIS_sharpen_texture -// if (gl.isExtensionAvailable("GL_SGIS_detail_texture")) { -// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_DETAIL; -// } - -// FIXME: GL_SGIS_texture_filter4 -// if (gl.isExtensionAvailable("GL_SGIS_texture_filter4")) { -// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_FILTER4; -// } - - if (gl.isExtensionAvailable("GL_EXT_texture_filter_anisotropic")) { - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_ANISOTROPIC_FILTER; - float[] tmp = new float[1]; - gl.glGetFloatv(GL. GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, tmp, 0); - cv.anisotropicDegreeMax = tmp[0]; - } - -// FIXME: GL_SGIX_texture_lod_bias -// if (gl.isExtensionAvailable("GL_SGIX_texture_lod_bias")) { -// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_LOD_OFFSET; -// } - - if (!VirtualUniverse.mc.enforcePowerOfTwo && - gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two")) { - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_NON_POWER_OF_TWO; - } - - if (gl.isExtensionAvailable("GL_SGIS_generate_mipmap")) { - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_AUTO_MIPMAP_GENERATION; - } - - } - - - private void checkGLSLShaderExtensions(Canvas3D cv, - JoglContext ctx, - GL gl, - boolean glslLibraryAvailable) { - if (glslLibraryAvailable && - gl.isExtensionAvailable("GL_ARB_shader_objects") && - gl.isExtensionAvailable("GL_ARB_shading_language_100")) { - // Initialize shader vertex attribute function pointers - ctx.initGLSLVertexAttributeImpl(); - - // FIXME: this isn't complete and would need to set up the - // JoglContext for dispatch of various routines such as those - // related to vertex attributes - int[] tmp = new int[1]; - gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_IMAGE_UNITS_ARB, tmp, 0); - cv.maxTextureImageUnits = tmp[0]; - gl.glGetIntegerv(GL2.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, tmp, 0); - cv.maxVertexTextureImageUnits = tmp[0]; - gl.glGetIntegerv(GL2.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, tmp, 0); - cv.maxCombinedTextureImageUnits = tmp[0]; - int vertexAttrOffset = VirtualUniverse.mc.glslVertexAttrOffset; - ctx.setGLSLVertexAttrOffset(vertexAttrOffset); - gl.glGetIntegerv(GL2.GL_MAX_VERTEX_ATTRIBS_ARB, tmp, 0); - cv.maxVertexAttrs = tmp[0]; - // decr count to allow for reserved vertex attrs - cv.maxVertexAttrs -= vertexAttrOffset; - if (cv.maxVertexAttrs < 0) { - cv.maxVertexAttrs = 0; - } - cv.shadingLanguageGLSL = true; - } - } - - private void setupCanvasProperties(Canvas3D cv, - JoglContext ctx, - GL gl, - boolean glslLibraryAvailable) { - // Note: this includes relevant portions from both the - // NativePipeline's getPropertiesFromCurrentContext and setupCanvasProperties - - // Reset all fields - cv.multiTexAccelerated = false; - cv.maxTextureUnits = 1; - cv.maxTexCoordSets = 1; - cv.maxTextureImageUnits = 0; - cv.maxVertexTextureImageUnits = 0; - cv.maxCombinedTextureImageUnits = 0; - cv.maxVertexAttrs = 0; - cv.extensionsSupported = 0; - cv.textureExtendedFeatures = 0; - cv.textureColorTableSize = 0; - cv.anisotropicDegreeMax = 0; - cv.textureBoundaryWidthMax = 0; - cv.textureWidthMax = 0; - cv.textureHeightMax = 0; - cv.texture3DWidthMax = 0; - cv.texture3DHeightMax = 0; - cv.texture3DDepthMax = 0; - cv.shadingLanguageGLSL = false; - - // Now make queries and set up these fields - String glVersion = gl.glGetString(GL.GL_VERSION); - String glVendor = gl.glGetString(GL.GL_VENDOR); - String glRenderer = gl.glGetString(GL.GL_RENDERER); - cv.nativeGraphicsVersion = glVersion; - cv.nativeGraphicsVendor = glVendor; - cv.nativeGraphicsRenderer = glRenderer; - - // find out the version, major and minor version number - int[] versionNumbers = extractVersionInfo(glVersion); - int major = versionNumbers[0]; - int minor = versionNumbers[1]; - - /////////////////////////////////////////// - // setup the graphics context properties // - - // NOTE: Java 3D now requires OpenGL 1.3 for full functionality. - // For backwards compatibility with certain older graphics cards and - // drivers (e.g., the Linux DRI driver for older ATI cards), - // we will try to run on OpenGL 1.2 in an unsupported manner. However, - // we will not attempt to use OpenGL extensions for any features that - // are available in OpenGL 1.3, specifically multitexture, multisample, - // and cube map textures. - - if (major < 1 || (major == 1 && minor < 2)) { - throw new IllegalRenderingStateException( - "Java 3D ERROR : OpenGL 1.2 or better is required (GL_VERSION=" + - major + "." + minor + ")"); - } - - boolean gl20 = false; - boolean gl14 = false; - boolean gl13 = false; - - if (major == 1) { - if (minor == 2) { - System.err.println("JAVA 3D: OpenGL 1.2 detected; will run with reduced functionality"); - } - if (minor >= 3) { - gl13 = true; - } - if (minor >= 4) { - gl14 = true; - } - } else /* major >= 2 */ { - gl13 = true; - gl14 = true; - gl20 = true; - } - - if (gl20) { - assert gl13; - assert gl14; - assert gl.isExtensionAvailable("GL_VERSION_2_0"); - } - - if (gl14) { - assert gl13; - assert gl.isExtensionAvailable("GL_VERSION_1_4"); - } - - if (gl13) { - assert gl.isExtensionAvailable("GL_VERSION_1_3"); - } - - // Set up properties for OpenGL 1.3 - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_3D; - - // Note that we don't query for GL_ARB_imaging here - - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_LOD_RANGE; - - if (gl14) { - cv.textureExtendedFeatures |= Canvas3D.TEXTURE_AUTO_MIPMAP_GENERATION; - } - - // look for OpenGL 2.0 features - // Fix to Issue 455 : Need to disable NPOT textures for older cards that claim to support it. - // Some older cards (e.g., Nvidia fx500 and ATI 9800) claim to support OpenGL 2.0. - // This means that these cards have to support non-power-of-two (NPOT) texture, - // but their lack the necessary HW force the vendors the emulate this feature in software. - // The result is a ~100x slower down compare to power-of-two textures. - // Do not check for gl20 but instead check of GL_ARB_texture_non_power_of_two extension string - // if (gl20) { - // if(!VirtualUniverse.mc.enforcePowerOfTwo) { - // cv.textureExtendedFeatures |= Canvas3D.TEXTURE_NON_POWER_OF_TWO; - // } - // } - - - // Setup GL_EXT_abgr - if (gl.isExtensionAvailable("GL_EXT_abgr")) { - cv.extensionsSupported |= Canvas3D.EXT_ABGR; - } - - // GL_BGR is always supported - cv.extensionsSupported |= Canvas3D.EXT_BGR; - - // Setup multisample - // FIXME: this is not correct for the Windows platform yet - if (gl13) { - cv.extensionsSupported |= Canvas3D.MULTISAMPLE; - ctx.setHasMultisample(true); - } - - if ((cv.extensionsSupported & Canvas3D.MULTISAMPLE) != 0 && - !VirtualUniverse.mc.implicitAntialiasing) { - gl.glDisable(GL.GL_MULTISAMPLE); - } - - // Check texture extensions - checkTextureExtensions(cv, ctx, gl, gl13); - - // Check shader extensions - if (gl13) { - checkGLSLShaderExtensions(cv, ctx, gl, glslLibraryAvailable); - } else { - // Force shaders to be disabled, since no multitexture support - checkGLSLShaderExtensions(cv, ctx, gl, false); - } - - // Setup GL_SUN_gloabl_alpha -// FIXME: SUN_global_alpha -// if (gl.isExtensionAvailable("GL_SUN_gloabl_alpha")) { -// cv.extensionsSupported |= Canvas3D.SUN_GLOBAL_ALPHA; -// } - - cv.textureBoundaryWidthMax = 1; - { - int[] tmp = new int[1]; - gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, tmp, 0); - cv.textureWidthMax = tmp[0]; - cv.textureHeightMax = tmp[0]; - - tmp[0] = -1; - gl.glGetIntegerv(GL2.GL_MAX_3D_TEXTURE_SIZE, tmp, 0); - cv.texture3DWidthMax = tmp[0]; - cv.texture3DHeightMax = tmp[0]; - cv.texture3DDepthMax = tmp[0]; - } - } - - /* - * Function to disable most rendering attributes when doing a 2D - * clear, image copy, or image composite operation. Note that the - * caller must save/restore the attributes with - * pushAttrib(GL_ENABLE_BIT|...) and popAttrib() - */ - private void disableAttribFor2D(GL gl) { - gl.glDisable(GL2.GL_ALPHA_TEST); - gl.glDisable(GL.GL_BLEND); - gl.glDisable(GL.GL_COLOR_LOGIC_OP); - gl.glDisable(GL2.GL_COLOR_MATERIAL); - gl.glDisable(GL.GL_CULL_FACE); - gl.glDisable(GL.GL_DEPTH_TEST); - gl.glDisable(GL2.GL_FOG); - gl.glDisable(GL2.GL_LIGHTING); - gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); - gl.glDisable(GL2.GL_POLYGON_STIPPLE); - gl.glDisable(GL.GL_STENCIL_TEST); - gl.glDisable(GL.GL_TEXTURE_2D); - gl.glDisable(GL2.GL_TEXTURE_GEN_Q); - gl.glDisable(GL2.GL_TEXTURE_GEN_R); - gl.glDisable(GL2.GL_TEXTURE_GEN_S); - gl.glDisable(GL2.GL_TEXTURE_GEN_T); - - - for (int i = 0; i < 6; i++) { - gl.glDisable(GL2.GL_CLIP_PLANE0 + i); - } - - gl.glDisable(GL2.GL_TEXTURE_3D); - gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); - -// FIXME: GL_NV_register_combiners -// if (gl.isExtensionAvailable("GL_NV_register_combiners")) { -// gl.glDisable(GL.GL_REGISTER_COMBINERS_NV); -// } -// FIXME: GL_SGI_texture_color_table -// if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) { -// gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI); -// } -// FIXME: SUN_global_alpha -// if (gl.isExtensionAvailable("GL_SUN_global_alpha")) { -// gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN); -// } - - } - - private void disableAttribForRaster(GL gl) { - - gl.glDisable(GL2.GL_COLOR_MATERIAL); - gl.glDisable(GL.GL_CULL_FACE); - gl.glDisable(GL2.GL_LIGHTING); - gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); - gl.glDisable(GL2.GL_POLYGON_STIPPLE); - - // TODO: Disable if Raster.CLIP_POSITION is true -// for (int i = 0; i < 6; i++) { -// gl.glDisable(GL2.GL_CLIP_PLANE0 + i); -// } - -// FIXME: SUN_global_alpha -// if (gl.isExtensionAvailable("GL_SUN_global_alpha")) { -// gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN); -// } - } - - private void copyTranspose(double[] src, double[] dst) { - dst[0] = src[0]; - dst[1] = src[4]; - dst[2] = src[8]; - dst[3] = src[12]; - dst[4] = src[1]; - dst[5] = src[5]; - dst[6] = src[9]; - dst[7] = src[13]; - dst[8] = src[2]; - dst[9] = src[6]; - dst[10] = src[10]; - dst[11] = src[14]; - dst[12] = src[3]; - dst[13] = src[7]; - dst[14] = src[11]; - dst[15] = src[15]; - } - - // --------------------------------------------------------------------- - - // - // Canvas3D / GraphicsConfigTemplate3D methods - logic dealing with - // native graphics configuration or drawing surface - // - - // Return a graphics config based on the one passed in. Note that we can - // assert that the input config is non-null and was created from a - // GraphicsConfigTemplate3D. - // This method must return a valid GraphicsConfig, or else it must throw - // an exception if one cannot be returned. - GraphicsConfiguration getGraphicsConfig(GraphicsConfiguration gconfig) { - if (VERBOSE) System.err.println("JoglPipeline.getGraphicsConfig()"); - JoglGraphicsConfiguration config = (JoglGraphicsConfiguration) gconfig; - GLCapabilitiesChooser indexChooser = null; - if (config.getChosenIndex() >= 0) { - indexChooser = new IndexCapabilitiesChooser(config.getChosenIndex()); - } - - AWTGraphicsDevice awtGraphicsDevice = ((JoglGraphicsConfiguration)gconfig).getAwtGraphicsDevice()/*new AWTGraphicsDevice(config.getDevice(), 0)*/; - GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtGraphicsDevice); - - AbstractGraphicsConfiguration absConfig = - factory.chooseGraphicsConfiguration(config.getGLCapabilities(), config.getGLCapabilities(), - indexChooser, new AWTGraphicsScreen(awtGraphicsDevice)); - if (absConfig == null) { - return null; - } - return ((AWTGraphicsConfiguration) absConfig).getAWTGraphicsConfiguration(); - - /* - - System.err.println("JoglPipeline.getGraphicsConfig()"); - // Just return the input graphics config for now. eventually, we will - // use the input graphics config to get the GraphicsConfigTemplate3D - // parameters, which we will use to create a new graphics config with JOGL. - return gconfig; - */ - } - - // Get the native FBconfig pointer - long getFbConfig(GraphicsConfigInfo gcInfo) { - if (VERBOSE) System.err.println("JoglPipeline.getFbConfig()"); - return 0L; // Dummy method in JOGL - } - - - private static final int DISABLE_STEREO = 1; - private static final int DISABLE_AA = 2; - private static final int DISABLE_DOUBLE_BUFFER = 3; - - // Get best graphics config from pipeline - GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate3D gct, - GraphicsConfiguration[] gc) { - if (VERBOSE) System.err.println("JoglPipeline.getBestConfiguration()"); - /* - System.err.println("gct.getDoubleBuffer(): " + gct.getDoubleBuffer()); - System.err.println("gct.getStereo(): " + gct.getStereo()); - System.err.println("gct.getDepthBits(): " + gct.getDepthSize()); - System.err.println("gct.getRedSize(): " + gct.getRedSize()); - System.err.println("gct.getGreenSize(): " + gct.getGreenSize()); - System.err.println("gct.getBlueSize(): " + gct.getBlueSize()); - System.err.println("gct.getSceneAntialiasing(): " + gct.getSceneAntialiasing()); - */ - - // Create a GLCapabilities based on the GraphicsConfigTemplate3D - GLCapabilities caps = new GLCapabilities(getDefaultProfile()); - caps.setDoubleBuffered(gct.getDoubleBuffer() <= GraphicsConfigTemplate.PREFERRED); - caps.setStereo (gct.getStereo() <= GraphicsConfigTemplate.PREFERRED); - caps.setDepthBits (gct.getDepthSize()); - caps.setStencilBits (gct.getStencilSize()); - caps.setRedBits (Math.max(5, gct.getRedSize())); - caps.setGreenBits (Math.max(5, gct.getGreenSize())); - caps.setBlueBits (Math.max(5, gct.getBlueSize())); - caps.setSampleBuffers(gct.getSceneAntialiasing() <= GraphicsConfigTemplate.PREFERRED); - // FIXME: should be smarter about choosing the number of samples - // (Java3D's native code has a loop trying 8, 6, 4, 3, and 2 samples) - caps.setNumSamples(4); - - // Issue 399: Request alpha buffer if transparentOffScreen is set - if (VirtualUniverse.mc.transparentOffScreen) { - caps.setAlphaBits(1); - } - - java.util.List capsToDisable = new ArrayList(); - // Add PREFERRED capabilities in order we will try disabling them - if (gct.getStereo() == GraphicsConfigTemplate.PREFERRED) { - capsToDisable.add(new Integer(DISABLE_STEREO)); - } - if (gct.getSceneAntialiasing() == GraphicsConfigTemplate.PREFERRED) { - capsToDisable.add(new Integer(DISABLE_AA)); - } - if (gct.getDoubleBuffer() == GraphicsConfigTemplate.PREFERRED) { - capsToDisable.add(new Integer(DISABLE_DOUBLE_BUFFER)); - } - - // Pick the GraphicsDevice from a random configuration - GraphicsDevice dev = gc[0].getDevice(); - - // Create a Frame and dummy GLCanvas to perform eager pixel format selection - - // Note that we loop in similar fashion to the NativePipeline's - // native code in the situation where we need to disable certain - // capabilities which aren't required - boolean tryAgain = true; - CapabilitiesCapturer capturer = null; - while (tryAgain) { - Frame f = new Frame(dev.getDefaultConfiguration()); - f.setUndecorated(true); - f.setLayout(new BorderLayout()); - capturer = new CapabilitiesCapturer(); - try { - AWTGraphicsConfiguration awtGraphicsConfiguration = createAwtGraphicsConfiguration(caps, capturer, dev/*null*/); - QueryCanvas canvas = new QueryCanvas(awtGraphicsConfiguration, capturer); - f.add(canvas, BorderLayout.CENTER); - f.setSize(MIN_FRAME_SIZE, MIN_FRAME_SIZE); - f.setVisible(true); - canvas.doQuery(); - if (DEBUG_CONFIG) { - System.err.println("Waiting for CapabilitiesCapturer"); - } - // Try to wait for result without blocking EDT - if (!EventQueue.isDispatchThread()) { - synchronized(capturer) { - if (!capturer.done()) { - try { - capturer.wait(WAIT_TIME); - } catch (InterruptedException e) { - } - } - } - } - disposeOnEDT(f); - tryAgain = false; - } catch (GLException e) { - // Failure to select a pixel format; try switching off one - // of the only-preferred capabilities - if (capsToDisable.size() == 0) { - tryAgain = false; - } else { - int whichToDisable = capsToDisable.remove(0).intValue(); - switch (whichToDisable) { - case DISABLE_STEREO: - caps.setStereo(false); - break; - - case DISABLE_AA: - caps.setSampleBuffers(false); - break; - - case DISABLE_DOUBLE_BUFFER: - caps.setDoubleBuffered(false); - break; - - default: - throw new AssertionError("missing case statement"); - } - } - } - } - int chosenIndex = capturer.getChosenIndex(); - GLCapabilities chosenCaps = null; - if (chosenIndex < 0) { - if (DEBUG_CONFIG) { - System.err.println("CapabilitiesCapturer returned invalid index"); - } - // It's possible some platforms or implementations might not - // support the GLCapabilitiesChooser mechanism; feed in the - // same GLCapabilities later which we gave to the selector - chosenCaps = caps; - } else { - if (DEBUG_CONFIG) { - System.err.println("CapabilitiesCapturer returned index=" + chosenIndex); - } - chosenCaps = capturer.getCapabilities(); - } - - JoglGraphicsConfiguration config = new JoglGraphicsConfiguration(chosenCaps, chosenIndex, dev); - - // FIXME: because of the fact that JoglGraphicsConfiguration - // doesn't override hashCode() or equals(), we will basically be - // creating a new one each time getBestConfiguration() is - // called; in theory, we should probably map the same - // GLCapabilities on the same GraphicsDevice to the same - // JoglGraphicsConfiguration object - - // Cache the GraphicsTemplate3D - synchronized (Canvas3D.graphicsConfigTable) { - GraphicsConfigInfo gcInfo = new GraphicsConfigInfo(gct); - // We don't need this - // gcInfo.setPrivateData(privateData); - Canvas3D.graphicsConfigTable.put(config, gcInfo); - } - - return config; - - /* - - // TODO: implement this - - // TODO: construct a unique GraphicsConfiguration object that will be - // used the key in the hashmap so we can lookup the GraphicsTemplate3D - GraphicsConfiguration gc1 = GraphicsEnvironment.getLocalGraphicsEnvironment(). - getDefaultScreenDevice().getDefaultConfiguration(); - - // Cache the GraphicsTemplate3D - synchronized (Canvas3D.graphicsConfigTable) { - if (Canvas3D.graphicsConfigTable.get(gc1) == null) { - GraphicsConfigInfo gcInfo = new GraphicsConfigInfo(gct); - // gcInfo.setPrivateData(privateData); - Canvas3D.graphicsConfigTable.put(gc1, gcInfo); - } - } - return gc1; - - */ - } - - // Determine whether specified graphics config is supported by pipeline - boolean isGraphicsConfigSupported(GraphicsConfigTemplate3D gct, - GraphicsConfiguration gc) { - if (VERBOSE) System.err.println("JoglPipeline.isGraphicsConfigSupported()"); - - // FIXME: it looks like this method is implemented incorrectly - // in the existing NativePipeline in both the Windows and X11 - // ports. According to the semantics of the javadoc, it looks - // like this method is supposed to figure out the OpenGL - // capabilities which would be requested by the passed - // GraphicsConfiguration object were it to be used, and see - // whether it is possible to create a context with them. - // Instead, on both platforms, the implementations basically set - // up a query based on the contents of the - // GraphicsConfigTemplate3D object, using the - // GraphicsConfiguration object only to figure out on which - // GraphicsDevice and screen we're making the request, and see - // whether it's possible to choose an OpenGL pixel format based - // on that information. This makes this method less useful and - // we can probably just safely return true here uniformly - // without breaking anything. - return true; - } - - // Methods to get actual capabilities from Canvas3D - boolean hasDoubleBuffer(Canvas3D cv) { - if (VERBOSE) System.err.println("JoglPipeline.hasDoubleBuffer()"); - if (VERBOSE) System.err.println(" Returning " + caps(cv).getDoubleBuffered()); - return caps(cv).getDoubleBuffered(); - } - - boolean hasStereo(Canvas3D cv) { - if (VERBOSE) System.err.println("JoglPipeline.hasStereo()"); - if (VERBOSE) System.err.println(" Returning " + caps(cv).getStereo()); - return caps(cv).getStereo(); - } - - int getStencilSize(Canvas3D cv) { - if (VERBOSE) System.err.println("JoglPipeline.getStencilSize()"); - if (VERBOSE) System.err.println(" Returning " + caps(cv).getStencilBits()); - return caps(cv).getStencilBits(); - } - - boolean hasSceneAntialiasingMultisample(Canvas3D cv) { - if (VERBOSE) System.err.println("JoglPipeline.hasSceneAntialiasingMultisample()"); - if (VERBOSE) System.err.println(" Returning " + caps(cv).getSampleBuffers()); - - return caps(cv).getSampleBuffers(); - } - - boolean hasSceneAntialiasingAccum(Canvas3D cv) { - if (VERBOSE) System.err.println("JoglPipeline.hasSceneAntialiasingAccum()"); - GLCapabilities caps = caps(cv); - if (VERBOSE) System.err.println(" Returning " + (caps.getAccumRedBits() > 0 && - caps.getAccumGreenBits() > 0 && - caps.getAccumBlueBits() > 0)); - return (caps.getAccumRedBits() > 0 && - caps.getAccumGreenBits() > 0 && - caps.getAccumBlueBits() > 0); - } - - // Methods to get native WS display and screen - long getDisplay() { - if (VERBOSE) System.err.println("JoglPipeline.getDisplay()"); - return 0L; // Dummy method in JOGL - } - - private boolean checkedForGetScreenMethod = false; - private Method getScreenMethod = null; - int getScreen(final GraphicsDevice graphicsDevice) { - if (VERBOSE) System.err.println("JoglPipeline.getScreen()"); - - if (!checkedForGetScreenMethod) { - // All of the Sun GraphicsDevice implementations have a method - // int getScreen(); - // which we want to call reflectively if it's available. - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - try { - getScreenMethod = graphicsDevice.getClass().getDeclaredMethod("getScreen", new Class[] {}); - getScreenMethod.setAccessible(true); - } catch (Exception e) { - } - checkedForGetScreenMethod = true; - return null; - } - }); - } - - if (getScreenMethod != null) { - try { - return ((Integer) getScreenMethod.invoke(graphicsDevice, (Object[]) null)).intValue(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - return 0; - } - - //---------------------------------------------------------------------- - // Helper classes and methods to support query context functionality - // and pixel format selection - - interface ExtendedCapabilitiesChooser extends GLCapabilitiesChooser { - public void init(GLContext context); - } - - // Canvas subclass to help with various query operations such as the - // "query context" mechanism and pixel format selection. - // Must defeat and simplify the single-threading behavior of JOGL's - // GLCanvas in order to be able to set up a temporary pixel format - // and OpenGL context. Apparently simply turning off the - // single-threaded mode isn't enough to do this. - class QueryCanvas extends Canvas { - private GLDrawable drawable; - private ExtendedCapabilitiesChooser chooser; - private boolean alreadyRan; - - public QueryCanvas(AWTGraphicsConfiguration awtGraphicsConfiguration, ExtendedCapabilitiesChooser chooser) { - // The platform-specific GLDrawableFactory will only provide a - // non-null GraphicsConfiguration on platforms where this is - // necessary (currently only X11, as Windows allows the pixel - // format of the window to be set later and Mac OS X seems to - // handle this very differently than all other platforms). On - // other platforms this method returns null; it is the case (at - // least in the Sun AWT implementation) that this will result in - // equivalent behavior to calling the no-arg super() constructor - // for Canvas. - super(unwrap(awtGraphicsConfiguration)); - NativeWindow nativeWindow = NativeWindowFactory.getNativeWindow(this, awtGraphicsConfiguration); - drawable = GLDrawableFactory.getFactory(getDefaultProfile()).createGLDrawable(nativeWindow); - this.chooser = chooser; - } - - public void addNotify() { - super.addNotify(); - drawable.setRealized(true); - } - - // It seems that at least on Mac OS X we need to do the OpenGL - // context-related work outside of the addNotify call because the - // Canvas hasn't been resized to a non-zero size by that point - public void doQuery() { - if (alreadyRan) - return; - GLContext context = drawable.createContext(null); - int res = context.makeCurrent(); - if (res != GLContext.CONTEXT_NOT_CURRENT) { - try { - chooser.init(context); - } finally { - context.release(); - } - } - context.destroy(); - alreadyRan = true; - } - } - - private static AWTGraphicsConfiguration createAwtGraphicsConfiguration(GLCapabilities capabilities, - CapabilitiesChooser chooser, - GraphicsDevice device) { - //FIXME unit id? - AWTGraphicsDevice awtGraphicsDevice = new AWTGraphicsDevice(device, 0); - GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtGraphicsDevice); - AWTGraphicsConfiguration awtGraphicsConfiguration = (AWTGraphicsConfiguration) factory.chooseGraphicsConfiguration(capabilities, capabilities, - chooser, new AWTGraphicsScreen(awtGraphicsDevice)); - return awtGraphicsConfiguration; - } - - private static AWTGraphicsConfiguration createAwtGraphicsConfiguration(GLCapabilities capabilities, - CapabilitiesChooser chooser, - AWTGraphicsDevice awtGraphicsDevice) { - GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtGraphicsDevice); - AWTGraphicsConfiguration awtGraphicsConfiguration = (AWTGraphicsConfiguration) factory.chooseGraphicsConfiguration(capabilities, capabilities, - chooser, new AWTGraphicsScreen(awtGraphicsDevice)); - return awtGraphicsConfiguration; - } - - private static GraphicsConfiguration unwrap(AWTGraphicsConfiguration config) { - if (config == null) { - return null; - } - return config.getAWTGraphicsConfiguration(); - } - - // Used in conjunction with IndexCapabilitiesChooser in pixel format - // selection -- see getBestConfiguration - class CapabilitiesCapturer extends DefaultGLCapabilitiesChooser implements ExtendedCapabilitiesChooser { - private boolean done; - private GLCapabilities capabilities; - private int chosenIndex = -1; - - public boolean done() { - return done; - } - - public GLCapabilities getCapabilities() { - return capabilities; - } - - public int getChosenIndex() { - return chosenIndex; - } - - public int chooseCapabilities(GLCapabilities desired, - GLCapabilities[] available, - int windowSystemRecommendedChoice) { - int res = super.chooseCapabilities(desired, Arrays.asList(available), windowSystemRecommendedChoice); - capabilities = available[res]; - chosenIndex = res; - markDone(); - return res; - } - - public void init(GLContext context) { - // Avoid hanging things up for several seconds - kick(); - } - - private void markDone() { - synchronized (this) { - done = true; - notifyAll(); - } - } - - private void kick() { - synchronized (this) { - notifyAll(); - } - } - } - - // Used to support the query context mechanism -- needs to be more - // than just a GLCapabilitiesChooser - class ContextQuerier extends DefaultGLCapabilitiesChooser implements ExtendedCapabilitiesChooser { - private Canvas3D canvas; - private boolean glslLibraryAvailable; - private boolean done; - - public ContextQuerier(Canvas3D canvas, - boolean glslLibraryAvailable) { - this.canvas = canvas; - this.glslLibraryAvailable = glslLibraryAvailable; - } - - public boolean done() { - return done; - } - - public void init(GLContext context) { - // This is basically a temporary - JoglContext jctx = new JoglContext(context); - // Set up various properties - if (getPropertiesFromCurrentContext(jctx)) { - setupCanvasProperties(canvas, jctx, context.getGL(), - glslLibraryAvailable); - } - markDone(); - } - - private void markDone() { - synchronized (this) { - done = true; - notifyAll(); - } - } - } - - // Used in two phases of pixel format selection: transforming the - // JoglGraphicsConfiguration to a real AWT GraphicsConfiguration and - // during context creation to select exactly the same graphics - // configuration as was done during getBestConfiguration. - class IndexCapabilitiesChooser implements GLCapabilitiesChooser { - private int indexToChoose; - - IndexCapabilitiesChooser(int indexToChoose) { - this.indexToChoose = indexToChoose; - } - - public int chooseCapabilities(CapabilitiesImmutable desired, - List available, - int windowSystemRecommendedChoice) { - if (DEBUG_CONFIG) { - System.err.println("IndexCapabilitiesChooser returning index=" + indexToChoose); - } - return indexToChoose; - } - } - - private void disposeOnEDT(final Frame f) { - Runnable r = new Runnable() { - public void run() { - f.setVisible(false); - f.dispose(); - } - }; - if (!EventQueue.isDispatchThread()) { - EventQueue.invokeLater(r); - } else { - r.run(); - } - } - - - // --------------------------------------------------------------------- - - // - // DrawingSurfaceObject methods - // - - // Method to construct a new DrawingSurfaceObject - DrawingSurfaceObject createDrawingSurfaceObject(Canvas3D cv) { - if (VERBOSE) System.err.println("JoglPipeline.createDrawingSurfaceObject()"); - return new JoglDrawingSurfaceObject(cv); - } - - // Method to free the drawing surface object - void freeDrawingSurface(Canvas3D cv, DrawingSurfaceObject drawingSurfaceObject) { - if (VERBOSE) System.err.println("JoglPipeline.freeDrawingSurface()"); - // This method is a no-op - } - - // Method to free the native drawing surface object - void freeDrawingSurfaceNative(Object o) { - if (VERBOSE) System.err.println("JoglPipeline.freeDrawingSurfaceNative()"); - // This method is a no-op - } - - //---------------------------------------------------------------------- - // Context-related routines - // - - // Helper used everywhere - GLContext context(Context ctx) { - if (ctx == null) - return null; - return ((JoglContext) ctx).getGLContext(); - } - - // Helper used everywhere - GLDrawable drawable(Drawable drawable) { - if (drawable == null) - return null; - return ((JoglDrawable) drawable).getGLDrawable(); - } - - GLCapabilities caps(Canvas3D ctx) { - return ((JoglGraphicsConfiguration) ctx.graphicsConfiguration).getGLCapabilities(); - } - - //---------------------------------------------------------------------- - // General helper routines - // - - private static ThreadLocal nioVertexTemp = new ThreadLocal(); - private static ThreadLocal nioVertexDoubleTemp = new ThreadLocal(); - private static ThreadLocal nioColorTemp = new ThreadLocal(); - private static ThreadLocal nioColorByteTemp = new ThreadLocal(); - private static ThreadLocal nioNormalTemp = new ThreadLocal(); - private static ThreadLocal nioTexCoordSetTemp = new ThreadLocal(); - private static ThreadLocal nioVertexAttrSetTemp = new ThreadLocal(); - - private static FloatBuffer getVertexArrayBuffer(float[] vertexArray) { - return getVertexArrayBuffer(vertexArray, true); - } - - private static FloatBuffer getVertexArrayBuffer(float[] vertexArray, boolean copyData) { - return getNIOBuffer(vertexArray, nioVertexTemp, copyData); - } - - private static DoubleBuffer getVertexArrayBuffer(double[] vertexArray) { - return getVertexArrayBuffer(vertexArray, true); - } - - private static DoubleBuffer getVertexArrayBuffer(double[] vertexArray, boolean copyData) { - return getNIOBuffer(vertexArray, nioVertexDoubleTemp, true); - } - - private static FloatBuffer getColorArrayBuffer(float[] colorArray) { - return getColorArrayBuffer(colorArray, true); - } - - private static FloatBuffer getColorArrayBuffer(float[] colorArray, boolean copyData) { - return getNIOBuffer(colorArray, nioColorTemp, true); - } - - private static ByteBuffer getColorArrayBuffer(byte[] colorArray) { - return getColorArrayBuffer(colorArray, true); - } - - private static ByteBuffer getColorArrayBuffer(byte[] colorArray, boolean copyData) { - return getNIOBuffer(colorArray, nioColorByteTemp, true); - } - - private static FloatBuffer getNormalArrayBuffer(float[] normalArray) { - return getNormalArrayBuffer(normalArray, true); - } - - private static FloatBuffer getNormalArrayBuffer(float[] normalArray, boolean copyData) { - return getNIOBuffer(normalArray, nioNormalTemp, true); - } - - private static FloatBuffer[] getTexCoordSetBuffer(Object[] texCoordSet) { - return getNIOBuffer(texCoordSet, nioTexCoordSetTemp); - } - - private static FloatBuffer[] getVertexAttrSetBuffer(Object[] vertexAttrSet) { - return getNIOBuffer(vertexAttrSet, nioVertexAttrSetTemp); - } - - private static FloatBuffer getNIOBuffer(float[] array, ThreadLocal threadLocal, boolean copyData) { - if (array == null) { - return null; - } - FloatBuffer buf = threadLocal.get(); - if (buf == null) { - buf = Buffers.newDirectFloatBuffer(array.length); - threadLocal.set(buf); - } else { - buf.rewind(); - if (buf.remaining() < array.length) { - int newSize = Math.max(2 * buf.remaining(), array.length); - buf = Buffers.newDirectFloatBuffer(newSize); - threadLocal.set(buf); - } - } - if (copyData) { - buf.put(array); - buf.rewind(); - } - return buf; - } - - private static DoubleBuffer getNIOBuffer(double[] array, ThreadLocal threadLocal, boolean copyData) { - if (array == null) { - return null; - } - DoubleBuffer buf = threadLocal.get(); - if (buf == null) { - buf = Buffers.newDirectDoubleBuffer(array.length); - threadLocal.set(buf); - } else { - buf.rewind(); - if (buf.remaining() < array.length) { - int newSize = Math.max(2 * buf.remaining(), array.length); - buf = Buffers.newDirectDoubleBuffer(newSize); - threadLocal.set(buf); - } - } - if (copyData) { - buf.put(array); - buf.rewind(); - } - return buf; - } - - private static ByteBuffer getNIOBuffer(byte[] array, ThreadLocal threadLocal, boolean copyData) { - if (array == null) { - return null; - } - ByteBuffer buf = threadLocal.get(); - if (buf == null) { - buf = Buffers.newDirectByteBuffer(array.length); - threadLocal.set(buf); - } else { - buf.rewind(); - if (buf.remaining() < array.length) { - int newSize = Math.max(2 * buf.remaining(), array.length); - buf = Buffers.newDirectByteBuffer(newSize); - threadLocal.set(buf); - } - } - if (copyData) { - buf.put(array); - buf.rewind(); - } - return buf; - } - - private static FloatBuffer[] getNIOBuffer(Object[] array, ThreadLocal threadLocal) { - if (array == null) { - return null; - } - FloatBuffer[] bufs = threadLocal.get(); - - // First resize array of FloatBuffers - if (bufs == null) { - bufs = new FloatBuffer[array.length]; - threadLocal.set(bufs); - } else if (bufs.length < array.length) { - FloatBuffer[] newBufs = new FloatBuffer[array.length]; - System.arraycopy(bufs, 0, newBufs, 0, bufs.length); - bufs = newBufs; - threadLocal.set(bufs); - } - - // Now go down array of arrays, converting each into a direct FloatBuffer - for (int i = 0; i < array.length; i++) { - float[] cur = (float[]) array[i]; - FloatBuffer buf = bufs[i]; - if (buf == null) { - buf = Buffers.newDirectFloatBuffer(cur.length); - bufs[i] = buf; - } else { - buf.rewind(); - if (buf.remaining() < cur.length) { - int newSize = Math.max(2 * buf.remaining(), cur.length); - buf = Buffers.newDirectFloatBuffer(newSize); - bufs[i] = buf; - } - } - buf.put(cur); - buf.rewind(); - } - - return bufs; - } -} diff --git a/src/classes/jogl/javax/media/j3d/JoglShaderObject.java b/src/classes/jogl/javax/media/j3d/JoglShaderObject.java deleted file mode 100755 index da4b77c..0000000 --- a/src/classes/jogl/javax/media/j3d/JoglShaderObject.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * $RCSfile$ - * - * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Sun designates this - * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * $Revision$ - * $Date$ - * $State$ - */ - -package javax.media.j3d; - -class JoglShaderObject implements ShaderProgramId, ShaderId, ShaderAttrLoc { - private int val; - - JoglShaderObject(int val) { - this.val = val; - } - - int getValue() { - return val; - } -} diff --git a/src/classes/share/javax/media/j3d/JoglContext.java b/src/classes/share/javax/media/j3d/JoglContext.java new file mode 100644 index 0000000..a1f33c5 --- /dev/null +++ b/src/classes/share/javax/media/j3d/JoglContext.java @@ -0,0 +1,166 @@ +/* + * $RCSfile$ + * + * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package javax.media.j3d; + +import java.nio.Buffer; +import java.nio.FloatBuffer; + +import javax.media.opengl.GL; +import javax.media.opengl.GLContext; + +/** + * Graphics context objects for Jogl rendering pipeline. + */ +class JoglContext implements Context { + private GLContext context; + + // Properties we need to keep track of for efficiency + private int maxTexCoordSets; + private float alphaClearValue; + private int currentTextureUnit; + private int currentCombinerUnit; + private boolean hasMultisample; + + // Needed for vertex attribute implementation + private JoglShaderObject shaderProgram; + + // Implementation of vertex attribute methods + static interface VertexAttributeImpl { + public void vertexAttrPointer(GL gl, + int index, int size, int type, int stride, Buffer pointer); + public void enableVertexAttrArray(GL gl, int index); + public void disableVertexAttrArray(GL gl, int index); + public void vertexAttr1fv(GL gl, int index, FloatBuffer buf); + public void vertexAttr2fv(GL gl, int index, FloatBuffer buf); + public void vertexAttr3fv(GL gl, int index, FloatBuffer buf); + public void vertexAttr4fv(GL gl, int index, FloatBuffer buf); + } + private VertexAttributeImpl vertexAttrImpl; + + class GLSLVertexAttributeImpl implements VertexAttributeImpl { + public void vertexAttrPointer(GL gl, + int index, int size, int type, int stride, Buffer pointer) { + gl.getGL2().glVertexAttribPointerARB(index + glslVertexAttrOffset, + size, type, false, stride, pointer); + } + + public void enableVertexAttrArray(GL gl, int index) { + gl.getGL2().glEnableVertexAttribArrayARB(index + glslVertexAttrOffset); + } + + public void disableVertexAttrArray(GL gl, int index) { + gl.getGL2().glDisableVertexAttribArrayARB(index + glslVertexAttrOffset); + } + + public void vertexAttr1fv(GL gl, int index, FloatBuffer buf) { + gl.getGL2().glVertexAttrib1fvARB(index + glslVertexAttrOffset, buf); + } + + public void vertexAttr2fv(GL gl, int index, FloatBuffer buf) { + gl.getGL2().glVertexAttrib2fvARB(index + glslVertexAttrOffset, buf); + } + + public void vertexAttr3fv(GL gl, int index, FloatBuffer buf) { + gl.getGL2().glVertexAttrib3fvARB(index + glslVertexAttrOffset, buf); + } + + public void vertexAttr4fv(GL gl, int index, FloatBuffer buf) { + gl.getGL2().glVertexAttrib4fvARB(index + glslVertexAttrOffset, buf); + } + } + + // Only used when GLSL shader library is active + private int glslVertexAttrOffset; + + JoglContext(GLContext context) { + this.context = context; + } + + GLContext getGLContext() { + return context; + } + + int getMaxTexCoordSets() { return maxTexCoordSets; } + void setMaxTexCoordSets(int val) { maxTexCoordSets = val; } + float getAlphaClearValue() { return alphaClearValue; } + void setAlphaClearValue(float val) { alphaClearValue = val; } + int getCurrentTextureUnit() { return currentTextureUnit; } + void setCurrentTextureUnit(int val) { currentTextureUnit = val; } + int getCurrentCombinerUnit() { return currentCombinerUnit; } + void setCurrentCombinerUnit(int val) { currentCombinerUnit = val; } + boolean getHasMultisample() { return hasMultisample; } + void setHasMultisample(boolean val){ hasMultisample = val; } + + void initGLSLVertexAttributeImpl() { + if (vertexAttrImpl != null) { + throw new RuntimeException("Should not initialize the vertex attribute implementation twice"); + } + vertexAttrImpl = new GLSLVertexAttributeImpl(); + } + + void vertexAttrPointer(GL gl, + int index, int size, int type, int stride, Buffer pointer) { + vertexAttrImpl.vertexAttrPointer(gl, index, size, type, stride, pointer); + } + + void enableVertexAttrArray(GL gl, int index) { + vertexAttrImpl.enableVertexAttrArray(gl, index); + } + + void disableVertexAttrArray(GL gl, int index) { + vertexAttrImpl.disableVertexAttrArray(gl, index); + } + + void vertexAttr1fv(GL gl, int index, FloatBuffer buf) { + vertexAttrImpl.vertexAttr1fv(gl, index, buf); + } + + void vertexAttr2fv(GL gl, int index, FloatBuffer buf) { + vertexAttrImpl.vertexAttr2fv(gl, index, buf); + } + + void vertexAttr3fv(GL gl, int index, FloatBuffer buf) { + vertexAttrImpl.vertexAttr3fv(gl, index, buf); + } + + void vertexAttr4fv(GL gl, int index, FloatBuffer buf) { + vertexAttrImpl.vertexAttr4fv(gl, index, buf); + } + + // Used in vertex attribute implementation + JoglShaderObject getShaderProgram() { return shaderProgram; } + void setShaderProgram(JoglShaderObject object) { shaderProgram = object; } + + // Only used when GLSL shaders are in use + int getGLSLVertexAttrOffset() { return glslVertexAttrOffset; } + void setGLSLVertexAttrOffset(int offset) { glslVertexAttrOffset = offset; } +} diff --git a/src/classes/share/javax/media/j3d/JoglDrawable.java b/src/classes/share/javax/media/j3d/JoglDrawable.java new file mode 100644 index 0000000..7adabcb --- /dev/null +++ b/src/classes/share/javax/media/j3d/JoglDrawable.java @@ -0,0 +1,49 @@ +/* + * $RCSfile$ + * + * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package javax.media.j3d; + +import javax.media.opengl.GLDrawable; + +/** + * Drawable class for the Jogl rendering pipeline. + */ +class JoglDrawable implements Drawable { + private GLDrawable drawable; + + JoglDrawable(GLDrawable drawable) { + this.drawable = drawable; + } + + GLDrawable getGLDrawable() { + return drawable; + } +} diff --git a/src/classes/share/javax/media/j3d/JoglDrawingSurfaceObject.java b/src/classes/share/javax/media/j3d/JoglDrawingSurfaceObject.java new file mode 100644 index 0000000..439213e --- /dev/null +++ b/src/classes/share/javax/media/j3d/JoglDrawingSurfaceObject.java @@ -0,0 +1,79 @@ +/* + * $RCSfile$ + * + * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package javax.media.j3d; + +/** + * The DrawingSurfaceObject class is used to manage native drawing surface + */ +class JoglDrawingSurfaceObject extends DrawingSurfaceObject { + + JoglDrawingSurfaceObject(Canvas3D cv) { + super(cv); + + // System.err.println("JoglDrawingSurfaceObject constructed"); + } + + synchronized boolean renderLock() { + // System.err.println("JoglDrawingSurfaceObject.renderLock()"); + gotDsiLock = true; + return true; + } + + synchronized void unLock() { + // System.err.println("JoglDrawingSurfaceObject.unLock()"); + gotDsiLock = false; + } + + synchronized void getDrawingSurfaceObjectInfo() { + // FIXME: we don't have all of the information we need here to + // create a GLDrawable for the Canvas3D, so for now, do nothing + + // FIXME: this mechanism is much too complicated + + /* + System.err.println("JoglDrawingSurfaceObject.getDrawingSurfaceObjectInfo()"); + + if (canvas.drawable == null) { + System.err.println( + "JoglDrawingSurfaceObject.getDrawingSurfaceObjectInfo: window = " + + canvas.drawable); + + // TODO: replace with a real JoglDrawable + canvas.drawable = new JoglDrawable(); + } + */ + } + + synchronized void invalidate() { + System.err.println("JoglDrawingSurfaceObject.invalidate()"); + } +} diff --git a/src/classes/share/javax/media/j3d/JoglGraphicsConfiguration.java b/src/classes/share/javax/media/j3d/JoglGraphicsConfiguration.java new file mode 100644 index 0000000..1f5989e --- /dev/null +++ b/src/classes/share/javax/media/j3d/JoglGraphicsConfiguration.java @@ -0,0 +1,138 @@ +/* + * $RCSfile$ + * + * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package javax.media.j3d; + +import java.awt.AWTException; +import java.awt.DisplayMode; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.ImageCapabilities; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.VolatileImage; + +import com.jogamp.nativewindow.awt.AWTGraphicsDevice; +import javax.media.opengl.GLCapabilities; + +/** + * Class implementing the GraphicsConfiguration API, but not a "real" + * GraphicsConfiguration object. Wraps a GLCapabilities object and + * supports either immediate or deferred pixel format / visual + * selection depending on which platform we are running. + */ + +class JoglGraphicsConfiguration extends GraphicsConfiguration { + private GLCapabilities caps; + private int chosenIndex; + private GraphicsDevice device; + private AWTGraphicsDevice awtGraphicsDevice; + // Needed for Screen3D + private int width; + private int height; + + JoglGraphicsConfiguration(GLCapabilities caps, int chosenIndex, GraphicsDevice device) { + super(); + this.caps = caps; + this.chosenIndex = chosenIndex; + this.device = device; + //FIXME unit id? + this.awtGraphicsDevice = new AWTGraphicsDevice(this.device, 0); + DisplayMode m = device.getDisplayMode(); + width = m.getWidth(); + height = m.getHeight(); + } + + GLCapabilities getGLCapabilities() { + return caps; + } + + int getChosenIndex() { + return chosenIndex; + } + + public BufferedImage createCompatibleImage(int width, int height) { + throw new RuntimeException("Unimplemented"); + } + + public BufferedImage createCompatibleImage(int width, int height, + int transparency) { + throw new RuntimeException("Unimplemented"); + } + + public VolatileImage createCompatibleVolatileImage(int width, int height) { + throw new RuntimeException("Unimplemented"); + } + + public VolatileImage createCompatibleVolatileImage(int width, int height, int transparency) { + throw new RuntimeException("Unimplemented"); + } + + public VolatileImage createCompatibleVolatileImage(int width, int height, + ImageCapabilities caps) throws AWTException { + throw new RuntimeException("Unimplemented"); + } + + public VolatileImage createCompatibleVolatileImage(int width, int height, + ImageCapabilities caps, int transparency) throws AWTException { + throw new RuntimeException("Unimplemented"); + } + + public Rectangle getBounds() { + return new Rectangle(0, 0, width, height); + } + + public ColorModel getColorModel() { + throw new RuntimeException("Unimplemented"); + } + + public ColorModel getColorModel(int transparency) { + throw new RuntimeException("Unimplemented"); + } + + public AffineTransform getDefaultTransform() { + throw new RuntimeException("Unimplemented"); + } + + public GraphicsDevice getDevice() { + return device; + } + + public AWTGraphicsDevice getAwtGraphicsDevice() { + return awtGraphicsDevice; + } + + public AffineTransform getNormalizingTransform() { + throw new RuntimeException("Unimplemented"); + } +} diff --git a/src/classes/share/javax/media/j3d/JoglPipeline.java b/src/classes/share/javax/media/j3d/JoglPipeline.java new file mode 100644 index 0000000..d3e3a8d --- /dev/null +++ b/src/classes/share/javax/media/j3d/JoglPipeline.java @@ -0,0 +1,8631 @@ +/* + * $RCSfile$ + * + * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package javax.media.j3d; + +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.DisplayMode; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GraphicsConfigTemplate; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Method; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration; +import com.jogamp.nativewindow.awt.AWTGraphicsDevice; +import com.jogamp.nativewindow.awt.AWTGraphicsScreen; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.CapabilitiesChooser; +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.opengl.DefaultGLCapabilitiesChooser; +import javax.media.opengl.GL; +import javax.media.opengl.GL2; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesChooser; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawable; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLException; +import javax.media.opengl.GLPbuffer; +import javax.media.opengl.GLProfile; +import javax.media.opengl.Threading; +import javax.media.opengl.glu.GLU; + +import com.jogamp.common.nio.Buffers; + +/** + * Concrete implementation of Pipeline class for the JOGL rendering + * pipeline. + */ +class JoglPipeline extends Pipeline { + // Currently prints for entry points not yet implemented + private static final boolean DEBUG = true; + // Currently prints for entry points already implemented + private static final boolean VERBOSE = false; + // Debugging output for graphics configuration selection + private static final boolean DEBUG_CONFIG = false; + // Prints extra debugging information + private static final boolean EXTRA_DEBUGGING = false; + // Number of milliseconds to wait for windows to pop up on screen + private static final int WAIT_TIME = 1000; + // Configurable constant just in case we want to change this later + private static final int MIN_FRAME_SIZE = 1; + + /** + * Constructor for singleton JoglPipeline instance + */ + protected JoglPipeline() { + } + + /** + * Initialize the pipeline + */ + void initialize(Pipeline.Type pipelineType) { + super.initialize(pipelineType); + + assert pipelineType == Pipeline.Type.JOGL; + + // Java3D maintains strict control over which threads perform OpenGL work + Threading.disableSingleThreading(); + + // TODO: finish this with any other needed initialization + } + + /** + * Returns true if the GLSL library is loaded and available. Note that this + * does not necessarily mean that GLSL is supported by the graphics card. + */ + boolean isGLSLLibraryAvailable() { + return true; + } + + + // --------------------------------------------------------------------- + + // + // GeometryArrayRetained methods + // + + // used for GeometryArrays by Copy or interleaved + void execute(Context ctx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, + boolean useAlpha, + boolean ignoreVertexColors, + int startVIndex, int vcount, int vformat, + int texCoordSetCount, int[] texCoordSetMap, + int texCoordSetMapLen, + int[] texUnitOffset, + int numActiveTexUnitState, + int vertexAttrCount, int[] vertexAttrSizes, + float[] varray, float[] carray, int cDirty) { + if (VERBOSE) System.err.println("JoglPipeline.execute()"); + + executeGeometryArray(ctx, geo, geo_type, isNonUniformScale, useAlpha, + ignoreVertexColors, startVIndex, vcount, vformat, + texCoordSetCount, texCoordSetMap, texCoordSetMapLen, + texUnitOffset, numActiveTexUnitState, + vertexAttrCount, vertexAttrSizes, + varray, null, carray, cDirty); + } + + // used by GeometryArray by Reference with java arrays + void executeVA(Context ctx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, + boolean ignoreVertexColors, + int vcount, + int vformat, + int vdefined, + int initialCoordIndex, float[] vfcoords, double[] vdcoords, + int initialColorIndex, float[] cfdata, byte[] cbdata, + int initialNormalIndex, float[] ndata, + int vertexAttrCount, int[] vertexAttrSizes, + int[] vertexAttrIndices, float[][] vertexAttrData, + int texCoordMapLength, + int[] texcoordoffset, + int numActiveTexUnitState, + int[] texIndex, int texstride, Object[] texCoords, + int cdirty) { + if (VERBOSE) System.err.println("JoglPipeline.executeVA()"); + + boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); + boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); + boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); + boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); + boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); + boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); + boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); + + FloatBuffer fverts = null; + DoubleBuffer dverts = null; + FloatBuffer fclrs = null; + ByteBuffer bclrs = null; + FloatBuffer[] texCoordBufs = null; + FloatBuffer norms = null; + FloatBuffer[] vertexAttrBufs = null; + + // Get vertex attribute arrays + if (vattrDefined) { + vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData); + } + + // get texture arrays + if (textureDefined) { + texCoordBufs = getTexCoordSetBuffer(texCoords); + } + + // get coordinate array + if (floatCoordDefined) { + fverts = getVertexArrayBuffer(vfcoords); + } else if (doubleCoordDefined) { + dverts = getVertexArrayBuffer(vdcoords); + } + + // get color array + if (floatColorsDefined) { + fclrs = getColorArrayBuffer(cfdata); + } else if (byteColorsDefined) { + bclrs = getColorArrayBuffer(cbdata); + } + + // get normal array + if (normalsDefined) { + norms = getNormalArrayBuffer(ndata); + } + + int[] sarray = null; + int[] start_array = null; + int strip_len = 0; + if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { + sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts; + strip_len = sarray.length; + start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices; + } + + executeGeometryArrayVA(ctx, geo, geo_type, + isNonUniformScale, ignoreVertexColors, + vcount, vformat, vdefined, + initialCoordIndex, fverts, dverts, + initialColorIndex, fclrs, bclrs, + initialNormalIndex, norms, + vertexAttrCount, vertexAttrSizes, + vertexAttrIndices, vertexAttrBufs, + texCoordMapLength, + texcoordoffset, numActiveTexUnitState, + texIndex, texstride, texCoordBufs, cdirty, + sarray, strip_len, start_array); + } + + // used by GeometryArray by Reference with NIO buffer + void executeVABuffer(Context ctx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, + boolean ignoreVertexColors, + int vcount, + int vformat, + int vdefined, + int initialCoordIndex, + Object vcoords, + int initialColorIndex, + Object cdataBuffer, + float[] cfdata, byte[] cbdata, + int initialNormalIndex, Object ndata, + int vertexAttrCount, int[] vertexAttrSizes, + int[] vertexAttrIndices, Object[] vertexAttrData, + int texCoordMapLength, + int[] texcoordoffset, + int numActiveTexUnitState, + int[] texIndex, int texstride, Object[] texCoords, + int cdirty) { + if (VERBOSE) System.err.println("JoglPipeline.executeVABuffer()"); + + boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); + boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); + boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); + boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); + boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); + boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); + boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); + + FloatBuffer fverts = null; + DoubleBuffer dverts = null; + FloatBuffer fclrs = null; + ByteBuffer bclrs = null; + FloatBuffer[] texCoordBufs = null; + FloatBuffer norms = null; + FloatBuffer[] vertexAttrBufs = null; + + // Get vertex attribute arrays + if (vattrDefined) { + vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData); + } + + // get texture arrays + if (textureDefined) { + texCoordBufs = new FloatBuffer[texCoords.length]; + for (int i = 0; i < texCoords.length; i++) { + texCoordBufs[i] = (FloatBuffer) texCoords[i]; + } + } + + // get coordinate array + if (floatCoordDefined) { + fverts = (FloatBuffer) vcoords; + } else if (doubleCoordDefined) { + dverts = (DoubleBuffer) vcoords; + } + + if (fverts == null && dverts == null) { + return; + } + + // get color array + if (floatColorsDefined) { + if (cfdata != null) + fclrs = getColorArrayBuffer(cfdata); + else + fclrs = (FloatBuffer) cdataBuffer; + } else if (byteColorsDefined) { + if (cbdata != null) + bclrs = getColorArrayBuffer(cbdata); + else + bclrs = (ByteBuffer) cdataBuffer; + } + + // get normal array + if (normalsDefined) { + norms = (FloatBuffer) ndata; + } + + int[] sarray = null; + int[] start_array = null; + int strip_len = 0; + if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { + sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts; + strip_len = sarray.length; + start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices; + } + + executeGeometryArrayVA(ctx, geo, geo_type, + isNonUniformScale, ignoreVertexColors, + vcount, vformat, vdefined, + initialCoordIndex, fverts, dverts, + initialColorIndex, fclrs, bclrs, + initialNormalIndex, norms, + vertexAttrCount, vertexAttrSizes, + vertexAttrIndices, vertexAttrBufs, + texCoordMapLength, + texcoordoffset, numActiveTexUnitState, + texIndex, texstride, texCoordBufs, cdirty, + sarray, strip_len, start_array); + } + + // used by GeometryArray by Reference in interleaved format with NIO buffer + void executeInterleavedBuffer(Context ctx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, + boolean useAlpha, + boolean ignoreVertexColors, + int startVIndex, int vcount, int vformat, + int texCoordSetCount, int[] texCoordSetMap, + int texCoordSetMapLen, + int[] texUnitOffset, + int numActiveTexUnit, + Object varray, float[] cdata, int cdirty) { + if (VERBOSE) System.err.println("JoglPipeline.executeInterleavedBuffer()"); + + executeGeometryArray(ctx, geo, geo_type, + isNonUniformScale, useAlpha, ignoreVertexColors, + startVIndex, vcount, vformat, + texCoordSetCount, texCoordSetMap, texCoordSetMapLen, + texUnitOffset, numActiveTexUnit, 0, null, + null, (Buffer) varray, cdata, cdirty); + } + + void setVertexFormat(Context ctx, GeometryArrayRetained geo, + int vformat, boolean useAlpha, boolean ignoreVertexColors) { + if (VERBOSE) System.err.println("JoglPipeline.setVertexFormat()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + // Enable and disable the appropriate pointers + if ((vformat & GeometryArray.NORMALS) != 0) { + gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); + } else { + gl.glDisableClientState(GL2.GL_NORMAL_ARRAY); + } + if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) { + gl.glEnableClientState(GL2.GL_COLOR_ARRAY); + } else { + gl.glDisableClientState(GL2.GL_COLOR_ARRAY); + } + +// FIXME: SUN_global_alpha +// if (gl.isExtensionAvailable("GL_SUN_global_alpha")) { +// if (useAlpha) { +// gl.glEnable(GL.GL_GLOBAL_ALPHA_SUN); +// } else { +// gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN); +// } +// } + + if ((vformat & GeometryArray.COORDINATES) != 0) { + gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); + } else { + gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); + } + } + + void disableGlobalAlpha(Context ctx, GeometryArrayRetained geo, int vformat, + boolean useAlpha, boolean ignoreVertexColors) { + if (VERBOSE) System.err.println("JoglPipeline.disableGlobalAlpha()"); +// FIXME: SUN_global_alpha +// GL gl = context(ctx).getGL(); + +// if (gl.isExtensionAvailable("GL_SUN_global_alpha")) { +// if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) { +// if (useAlpha) { +// gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN); +// } +// } +// } + } + + // used for GeometryArrays + void buildGA(Context ctx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, boolean updateAlpha, + float alpha, + boolean ignoreVertexColors, + int startVIndex, + int vcount, int vformat, + int texCoordSetCount, int[] texCoordSetMap, + int texCoordSetMapLen, int[] texCoordSetMapOffset, + int vertexAttrCount, int[] vertexAttrSizes, + double[] xform, double[] nxform, + float[] varray) { + if (VERBOSE) System.err.println("JoglPipeline.buildGA()"); + JoglContext jctx = (JoglContext) ctx; + GL2 gl = context(ctx).getGL().getGL2(); + FloatBuffer verts = null; + int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0; + int texStride = 0; + int vAttrOff = 0; + if ((vformat & GeometryArray.COORDINATES) != 0) { + stride += 3; + } + if ((vformat & GeometryArray.NORMALS) != 0) { + stride += 3; + coordoff += 3; + } + + if ((vformat & GeometryArray.COLOR) != 0) { + if ((vformat & GeometryArray.BY_REFERENCE) != 0) { + if ((vformat & GeometryArray.WITH_ALPHA) != 0) { + stride += 4; + normoff += 4; + coordoff += 4; + } else { + stride += 3; + normoff += 3; + coordoff += 3; + } + } else { + stride += 4; + normoff += 4; + coordoff += 4; + } + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { + texStride = 2 * texCoordSetCount; + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { + texStride = 3 * texCoordSetCount; + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { + texStride = 4 * texCoordSetCount; + } + stride += texStride; + normoff += texStride; + coloroff += texStride; + coordoff += texStride; + } + + int vAttrStride = 0; + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + vAttrStride += vertexAttrSizes[i]; + } + stride += vAttrStride; + normoff += vAttrStride; + coloroff += vAttrStride; + coordoff += vAttrStride; + texCoordoff += vAttrStride; + } + + int bstride = stride * Buffers.SIZEOF_FLOAT; + // Start sending down from the startVIndex + int initialOffset = startVIndex * stride; + normoff += initialOffset; + coloroff += initialOffset; + coordoff += initialOffset; + texCoordoff += initialOffset; + vAttrOff += initialOffset; + + // process alpha for geometryArray without alpha + boolean useAlpha = false; + if (updateAlpha && !ignoreVertexColors) { + useAlpha = true; + } + + if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { + int[] sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts; + + int primType = 0; + switch (geo_type) { + case GeometryRetained.GEO_TYPE_TRI_STRIP_SET : + primType = GL.GL_TRIANGLE_STRIP; + break; + case GeometryRetained.GEO_TYPE_TRI_FAN_SET : + primType = GL.GL_TRIANGLE_FAN; + break; + case GeometryRetained.GEO_TYPE_LINE_STRIP_SET : + primType = GL.GL_LINE_STRIP; + break; + } + + if (ignoreVertexColors) { + vformat &= ~GeometryArray.COLOR; + } + + for (int i = 0; i < sarray.length; i++) { + gl.glBegin(primType); + for (int j = 0; j < sarray[i]; j++) { + if ((vformat & GeometryArray.NORMALS) != 0) { + if (nxform != null) { + float nx = (float) (nxform[0] * varray[normoff] + + nxform[1] * varray[normoff+1] + + nxform[2] * varray[normoff+2]); + float ny = (float) (nxform[4] * varray[normoff] + + nxform[5] * varray[normoff+1] + + nxform[6] * varray[normoff+2]); + float nz = (float) (nxform[8] * varray[normoff] + + nxform[9] * varray[normoff+1] + + nxform[10] * varray[normoff+2]); + gl.glNormal3f(nx, ny, nz); + } else { + gl.glNormal3f(varray[normoff], varray[normoff+1], varray[normoff+2]); + } + } + if ((vformat & GeometryArray.COLOR) != 0) { + if (useAlpha) { + gl.glColor4f(varray[coloroff], + varray[coloroff+1], + varray[coloroff+2], + varray[coloroff+3] * alpha); + } else { + if ((vformat & GeometryArray.WITH_ALPHA) != 0) { // alpha is present + gl.glColor4f(varray[coloroff], + varray[coloroff+1], + varray[coloroff+2], + varray[coloroff+3]); + } else { + gl.glColor3f(varray[coloroff], + varray[coloroff+1], + varray[coloroff+2]); + } + } + } + + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + int vaOff = vAttrOff; + if (verts == null) { + verts = FloatBuffer.wrap(varray); + } + for (int vaIdx = 0; vaIdx < vertexAttrCount; vaIdx++) { + switch (vertexAttrSizes[vaIdx]) { + case 1: + verts.position(vaOff); + jctx.vertexAttr1fv(gl, vaIdx, verts); + break; + case 2: + verts.position(vaOff); + jctx.vertexAttr2fv(gl, vaIdx, verts); + break; + case 3: + verts.position(vaOff); + jctx.vertexAttr3fv(gl, vaIdx, verts); + break; + case 4: + verts.position(vaOff); + jctx.vertexAttr4fv(gl, vaIdx, verts); + break; + } + + vaOff += vertexAttrSizes[vaIdx]; + } + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + if (texCoordSetMapLen > 0) { + if (gl.isExtensionAvailable("GL_VERSION_1_3")) { + if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { + for (int k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + int off = texCoordoff + texCoordSetMapOffset[k]; + gl.glMultiTexCoord2f(GL.GL_TEXTURE0 + k, + varray[off], + varray[off + 1]); + } + } + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { + for (int k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + int off = texCoordoff + texCoordSetMapOffset[k]; + gl.glMultiTexCoord3f(GL.GL_TEXTURE0 + k, + varray[off], + varray[off + 1], + varray[off + 2]); + } + } + } else { + for (int k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + int off = texCoordoff + texCoordSetMapOffset[k]; + gl.glMultiTexCoord4f(GL.GL_TEXTURE0 + k, + varray[off], + varray[off + 1], + varray[off + 2], + varray[off + 3]); + } + } + } + } else { // no multitexture + if (texCoordSetMapOffset[0] != -1) { + int off = texCoordoff + texCoordSetMapOffset[0]; + if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { + gl.glTexCoord2f(varray[off], varray[off + 1]); + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { + gl.glTexCoord3f(varray[off], varray[off + 1], varray[off + 2]); + } else { + gl.glTexCoord4f(varray[off], varray[off + 1], varray[off + 2], varray[off + 3]); + } + } + } // no multitexture + } + // texCoordSetMapLen can't be 0 if texture coordinates + // is to be specified + } + + if ((vformat & GeometryArray.COORDINATES) != 0) { + if (xform != null) { + // transform the vertex data with the static transform + float w = (float) (xform[12] * varray[coordoff] + + xform[13] * varray[coordoff+1] + + xform[14] * varray[coordoff+2] + + xform[15]); + float winv = 1.0f/w; + float vx = (float) (xform[0] * varray[coordoff] + + xform[1] * varray[coordoff+1] + + xform[2] * varray[coordoff+2] + + xform[3]) * winv; + float vy = (float) (xform[4] * varray[coordoff] + + xform[5] * varray[coordoff+1] + + xform[6] * varray[coordoff+2] + + xform[7]) * winv; + float vz = (float) (xform[8] * varray[coordoff] + + xform[9] * varray[coordoff+1] + + xform[10] * varray[coordoff+2] + + xform[11]) * winv; + gl.glVertex3f(vx, vy, vz); + } else { + gl.glVertex3f(varray[coordoff], varray[coordoff + 1], varray[coordoff + 2]); + } + } + normoff += stride; + coloroff += stride; + coordoff += stride; + texCoordoff += stride; + vAttrOff += stride; + } + gl.glEnd(); + } + } else if ((geo_type == GeometryRetained.GEO_TYPE_QUAD_SET) || + (geo_type == GeometryRetained.GEO_TYPE_TRI_SET) || + (geo_type == GeometryRetained.GEO_TYPE_POINT_SET) || + (geo_type == GeometryRetained.GEO_TYPE_LINE_SET)) { + int primType = 0; + switch (geo_type) { + case GeometryRetained.GEO_TYPE_QUAD_SET : + primType = GL2.GL_QUADS; + break; + case GeometryRetained.GEO_TYPE_TRI_SET : + primType = GL.GL_TRIANGLES; + break; + case GeometryRetained.GEO_TYPE_POINT_SET : + primType = GL.GL_POINTS; + break; + case GeometryRetained.GEO_TYPE_LINE_SET : + primType = GL.GL_LINES; + break; + } + + if (ignoreVertexColors) { + vformat &= ~GeometryArray.COLOR; + } + + gl.glBegin(primType); + for (int j = 0; j < vcount; j++) { + if ((vformat & GeometryArray.NORMALS) != 0) { + if (nxform != null) { + float nx = (float) (nxform[0] * varray[normoff] + + nxform[1] * varray[normoff+1] + + nxform[2] * varray[normoff+2]); + float ny = (float) (nxform[4] * varray[normoff] + + nxform[5] * varray[normoff+1] + + nxform[6] * varray[normoff+2]); + float nz = (float) (nxform[8] * varray[normoff] + + nxform[9] * varray[normoff+1] + + nxform[10] * varray[normoff+2]); + gl.glNormal3f(nx, ny, nz); + } else { + gl.glNormal3f(varray[normoff], varray[normoff + 1], varray[normoff + 2]); + } + } + if ((vformat & GeometryArray.COLOR) != 0) { + if (useAlpha) { + float cr, cg, cb, ca; + if ((vformat & GeometryArray.WITH_ALPHA) != 0) { + cr = varray[coloroff]; + cg = varray[coloroff + 1]; + cb = varray[coloroff + 2]; + ca = varray[coloroff + 3] * alpha; + } else { + cr = varray[coloroff]; + cg = varray[coloroff + 1]; + cb = varray[coloroff + 2]; + ca = alpha; + } + gl.glColor4f(cr, cg, cb, ca); + } else { + if ((vformat & GeometryArray.WITH_ALPHA) != 0) { // alpha is present + gl.glColor4f(varray[coloroff], + varray[coloroff + 1], + varray[coloroff + 2], + varray[coloroff + 3]); + } else { + gl.glColor3f(varray[coloroff], + varray[coloroff + 1], + varray[coloroff + 2]); + } + } + } + + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + int vaOff = vAttrOff; + if (verts == null) { + verts = FloatBuffer.wrap(varray); + } + for (int vaIdx = 0; vaIdx < vertexAttrCount; vaIdx++) { + switch (vertexAttrSizes[vaIdx]) { + case 1: + verts.position(vaOff); + jctx.vertexAttr1fv(gl, vaIdx, verts); + break; + case 2: + verts.position(vaOff); + jctx.vertexAttr2fv(gl, vaIdx, verts); + break; + case 3: + verts.position(vaOff); + jctx.vertexAttr3fv(gl, vaIdx, verts); + break; + case 4: + verts.position(vaOff); + jctx.vertexAttr4fv(gl, vaIdx, verts); + break; + } + + vaOff += vertexAttrSizes[vaIdx]; + } + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + if (texCoordSetMapLen > 0) { + if (gl.isExtensionAvailable("GL_VERSION_1_3")) { + if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { + for (int k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + int off = texCoordoff + texCoordSetMapOffset[k]; + gl.glMultiTexCoord2f(GL.GL_TEXTURE0 + k, + varray[off], + varray[off + 1]); + } + } + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { + for (int k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + int off = texCoordoff + texCoordSetMapOffset[k]; + gl.glMultiTexCoord3f(GL.GL_TEXTURE0 + k, + varray[off], + varray[off + 1], + varray[off + 2]); + } + } + } else { + for (int k = 0; k < texCoordSetMapLen; k++) { + if (texCoordSetMapOffset[k] != -1) { + int off = texCoordoff + texCoordSetMapOffset[k]; + gl.glMultiTexCoord4f(GL.GL_TEXTURE0 + k, + varray[off], + varray[off + 1], + varray[off + 2], + varray[off + 3]); + } + } + } + } else { // no multitexture + if (texCoordSetMapOffset[0] != -1) { + int off = texCoordoff + texCoordSetMapOffset[0]; + if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { + gl.glTexCoord2f(varray[off], varray[off + 1]); + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { + gl.glTexCoord3f(varray[off], varray[off + 1], varray[off + 2]); + } else { + gl.glTexCoord4f(varray[off], varray[off + 1], varray[off + 2], varray[off + 3]); + } + } + } // no multitexture + } + // texCoordSetMapLen can't be 0 if texture coordinates is + // to be specified + } + + if ((vformat & GeometryArray.COORDINATES) != 0) { + if (xform != null) { + // transform the vertex data with the static transform + float w = (float) (xform[12] * varray[coordoff] + + xform[13] * varray[coordoff+1] + + xform[14] * varray[coordoff+2] + + xform[15]); + float winv = 1.0f/w; + float vx = (float) (xform[0] * varray[coordoff] + + xform[1] * varray[coordoff+1] + + xform[2] * varray[coordoff+2] + + xform[3]) * winv; + float vy = (float) (xform[4] * varray[coordoff] + + xform[5] * varray[coordoff+1] + + xform[6] * varray[coordoff+2] + + xform[7]) * winv; + float vz = (float) (xform[8] * varray[coordoff] + + xform[9] * varray[coordoff+1] + + xform[10] * varray[coordoff+2] + + xform[11]) * winv; + gl.glVertex3f(vx, vy, vz); + } else { + gl.glVertex3f(varray[coordoff], varray[coordoff + 1], varray[coordoff + 2]); + } + } + normoff += stride; + coloroff += stride; + coordoff += stride; + texCoordoff += stride; + vAttrOff += stride; + } + gl.glEnd(); + } + } + + // used to Build Dlist GeometryArray by Reference with java arrays + void buildGAForByRef(Context ctx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, boolean updateAlpha, + float alpha, + boolean ignoreVertexColors, + int vcount, + int vformat, + int vdefined, + int initialCoordIndex, float[] vfcoords, double[] vdcoords, + int initialColorIndex, float[] cfdata, byte[] cbdata, + int initialNormalIndex, float[] ndata, + int vertexAttrCount, int[] vertexAttrSizes, + int[] vertexAttrIndices, float[][] vertexAttrData, + int texCoordMapLength, + int[] tcoordsetmap, + int[] texIndices, int texStride, Object[] texCoords, + double[] xform, double[] nxform) { + if (VERBOSE) System.err.println("JoglPipeline.buildGAForByRef()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); + boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); + boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); + boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); + boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); + boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); + boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); + + FloatBuffer fverts = null; + DoubleBuffer dverts = null; + FloatBuffer fclrs = null; + ByteBuffer bclrs = null; + FloatBuffer[] texCoordBufs = null; + FloatBuffer norms = null; + FloatBuffer[] vertexAttrBufs = null; + + // Get vertex attribute arrays + if (vattrDefined) { + vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData); + } + + // get texture arrays + if (textureDefined) { + texCoordBufs = getTexCoordSetBuffer(texCoords); + } + + // process alpha for geometryArray without alpha + boolean useAlpha = false; + if (updateAlpha && !ignoreVertexColors) { + useAlpha = true; + } + + int[] sarray = null; + int[] start_array = null; + int strip_len = 0; + if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { + sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts; + strip_len = sarray.length; + start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices; + } + + if (ignoreVertexColors) { + vformat &= ~GeometryArray.COLOR; + floatColorsDefined = false; + byteColorsDefined = false; + } + + // get coordinate array + if (floatCoordDefined) { + gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); + fverts = getVertexArrayBuffer(vfcoords, (xform == null)); + if (xform != null) { + // Must copy in and transform data + for (int i = initialCoordIndex; i < vcount * 3; i += 3) { + fverts.put(i , (float) (xform[0] * vfcoords[i] + + xform[1] * vfcoords[i+1] + + xform[2] * vfcoords[i+2])); + fverts.put(i+1, (float) (xform[4] * vfcoords[i] + + xform[5] * vfcoords[i+1] + + xform[6] * vfcoords[i+2])); + fverts.put(i+2, (float) (xform[8] * vfcoords[i] + + xform[9] * vfcoords[i+1] + + xform[10] * vfcoords[i+2])); + } + } + } else if (doubleCoordDefined) { + gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); + dverts = getVertexArrayBuffer(vdcoords, (xform == null)); + if (xform != null) { + // Must copy in and transform data + for (int i = initialCoordIndex; i < vcount * 3; i += 3) { + dverts.put(i , (xform[0] * vdcoords[i] + + xform[1] * vdcoords[i+1] + + xform[2] * vdcoords[i+2])); + dverts.put(i+1, (xform[4] * vdcoords[i] + + xform[5] * vdcoords[i+1] + + xform[6] * vdcoords[i+2])); + dverts.put(i+2, (xform[8] * vdcoords[i] + + xform[9] * vdcoords[i+1] + + xform[10] * vdcoords[i+2])); + } + } + } else { + gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); + } + + // get color array + if (floatColorsDefined) { + gl.glEnableClientState(GL2.GL_COLOR_ARRAY); + fclrs = getColorArrayBuffer(cfdata, !useAlpha); + if (useAlpha) { + // Must copy in and modify color data + if ((vformat & GeometryArray.WITH_ALPHA) != 0) { + for (int i = initialColorIndex; i < vcount * 4; i += 4) { + fclrs.put(i , cfdata[i]); + fclrs.put(i+1, cfdata[i+1]); + fclrs.put(i+2, cfdata[i+2]); + fclrs.put(i+3, alpha * cfdata[i+3]); + } + } else { + int k = 0; + for (int i = initialColorIndex; i < vcount * 4; i += 4) { + fclrs.put(i , cfdata[k++]); + fclrs.put(i+1, cfdata[k++]); + fclrs.put(i+2, cfdata[k++]); + fclrs.put(i+3, alpha); + } + } + vformat |= GeometryArray.WITH_ALPHA; + } + } else if (byteColorsDefined) { + gl.glEnableClientState(GL2.GL_COLOR_ARRAY); + bclrs = getColorArrayBuffer(cbdata, !useAlpha); + if (useAlpha) { + // Must copy in and modify color data + if ((vformat & GeometryArray.WITH_ALPHA) != 0) { + for (int i = initialColorIndex; i < vcount * 4; i += 4) { + bclrs.put(i , cbdata[i]); + bclrs.put(i+1, cbdata[i+1]); + bclrs.put(i+2, cbdata[i+2]); + bclrs.put(i+3, (byte) (alpha * (int) (cbdata[i+3] & 0xFF))); + } + } else { + int k = 0; + for (int i = initialColorIndex; i < vcount * 4; i += 4) { + bclrs.put(i , cbdata[k++]); + bclrs.put(i+1, cbdata[k++]); + bclrs.put(i+2, cbdata[k++]); + bclrs.put(i+3, (byte) (alpha * 255.0f)); + } + } + vformat |= GeometryArray.WITH_ALPHA; + } + } else { + gl.glDisableClientState(GL2.GL_COLOR_ARRAY); + } + + // get normal array + if (normalsDefined) { + gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); + norms = getNormalArrayBuffer(ndata, (nxform == null)); + if (nxform != null) { + // Must copy in and transform data + for (int i = initialNormalIndex; i < vcount * 3; i += 3) { + norms.put(i , (float) (nxform[0] * ndata[i] + + nxform[1] * ndata[i+1] + + nxform[2] * ndata[i+2])); + norms.put(i+1, (float) (nxform[4] * ndata[i] + + nxform[5] * ndata[i+1] + + nxform[6] * ndata[i+2])); + norms.put(i+2, (float) (nxform[8] * ndata[i] + + nxform[9] * ndata[i+1] + + nxform[10] * ndata[i+2])); + } + } + } else { + gl.glDisableClientState(GL2.GL_NORMAL_ARRAY); + } + + executeGeometryArrayVA(ctx, geo, geo_type, + isNonUniformScale, ignoreVertexColors, + vcount, vformat, vdefined, + initialCoordIndex, fverts, dverts, + initialColorIndex, fclrs, bclrs, + initialNormalIndex, norms, + vertexAttrCount, vertexAttrSizes, + vertexAttrIndices, vertexAttrBufs, + texCoordMapLength, + tcoordsetmap, texCoordMapLength, + texIndices, texStride, texCoordBufs, 0, + sarray, strip_len, start_array); + } + + //---------------------------------------------------------------------- + // Private helper methods for GeometryArrayRetained + // + + private void + testForInterleavedArrays(int vformat, + boolean[] useInterleavedArrays, + int[] iaFormat) { + if (VERBOSE) System.err.println("JoglPipeline.testForInterleavedArrays()"); + useInterleavedArrays[0] = true; + switch (vformat) { + case GeometryArray.COORDINATES : + iaFormat[0] = GL2.GL_V3F; break; + case (GeometryArray.COORDINATES | GeometryArray.NORMALS) : + iaFormat[0] = GL2.GL_N3F_V3F; break; + case (GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2) : + iaFormat[0] = GL2.GL_T2F_V3F; break; + case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR) : + case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR | GeometryArray.WITH_ALPHA) : + iaFormat[0] = GL2.GL_C4F_N3F_V3F; break; + case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.TEXTURE_COORDINATE_2) : + iaFormat[0] = GL2.GL_T2F_N3F_V3F; break; + case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR | GeometryArray.TEXTURE_COORDINATE_2): + case (GeometryArray.COORDINATES | GeometryArray.NORMALS | GeometryArray.COLOR | GeometryArray.WITH_ALPHA | GeometryArray.TEXTURE_COORDINATE_2): + iaFormat[0] = GL2.GL_T2F_C4F_N3F_V3F; break; + default: + useInterleavedArrays[0] = false; break; + } + } + + private void + enableTexCoordPointer(GL2 gl, + int texUnit, + int texSize, + int texDataType, + int stride, + Buffer pointer) { + if (VERBOSE) System.err.println("JoglPipeline.enableTexCoordPointer()"); + clientActiveTextureUnit(gl, texUnit); + gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY); + gl.glTexCoordPointer(texSize, texDataType, stride, pointer); + } + + private void disableTexCoordPointer(GL2 gl, int texUnit) { + if (VERBOSE) System.err.println("JoglPipeline.disableTexCoordPointer()"); + clientActiveTextureUnit(gl, texUnit); + gl.glDisableClientState(GL2.GL_TEXTURE_COORD_ARRAY); + } + + private void clientActiveTextureUnit(GL2 gl, int texUnit) { + if (VERBOSE) System.err.println("JoglPipeline.clientActiveTextureUnit()"); + if (gl.isExtensionAvailable("GL_VERSION_1_3")) { + gl.glClientActiveTexture(texUnit + GL.GL_TEXTURE0); + } + } + + + private void + executeTexture(int texCoordSetMapLen, + int texSize, int bstride, int texCoordoff, + int[] texCoordSetMapOffset, + int numActiveTexUnit, + FloatBuffer verts, GL2 gl) { + if (VERBOSE) System.err.println("JoglPipeline.executeTexture()"); + int tus = 0; /* texture unit state index */ + + for (int i = 0; i < numActiveTexUnit; i++) { + + tus = i; + + /* + * it's possible thattexture unit state index (tus) + * is greater than the texCoordSetMapOffsetLen, in this + * case, just disable TexCoordPointer. + */ + if ((tus < texCoordSetMapLen) && + (texCoordSetMapOffset[tus] != -1)) { + if (EXTRA_DEBUGGING) { + System.err.println(" texCoord position " + i + ": " + (texCoordoff + texCoordSetMapOffset[tus])); + } + verts.position(texCoordoff + texCoordSetMapOffset[tus]); + enableTexCoordPointer(gl, i, + texSize, GL.GL_FLOAT, bstride, + verts); + } else { + disableTexCoordPointer(gl, i); + } + } + } + + private void resetTexture(GL2 gl, JoglContext ctx) { + if (VERBOSE) System.err.println("JoglPipeline.resetTexture()"); + /* Disable texture coordinate arrays for all texture units */ + for (int i = 0; i < ctx.getMaxTexCoordSets(); i++) { + disableTexCoordPointer(gl, i); + } + /* Reset client active texture unit to 0 */ + clientActiveTextureUnit(gl, 0); + } + + private void + executeGeometryArray(Context absCtx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, + boolean useAlpha, + boolean ignoreVertexColors, + int startVIndex, int vcount, int vformat, + int texCoordSetCount, int[] texCoordSetMap, + int texCoordSetMapLen, + int[] texCoordSetMapOffset, + int numActiveTexUnitState, + int vertexAttrCount, int[] vertexAttrSizes, + float[] varray, Buffer varrayBuffer, + float[] carray, int cDirty) { + if (VERBOSE) System.err.println("JoglPipeline.executeGeometryArray()"); + JoglContext ctx = (JoglContext) absCtx; + GLContext context = context(ctx); + GL2 gl = context.getGL().getGL2(); + + boolean useInterleavedArrays; + int iaFormat = 0; + int primType = 0; + int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0; + int texSize = 0, texStride = 0; + int vAttrOff = 0; + int vAttrStride = 0; + int bstride = 0, cbstride = 0; + FloatBuffer verts = null; + FloatBuffer clrs = null; + int[] sarray = null; + int[] start_array = null; + + if (EXTRA_DEBUGGING) { + System.err.println("Vertex format: " + getVertexDescription(vformat)); + System.err.println("Geometry type: " + getGeometryDescription(geo_type)); + if (carray != null) { + System.err.println(" Separate color array"); + } else { + System.err.println(" Colors (if any) interleaved"); + } + } + + if ((vformat & GeometryArray.COORDINATES) != 0) { + stride += 3; + } + if ((vformat & GeometryArray.NORMALS) != 0) { + stride += 3; + coordoff += 3; + } + if ((vformat & GeometryArray.COLOR) != 0) { + if ((vformat & GeometryArray.WITH_ALPHA) != 0 ) { + stride += 4; + normoff += 4; + coordoff += 4; + } else { /* Handle the case of executeInterleaved 3f */ + stride += 3; + normoff += 3; + coordoff += 3; + } + } + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + if (EXTRA_DEBUGGING) { + System.err.println(" Number of tex coord sets: " + texCoordSetCount); + } + if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { + texSize = 2; + texStride = 2 * texCoordSetCount; + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { + texSize = 3; + texStride = 3 * texCoordSetCount; + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { + texSize = 4; + texStride = 4 * texCoordSetCount; + } + stride += texStride; + normoff += texStride; + coloroff += texStride; + coordoff += texStride; + } + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + vAttrStride += vertexAttrSizes[i]; + } + stride += vAttrStride; + normoff += vAttrStride; + coloroff += vAttrStride; + coordoff += vAttrStride; + texCoordoff += vAttrStride; + } + + bstride = stride * Buffers.SIZEOF_FLOAT; + + if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { + sarray = ((GeometryStripArrayRetained) geo).stripVertexCounts; + start_array = ((GeometryStripArrayRetained) geo).stripStartOffsetIndices; + } + + // We have to copy if the data isn't specified using NIO + if (varray != null) { + verts = getVertexArrayBuffer(varray); + } else if (varrayBuffer != null) { + verts = (FloatBuffer) varrayBuffer; + } else { + // This should never happen + throw new AssertionError("Unable to get vertex pointer"); + } + + // using byRef interleaved array and has a separate pointer, then .. + int cstride = stride; + if (carray != null) { + clrs = getColorArrayBuffer(carray); + cstride = 4; + } else { + // FIXME: need to "auto-slice" this buffer later + clrs = verts; + } + + cbstride = cstride * Buffers.SIZEOF_FLOAT; + + // Enable normalize for non-uniform scale (which rescale can't handle) + if (isNonUniformScale) { + gl.glEnable(GL2.GL_NORMALIZE); + } + + int startVertex = stride * startVIndex; + int startClrs = cstride * startVIndex; + if (clrs == verts) { + startClrs += coloroff; + } + + /*** Handle non-indexed strip GeometryArray first *******/ + if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { + if (ignoreVertexColors || (carray != null) || + ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = false; + } else { + boolean[] tmp = new boolean[1]; + int[] tmp2 = new int[1]; + testForInterleavedArrays(vformat, tmp, tmp2); + useInterleavedArrays = tmp[0]; + iaFormat = tmp2[0]; + } + if (useInterleavedArrays) { + verts.position(startVertex); + gl.glInterleavedArrays(iaFormat, bstride, verts); + } else { + if ((vformat & GeometryArray.NORMALS) != 0) { + verts.position(startVertex + normoff); + gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); + } + if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) { + if (EXTRA_DEBUGGING) { + System.err.println(" Doing colors"); + } + clrs.position(startClrs); + if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) { + gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs); + } else { + gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs); + } + } + if ((vformat & GeometryArray.COORDINATES) != 0) { + verts.position(startVertex + coordoff); + gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + executeTexture(texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetMapOffset, + numActiveTexUnitState, + verts, gl); + } + + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + int vAttrOffset = startVertex + vAttrOff; + for (int i = 0; i < vertexAttrCount; i++) { + ctx.enableVertexAttrArray(gl, i); + verts.position(vAttrOffset); + ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], + GL.GL_FLOAT, bstride, verts); + vAttrOffset += vertexAttrSizes[i]; + } + } + } + + switch (geo_type) { + case GeometryRetained.GEO_TYPE_TRI_STRIP_SET: + primType = GL.GL_TRIANGLE_STRIP; + break; + case GeometryRetained.GEO_TYPE_TRI_FAN_SET: + primType = GL.GL_TRIANGLE_FAN; + break; + case GeometryRetained.GEO_TYPE_LINE_STRIP_SET: + primType = GL.GL_LINE_STRIP; + break; + } + + if (gl.isExtensionAvailable("GL_EXT_multi_draw_arrays")) { + gl.glMultiDrawArrays(primType, start_array, 0, sarray, 0, sarray.length); + } else { + for (int i = 0; i < sarray.length; i++) { + gl.glDrawArrays(primType, start_array[i], sarray[i]); + } + } + } else if ((geo_type == GeometryRetained.GEO_TYPE_QUAD_SET) || + (geo_type == GeometryRetained.GEO_TYPE_TRI_SET) || + (geo_type == GeometryRetained.GEO_TYPE_POINT_SET) || + (geo_type == GeometryRetained.GEO_TYPE_LINE_SET)) { + /******* Handle non-indexed non-striped GeometryArray now *****/ + if (ignoreVertexColors || (carray != null) || + ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = false; + } else { + boolean[] tmp = new boolean[1]; + int[] tmp2 = new int[1]; + testForInterleavedArrays(vformat, tmp, tmp2); + useInterleavedArrays = tmp[0]; + iaFormat = tmp2[0]; + } + + if (useInterleavedArrays) { + verts.position(startVertex); + gl.glInterleavedArrays(iaFormat, bstride, verts); + } else { + if (EXTRA_DEBUGGING) { + System.err.println(" startVertex: " + startVertex); + System.err.println(" stride: " + stride); + System.err.println(" bstride: " + bstride); + System.err.println(" normoff: " + normoff); + System.err.println(" coloroff: " + coloroff); + System.err.println(" coordoff: " + coordoff); + System.err.println(" texCoordoff: " + texCoordoff); + } + if ((vformat & GeometryArray.NORMALS) != 0) { + verts.position(startVertex + normoff); + gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); + } + if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) { + clrs.position(startClrs); + if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) { + gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs); + } else { + gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs); + } + } + if ((vformat & GeometryArray.COORDINATES) != 0) { + verts.position(startVertex + coordoff); + gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + executeTexture(texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetMapOffset, + numActiveTexUnitState, + verts, gl); + } + + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + int vAttrOffset = startVertex + vAttrOff; + for (int i = 0; i < vertexAttrCount; i++) { + ctx.enableVertexAttrArray(gl, i); + verts.position(vAttrOffset); + ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], + GL.GL_FLOAT, bstride, verts); + vAttrOffset += vertexAttrSizes[i]; + } + } + } + switch (geo_type){ + case GeometryRetained.GEO_TYPE_QUAD_SET : gl.glDrawArrays(GL2.GL_QUADS, 0, vcount); break; + case GeometryRetained.GEO_TYPE_TRI_SET : gl.glDrawArrays(GL.GL_TRIANGLES, 0, vcount); break; + case GeometryRetained.GEO_TYPE_POINT_SET: gl.glDrawArrays(GL.GL_POINTS, 0, vcount); break; + case GeometryRetained.GEO_TYPE_LINE_SET : gl.glDrawArrays(GL.GL_LINES, 0, vcount); break; + } + } + + /* clean up if we turned on normalize */ + if (isNonUniformScale) { + gl.glDisable(GL2.GL_NORMALIZE); + } + + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + resetVertexAttrs(gl, ctx, vertexAttrCount); + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + resetTexture(gl, ctx); + } + } + + + // glLockArrays() is invoked only for indexed geometry, and the + // vertexCount is guarenteed to be >= 0. + private void lockArray(GL2 gl, int vertexCount) { + if (gl.isExtensionAvailable("GL_EXT_compiled_vertex_array")) { + gl.glLockArraysEXT(0, vertexCount); + } + } + + private void unlockArray(GL2 gl) { + if (gl.isExtensionAvailable("GL_EXT_compiled_vertex_array")) { + gl.glUnlockArraysEXT(); + } + } + + private void + executeGeometryArrayVA(Context absCtx, + GeometryArrayRetained geo, + int geo_type, + boolean isNonUniformScale, + boolean ignoreVertexColors, + int vcount, + int vformat, + int vdefined, + int initialCoordIndex, FloatBuffer fverts, DoubleBuffer dverts, + int initialColorIndex, FloatBuffer fclrs, ByteBuffer bclrs, + int initialNormalIndex, FloatBuffer norms, + int vertexAttrCount, int[] vertexAttrSizes, + int[] vertexAttrIndices, FloatBuffer[] vertexAttrData, + int texCoordMapLength, + int[] texCoordSetMap, + int numActiveTexUnit, + int[] texindices, int texStride, FloatBuffer[] texCoords, + int cdirty, + int[] sarray, + int strip_len, + int[] start_array) { + JoglContext ctx = (JoglContext) absCtx; + GLContext context = context(ctx); + GL2 gl = context.getGL().getGL2(); + + boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); + boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); + boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); + boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); + boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); + boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); + boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); + + // Enable normalize for non-uniform scale (which rescale can't handle) + if (isNonUniformScale) { + gl.glEnable(GL2.GL_NORMALIZE); + } + + int coordoff = 3 * initialCoordIndex; + // Define the data pointers + if (floatCoordDefined) { + fverts.position(coordoff); + gl.glVertexPointer(3, GL.GL_FLOAT, 0, fverts); + } else if (doubleCoordDefined){ + dverts.position(coordoff); + gl.glVertexPointer(3, GL2.GL_DOUBLE, 0, dverts); + } + + if (floatColorsDefined) { + int coloroff; + int sz; + if ((vformat & GeometryArray.WITH_ALPHA) != 0) { + coloroff = 4 * initialColorIndex; + sz = 4; + } else { + coloroff = 3 * initialColorIndex; + sz = 3; + } + fclrs.position(coloroff); + gl.glColorPointer(sz, GL.GL_FLOAT, 0, fclrs); + } else if (byteColorsDefined) { + int coloroff; + int sz; + if ((vformat & GeometryArray.WITH_ALPHA) != 0) { + coloroff = 4 * initialColorIndex; + sz = 4; + } else { + coloroff = 3 * initialColorIndex; + sz = 3; + } + bclrs.position(coloroff); + gl.glColorPointer(sz, GL.GL_UNSIGNED_BYTE, 0, bclrs); + } + if (normalsDefined) { + int normoff = 3 * initialNormalIndex; + norms.position(normoff); + gl.glNormalPointer(GL.GL_FLOAT, 0, norms); + } + + if (vattrDefined) { + for (int i = 0; i < vertexAttrCount; i++) { + FloatBuffer vertexAttrs = vertexAttrData[i]; + int sz = vertexAttrSizes[i]; + int initIdx = vertexAttrIndices[i]; + ctx.enableVertexAttrArray(gl, i); + vertexAttrs.position(initIdx * sz); + ctx.vertexAttrPointer(gl, i, sz, GL.GL_FLOAT, 0, vertexAttrs); + } + } + + if (textureDefined) { + int texSet = 0; + for (int i = 0; i < numActiveTexUnit; i++) { + if (( i < texCoordMapLength) && + ((texSet = texCoordSetMap[i]) != -1)) { + FloatBuffer buf = texCoords[texSet]; + buf.position(texStride * texindices[texSet]); + enableTexCoordPointer(gl, i, texStride, + GL.GL_FLOAT, 0, buf); + } else { + disableTexCoordPointer(gl, i); + } + } + + // Reset client active texture unit to 0 + clientActiveTextureUnit(gl, 0); + } + + if (geo_type == GeometryRetained.GEO_TYPE_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_LINE_STRIP_SET) { + int primType = 0; + switch (geo_type) { + case GeometryRetained.GEO_TYPE_TRI_STRIP_SET: + primType = GL.GL_TRIANGLE_STRIP; + break; + case GeometryRetained.GEO_TYPE_TRI_FAN_SET: + primType = GL.GL_TRIANGLE_FAN; + break; + case GeometryRetained.GEO_TYPE_LINE_STRIP_SET: + primType = GL.GL_LINE_STRIP; + break; + } + if (gl.isExtensionAvailable("GL_EXT_multi_draw_arrays")) { + gl.glMultiDrawArrays(primType, start_array, 0, sarray, 0, strip_len); + } else if (gl.isExtensionAvailable("GL_VERSION_1_4")) { + gl.glMultiDrawArrays(primType, start_array, 0, sarray, 0, strip_len); + } else { + for (int i = 0; i < strip_len; i++) { + gl.glDrawArrays(primType, start_array[i], sarray[i]); + } + } + } else { + switch (geo_type){ + case GeometryRetained.GEO_TYPE_QUAD_SET : gl.glDrawArrays(GL2.GL_QUADS, 0, vcount); break; + case GeometryRetained.GEO_TYPE_TRI_SET : gl.glDrawArrays(GL.GL_TRIANGLES, 0, vcount); break; + case GeometryRetained.GEO_TYPE_POINT_SET : gl.glDrawArrays(GL.GL_POINTS, 0, vcount); break; + case GeometryRetained.GEO_TYPE_LINE_SET : gl.glDrawArrays(GL.GL_LINES, 0, vcount); break; + } + } + + // clean up if we turned on normalize + if (isNonUniformScale) { + gl.glDisable(GL2.GL_NORMALIZE); + } + + if (vattrDefined) { + resetVertexAttrs(gl, ctx, vertexAttrCount); + } + + if (textureDefined) { + resetTexture(gl, ctx); + } + } + + private String getVertexDescription(int vformat) { + String res = ""; + if ((vformat & GeometryArray.COORDINATES) != 0) res += "COORDINATES "; + if ((vformat & GeometryArray.NORMALS) != 0) res += "NORMALS "; + if ((vformat & GeometryArray.COLOR) != 0) res += "COLOR "; + if ((vformat & GeometryArray.WITH_ALPHA) != 0) res += "(WITH_ALPHA) "; + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) res += "TEXTURE_COORDINATE "; + if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) res += "(2) "; + if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) res += "(3) "; + if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) res += "(4) "; + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) res += "VERTEX_ATTRIBUTES "; + return res; + } + + private String getGeometryDescription(int geo_type) { + switch (geo_type) { + case GeometryRetained.GEO_TYPE_TRI_STRIP_SET : return "GEO_TYPE_TRI_STRIP_SET"; + case GeometryRetained.GEO_TYPE_TRI_FAN_SET : return "GEO_TYPE_TRI_FAN_SET"; + case GeometryRetained.GEO_TYPE_LINE_STRIP_SET: return "GEO_TYPE_LINE_STRIP_SET"; + case GeometryRetained.GEO_TYPE_QUAD_SET : return "GEO_TYPE_QUAD_SET"; + case GeometryRetained.GEO_TYPE_TRI_SET : return "GEO_TYPE_TRI_SET"; + case GeometryRetained.GEO_TYPE_POINT_SET : return "GEO_TYPE_POINT_SET"; + case GeometryRetained.GEO_TYPE_LINE_SET : return "GEO_TYPE_LINE_SET"; + default: return "(unknown " + geo_type + ")"; + } + } + + private void resetVertexAttrs(GL gl, JoglContext ctx, int vertexAttrCount) { + // Disable specified vertex attr arrays + for (int i = 0; i < vertexAttrCount; i++) { + ctx.disableVertexAttrArray(gl, i); + } + } + + + // --------------------------------------------------------------------- + + // + // IndexedGeometryArrayRetained methods + // + + // by-copy or interleaved, by reference, Java arrays + void executeIndexedGeometry(Context ctx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, + boolean useAlpha, + boolean ignoreVertexColors, + int initialIndexIndex, + int indexCount, + int vertexCount, int vformat, + int vertexAttrCount, int[] vertexAttrSizes, + int texCoordSetCount, int[] texCoordSetMap, + int texCoordSetMapLen, + int[] texCoordSetOffset, + int numActiveTexUnitState, + float[] varray, float[] carray, + int cdirty, + int[] indexCoord) { + if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometry()"); + + executeIndexedGeometryArray(ctx, geo, geo_type, + isNonUniformScale, useAlpha, ignoreVertexColors, + initialIndexIndex, indexCount, + vertexCount, vformat, + vertexAttrCount, vertexAttrSizes, + texCoordSetCount, texCoordSetMap, texCoordSetMapLen, + texCoordSetOffset, + numActiveTexUnitState, + varray, null, carray, + cdirty, indexCoord); + } + + // interleaved, by reference, nio buffer + void executeIndexedGeometryBuffer(Context ctx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, + boolean useAlpha, + boolean ignoreVertexColors, + int initialIndexIndex, + int indexCount, + int vertexCount, int vformat, + int texCoordSetCount, int[] texCoordSetMap, + int texCoordSetMapLen, + int[] texCoordSetOffset, + int numActiveTexUnitState, + Object vdata, float[] carray, + int cDirty, + int[] indexCoord) { + if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometryBuffer()"); + + executeIndexedGeometryArray(ctx, geo, geo_type, + isNonUniformScale, useAlpha, ignoreVertexColors, + initialIndexIndex, indexCount, vertexCount, vformat, + 0, null, + texCoordSetCount, texCoordSetMap, texCoordSetMapLen, texCoordSetOffset, + numActiveTexUnitState, + null, (FloatBuffer) vdata, carray, + cDirty, indexCoord); + } + + // non interleaved, by reference, Java arrays + void executeIndexedGeometryVA(Context ctx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, + boolean ignoreVertexColors, + int initialIndexIndex, + int validIndexCount, + int vertexCount, + int vformat, + int vdefined, + float[] vfcoords, double[] vdcoords, + float[] cfdata, byte[] cbdata, + float[] ndata, + int vertexAttrCount, int[] vertexAttrSizes, + float[][] vertexAttrData, + int texCoordMapLength, + int[] texcoordoffset, + int numActiveTexUnitState, + int texStride, Object[] texCoords, + int cdirty, + int[] indexCoord) { + if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometryVA()"); + + boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); + boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); + boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); + boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); + boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); + boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); + boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); + + FloatBuffer fverts = null; + DoubleBuffer dverts = null; + FloatBuffer fclrs = null; + ByteBuffer bclrs = null; + FloatBuffer[] texCoordBufs = null; + FloatBuffer norms = null; + FloatBuffer[] vertexAttrBufs = null; + + // Get vertex attribute arrays + if (vattrDefined) { + vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData); + } + + // get texture arrays + if (textureDefined) { + texCoordBufs = getTexCoordSetBuffer(texCoords); + } + + int[] sarray = null; + int strip_len = 0; + if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { + sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts; + strip_len = sarray.length; + } + + // get coordinate array + if (floatCoordDefined) { + fverts = getVertexArrayBuffer(vfcoords); + } else if (doubleCoordDefined) { + dverts = getVertexArrayBuffer(vdcoords); + } + + // get color array + if (floatColorsDefined) { + fclrs = getColorArrayBuffer(cfdata); + } else if (byteColorsDefined) { + bclrs = getColorArrayBuffer(cbdata); + } + + // get normal array + if (normalsDefined) { + norms = getNormalArrayBuffer(ndata); + } + + executeIndexedGeometryArrayVA(ctx, geo, geo_type, + isNonUniformScale, ignoreVertexColors, + initialIndexIndex, validIndexCount, vertexCount, + vformat, vdefined, + fverts, dverts, + fclrs, bclrs, + norms, + vertexAttrCount, vertexAttrSizes, vertexAttrBufs, + texCoordMapLength, texcoordoffset, + numActiveTexUnitState, + texStride, texCoordBufs, + cdirty, indexCoord, + sarray, strip_len); + } + + // non interleaved, by reference, nio buffer + void executeIndexedGeometryVABuffer(Context ctx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, + boolean ignoreVertexColors, + int initialIndexIndex, + int validIndexCount, + int vertexCount, + int vformat, + int vdefined, + Object vcoords, + Object cdataBuffer, + float[] cfdata, byte[] cbdata, + Object ndata, + int vertexAttrCount, int[] vertexAttrSizes, + Object[] vertexAttrData, + int texCoordMapLength, + int[] texcoordoffset, + int numActiveTexUnitState, + int texStride, Object[] texCoords, + int cdirty, + int[] indexCoord) { + if (VERBOSE) System.err.println("JoglPipeline.executeIndexedGeometryVABuffer()"); + + boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); + boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); + boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); + boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); + boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); + boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); + boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); + + FloatBuffer fverts = null; + DoubleBuffer dverts = null; + FloatBuffer fclrs = null; + ByteBuffer bclrs = null; + FloatBuffer[] texCoordBufs = null; + FloatBuffer norms = null; + FloatBuffer[] vertexAttrBufs = null; + + // Get vertex attribute arrays + if (vattrDefined) { + vertexAttrBufs = getVertexAttrSetBuffer(vertexAttrData); + } + + // get texture arrays + if (textureDefined) { + texCoordBufs = new FloatBuffer[texCoords.length]; + for (int i = 0; i < texCoords.length; i++) { + texCoordBufs[i] = (FloatBuffer) texCoords[i]; + } + } + + // get coordinate array + if (floatCoordDefined) { + fverts = (FloatBuffer) vcoords; + } else if (doubleCoordDefined) { + dverts = (DoubleBuffer) vcoords; + } + + if (fverts == null && dverts == null) { + return; + } + + int[] sarray = null; + int strip_len = 0; + if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { + sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts; + strip_len = sarray.length; + } + + // get color array + if (floatColorsDefined) { + if (cfdata != null) + fclrs = getColorArrayBuffer(cfdata); + else + fclrs = (FloatBuffer) cdataBuffer; + } else if (byteColorsDefined) { + if (cbdata != null) + bclrs = getColorArrayBuffer(cbdata); + else + bclrs = (ByteBuffer) cdataBuffer; + } + + // get normal array + if (normalsDefined) { + norms = (FloatBuffer) ndata; + } + + executeIndexedGeometryArrayVA(ctx, geo, geo_type, + isNonUniformScale, ignoreVertexColors, + initialIndexIndex, validIndexCount, vertexCount, + vformat, vdefined, + fverts, dverts, + fclrs, bclrs, + norms, + vertexAttrCount, vertexAttrSizes, vertexAttrBufs, + texCoordMapLength, texcoordoffset, + numActiveTexUnitState, + texStride, texCoordBufs, + cdirty, indexCoord, + sarray, strip_len); + } + + // by-copy geometry + void buildIndexedGeometry(Context absCtx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, boolean updateAlpha, + float alpha, + boolean ignoreVertexColors, + int initialIndexIndex, + int validIndexCount, + int vertexCount, + int vformat, + int vertexAttrCount, int[] vertexAttrSizes, + int texCoordSetCount, int[] texCoordSetMap, + int texCoordSetMapLen, + int[] texCoordSetMapOffset, + double[] xform, double[] nxform, + float[] varray, int[] indexCoord) { + if (VERBOSE) System.err.println("JoglPipeline.buildIndexedGeometry()"); + + JoglContext ctx = (JoglContext) absCtx; + GL2 gl = context(ctx).getGL().getGL2(); + + boolean useInterleavedArrays; + int iaFormat = 0; + int primType = 0; + int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0; + int texSize = 0, texStride = 0; + int vAttrOff = 0; + int vAttrStride = 0; + int bstride = 0, cbstride = 0; + FloatBuffer verts = null; + FloatBuffer clrs = null; + int[] sarray = null; + int strip_len = 0; + boolean useAlpha = false; + + if ((vformat & GeometryArray.COORDINATES) != 0) { + gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); + stride += 3; + } else { + gl.glDisableClientState(GL2.GL_VERTEX_ARRAY); + } + + if ((vformat & GeometryArray.NORMALS) != 0) { + gl.glEnableClientState(GL2.GL_NORMAL_ARRAY); + stride += 3; + coordoff += 3; + } else { + gl.glDisableClientState(GL2.GL_NORMAL_ARRAY); + } + + if ((vformat & GeometryArray.COLOR) != 0) { + gl.glEnableClientState(GL2.GL_COLOR_ARRAY); + stride += 4; + normoff += 4; + coordoff += 4; + } else { + gl.glDisableClientState(GL2.GL_COLOR_ARRAY); + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { + texSize = 2; + texStride = 2 * texCoordSetCount; + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { + texSize = 3; + texStride = 3 * texCoordSetCount; + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { + texSize = 4; + texStride = 4 * texCoordSetCount; + } + stride += texStride; + normoff += texStride; + coloroff += texStride; + coordoff += texStride; + } + + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + vAttrStride += vertexAttrSizes[i]; + } + stride += vAttrStride; + normoff += vAttrStride; + coloroff += vAttrStride; + coordoff += vAttrStride; + texCoordoff += vAttrStride; + } + + bstride = stride * Buffers.SIZEOF_FLOAT; + + // process alpha for geometryArray without alpha + if (updateAlpha && !ignoreVertexColors) { + useAlpha = true; + } + + if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { + sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts; + strip_len = sarray.length; + } + + // Copy data into NIO array + verts = getVertexArrayBuffer(varray); + + // Apply normal transform if necessary + if ((vformat & GeometryArray.NORMALS) != 0 && nxform != null) { + int off = normoff; + for (int i = 0; i < vertexCount * 3; i+=3) { + verts.put(off , (float) (nxform[0] * varray[off] + + nxform[1] * varray[off+1] + + nxform[2] * varray[off+2])); + verts.put(off+1, (float) (nxform[4] * varray[off] + + nxform[5] * varray[off+1] + + nxform[6] * varray[off+2])); + verts.put(off+2, (float) (nxform[8] * varray[off] + + nxform[9] * varray[off+1] + + nxform[10] * varray[off+2])); + off += stride; + } + } + + // Apply coordinate transform if necessary + if ((vformat & GeometryArray.COORDINATES) != 0 && xform != null) { + int off = coordoff; + for (int i = 0; i < vertexCount * 3; i+=3) { + verts.put(off , (float) (xform[0] * varray[off] + + xform[1] * varray[off+1] + + xform[2] * varray[off+2])); + verts.put(off+1, (float) (xform[4] * varray[off] + + xform[5] * varray[off+1] + + xform[6] * varray[off+2])); + verts.put(off+2, (float) (xform[8] * varray[off] + + xform[9] * varray[off+1] + + xform[10] * varray[off+2])); + off += stride; + } + } + + if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { + // Note we can use interleaved arrays even if we have a + // non-null xform since we use the same data layout unlike the + // C code + if (ignoreVertexColors || + (((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = false; + } else { + boolean[] tmp = new boolean[1]; + int[] tmp2 = new int[1]; + testForInterleavedArrays(vformat, tmp, tmp2); + useInterleavedArrays = tmp[0]; + iaFormat = tmp2[0]; + } + + if (useInterleavedArrays) { + verts.position(0); + gl.glInterleavedArrays(iaFormat, bstride, verts); + } else { + if ((vformat & GeometryArray.NORMALS) != 0) { + verts.position(normoff); + gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); + } + if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) { + verts.position(coloroff); + if (((vformat & GeometryArray.WITH_ALPHA) != 0) || useAlpha) { + gl.glColorPointer(4, GL.GL_FLOAT, bstride, verts); + } else { + gl.glColorPointer(3, GL.GL_FLOAT, bstride, verts); + } + } + if ((vformat & GeometryArray.COORDINATES) != 0) { + verts.position(coordoff); + gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); + } + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + executeTexture(texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetMapOffset, + texCoordSetMapLen, + verts, gl); + } + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + int vAttrOffset = vAttrOff; + for (int i = 0; i < vertexAttrCount; i++) { + ctx.enableVertexAttrArray(gl, i); + verts.position(vAttrOffset); + ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], + GL.GL_FLOAT, bstride, verts); + vAttrOffset += vertexAttrSizes[i]; + } + } + } + + switch (geo_type) { + case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET: + primType = GL.GL_TRIANGLE_STRIP; + break; + case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET: + primType = GL.GL_TRIANGLE_FAN; + break; + case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET: + primType = GL.GL_LINE_STRIP; + break; + } + + lockArray(gl, vertexCount); + + // Note: using MultiDrawElements is probably more expensive than + // not in this case due to the need to allocate more temporary + // direct buffers and slice up the incoming indices array + int offset = initialIndexIndex; + IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord); + for (int i = 0; i < strip_len; i++) { + indicesBuffer.position(offset); + int count = sarray[i]; + gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT, indicesBuffer); + offset += count; + } + } else if ((geo_type == GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET) || + (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_SET) || + (geo_type == GeometryRetained.GEO_TYPE_INDEXED_POINT_SET) || + (geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_SET)) { + // Note we can use interleaved arrays even if we have a + // non-null xform since we use the same data layout unlike the + // C code + if (ignoreVertexColors || + (((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = false; + } else { + boolean[] tmp = new boolean[1]; + int[] tmp2 = new int[1]; + testForInterleavedArrays(vformat, tmp, tmp2); + useInterleavedArrays = tmp[0]; + iaFormat = tmp2[0]; + } + + if (useInterleavedArrays) { + verts.position(0); + gl.glInterleavedArrays(iaFormat, bstride, verts); + } else { + if ((vformat & GeometryArray.NORMALS) != 0) { + verts.position(normoff); + gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); + } + + if (!ignoreVertexColors && ((vformat & GeometryArray.COLOR) != 0)) { + verts.position(coloroff); + if (((vformat & GeometryArray.WITH_ALPHA) != 0) || useAlpha) { + gl.glColorPointer(4, GL.GL_FLOAT, bstride, verts); + } else { + gl.glColorPointer(3, GL.GL_FLOAT, bstride, verts); + } + } + if ((vformat & GeometryArray.COORDINATES) != 0) { + verts.position(coordoff); + gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); + } + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + executeTexture(texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetMapOffset, + texCoordSetMapLen, + verts, gl); + } + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + int vAttrOffset = vAttrOff; + for (int i = 0; i < vertexAttrCount; i++) { + ctx.enableVertexAttrArray(gl, i); + verts.position(vAttrOffset); + ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], + GL.GL_FLOAT, bstride, verts); + vAttrOffset += vertexAttrSizes[i]; + } + } + + switch (geo_type) { + case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET : + primType = GL2.GL_QUADS; + break; + case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET : + primType = GL.GL_TRIANGLES; + break; + case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET : + primType = GL.GL_POINTS; + break; + case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET : + primType = GL.GL_LINES; + break; + } + + lockArray(gl, vertexCount); + + IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord); + indicesBuffer.position(initialIndexIndex); + gl.glDrawElements(primType, validIndexCount, GL.GL_UNSIGNED_INT, indicesBuffer); + } + } + + unlockArray(gl); + + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + resetVertexAttrs(gl, ctx, vertexAttrCount); + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + resetTexture(gl, ctx); + } + } + + + //---------------------------------------------------------------------- + // + // Helper routines for IndexedGeometryArrayRetained + // + + private void executeIndexedGeometryArray(Context absCtx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, + boolean useAlpha, + boolean ignoreVertexColors, + int initialIndexIndex, + int indexCount, + int vertexCount, int vformat, + int vertexAttrCount, int[] vertexAttrSizes, + int texCoordSetCount, int[] texCoordSetMap, + int texCoordSetMapLen, + int[] texCoordSetOffset, + int numActiveTexUnitState, + float[] varray, FloatBuffer vdata, float[] carray, + int cDirty, + int[] indexCoord) { + JoglContext ctx = (JoglContext) absCtx; + GL2 gl = context(ctx).getGL().getGL2(); + + boolean useInterleavedArrays; + int iaFormat = 0; + int primType = 0; + int stride = 0, coordoff = 0, normoff = 0, coloroff = 0, texCoordoff = 0; + int texSize = 0, texStride = 0; + int vAttrOff = 0; + int vAttrStride = 0; + int bstride = 0, cbstride = 0; + FloatBuffer verts = null; + FloatBuffer clrs = null; + int[] sarray = null; + int strip_len = 0; + + if ((vformat & GeometryArray.COORDINATES) != 0) { + stride += 3; + } + if ((vformat & GeometryArray.NORMALS) != 0) { + stride += 3; + coordoff += 3; + } + + if ((vformat & GeometryArray.COLOR) != 0) { + if ((vformat & GeometryArray.WITH_ALPHA) != 0) { + stride += 4; + normoff += 4; + coordoff += 4; + } else { // Handle the case of executeInterleaved 3f + stride += 3; + normoff += 3; + coordoff += 3; + } + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + if ((vformat & GeometryArray.TEXTURE_COORDINATE_2) != 0) { + texSize = 2; + texStride = 2 * texCoordSetCount; + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_3) != 0) { + texSize = 3; + texStride = 3 * texCoordSetCount; + } else if ((vformat & GeometryArray.TEXTURE_COORDINATE_4) != 0) { + texSize = 4; + texStride = 4 * texCoordSetCount; + } + stride += texStride; + normoff += texStride; + coloroff += texStride; + coordoff += texStride; + } + + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + for (int i = 0; i < vertexAttrCount; i++) { + vAttrStride += vertexAttrSizes[i]; + } + stride += vAttrStride; + normoff += vAttrStride; + coloroff += vAttrStride; + coordoff += vAttrStride; + texCoordoff += vAttrStride; + } + + bstride = stride * Buffers.SIZEOF_FLOAT; + + if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { + sarray = ((IndexedGeometryStripArrayRetained) geo).stripIndexCounts; + strip_len = sarray.length; + } + + // We have to copy if the data isn't specified using NIO + if (varray != null) { + verts = getVertexArrayBuffer(varray); + } else if (vdata != null) { + verts = vdata; + } else { + // This should never happen + throw new AssertionError("Unable to get vertex pointer"); + } + + // using byRef interleaved array and has a separate pointer, then .. + int cstride = stride; + if (carray != null) { + clrs = getColorArrayBuffer(carray); + cstride = 4; + } else { + // FIXME: need to "auto-slice" this buffer later + clrs = verts; + } + + cbstride = cstride * Buffers.SIZEOF_FLOAT; + + // Enable normalize for non-uniform scale (which rescale can't handle) + if (isNonUniformScale) { + gl.glEnable(GL2.GL_NORMALIZE); + } + + /*** Handle non-indexed strip GeometryArray first *******/ + if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { + if (ignoreVertexColors || (carray != null) || + ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = false; + } else { + boolean[] tmp = new boolean[1]; + int[] tmp2 = new int[1]; + testForInterleavedArrays(vformat, tmp, tmp2); + useInterleavedArrays = tmp[0]; + iaFormat = tmp2[0]; + } + if (useInterleavedArrays) { + verts.position(0); + gl.glInterleavedArrays(iaFormat, bstride, verts); + } else { + if ((vformat & GeometryArray.NORMALS) != 0) { + verts.position(normoff); + gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); + } + if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) { + if (clrs == verts) { + clrs.position(coloroff); + } + if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) { + gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs); + } else { + gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs); + } + } + if ((vformat & GeometryArray.COORDINATES) != 0) { + verts.position(coordoff); + gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + /* XXXX: texCoordoff == 0 ???*/ + executeTexture(texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetOffset, + numActiveTexUnitState, + verts, gl); + } + + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + int vAttrOffset = vAttrOff; + for (int i = 0; i < vertexAttrCount; i++) { + ctx.enableVertexAttrArray(gl, i); + verts.position(vAttrOffset); + ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], + GL.GL_FLOAT, bstride, verts); + vAttrOffset += vertexAttrSizes[i]; + } + } + } + + switch (geo_type) { + case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET: + primType = GL.GL_TRIANGLE_STRIP; + break; + case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET: + primType = GL.GL_TRIANGLE_FAN; + break; + case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET: + primType = GL.GL_LINE_STRIP; + break; + } + + lockArray(gl, vertexCount); + + // Note: using MultiDrawElements is probably more expensive than + // not in this case due to the need to allocate more temporary + // direct buffers and slice up the incoming indices array + int offset = initialIndexIndex; + IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord); + for (int i = 0; i < strip_len; i++) { + indicesBuffer.position(offset); + int count = sarray[i]; + gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT, indicesBuffer); + offset += count; + } + } else if ((geo_type == GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET) || + (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_SET) || + (geo_type == GeometryRetained.GEO_TYPE_INDEXED_POINT_SET) || + (geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_SET)) { + /******* Handle non-indexed non-striped GeometryArray now *****/ + if (ignoreVertexColors || (carray != null) || + ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0 && ((texCoordSetMapLen > 1) || + (texCoordSetCount > 1)))) { + useInterleavedArrays = false; + } else { + boolean[] tmp = new boolean[1]; + int[] tmp2 = new int[1]; + testForInterleavedArrays(vformat, tmp, tmp2); + useInterleavedArrays = tmp[0]; + iaFormat = tmp2[0]; + } + + if (useInterleavedArrays) { + verts.position(0); + gl.glInterleavedArrays(iaFormat, bstride, verts); + } else { + if ((vformat & GeometryArray.NORMALS) != 0) { + verts.position(normoff); + gl.glNormalPointer(GL.GL_FLOAT, bstride, verts); + } + + if (!ignoreVertexColors && (vformat & GeometryArray.COLOR) != 0) { + if (clrs == verts) { + clrs.position(coloroff); + } + if ((vformat & GeometryArray.WITH_ALPHA) != 0 || useAlpha) { + gl.glColorPointer(4, GL.GL_FLOAT, cbstride, clrs); + } else { + gl.glColorPointer(3, GL.GL_FLOAT, cbstride, clrs); + } + } + if ((vformat & GeometryArray.COORDINATES) != 0) { + verts.position(coordoff); + gl.glVertexPointer(3, GL.GL_FLOAT, bstride, verts); + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + /* XXXX: texCoordoff == 0 ???*/ + executeTexture(texCoordSetMapLen, + texSize, bstride, texCoordoff, + texCoordSetOffset, + numActiveTexUnitState, + verts, gl); + } + + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + int vAttrOffset = vAttrOff; + for (int i = 0; i < vertexAttrCount; i++) { + ctx.enableVertexAttrArray(gl, i); + verts.position(vAttrOffset); + ctx.vertexAttrPointer(gl, i, vertexAttrSizes[i], + GL.GL_FLOAT, bstride, verts); + vAttrOffset += vertexAttrSizes[i]; + } + } + } + + lockArray(gl, vertexCount); + IntBuffer buf = IntBuffer.wrap(indexCoord); + buf.position(initialIndexIndex); + switch (geo_type){ + case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET : gl.glDrawElements(GL2.GL_QUADS, indexCount, GL.GL_UNSIGNED_INT, buf); break; + case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET : gl.glDrawElements(GL.GL_TRIANGLES, indexCount, GL.GL_UNSIGNED_INT, buf); break; + case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET: gl.glDrawElements(GL.GL_POINTS, indexCount, GL.GL_UNSIGNED_INT, buf); break; + case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET : gl.glDrawElements(GL.GL_LINES, indexCount, GL.GL_UNSIGNED_INT, buf); break; + } + } + + unlockArray(gl); + + if ((vformat & GeometryArray.VERTEX_ATTRIBUTES) != 0) { + resetVertexAttrs(gl, ctx, vertexAttrCount); + } + + if ((vformat & GeometryArray.TEXTURE_COORDINATE) != 0) { + resetTexture(gl, ctx); + } + + // clean up if we turned on normalize + if (isNonUniformScale) { + gl.glDisable(GL2.GL_NORMALIZE); + } + } + + + private void executeIndexedGeometryArrayVA(Context absCtx, + GeometryArrayRetained geo, int geo_type, + boolean isNonUniformScale, + boolean ignoreVertexColors, + int initialIndexIndex, + int validIndexCount, + int vertexCount, int vformat, int vdefined, + FloatBuffer fverts, DoubleBuffer dverts, + FloatBuffer fclrs, ByteBuffer bclrs, + FloatBuffer norms, + int vertexAttrCount, int[] vertexAttrSizes, FloatBuffer[] vertexAttrBufs, + int texCoordSetCount, int[] texCoordSetMap, + int numActiveTexUnitState, + int texStride, + FloatBuffer[] texCoords, + int cDirty, int[] indexCoord, int[] sarray, int strip_len) { + JoglContext ctx = (JoglContext) absCtx; + GL2 gl = context(ctx).getGL().getGL2(); + + boolean floatCoordDefined = ((vdefined & GeometryArrayRetained.COORD_FLOAT) != 0); + boolean doubleCoordDefined = ((vdefined & GeometryArrayRetained.COORD_DOUBLE) != 0); + boolean floatColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_FLOAT) != 0); + boolean byteColorsDefined = ((vdefined & GeometryArrayRetained.COLOR_BYTE) != 0); + boolean normalsDefined = ((vdefined & GeometryArrayRetained.NORMAL_FLOAT) != 0); + boolean vattrDefined = ((vdefined & GeometryArrayRetained.VATTR_FLOAT) != 0); + boolean textureDefined = ((vdefined & GeometryArrayRetained.TEXCOORD_FLOAT) != 0); + + // Enable normalize for non-uniform scale (which rescale can't handle) + if (isNonUniformScale) { + gl.glEnable(GL2.GL_NORMALIZE); + } + + // Define the data pointers + if (floatCoordDefined) { + fverts.position(0); + gl.glVertexPointer(3, GL.GL_FLOAT, 0, fverts); + } else if (doubleCoordDefined){ + dverts.position(0); + gl.glVertexPointer(3, GL2.GL_DOUBLE, 0, dverts); + } + if (floatColorsDefined) { + fclrs.position(0); + if ((vformat & GeometryArray.WITH_ALPHA) != 0) { + gl.glColorPointer(4, GL.GL_FLOAT, 0, fclrs); + } else { + gl.glColorPointer(3, GL.GL_FLOAT, 0, fclrs); + } + } else if (byteColorsDefined) { + bclrs.position(0); + if ((vformat & GeometryArray.WITH_ALPHA) != 0) { + gl.glColorPointer(4, GL.GL_UNSIGNED_BYTE, 0, bclrs); + } else { + gl.glColorPointer(3, GL.GL_UNSIGNED_BYTE, 0, bclrs); + } + } + if (normalsDefined) { + norms.position(0); + gl.glNormalPointer(GL.GL_FLOAT, 0, norms); + } + + if (vattrDefined) { + for (int i = 0; i < vertexAttrCount; i++) { + FloatBuffer vertexAttrs = vertexAttrBufs[i]; + int sz = vertexAttrSizes[i]; + ctx.enableVertexAttrArray(gl, i); + vertexAttrs.position(0); + ctx.vertexAttrPointer(gl, i, sz, GL.GL_FLOAT, 0, vertexAttrs); + } + } + + if (textureDefined) { + int texSet = 0; + for (int i = 0; i < numActiveTexUnitState; i++) { + if ((i < texCoordSetCount) && + ((texSet = texCoordSetMap[i]) != -1)) { + FloatBuffer buf = texCoords[texSet]; + buf.position(0); + enableTexCoordPointer(gl, i, texStride, + GL.GL_FLOAT, 0, buf); + } else { + disableTexCoordPointer(gl, i); + } + } + + // Reset client active texture unit to 0 + clientActiveTextureUnit(gl, 0); + } + + lockArray(gl, vertexCount); + + if (geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET || + geo_type == GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET) { + int primType = 0; + switch (geo_type) { + case GeometryRetained.GEO_TYPE_INDEXED_TRI_STRIP_SET: + primType = GL.GL_TRIANGLE_STRIP; + break; + case GeometryRetained.GEO_TYPE_INDEXED_TRI_FAN_SET: + primType = GL.GL_TRIANGLE_FAN; + break; + case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET: + primType = GL.GL_LINE_STRIP; + break; + } + + // Note: using MultiDrawElements is probably more expensive than + // not in this case due to the need to allocate more temporary + // direct buffers and slice up the incoming indices array + int offset = initialIndexIndex; + IntBuffer indicesBuffer = IntBuffer.wrap(indexCoord); + for (int i = 0; i < strip_len; i++) { + indicesBuffer.position(offset); + int count = sarray[i]; + gl.glDrawElements(primType, count, GL.GL_UNSIGNED_INT, indicesBuffer); + offset += count; + } + } else { + IntBuffer buf = IntBuffer.wrap(indexCoord); + buf.position(initialIndexIndex); + switch (geo_type){ + case GeometryRetained.GEO_TYPE_INDEXED_QUAD_SET : gl.glDrawElements(GL2.GL_QUADS, validIndexCount, GL.GL_UNSIGNED_INT, buf); break; + case GeometryRetained.GEO_TYPE_INDEXED_TRI_SET : gl.glDrawElements(GL.GL_TRIANGLES, validIndexCount, GL.GL_UNSIGNED_INT, buf); break; + case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET: gl.glDrawElements(GL.GL_POINTS, validIndexCount, GL.GL_UNSIGNED_INT, buf); break; + case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET : gl.glDrawElements(GL.GL_LINES, validIndexCount, GL.GL_UNSIGNED_INT, buf); break; + } + } + + unlockArray(gl); + + // clean up if we turned on normalize + if (isNonUniformScale) { + gl.glDisable(GL2.GL_NORMALIZE); + } + + if (vattrDefined) { + resetVertexAttrs(gl, ctx, vertexAttrCount); + } + + if (textureDefined) { + resetTexture(gl, ctx); + } + } + + + // --------------------------------------------------------------------- + + // + // GraphicsContext3D methods + // + + // Native method for readRaster + void readRaster(Context ctx, + int type, int xSrcOffset, int ySrcOffset, + int width, int height, int hCanvas, + int imageDataType, + int imageFormat, + Object imageBuffer, + int depthFormat, + Object depthBuffer) { + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, width); + gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1); + int yAdjusted = hCanvas - height - ySrcOffset; + + if ((type & Raster.RASTER_COLOR) != 0) { + int oglFormat = 0; + if(imageDataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) { + + switch (imageFormat) { + case ImageComponentRetained.TYPE_BYTE_BGR: + oglFormat = GL2.GL_BGR; + break; + case ImageComponentRetained.TYPE_BYTE_RGB: + oglFormat = GL.GL_RGB; + break; + case ImageComponentRetained.TYPE_BYTE_ABGR: + if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here! + oglFormat = GL2.GL_ABGR_EXT; + } else { + assert false; + return; + } + break; + case ImageComponentRetained.TYPE_BYTE_RGBA: + // all RGB types are stored as RGBA + oglFormat = GL.GL_RGBA; + break; + case ImageComponentRetained.TYPE_BYTE_LA: + // all LA types are stored as LA8 + oglFormat = GL.GL_LUMINANCE_ALPHA; + break; + case ImageComponentRetained.TYPE_BYTE_GRAY: + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_INT_BGR: + case ImageComponentRetained.TYPE_INT_RGB: + case ImageComponentRetained.TYPE_INT_ARGB: + default: + assert false; + return; + } + + gl.glReadPixels(xSrcOffset, yAdjusted, width, height, + oglFormat, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[]) imageBuffer)); + + + } else if(imageDataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) { + int intType = GL2.GL_UNSIGNED_INT_8_8_8_8; + boolean forceAlphaToOne = false; + + switch (imageFormat) { + /* GL_BGR */ + case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ + oglFormat = GL.GL_RGBA; + intType = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + forceAlphaToOne = true; + break; + case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ + forceAlphaToOne = true; + /* Fall through to next case */ + case ImageComponentRetained.TYPE_INT_ARGB: + oglFormat = GL2.GL_BGRA; + intType = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + break; + /* This method only supports 3 and 4 components formats and INT types. */ + case ImageComponentRetained.TYPE_BYTE_LA: + case ImageComponentRetained.TYPE_BYTE_GRAY: + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_BYTE_BGR: + case ImageComponentRetained.TYPE_BYTE_RGB: + case ImageComponentRetained.TYPE_BYTE_RGBA: + case ImageComponentRetained.TYPE_BYTE_ABGR: + default: + assert false; + return; + } + + /* Force Alpha to 1.0 if needed */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); + } + + gl.glReadPixels(xSrcOffset, yAdjusted, width, height, + oglFormat, intType, IntBuffer.wrap((int[]) imageBuffer)); + + /* Restore Alpha scale and bias */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); + } + + } else { + assert false; + } + } + + if ((type & Raster.RASTER_DEPTH) != 0) { + + if (depthFormat == DepthComponentRetained.DEPTH_COMPONENT_TYPE_INT) { + // yOffset is adjusted for OpenGL - Y upward + gl.glReadPixels(xSrcOffset, yAdjusted, width, height, + GL2.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT, IntBuffer.wrap((int[]) depthBuffer)); + } else { + // DEPTH_COMPONENT_TYPE_FLOAT + // yOffset is adjusted for OpenGL - Y upward + gl.glReadPixels(xSrcOffset, yAdjusted, width, height, + GL2.GL_DEPTH_COMPONENT, GL.GL_FLOAT, FloatBuffer.wrap((float[]) depthBuffer)); + } + } + + } + + // --------------------------------------------------------------------- + + // + // GLSLShaderProgramRetained methods + // + + // ShaderAttributeValue methods + + ShaderError setGLSLUniform1i(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1i()"); + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform1iARB(unbox(uniformLocation), value); + return null; + } + + ShaderError setGLSLUniform1f(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + float value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1f()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform1fARB(unbox(uniformLocation), value); + return null; + } + + ShaderError setGLSLUniform2i(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2i()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform2iARB(unbox(uniformLocation), value[0], value[1]); + return null; + } + + ShaderError setGLSLUniform2f(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + float[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2f()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform2fARB(unbox(uniformLocation), value[0], value[1]); + return null; + } + + ShaderError setGLSLUniform3i(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3i()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform3iARB(unbox(uniformLocation), value[0], value[1], value[2]); + return null; + } + + ShaderError setGLSLUniform3f(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + float[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3f()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform3fARB(unbox(uniformLocation), value[0], value[1], value[2]); + return null; + } + + ShaderError setGLSLUniform4i(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4i()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform4iARB(unbox(uniformLocation), value[0], value[1], value[2], value[3]); + return null; + } + + ShaderError setGLSLUniform4f(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + float[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4f()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform4fARB(unbox(uniformLocation), value[0], value[1], value[2], value[3]); + return null; + } + + ShaderError setGLSLUniformMatrix3f(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + float[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix3f()"); + + // Load attribute + // transpose is true : each matrix is supplied in row major order + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniformMatrix3fvARB(unbox(uniformLocation), 1, true, value, 0); + return null; + } + + ShaderError setGLSLUniformMatrix4f(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + float[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix4f()"); + + // Load attribute + // transpose is true : each matrix is supplied in row major order + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniformMatrix4fvARB(unbox(uniformLocation), 1, true, value, 0); + return null; + } + + // ShaderAttributeArray methods + + ShaderError setGLSLUniform1iArray(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int numElements, + int[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1iArray()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform1ivARB(unbox(uniformLocation), numElements, value, 0); + return null; + } + + ShaderError setGLSLUniform1fArray(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int numElements, + float[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform1fArray()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform1fvARB(unbox(uniformLocation), numElements, value, 0); + return null; + } + + ShaderError setGLSLUniform2iArray(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int numElements, + int[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2iArray()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform2ivARB(unbox(uniformLocation), numElements, value, 0); + return null; + } + + ShaderError setGLSLUniform2fArray(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int numElements, + float[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform2fArray()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform2fvARB(unbox(uniformLocation), numElements, value, 0); + return null; + } + + ShaderError setGLSLUniform3iArray(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int numElements, + int[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3iArray()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform3ivARB(unbox(uniformLocation), numElements, value, 0); + return null; + } + + ShaderError setGLSLUniform3fArray(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int numElements, + float[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform3fArray()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform3fvARB(unbox(uniformLocation), numElements, value, 0); + return null; + } + + ShaderError setGLSLUniform4iArray(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int numElements, + int[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4iArray()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform4ivARB(unbox(uniformLocation), numElements, value, 0); + return null; + } + + ShaderError setGLSLUniform4fArray(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int numElements, + float[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniform4fArray()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniform4fvARB(unbox(uniformLocation), numElements, value, 0); + return null; + } + + ShaderError setGLSLUniformMatrix3fArray(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int numElements, + float[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix3fArray()"); + + // Load attribute + // transpose is true : each matrix is supplied in row major order + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniformMatrix3fvARB(unbox(uniformLocation), numElements, true, value, 0); + return null; + } + + ShaderError setGLSLUniformMatrix4fArray(Context ctx, + ShaderProgramId shaderProgramId, + ShaderAttrLoc uniformLocation, + int numElements, + float[] value) { + if (VERBOSE) System.err.println("JoglPipeline.setGLSLUniformMatrix4fArray()"); + + // Load attribute + // transpose is true : each matrix is supplied in row major order + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUniformMatrix4fvARB(unbox(uniformLocation), numElements, true, value, 0); + return null; + } + + // interfaces for shader compilation, etc. + ShaderError createGLSLShader(Context ctx, int shaderType, ShaderId[] shaderId) { + if (VERBOSE) System.err.println("JoglPipeline.createGLSLShader()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + int shaderHandle = 0; + if (shaderType == Shader.SHADER_TYPE_VERTEX) { + shaderHandle = gl.glCreateShaderObjectARB(GL2.GL_VERTEX_SHADER); + } else if (shaderType == Shader.SHADER_TYPE_FRAGMENT) { + shaderHandle = gl.glCreateShaderObjectARB(GL2.GL_FRAGMENT_SHADER); + } + + if (shaderHandle == 0) { + return new ShaderError(ShaderError.COMPILE_ERROR, + "Unable to create native shader object"); + } + + shaderId[0] = new JoglShaderObject(shaderHandle); + return null; + } + ShaderError destroyGLSLShader(Context ctx, ShaderId shaderId) { + if (VERBOSE) System.err.println("JoglPipeline.destroyGLSLShader()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glDeleteObjectARB(unbox(shaderId)); + return null; + } + ShaderError compileGLSLShader(Context ctx, ShaderId shaderId, String program) { + if (VERBOSE) System.err.println("JoglPipeline.compileGLSLShader()"); + + int id = unbox(shaderId); + if (id == 0) { + throw new AssertionError("shaderId == 0"); + } + + if (program == null) { + throw new AssertionError("shader program string is null"); + } + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glShaderSourceARB(id, 1, new String[] { program }, null, 0); + gl.glCompileShaderARB(id); + int[] status = new int[1]; + gl.glGetObjectParameterivARB(id, GL2.GL_OBJECT_COMPILE_STATUS_ARB, status, 0); + if (status[0] == 0) { + String detailMsg = getInfoLog(gl, id); + ShaderError res = new ShaderError(ShaderError.COMPILE_ERROR, + "GLSL shader compile error"); + res.setDetailMessage(detailMsg); + return res; + } + return null; + } + + ShaderError createGLSLShaderProgram(Context ctx, ShaderProgramId[] shaderProgramId) { + if (VERBOSE) System.err.println("JoglPipeline.createGLSLShaderProgram()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + int shaderProgramHandle = gl.glCreateProgramObjectARB(); + if (shaderProgramHandle == 0) { + return new ShaderError(ShaderError.LINK_ERROR, + "Unable to create native shader program object"); + } + shaderProgramId[0] = new JoglShaderObject(shaderProgramHandle); + return null; + } + ShaderError destroyGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId) { + if (VERBOSE) System.err.println("JoglPipeline.destroyGLSLShaderProgram()"); + GL2 gl = context(ctx).getGL().getGL2(); + gl.glDeleteObjectARB(unbox(shaderProgramId)); + return null; + } + ShaderError linkGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId, + ShaderId[] shaderIds) { + if (VERBOSE) System.err.println("JoglPipeline.linkGLSLShaderProgram()"); + + GL2 gl = context(ctx).getGL().getGL2(); + int id = unbox(shaderProgramId); + for (int i = 0; i < shaderIds.length; i++) { + gl.glAttachObjectARB(id, unbox(shaderIds[i])); + } + gl.glLinkProgramARB(id); + int[] status = new int[1]; + gl.glGetObjectParameterivARB(id, GL2.GL_OBJECT_LINK_STATUS_ARB, status, 0); + if (status[0] == 0) { + String detailMsg = getInfoLog(gl, id); + ShaderError res = new ShaderError(ShaderError.LINK_ERROR, + "GLSL shader program link error"); + res.setDetailMessage(detailMsg); + return res; + } + return null; + } + ShaderError bindGLSLVertexAttrName(Context ctx, ShaderProgramId shaderProgramId, + String attrName, int attrIndex) { + if (VERBOSE) System.err.println("JoglPipeline.bindGLSLVertexAttrName()"); + + JoglContext jctx = (JoglContext) ctx; + GL2 gl = context(ctx).getGL().getGL2(); + gl.glBindAttribLocation(unbox(shaderProgramId), + attrIndex + VirtualUniverse.mc.glslVertexAttrOffset, + attrName); + return null; + } + void lookupGLSLShaderAttrNames(Context ctx, ShaderProgramId shaderProgramId, + int numAttrNames, String[] attrNames, ShaderAttrLoc[] locArr, + int[] typeArr, int[] sizeArr, boolean[] isArrayArr) { + if (VERBOSE) System.err.println("JoglPipeline.lookupGLSLShaderAttrNames()"); + + // set the loc, type, and size arrays to out-of-bound values + for (int i = 0; i < attrNames.length; i++) { + locArr[i] = null; + typeArr[i] = -1; + sizeArr[i] = -1; + } + + // Loop through the list of active uniform variables, one at a + // time, searching for a match in the attrNames array. + // + // NOTE: Since attrNames isn't sorted, and we don't have a + // hashtable of names to index locations, we will do a + // brute-force, linear search of the array. This leads to an + // O(n^2) algorithm (actually O(n*m) where n is attrNames.length + // and m is the number of uniform variables), but since we expect + // N to be small, we will not optimize this at this time. + int id = unbox(shaderProgramId); + int[] tmp = new int[1]; + int[] tmp2 = new int[1]; + int[] tmp3 = new int[1]; + GL2 gl = context(ctx).getGL().getGL2(); + gl.glGetObjectParameterivARB(id, + GL2.GL_OBJECT_ACTIVE_UNIFORMS_ARB, + tmp, 0); + int numActiveUniforms = tmp[0]; + gl.glGetObjectParameterivARB(id, + GL2.GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, + tmp, 0); + int maxStrLen = tmp[0]; + byte[] nameBuf = new byte[maxStrLen]; + + for (int i = 0; i < numActiveUniforms; i++) { + gl.glGetActiveUniformARB(id, i, maxStrLen, tmp3, 0, + tmp, 0, + tmp2, 0, + nameBuf, 0); + int size = tmp[0]; + int type = tmp2[0]; + String name = null; + try { + // TODO KCR : Shouldn't this use the default locale? + name = new String(nameBuf, 0, tmp3[0], "US-ASCII"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + + // Issue 247 - we need to workaround an ATI bug where they erroneously + // report individual elements of arrays rather than the array itself + if (name.length() >= 3 && name.endsWith("]")) { + if (name.endsWith("[0]")) { + name = name.substring(0, name.length() - 3); + } else { + // Ignore this name + continue; + } + } + + // Now try to find the name + for (int j = 0; j < numAttrNames; j++) { + if (name.equals(attrNames[j])) { + sizeArr[j] = size; + isArrayArr[j] = (size > 1); + typeArr[j] = glslToJ3dType(type); + break; + } + } + } + + // Now lookup the location of each name in the attrNames array + for (int i = 0; i < numAttrNames; i++) { + // Get uniform attribute location + int loc = gl.glGetUniformLocationARB(id, attrNames[i]); + locArr[i] = new JoglShaderObject(loc); + } + } + + ShaderError useGLSLShaderProgram(Context ctx, ShaderProgramId shaderProgramId) { + if (VERBOSE) System.err.println("JoglPipeline.useGLSLShaderProgram()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glUseProgramObjectARB(unbox(shaderProgramId)); + ((JoglContext) ctx).setShaderProgram((JoglShaderObject) shaderProgramId); + return null; + } + + //---------------------------------------------------------------------- + // Helper methods for above shader routines + // + private int unbox(ShaderAttrLoc loc) { + if (loc == null) + return 0; + return ((JoglShaderObject) loc).getValue(); + } + + private int unbox(ShaderProgramId id) { + if (id == null) + return 0; + return ((JoglShaderObject) id).getValue(); + } + + private int unbox(ShaderId id) { + if (id == null) + return 0; + return ((JoglShaderObject) id).getValue(); + } + + private String getInfoLog(GL2 gl, int id) { + int[] infoLogLength = new int[1]; + gl.glGetObjectParameterivARB(id, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, infoLogLength, 0); + if (infoLogLength[0] > 0) { + byte[] storage = new byte[infoLogLength[0]]; + int[] len = new int[1]; + gl.glGetInfoLogARB(id, infoLogLength[0], len, 0, storage, 0); + try { + // TODO KCR : Shouldn't this use the default locale? + return new String(storage, 0, len[0], "US-ASCII"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + return null; + } + + private int glslToJ3dType(int type) { + switch (type) { + case GL2.GL_BOOL_ARB: + case GL2.GL_INT: + case GL2.GL_SAMPLER_2D_ARB: + case GL2.GL_SAMPLER_3D_ARB: + case GL2.GL_SAMPLER_CUBE_ARB: + return ShaderAttributeObjectRetained.TYPE_INTEGER; + + case GL.GL_FLOAT: + return ShaderAttributeObjectRetained.TYPE_FLOAT; + + case GL2.GL_INT_VEC2_ARB: + case GL2.GL_BOOL_VEC2_ARB: + return ShaderAttributeObjectRetained.TYPE_TUPLE2I; + + case GL2.GL_FLOAT_VEC2_ARB: + return ShaderAttributeObjectRetained.TYPE_TUPLE2F; + + case GL2.GL_INT_VEC3_ARB: + case GL2.GL_BOOL_VEC3_ARB: + return ShaderAttributeObjectRetained.TYPE_TUPLE3I; + + case GL2.GL_FLOAT_VEC3_ARB: + return ShaderAttributeObjectRetained.TYPE_TUPLE3F; + + case GL2.GL_INT_VEC4_ARB: + case GL2.GL_BOOL_VEC4_ARB: + return ShaderAttributeObjectRetained.TYPE_TUPLE4I; + + case GL2.GL_FLOAT_VEC4_ARB: + return ShaderAttributeObjectRetained.TYPE_TUPLE4F; + + // case GL.GL_FLOAT_MAT2_ARB: + + case GL2.GL_FLOAT_MAT3_ARB: + return ShaderAttributeObjectRetained.TYPE_MATRIX3F; + + case GL2.GL_FLOAT_MAT4_ARB: + return ShaderAttributeObjectRetained.TYPE_MATRIX4F; + + // Java 3D does not support the following sampler types: + // + // case GL.GL_SAMPLER_1D_ARB: + // case GL.GL_SAMPLER_1D_SHADOW_ARB: + // case GL.GL_SAMPLER_2D_SHADOW_ARB: + // case GL.GL_SAMPLER_2D_RECT_ARB: + // case GL.GL_SAMPLER_2D_RECT_SHADOW_ARB: + } + + return -1; + } + + // --------------------------------------------------------------------- + + // + // Renderer methods + // + + void cleanupRenderer() { + // Nothing to do + } + + + // --------------------------------------------------------------------- + + // + // ColoringAttributesRetained methods + // + + void updateColoringAttributes(Context ctx, + float dRed, float dGreen, float dBlue, + float red, float green, float blue, + float alpha, + boolean lightEnable, + int shadeModel) { + if (VERBOSE) System.err.println("JoglPipeline.updateColoringAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + float cr, cg, cb; + + if (lightEnable) { + cr = dRed; cg = dGreen; cb = dBlue; + } else { + cr = red; cg = green; cb = blue; + } + gl.glColor4f(cr, cg, cb, alpha); + if (shadeModel == ColoringAttributes.SHADE_FLAT) { + gl.glShadeModel(GL2.GL_FLAT); + } else { + gl.glShadeModel(GL2.GL_SMOOTH); + } + } + + + // --------------------------------------------------------------------- + + // + // DirectionalLightRetained methods + // + + private static final float[] black = new float[4]; + void updateDirectionalLight(Context ctx, + int lightSlot, float red, float green, + float blue, float dirx, float diry, float dirz) { + if (VERBOSE) System.err.println("JoglPipeline.updateDirectionalLight()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + int lightNum = GL2.GL_LIGHT0 + lightSlot; + float[] values = new float[4]; + + values[0] = red; + values[1] = green; + values[2] = blue; + values[3] = 1.0f; + gl.glLightfv(lightNum, GL2.GL_DIFFUSE, values, 0); + gl.glLightfv(lightNum, GL2.GL_SPECULAR, values, 0); + values[0] = -dirx; + values[1] = -diry; + values[2] = -dirz; + values[3] = 0.0f; + gl.glLightfv(lightNum, GL2.GL_POSITION, values, 0); + gl.glLightfv(lightNum, GL2.GL_AMBIENT, black, 0); + gl.glLightf(lightNum, GL2.GL_CONSTANT_ATTENUATION, 1.0f); + gl.glLightf(lightNum, GL2.GL_LINEAR_ATTENUATION, 0.0f); + gl.glLightf(lightNum, GL2.GL_QUADRATIC_ATTENUATION, 0.0f); + gl.glLightf(lightNum, GL2.GL_SPOT_EXPONENT, 0.0f); + gl.glLightf(lightNum, GL2.GL_SPOT_CUTOFF, 180.0f); + } + + + // --------------------------------------------------------------------- + + // + // PointLightRetained methods + // + + void updatePointLight(Context ctx, + int lightSlot, float red, float green, + float blue, float attenx, float atteny, float attenz, + float posx, float posy, float posz) { + if (VERBOSE) System.err.println("JoglPipeline.updatePointLight()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + int lightNum = GL2.GL_LIGHT0 + lightSlot; + float[] values = new float[4]; + + values[0] = red; + values[1] = green; + values[2] = blue; + values[3] = 1.0f; + gl.glLightfv(lightNum, GL2.GL_DIFFUSE, values, 0); + gl.glLightfv(lightNum, GL2.GL_SPECULAR, values, 0); + gl.glLightfv(lightNum, GL2.GL_AMBIENT, black, 0); + values[0] = posx; + values[1] = posy; + values[2] = posz; + gl.glLightfv(lightNum, GL2.GL_POSITION, values, 0); + gl.glLightf(lightNum, GL2.GL_CONSTANT_ATTENUATION, attenx); + gl.glLightf(lightNum, GL2.GL_LINEAR_ATTENUATION, atteny); + gl.glLightf(lightNum, GL2.GL_QUADRATIC_ATTENUATION, attenz); + gl.glLightf(lightNum, GL2.GL_SPOT_EXPONENT, 0.0f); + gl.glLightf(lightNum, GL2.GL_SPOT_CUTOFF, 180.0f); + } + + + // --------------------------------------------------------------------- + + // + // SpotLightRetained methods + // + + void updateSpotLight(Context ctx, + int lightSlot, float red, float green, + float blue, float attenx, float atteny, float attenz, + float posx, float posy, float posz, float spreadAngle, + float concentration, float dirx, float diry, + float dirz) { + if (VERBOSE) System.err.println("JoglPipeline.updateSpotLight()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + int lightNum = GL2.GL_LIGHT0 + lightSlot; + float[] values = new float[4]; + + values[0] = red; + values[1] = green; + values[2] = blue; + values[3] = 1.0f; + gl.glLightfv(lightNum, GL2.GL_DIFFUSE, values, 0); + gl.glLightfv(lightNum, GL2.GL_SPECULAR, values, 0); + gl.glLightfv(lightNum, GL2.GL_AMBIENT, black, 0); + values[0] = posx; + values[1] = posy; + values[2] = posz; + gl.glLightfv(lightNum, GL2.GL_POSITION, values, 0); + gl.glLightf(lightNum, GL2.GL_CONSTANT_ATTENUATION, attenx); + gl.glLightf(lightNum, GL2.GL_LINEAR_ATTENUATION, atteny); + gl.glLightf(lightNum, GL2.GL_QUADRATIC_ATTENUATION, attenz); + values[0] = dirx; + values[1] = diry; + values[2] = dirz; + gl.glLightfv(lightNum, GL2.GL_SPOT_DIRECTION, values, 0); + gl.glLightf(lightNum, GL2.GL_SPOT_EXPONENT, concentration); + gl.glLightf(lightNum, GL2.GL_SPOT_CUTOFF, (float) (spreadAngle * 180.0f / Math.PI)); + } + + + // --------------------------------------------------------------------- + + // + // ExponentialFogRetained methods + // + + void updateExponentialFog(Context ctx, + float red, float green, float blue, + float density) { + if (VERBOSE) System.err.println("JoglPipeline.updateExponentialFog()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + float[] color = new float[3]; + color[0] = red; + color[1] = green; + color[2] = blue; + gl.glFogi(GL2.GL_FOG_MODE, GL2.GL_EXP); + gl.glFogfv(GL2.GL_FOG_COLOR, color, 0); + gl.glFogf(GL2.GL_FOG_DENSITY, density); + gl.glEnable(GL2.GL_FOG); + } + + + // --------------------------------------------------------------------- + + // + // LinearFogRetained methods + // + + void updateLinearFog(Context ctx, + float red, float green, float blue, + double fdist, double bdist) { + if (VERBOSE) System.err.println("JoglPipeline.updateLinearFog()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + float[] color = new float[3]; + color[0] = red; + color[1] = green; + color[2] = blue; + gl.glFogi(GL2.GL_FOG_MODE, GL.GL_LINEAR); + gl.glFogfv(GL2.GL_FOG_COLOR, color, 0); + gl.glFogf(GL2.GL_FOG_START, (float) fdist); + gl.glFogf(GL2.GL_FOG_END, (float) bdist); + gl.glEnable(GL2.GL_FOG); + } + + + // --------------------------------------------------------------------- + + // + // LineAttributesRetained methods + // + + void updateLineAttributes(Context ctx, + float lineWidth, int linePattern, + int linePatternMask, + int linePatternScaleFactor, + boolean lineAntialiasing) { + if (VERBOSE) System.err.println("JoglPipeline.updateLineAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glLineWidth(lineWidth); + + if (linePattern == LineAttributes.PATTERN_SOLID) { + gl.glDisable(GL2.GL_LINE_STIPPLE); + } else { + if (linePattern == LineAttributes.PATTERN_DASH) { // dashed lines + gl.glLineStipple(1, (short) 0x00ff); + } else if (linePattern == LineAttributes.PATTERN_DOT) { // dotted lines + gl.glLineStipple(1, (short) 0x0101); + } else if (linePattern == LineAttributes.PATTERN_DASH_DOT) { // dash-dotted lines + gl.glLineStipple(1, (short) 0x087f); + } else if (linePattern == LineAttributes.PATTERN_USER_DEFINED) { // user-defined mask + gl.glLineStipple(linePatternScaleFactor, (short) linePatternMask); + } + gl.glEnable(GL2.GL_LINE_STIPPLE); + } + + /* XXXX: Polygon Mode check, blend enable */ + if (lineAntialiasing) { + gl.glEnable(GL.GL_LINE_SMOOTH); + } else { + gl.glDisable(GL.GL_LINE_SMOOTH); + } + } + + + // --------------------------------------------------------------------- + + // + // MaterialRetained methods + // + + void updateMaterial(Context ctx, + float red, float green, float blue, float alpha, + float aRed, float aGreen, float aBlue, + float eRed, float eGreen, float eBlue, + float dRed, float dGreen, float dBlue, + float sRed, float sGreen, float sBlue, + float shininess, int colorTarget, boolean lightEnable) { + if (VERBOSE) System.err.println("JoglPipeline.updateMaterial()"); + + float[] color = new float[4]; + + GL2 gl = context(ctx).getGL().getGL2(); + + gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL2.GL_SHININESS, shininess); + switch (colorTarget) { + case Material.DIFFUSE: + gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE); + break; + case Material.AMBIENT: + gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT); + break; + case Material.EMISSIVE: + gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_EMISSION); + break; + case Material.SPECULAR: + gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_SPECULAR); + break; + case Material.AMBIENT_AND_DIFFUSE: + gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT_AND_DIFFUSE); + break; + } + + color[0] = eRed; color[1] = eGreen; color[2] = eBlue; + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_EMISSION, color, 0); + + color[0] = aRed; color[1] = aGreen; color[2] = aBlue; + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_AMBIENT, color, 0); + + color[0] = sRed; color[1] = sGreen; color[2] = sBlue; + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, color, 0); + + float cr, cg, cb; + + if (lightEnable) { + color[0] = dRed; color[1] = dGreen; color[2] = dBlue; + } else { + color[0] = red; color[1] = green; color[2] = blue; + } + color[3] = alpha; + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE, color, 0); + gl.glColor4f(color[0], color[1], color[2], color[3]); + + if (lightEnable) { + gl.glEnable(GL2.GL_LIGHTING); + } else { + gl.glDisable(GL2.GL_LIGHTING); + } + } + + + // --------------------------------------------------------------------- + + // + // ModelClipRetained methods + // + + void updateModelClip(Context ctx, int planeNum, boolean enableFlag, + double A, double B, double C, double D) { + if (VERBOSE) System.err.println("JoglPipeline.updateModelClip()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + double[] equation = new double[4]; + int pl = GL2.GL_CLIP_PLANE0 + planeNum; + + // OpenGL clip planes are opposite to J3d clip planes + if (enableFlag) { + equation[0] = -A; + equation[1] = -B; + equation[2] = -C; + equation[3] = -D; + gl.glClipPlane(pl, DoubleBuffer.wrap(equation)); + gl.glEnable(pl); + } else { + gl.glDisable(pl); + } + } + + + // --------------------------------------------------------------------- + + // + // PointAttributesRetained methods + // + + void updatePointAttributes(Context ctx, float pointSize, boolean pointAntialiasing) { + if (VERBOSE) System.err.println("JoglPipeline.updatePointAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glPointSize(pointSize); + + // XXXX: Polygon Mode check, blend enable + if (pointAntialiasing) { + gl.glEnable(GL2.GL_POINT_SMOOTH); + } else { + gl.glDisable(GL2.GL_POINT_SMOOTH); + } + } + + + // --------------------------------------------------------------------- + + // + // PolygonAttributesRetained methods + // + + void updatePolygonAttributes(Context ctx, + int polygonMode, int cullFace, + boolean backFaceNormalFlip, + float polygonOffset, + float polygonOffsetFactor) { + if (VERBOSE) System.err.println("JoglPipeline.updatePolygonAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + if (cullFace == PolygonAttributes.CULL_NONE) { + gl.glDisable(GL.GL_CULL_FACE); + } else { + if (cullFace == PolygonAttributes.CULL_BACK) { + gl.glCullFace(GL.GL_BACK); + } else { + gl.glCullFace(GL.GL_FRONT); + } + gl.glEnable(GL.GL_CULL_FACE); + } + + if (backFaceNormalFlip && (cullFace != PolygonAttributes.CULL_BACK)) { + gl.glLightModeli(GL2.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_TRUE); + } else { + gl.glLightModeli(GL2.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_FALSE); + } + + if (polygonMode == PolygonAttributes.POLYGON_POINT) { + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_POINT); + } else if (polygonMode == PolygonAttributes.POLYGON_LINE) { + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_LINE); + } else { + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL); + } + + gl.glPolygonOffset(polygonOffsetFactor, polygonOffset); + + if ((polygonOffsetFactor != 0.0) || (polygonOffset != 0.0)) { + switch (polygonMode) { + case PolygonAttributes.POLYGON_POINT: + gl.glEnable(GL2.GL_POLYGON_OFFSET_POINT); + gl.glDisable(GL2.GL_POLYGON_OFFSET_LINE); + gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); + break; + case PolygonAttributes.POLYGON_LINE: + gl.glEnable(GL2.GL_POLYGON_OFFSET_LINE); + gl.glDisable(GL2.GL_POLYGON_OFFSET_POINT); + gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); + break; + case PolygonAttributes.POLYGON_FILL: + gl.glEnable(GL.GL_POLYGON_OFFSET_FILL); + gl.glDisable(GL2.GL_POLYGON_OFFSET_POINT); + gl.glDisable(GL2.GL_POLYGON_OFFSET_LINE); + break; + } + } else { + gl.glDisable(GL2.GL_POLYGON_OFFSET_POINT); + gl.glDisable(GL2.GL_POLYGON_OFFSET_LINE); + gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); + } + } + + + // --------------------------------------------------------------------- + + // + // RenderingAttributesRetained methods + // + + void updateRenderingAttributes(Context ctx, + boolean depthBufferWriteEnableOverride, + boolean depthBufferEnableOverride, + boolean depthBufferEnable, + boolean depthBufferWriteEnable, + int depthTestFunction, + float alphaTestValue, int alphaTestFunction, + boolean ignoreVertexColors, + boolean rasterOpEnable, int rasterOp, + boolean userStencilAvailable, boolean stencilEnable, + int stencilFailOp, int stencilZFailOp, int stencilZPassOp, + int stencilFunction, int stencilReferenceValue, + int stencilCompareMask, int stencilWriteMask ) { + if (VERBOSE) System.err.println("JoglPipeline.updateRenderingAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + if (!depthBufferEnableOverride) { + if (depthBufferEnable) { + gl.glEnable(GL.GL_DEPTH_TEST); + gl.glDepthFunc(getFunctionValue(depthTestFunction)); + } else { + gl.glDisable(GL.GL_DEPTH_TEST); + } + } + + if (!depthBufferWriteEnableOverride) { + if (depthBufferWriteEnable) { + gl.glDepthMask(true); + } else { + gl.glDepthMask(false); + } + } + + if (alphaTestFunction == RenderingAttributes.ALWAYS) { + gl.glDisable(GL2.GL_ALPHA_TEST); + } else { + gl.glEnable(GL2.GL_ALPHA_TEST); + gl.glAlphaFunc(getFunctionValue(alphaTestFunction), alphaTestValue); + } + + if (ignoreVertexColors) { + gl.glDisable(GL2.GL_COLOR_MATERIAL); + } else { + gl.glEnable(GL2.GL_COLOR_MATERIAL); + } + + if (rasterOpEnable) { + gl.glEnable(GL.GL_COLOR_LOGIC_OP); + switch (rasterOp) { + case RenderingAttributes.ROP_CLEAR: + gl.glLogicOp(GL.GL_CLEAR); + break; + case RenderingAttributes.ROP_AND: + gl.glLogicOp(GL.GL_AND); + break; + case RenderingAttributes.ROP_AND_REVERSE: + gl.glLogicOp(GL.GL_AND_REVERSE); + break; + case RenderingAttributes.ROP_COPY: + gl.glLogicOp(GL.GL_COPY); + break; + case RenderingAttributes.ROP_AND_INVERTED: + gl.glLogicOp(GL.GL_AND_INVERTED); + break; + case RenderingAttributes.ROP_NOOP: + gl.glLogicOp(GL.GL_NOOP); + break; + case RenderingAttributes.ROP_XOR: + gl.glLogicOp(GL.GL_XOR); + break; + case RenderingAttributes.ROP_OR: + gl.glLogicOp(GL.GL_OR); + break; + case RenderingAttributes.ROP_NOR: + gl.glLogicOp(GL.GL_NOR); + break; + case RenderingAttributes.ROP_EQUIV: + gl.glLogicOp(GL.GL_EQUIV); + break; + case RenderingAttributes.ROP_INVERT: + gl.glLogicOp(GL.GL_INVERT); + break; + case RenderingAttributes.ROP_OR_REVERSE: + gl.glLogicOp(GL.GL_OR_REVERSE); + break; + case RenderingAttributes.ROP_COPY_INVERTED: + gl.glLogicOp(GL.GL_COPY_INVERTED); + break; + case RenderingAttributes.ROP_OR_INVERTED: + gl.glLogicOp(GL.GL_OR_INVERTED); + break; + case RenderingAttributes.ROP_NAND: + gl.glLogicOp(GL.GL_NAND); + break; + case RenderingAttributes.ROP_SET: + gl.glLogicOp(GL.GL_SET); + break; + } + } else { + gl.glDisable(GL.GL_COLOR_LOGIC_OP); + } + + if (userStencilAvailable) { + if (stencilEnable) { + gl.glEnable(GL.GL_STENCIL_TEST); + + gl.glStencilOp(getStencilOpValue(stencilFailOp), + getStencilOpValue(stencilZFailOp), + getStencilOpValue(stencilZPassOp)); + + gl.glStencilFunc(getFunctionValue(stencilFunction), + stencilReferenceValue, stencilCompareMask); + + gl.glStencilMask(stencilWriteMask); + + } else { + gl.glDisable(GL.GL_STENCIL_TEST); + } + } + } + + private int getFunctionValue(int func) { + switch (func) { + case RenderingAttributes.ALWAYS: + func = GL.GL_ALWAYS; + break; + case RenderingAttributes.NEVER: + func = GL.GL_NEVER; + break; + case RenderingAttributes.EQUAL: + func = GL.GL_EQUAL; + break; + case RenderingAttributes.NOT_EQUAL: + func = GL.GL_NOTEQUAL; + break; + case RenderingAttributes.LESS: + func = GL.GL_LESS; + break; + case RenderingAttributes.LESS_OR_EQUAL: + func = GL.GL_LEQUAL; + break; + case RenderingAttributes.GREATER: + func = GL.GL_GREATER; + break; + case RenderingAttributes.GREATER_OR_EQUAL: + func = GL.GL_GEQUAL; + break; + } + + return func; + } + + private int getStencilOpValue(int op) { + switch (op) { + case RenderingAttributes.STENCIL_KEEP: + op = GL.GL_KEEP; + break; + case RenderingAttributes.STENCIL_ZERO: + op = GL.GL_ZERO; + break; + case RenderingAttributes.STENCIL_REPLACE: + op = GL.GL_REPLACE; + break; + case RenderingAttributes.STENCIL_INCR: + op = GL.GL_INCR; + break; + case RenderingAttributes.STENCIL_DECR: + op = GL.GL_DECR; + break; + case RenderingAttributes.STENCIL_INVERT: + op = GL.GL_INVERT; + break; + } + + return op; + } + + + // --------------------------------------------------------------------- + + // + // TexCoordGenerationRetained methods + // + + /** + * This method updates the native context: + * trans contains eyeTovworld transform in d3d + * trans contains vworldToEye transform in ogl + */ + void updateTexCoordGeneration(Context ctx, + boolean enable, int genMode, int format, + float planeSx, float planeSy, float planeSz, float planeSw, + float planeTx, float planeTy, float planeTz, float planeTw, + float planeRx, float planeRy, float planeRz, float planeRw, + float planeQx, float planeQy, float planeQz, float planeQw, + double[] vworldToEc) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexCoordGeneration()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + float[] planeS = new float[4]; + float[] planeT = new float[4]; + float[] planeR = new float[4]; + float[] planeQ = new float[4]; + + if (enable) { + gl.glEnable(GL2.GL_TEXTURE_GEN_S); + gl.glEnable(GL2.GL_TEXTURE_GEN_T); + if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { + gl.glEnable(GL2.GL_TEXTURE_GEN_R); + gl.glDisable(GL2.GL_TEXTURE_GEN_Q); + } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { + gl.glEnable(GL2.GL_TEXTURE_GEN_R); + gl.glEnable(GL2.GL_TEXTURE_GEN_Q); + } else { + gl.glDisable(GL2.GL_TEXTURE_GEN_R); + gl.glDisable(GL2.GL_TEXTURE_GEN_Q); + } + + if (genMode != TexCoordGeneration.SPHERE_MAP) { + planeS[0] = planeSx; planeS[1] = planeSy; + planeS[2] = planeSz; planeS[3] = planeSw; + planeT[0] = planeTx; planeT[1] = planeTy; + planeT[2] = planeTz; planeT[3] = planeTw; + if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { + planeR[0] = planeRx; planeR[1] = planeRy; + planeR[2] = planeRz; planeR[3] = planeRw; + } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { + planeR[0] = planeRx; planeR[1] = planeRy; + planeR[2] = planeRz; planeR[3] = planeRw; + planeQ[0] = planeQx; planeQ[1] = planeQy; + planeQ[2] = planeQz; planeQ[3] = planeQw; + } + } + + switch (genMode) { + case TexCoordGeneration.OBJECT_LINEAR: + gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_OBJECT_LINEAR); + gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_OBJECT_LINEAR); + gl.glTexGenfv(GL2.GL_S, GL2.GL_OBJECT_PLANE, planeS, 0); + gl.glTexGenfv(GL2.GL_T, GL2.GL_OBJECT_PLANE, planeT, 0); + + if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { + gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_OBJECT_LINEAR); + gl.glTexGenfv(GL2.GL_R, GL2.GL_OBJECT_PLANE, planeR, 0); + } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { + gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_OBJECT_LINEAR); + gl.glTexGenfv(GL2.GL_R, GL2.GL_OBJECT_PLANE, planeR, 0); + gl.glTexGeni(GL2.GL_Q, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_OBJECT_LINEAR); + gl.glTexGenfv(GL2.GL_Q, GL2.GL_OBJECT_PLANE, planeQ, 0); + } + break; + case TexCoordGeneration.EYE_LINEAR: + + gl.glMatrixMode(GL2.GL_MODELVIEW); + gl.glPushMatrix(); + + if (gl.isExtensionAvailable("GL_VERSION_1_3")) { + gl.glLoadTransposeMatrixd(vworldToEc, 0); + } else { + double[] v = new double[16]; + copyTranspose(vworldToEc, v); + gl.glLoadMatrixd(v, 0); + } + + gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_EYE_LINEAR); + gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_EYE_LINEAR); + gl.glTexGenfv(GL2.GL_S, GL2.GL_EYE_PLANE, planeS, 0); + gl.glTexGenfv(GL2.GL_T, GL2.GL_EYE_PLANE, planeT, 0); + + if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { + gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_EYE_LINEAR); + gl.glTexGenfv(GL2.GL_R, GL2.GL_EYE_PLANE, planeR, 0); + } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { + gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_EYE_LINEAR); + gl.glTexGenfv(GL2.GL_R, GL2.GL_EYE_PLANE, planeR, 0); + gl.glTexGeni(GL2.GL_Q, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_EYE_LINEAR); + gl.glTexGenfv(GL2.GL_Q, GL2.GL_EYE_PLANE, planeQ, 0); + } + gl.glPopMatrix(); + break; + case TexCoordGeneration.SPHERE_MAP: + gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); + gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); + if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { + gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); + } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { + gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); + gl.glTexGeni(GL2.GL_Q, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_SPHERE_MAP); + } + + break; + case TexCoordGeneration.NORMAL_MAP: + gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP); + gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP); + if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { + gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP); + } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { + gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP); + gl.glTexGeni(GL2.GL_Q, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP); + } + break; + case TexCoordGeneration.REFLECTION_MAP: + gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_REFLECTION_MAP); + gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_REFLECTION_MAP); + if (format == TexCoordGeneration.TEXTURE_COORDINATE_3) { + gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_REFLECTION_MAP); + } else if (format == TexCoordGeneration.TEXTURE_COORDINATE_4) { + gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_REFLECTION_MAP); + gl.glTexGeni(GL2.GL_Q, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_REFLECTION_MAP); + } + break; + } + } else { + gl.glDisable(GL2.GL_TEXTURE_GEN_S); + gl.glDisable(GL2.GL_TEXTURE_GEN_T); + gl.glDisable(GL2.GL_TEXTURE_GEN_R); + gl.glDisable(GL2.GL_TEXTURE_GEN_Q); + } + } + + + // --------------------------------------------------------------------- + + // + // TransparencyAttributesRetained methods + // + + private static final int screen_door[][] = { + /* 0 / 16 */ + { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + }, + /* 1 / 16 */ + { + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + 0x00000000, 0x22222222, 0x00000000, 0x00000000, + }, + /* 2 / 16 */ + { + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + 0x00000000, 0x22222222, 0x00000000, 0x88888888, + }, + /* 3 / 16 */ + { + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0x88888888, + }, + /* 4 / 16 */ + { + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x00000000, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + }, + /* 5 / 16 */ + { + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, + }, + /* 6 / 16 */ + { + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x11111111, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + }, + /* 7 / 16 */ + { + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x44444444, 0xaaaaaaaa, + }, + /* 8 / 16 */ + { + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + }, + /* 9 / 16 */ + { + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, + }, + /* 10 / 16 */ + { + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0x77777777, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + }, + /* 11 / 16 */ + { + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xdddddddd, 0xaaaaaaaa, + }, + /* 12 / 16 */ + { + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xaaaaaaaa, 0xffffffff, 0xaaaaaaaa, + }, + /* 13 / 16 */ + { + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xaaaaaaaa, + }, + /* 14 / 16 */ + { + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xbbbbbbbb, 0xffffffff, 0xeeeeeeee, + }, + /* 15 / 16 */ + { + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xeeeeeeee, + }, + /* 16 / 16 */ + { + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + }, + }; + private static final ByteBuffer[] screen_door_table = new ByteBuffer[screen_door.length]; + static { + int eachLen = screen_door[0].length * Buffers.SIZEOF_INT; + ByteBuffer buf = Buffers.newDirectByteBuffer(screen_door.length * eachLen); + IntBuffer intBuf = buf.asIntBuffer(); + for (int i = 0; i < screen_door.length; i++) { + intBuf.put(screen_door[i]); + } + buf.rewind(); + for (int i = 0; i < screen_door.length; i++) { + buf.position(i * eachLen); + buf.limit((i+1) * eachLen); + screen_door_table[i] = buf.slice(); + } + } + + private static final int[] blendFunctionTable = new int[TransparencyAttributes.MAX_BLEND_FUNC_TABLE_SIZE]; + static { + blendFunctionTable[TransparencyAttributes.BLEND_ZERO] = GL.GL_ZERO; + blendFunctionTable[TransparencyAttributes.BLEND_ONE] = GL.GL_ONE; + blendFunctionTable[TransparencyAttributes.BLEND_SRC_ALPHA] = GL.GL_SRC_ALPHA; + blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_SRC_ALPHA] = GL.GL_ONE_MINUS_SRC_ALPHA; + blendFunctionTable[TransparencyAttributes.BLEND_DST_COLOR] = GL.GL_DST_COLOR; + blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_DST_COLOR] = GL.GL_ONE_MINUS_DST_COLOR; + blendFunctionTable[TransparencyAttributes.BLEND_SRC_COLOR] = GL.GL_SRC_COLOR; + blendFunctionTable[TransparencyAttributes.BLEND_ONE_MINUS_SRC_COLOR] = GL.GL_ONE_MINUS_SRC_COLOR; + blendFunctionTable[TransparencyAttributes.BLEND_CONSTANT_COLOR] = GL2.GL_CONSTANT_COLOR; + } + + void updateTransparencyAttributes(Context ctx, + float alpha, int geometryType, + int polygonMode, + boolean lineAA, boolean pointAA, + int transparencyMode, + int srcBlendFunction, + int dstBlendFunction) { + if (VERBOSE) System.err.println("JoglPipeline.updateTransparencyAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + if (transparencyMode != TransparencyAttributes.SCREEN_DOOR) { + gl.glDisable(GL2.GL_POLYGON_STIPPLE); + } else { + gl.glEnable(GL2.GL_POLYGON_STIPPLE); + gl.glPolygonStipple(screen_door_table[(int)(alpha * 16)]); + } + + if ((transparencyMode < TransparencyAttributes.SCREEN_DOOR) || + ((((geometryType & RenderMolecule.LINE) != 0) || + (polygonMode == PolygonAttributes.POLYGON_LINE)) + && lineAA) || + ((((geometryType & RenderMolecule.POINT) != 0) || + (polygonMode == PolygonAttributes.POLYGON_POINT)) + && pointAA)) { + gl.glEnable(GL.GL_BLEND); + // valid range of blendFunction 0..3 is already verified in shared code. + gl.glBlendFunc(blendFunctionTable[srcBlendFunction], blendFunctionTable[dstBlendFunction]); + } else { + gl.glDisable(GL.GL_BLEND); + } + } + + + // --------------------------------------------------------------------- + + // + // TextureAttributesRetained methods + // + + void updateTextureAttributes(Context ctx, + double[] transform, boolean isIdentity, int textureMode, + int perspCorrectionMode, + float textureBlendColorRed, + float textureBlendColorGreen, + float textureBlendColorBlue, + float textureBlendColorAlpha, + int textureFormat) { + if (VERBOSE) System.err.println("JoglPipeline.updateTextureAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, + (perspCorrectionMode == TextureAttributes.NICEST) ? GL.GL_NICEST : GL.GL_FASTEST); + + // set OGL texture matrix + gl.glPushAttrib(GL2.GL_TRANSFORM_BIT); + gl.glMatrixMode(GL.GL_TEXTURE); + + if (isIdentity) { + gl.glLoadIdentity(); + } else if (gl.isExtensionAvailable("GL_VERSION_1_3")) { + gl.glLoadTransposeMatrixd(transform, 0); + } else { + double[] mx = new double[16]; + copyTranspose(transform, mx); + gl.glLoadMatrixd(mx, 0); + } + + gl.glPopAttrib(); + + // set texture color + float[] color = new float[4]; + color[0] = textureBlendColorRed; + color[1] = textureBlendColorGreen; + color[2] = textureBlendColorBlue; + color[3] = textureBlendColorAlpha; + gl.glTexEnvfv(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_COLOR, color, 0); + + // set texture environment mode + + switch (textureMode) { + case TextureAttributes.MODULATE: + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE); + break; + case TextureAttributes.DECAL: + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_DECAL); + break; + case TextureAttributes.BLEND: + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_BLEND); + break; + case TextureAttributes.REPLACE: + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); + break; + case TextureAttributes.COMBINE: + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_COMBINE); + break; + } +// FIXME: GL_SGI_texture_color_table +// if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) { +// gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI); +// } + } + + void updateRegisterCombiners(Context absCtx, + double[] transform, boolean isIdentity, int textureMode, + int perspCorrectionMode, + float textureBlendColorRed, + float textureBlendColorGreen, + float textureBlendColorBlue, + float textureBlendColorAlpha, + int textureFormat, + int combineRgbMode, int combineAlphaMode, + int[] combineRgbSrc, int[] combineAlphaSrc, + int[] combineRgbFcn, int[] combineAlphaFcn, + int combineRgbScale, int combineAlphaScale) { +// FIXME: GL_NV_register_combiners +// if (VERBOSE) System.err.println("JoglPipeline.updateRegisterCombiners()"); +// +// JoglContext ctx = (JoglContext) absCtx; +// GL2 gl = context(ctx).getGL().getGL2(); +// +// if (perspCorrectionMode == TextureAttributes.NICEST) { +// gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); +// } else { +// gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_FASTEST); +// } +// +// // set OGL texture matrix +// gl.glPushAttrib(GL2.GL_TRANSFORM_BIT); +// gl.glMatrixMode(GL.GL_TEXTURE); +// +// if (isIdentity) { +// gl.glLoadIdentity(); +// } else if (gl.isExtensionAvailable("GL_VERSION_1_3")) { +// gl.glLoadTransposeMatrixd(transform, 0); +// } else { +// double[] mx = new double[16]; +// copyTranspose(transform, mx); +// gl.glLoadMatrixd(mx, 0); +// } +// +// gl.glPopAttrib(); +// +// // set texture color +// float[] color = new float[4]; +// color[0] = textureBlendColorRed; +// color[1] = textureBlendColorGreen; +// color[2] = textureBlendColorBlue; +// color[3] = textureBlendColorAlpha; +// gl.glTexEnvfv(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_COLOR, color, 0); +// +// // set texture environment mode +// gl.glEnable(GL.GL_REGISTER_COMBINERS_NV); +// int textureUnit = ctx.getCurrentTextureUnit(); +// int combinerUnit = ctx.getCurrentCombinerUnit(); +// int fragment; +// if (combinerUnit == GL.GL_COMBINER0_NV) { +// fragment = GL.GL_PRIMARY_COLOR_NV; +// } else { +// fragment = GL.GL_SPARE0_NV; +// } +// +// switch (textureMode) { +// case TextureAttributes.MODULATE: +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_A_NV, fragment, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_B_NV, textureUnit, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_VARIABLE_A_NV, fragment, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); +// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_VARIABLE_B_NV, textureUnit, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); +// +// gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB, +// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, +// GL.GL_NONE, GL.GL_NONE, false, false, false); +// gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, +// GL.GL_NONE, GL.GL_NONE, false, false, false); +// break; +// +// case TextureAttributes.DECAL: +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_A_NV, fragment, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_B_NV, textureUnit, +// GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA); +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_C_NV, textureUnit, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_D_NV, textureUnit, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); +// +// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_VARIABLE_A_NV, fragment, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); +// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_VARIABLE_B_NV, GL.GL_ZERO, +// GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA); +// +// gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB, +// GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, GL.GL_SPARE0_NV, +// GL.GL_NONE, GL.GL_NONE, false, false, false); +// gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, +// GL.GL_NONE, GL.GL_NONE, false, false, false); +// break; +// +// case TextureAttributes.BLEND: +// gl.glCombinerParameterfvNV(GL.GL_CONSTANT_COLOR0_NV, color, 0); +// +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_A_NV, fragment, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_B_NV, textureUnit, +// GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_C_NV, GL.GL_CONSTANT_COLOR0_NV, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_D_NV, textureUnit, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// +// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_VARIABLE_A_NV, fragment, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); +// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_VARIABLE_B_NV, textureUnit, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); +// +// gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB, +// GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, GL.GL_SPARE0_NV, +// GL.GL_NONE, GL.GL_NONE, false, false, false); +// gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, +// GL.GL_NONE, GL.GL_NONE, false, false, false); +// break; +// +// case TextureAttributes.REPLACE: +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_A_NV, textureUnit, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_B_NV, GL.GL_ZERO, +// GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); +// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_VARIABLE_A_NV, textureUnit, +// GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); +// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_VARIABLE_B_NV, GL.GL_ZERO, +// GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA); +// +// gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB, +// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, +// GL.GL_NONE, GL.GL_NONE, false, false, false); +// gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, +// GL.GL_NONE, GL.GL_NONE, false, false, false); +// break; +// +// case TextureAttributes.COMBINE: +// if (combineRgbMode == TextureAttributes.COMBINE_DOT3) { +// int color1 = getCombinerArg(gl, combineRgbSrc[0], textureUnit, combinerUnit); +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_A_NV, color1, +// GL.GL_EXPAND_NORMAL_NV, GL.GL_RGB); +// int color2 = getCombinerArg(gl, combineRgbSrc[1], textureUnit, combinerUnit); +// gl.glCombinerInputNV(combinerUnit, GL.GL_RGB, +// GL.GL_VARIABLE_B_NV, color2, +// GL.GL_EXPAND_NORMAL_NV, GL.GL_RGB); +// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_VARIABLE_A_NV, GL.GL_ZERO, +// GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA); +// gl.glCombinerInputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_VARIABLE_B_NV, GL.GL_ZERO, +// GL.GL_UNSIGNED_INVERT_NV, GL.GL_ALPHA); +// +// gl.glCombinerOutputNV(combinerUnit, GL.GL_RGB, +// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, +// GL.GL_NONE/*SCALE_BY_FOUR_NV*/, GL.GL_NONE, true, +// false, false); +// gl.glCombinerOutputNV(combinerUnit, GL.GL_ALPHA, +// GL.GL_SPARE0_NV, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, +// GL.GL_NONE, GL.GL_NONE, false, +// false, false); +// } +// break; +// } +// +// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_A_NV, +// GL.GL_SPARE0_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_B_NV, +// GL.GL_ZERO, GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); +// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_C_NV, +// GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_D_NV, +// GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_E_NV, +// GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_F_NV, +// GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); +// gl.glFinalCombinerInputNV(GL.GL_VARIABLE_G_NV, +// GL.GL_SPARE0_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_ALPHA); +// +// if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) +// gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI); + // GL_SGI_texture_color_table + } + + void updateTextureColorTable(Context ctx, int numComponents, + int colorTableSize, + int[] textureColorTable) { +// FIXME: GL_SGI_texture_color_table +// if (VERBOSE) System.err.println("JoglPipeline.updateTextureColorTable()"); +// +// GL gl = context(ctx).getGL(); +// if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) { +// if (numComponents == 3) { +// gl.glColorTable(GL.GL_TEXTURE_COLOR_TABLE_SGI, GL.GL_RGB, +// colorTableSize, GL.GL_RGB, GL2.GL_INT, IntBuffer.wrap(textureColorTable)); +// } else { +// gl.glColorTable(GL.GL_TEXTURE_COLOR_TABLE_SGI, GL.GL_RGBA, +// colorTableSize, GL.GL_RGBA, GL2.GL_INT, IntBuffer.wrap(textureColorTable)); +// } +// gl.glEnable(GL.GL_TEXTURE_COLOR_TABLE_SGI); +// } + } + + void updateCombiner(Context ctx, + int combineRgbMode, int combineAlphaMode, + int[] combineRgbSrc, int[] combineAlphaSrc, + int[] combineRgbFcn, int[] combineAlphaFcn, + int combineRgbScale, int combineAlphaScale) { + if (VERBOSE) System.err.println("JoglPipeline.updateCombiner()"); + + GL2 gl = context(ctx).getGL().getGL2(); + int[] GLrgbMode = new int[1]; + int[] GLalphaMode = new int[1]; + getGLCombineMode(gl, combineRgbMode, combineAlphaMode, + GLrgbMode, GLalphaMode); + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_COMBINE_RGB, GLrgbMode[0]); + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_COMBINE_ALPHA, GLalphaMode[0]); + + int nargs; + if (combineRgbMode == TextureAttributes.COMBINE_REPLACE) { + nargs = 1; + } else if (combineRgbMode == TextureAttributes.COMBINE_INTERPOLATE) { + nargs = 3; + } else { + nargs = 2; + } + + for (int i = 0; i < nargs; i++) { + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, _gl_combineRgbSrcIndex[i], + _gl_combineSrc[combineRgbSrc[i]]); + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, _gl_combineRgbOpIndex[i], + _gl_combineFcn[combineRgbFcn[i]]); + } + + if (combineAlphaMode == TextureAttributes.COMBINE_REPLACE) { + nargs = 1; + } else if (combineAlphaMode == TextureAttributes.COMBINE_INTERPOLATE) { + nargs = 3; + } else { + nargs = 2; + } + + for (int i = 0; i < nargs; i++) { + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, _gl_combineAlphaSrcIndex[i], + _gl_combineSrc[combineAlphaSrc[i]]); + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, _gl_combineAlphaOpIndex[i], + _gl_combineFcn[combineAlphaFcn[i]]); + } + + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_RGB_SCALE, combineRgbScale); + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_ALPHA_SCALE, combineAlphaScale); + } + + // Helper routines for above + + private void getGLCombineMode(GL gl, int combineRgbMode, int combineAlphaMode, + int[] GLrgbMode, int[] GLalphaMode) { + switch (combineRgbMode) { + case TextureAttributes.COMBINE_REPLACE: + GLrgbMode[0] = GL.GL_REPLACE; + break; + case TextureAttributes.COMBINE_MODULATE: + GLrgbMode[0] = GL2.GL_MODULATE; + break; + case TextureAttributes.COMBINE_ADD: + GLrgbMode[0] = GL2.GL_ADD; + break; + case TextureAttributes.COMBINE_ADD_SIGNED: + GLrgbMode[0] = GL2.GL_ADD_SIGNED; + break; + case TextureAttributes.COMBINE_SUBTRACT: + GLrgbMode[0] = GL2.GL_SUBTRACT; + break; + case TextureAttributes.COMBINE_INTERPOLATE: + GLrgbMode[0] = GL2.GL_INTERPOLATE; + break; + case TextureAttributes.COMBINE_DOT3: + GLrgbMode[0] = GL2.GL_DOT3_RGB; + break; + default: + break; + } + + switch (combineAlphaMode) { + case TextureAttributes.COMBINE_REPLACE: + GLalphaMode[0] = GL.GL_REPLACE; + break; + case TextureAttributes.COMBINE_MODULATE: + GLalphaMode[0] = GL2.GL_MODULATE; + break; + case TextureAttributes.COMBINE_ADD: + GLalphaMode[0] = GL2.GL_ADD; + break; + case TextureAttributes.COMBINE_ADD_SIGNED: + GLalphaMode[0] = GL2.GL_ADD_SIGNED; + break; + case TextureAttributes.COMBINE_SUBTRACT: + GLalphaMode[0] = GL2.GL_SUBTRACT; + break; + case TextureAttributes.COMBINE_INTERPOLATE: + GLalphaMode[0] = GL2.GL_INTERPOLATE; + break; + case TextureAttributes.COMBINE_DOT3: + // dot3 will only make sense for alpha if rgb is also + // doing dot3. So if rgb is not doing dot3, fallback to replace + if (combineRgbMode == TextureAttributes.COMBINE_DOT3) { + GLrgbMode[0] = GL2.GL_DOT3_RGBA; + } else { + GLalphaMode[0] = GL.GL_REPLACE; + } + break; + default: + break; + } + } + + // mapping from java enum to gl enum + private static final int[] _gl_combineRgbSrcIndex = { + GL2.GL_SOURCE0_RGB, + GL2.GL_SOURCE1_RGB, + GL2.GL_SOURCE2_RGB, + }; + + private static final int[] _gl_combineAlphaSrcIndex = { + GL2.GL_SOURCE0_ALPHA, + GL2.GL_SOURCE1_ALPHA, + GL2.GL_SOURCE2_ALPHA, + }; + + private static final int[] _gl_combineRgbOpIndex = { + GL2.GL_OPERAND0_RGB, + GL2.GL_OPERAND1_RGB, + GL2.GL_OPERAND2_RGB, + }; + + private static final int[] _gl_combineAlphaOpIndex = { + GL2.GL_OPERAND0_ALPHA, + GL2.GL_OPERAND1_ALPHA, + GL2.GL_OPERAND2_ALPHA, + }; + + private static final int[] _gl_combineSrc = { + GL2.GL_PRIMARY_COLOR, // TextureAttributes.COMBINE_OBJECT_COLOR + GL.GL_TEXTURE, // TextureAttributes.COMBINE_TEXTURE + GL2.GL_CONSTANT, // TextureAttributes.COMBINE_CONSTANT_COLOR + GL2.GL_PREVIOUS, // TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE + }; + + private static final int[] _gl_combineFcn = { + GL.GL_SRC_COLOR, // TextureAttributes.COMBINE_SRC_COLOR + GL.GL_ONE_MINUS_SRC_COLOR, // TextureAttributes.COMBINE_ONE_MINUS_SRC_COLOR + GL.GL_SRC_ALPHA, // TextureAttributes.COMBINE_SRC_ALPHA + GL.GL_ONE_MINUS_SRC_ALPHA, // TextureAttributes.COMBINE_ONE_MINUS_SRC_ALPHA + }; + +// FIXME: GL_NV_register_combiners +// private int getCombinerArg(GL gl, int arg, int textureUnit, int combUnit) { +// int comb = 0; +// +// switch (arg) { +// case TextureAttributes.COMBINE_OBJECT_COLOR: +// if (combUnit == GL.GL_COMBINER0_NV) { +// comb = GL.GL_PRIMARY_COLOR_NV; +// } else { +// comb = GL.GL_SPARE0_NV; +// } +// break; +// case TextureAttributes.COMBINE_TEXTURE_COLOR: +// comb = textureUnit; +// break; +// case TextureAttributes.COMBINE_CONSTANT_COLOR: +// comb = GL.GL_CONSTANT_COLOR0_NV; +// break; +// case TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE: +// comb = textureUnit -1; +// break; +// } +// +// return comb; +// } + + + // --------------------------------------------------------------------- + + // + // TextureUnitStateRetained methods + // + + void updateTextureUnitState(Context ctx, int index, boolean enable) { + if (VERBOSE) System.err.println("JoglPipeline.updateTextureUnitState()"); + + GL2 gl = context(ctx).getGL().getGL2(); + JoglContext jctx = (JoglContext) ctx; + + if (index >= 0 && gl.isExtensionAvailable("GL_VERSION_1_3")) { + gl.glActiveTexture(index + GL.GL_TEXTURE0); + gl.glClientActiveTexture(GL.GL_TEXTURE0 + index); +// FIXME: GL_NV_register_combiners +// if (gl.isExtensionAvailable("GL_NV_register_combiners")) { +// jctx.setCurrentTextureUnit(index + GL.GL_TEXTURE0); +// jctx.setCurrentCombinerUnit(index + GL.GL_COMBINER0_NV); +// gl.glCombinerParameteriNV(GL.GL_NUM_GENERAL_COMBINERS_NV, index + 1); +// } + } + + if (!enable) { + // if not enabled, then don't enable any tex mapping + gl.glDisable(GL2.GL_TEXTURE_1D); + gl.glDisable(GL.GL_TEXTURE_2D); + gl.glDisable(GL2.GL_TEXTURE_3D); + gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); + } + + // if it is enabled, the enable flag will be taken care of + // in the bindTexture call + } + + + // --------------------------------------------------------------------- + + // + // TextureRetained methods + // Texture2DRetained methods + // + + void bindTexture2D(Context ctx, int objectId, boolean enable) { + if (VERBOSE) System.err.println("JoglPipeline.bindTexture2D(objectId=" + objectId + ",enable=" + enable + ")"); + + GL gl = context(ctx).getGL(); + gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); + gl.glDisable(GL2.GL_TEXTURE_3D); + + if (!enable) { + gl.glDisable(GL.GL_TEXTURE_2D); + } else { + gl.glBindTexture(GL.GL_TEXTURE_2D, objectId); + gl.glEnable(GL.GL_TEXTURE_2D); + } + } + + void updateTexture2DImage(Context ctx, + int numLevels, int level, + int textureFormat, int imageFormat, + int width, int height, + int boundaryWidth, + int dataType, Object data, boolean useAutoMipMap) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DImage(width=" + width + ",height=" + height + ",level=" + level + ")"); + + updateTexture2DImage(ctx, GL.GL_TEXTURE_2D, + numLevels, level, textureFormat, imageFormat, + width, height, boundaryWidth, dataType, data, useAutoMipMap); + } + + void updateTexture2DSubImage(Context ctx, + int level, int xoffset, int yoffset, + int textureFormat, int imageFormat, + int imgXOffset, int imgYOffset, + int tilew, int width, int height, + int dataType, Object data, boolean useAutoMipMap) { + + /* Note: useAutoMipMap is not use for SubImage in the jogl pipe */ + + if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DSubImage()"); + + updateTexture2DSubImage(ctx, GL.GL_TEXTURE_2D, + level, xoffset, yoffset, + textureFormat, imageFormat, + imgXOffset, imgYOffset, tilew, width, height, + dataType, data); + } + + void updateTexture2DLodRange(Context ctx, + int baseLevel, int maximumLevel, + float minimumLOD, float maximumLOD) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DLodRange()"); + + updateTextureLodRange(ctx, GL.GL_TEXTURE_2D, + baseLevel, maximumLevel, + minimumLOD, maximumLOD); + } + + void updateTexture2DLodOffset(Context ctx, + float lodOffsetS, float lodOffsetT, + float lodOffsetR) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DLodOffset()"); + + updateTextureLodOffset(ctx, GL.GL_TEXTURE_2D, + lodOffsetS, lodOffsetT, lodOffsetR); + } + + void updateTexture2DBoundary(Context ctx, + int boundaryModeS, int boundaryModeT, + float boundaryRed, float boundaryGreen, + float boundaryBlue, float boundaryAlpha) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DBoundary()"); + + updateTextureBoundary(ctx, GL.GL_TEXTURE_2D, + boundaryModeS, boundaryModeT, -1, + boundaryRed, boundaryGreen, + boundaryBlue, boundaryAlpha); + } + + void updateTexture2DFilterModes(Context ctx, + int minFilter, int magFilter) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DFilterModes()"); + + updateTextureFilterModes(ctx, GL.GL_TEXTURE_2D, minFilter, magFilter); + } + + void updateTexture2DSharpenFunc(Context ctx, + int numSharpenTextureFuncPts, + float[] sharpenTextureFuncPts) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DSharpenFunc()"); + + updateTextureSharpenFunc(ctx, GL.GL_TEXTURE_2D, + numSharpenTextureFuncPts, sharpenTextureFuncPts); + } + + void updateTexture2DFilter4Func(Context ctx, + int numFilter4FuncPts, + float[] filter4FuncPts) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DFilter4Func()"); + + updateTextureFilter4Func(ctx, GL.GL_TEXTURE_2D, + numFilter4FuncPts, filter4FuncPts); + } + + void updateTexture2DAnisotropicFilter(Context ctx, float degree) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture2DAnisotropicFilter()"); + + updateTextureAnisotropicFilter(ctx, GL.GL_TEXTURE_2D, degree); + } + + private void updateTextureLodRange(Context ctx, + int target, + int baseLevel, int maximumLevel, + float minimumLOD, float maximumLOD) { + GL gl = context(ctx).getGL(); + // checking of the availability of the extension is already done + // in the shared code + gl.glTexParameteri(target, GL2.GL_TEXTURE_BASE_LEVEL, baseLevel); + gl.glTexParameteri(target, GL2.GL_TEXTURE_MAX_LEVEL, maximumLevel); + gl.glTexParameterf(target, GL2.GL_TEXTURE_MIN_LOD, minimumLOD); + gl.glTexParameterf(target, GL2.GL_TEXTURE_MAX_LOD, maximumLOD); + } + + private void updateTextureLodOffset(Context ctx, + int target, + float lodOffsetS, float lodOffsetT, + float lodOffsetR) { +// FIXME: GL_SGIX_texture_lod_bias +// GL gl = context(ctx).getGL(); + // checking of the availability of the extension is already done + // in the shared code +// gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_S_SGIX, lodOffsetS); +// gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_T_SGIX, lodOffsetT); +// gl.glTexParameterf(target, GL.GL_TEXTURE_LOD_BIAS_R_SGIX, lodOffsetR); + } + + private void updateTextureAnisotropicFilter(Context ctx, int target, float degree) { + GL gl = context(ctx).getGL(); + // checking of the availability of anisotropic filter functionality + // is already done in the shared code + gl.glTexParameterf(target, + GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, + degree); + } + + // --------------------------------------------------------------------- + + // + // Texture3DRetained methods + // + + void bindTexture3D(Context ctx, int objectId, boolean enable) { + if (VERBOSE) System.err.println("JoglPipeline.bindTexture3D()"); + + GL gl = context(ctx).getGL(); + // textureCubeMap will take precedure over 3D Texture + gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); + + if (!enable) { + gl.glDisable(GL2.GL_TEXTURE_3D); + } else { + gl.glBindTexture(GL2.GL_TEXTURE_3D, objectId); + gl.glEnable(GL2.GL_TEXTURE_3D); + } + } + + void updateTexture3DImage(Context ctx, + int numLevels, int level, + int textureFormat, int imageFormat, + int width, int height, int depth, + int boundaryWidth, + int dataType, Object data, boolean useAutoMipMap) { + + if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DImage()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + int format = 0; + int internalFormat = 0; + int type = GL2.GL_UNSIGNED_INT_8_8_8_8; + boolean forceAlphaToOne = false; + + switch (textureFormat) { + case Texture.INTENSITY: + internalFormat = GL2.GL_INTENSITY; + break; + case Texture.LUMINANCE: + internalFormat = GL.GL_LUMINANCE; + break; + case Texture.ALPHA: + internalFormat = GL.GL_ALPHA; + break; + case Texture.LUMINANCE_ALPHA: + internalFormat = GL.GL_LUMINANCE_ALPHA; + break; + case Texture.RGB: + internalFormat = GL.GL_RGB; + break; + case Texture.RGBA: + internalFormat = GL.GL_RGBA; + break; + default: + assert false; + return; + } + + if (useAutoMipMap) { + gl.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_GENERATE_MIPMAP, GL.GL_TRUE); + } + else { + gl.glTexParameteri(GL2.GL_TEXTURE_3D, GL2.GL_GENERATE_MIPMAP, GL.GL_FALSE); + } + + if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) || + (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) { + + switch (imageFormat) { + case ImageComponentRetained.TYPE_BYTE_BGR: + format = GL2.GL_BGR; + break; + case ImageComponentRetained.TYPE_BYTE_RGB: + format = GL.GL_RGB; + break; + case ImageComponentRetained.TYPE_BYTE_ABGR: + if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here! + format = GL2.GL_ABGR_EXT; + } else { + assert false; + return; + } + break; + case ImageComponentRetained.TYPE_BYTE_RGBA: + // all RGB types are stored as RGBA + format = GL.GL_RGBA; + break; + case ImageComponentRetained.TYPE_BYTE_LA: + // all LA types are stored as LA8 + format = GL.GL_LUMINANCE_ALPHA; + break; + case ImageComponentRetained.TYPE_BYTE_GRAY: + if (internalFormat == GL.GL_ALPHA) { + format = GL.GL_ALPHA; + } else { + format = GL.GL_LUMINANCE; + } + break; + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_INT_BGR: + case ImageComponentRetained.TYPE_INT_RGB: + case ImageComponentRetained.TYPE_INT_ARGB: + default: + assert false; + return; + } + + if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) { + + gl.glTexImage3D(GL2.GL_TEXTURE_3D, + level, internalFormat, + width, height, depth, boundaryWidth, + format, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[]) data)); + } + else { + gl.glTexImage3D(GL2.GL_TEXTURE_3D, + level, internalFormat, + width, height, depth, boundaryWidth, + format, GL.GL_UNSIGNED_BYTE, (ByteBuffer) data); + } + + } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) || + (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) { + + switch (imageFormat) { + /* GL_BGR */ + case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ + format = GL.GL_RGBA; + type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + forceAlphaToOne = true; + break; + case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ + forceAlphaToOne = true; + /* Fall through to next case */ + case ImageComponentRetained.TYPE_INT_ARGB: + format = GL2.GL_BGRA; + type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + break; + /* This method only supports 3 and 4 components formats and INT types. */ + case ImageComponentRetained.TYPE_BYTE_LA: + case ImageComponentRetained.TYPE_BYTE_GRAY: + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_BYTE_BGR: + case ImageComponentRetained.TYPE_BYTE_RGB: + case ImageComponentRetained.TYPE_BYTE_RGBA: + case ImageComponentRetained.TYPE_BYTE_ABGR: + default: + assert false; + return; + } + + /* Force Alpha to 1.0 if needed */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); + } + + if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) { + gl.glTexImage3D(GL2.GL_TEXTURE_3D, + level, internalFormat, + width, height, depth, boundaryWidth, + format, type, IntBuffer.wrap((int[]) data)); + } else { + gl.glTexImage3D(GL2.GL_TEXTURE_3D, + level, internalFormat, + width, height, depth, boundaryWidth, + format, type, (Buffer) data); + } + + /* Restore Alpha scale and bias */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); + } + } else { + assert false; + } + } + + void updateTexture3DSubImage(Context ctx, + int level, + int xoffset, int yoffset, int zoffset, + int textureFormat, int imageFormat, + int imgXOffset, int imgYOffset, int imgZOffset, + int tilew, int tileh, + int width, int height, int depth, + int dataType, Object data, boolean useAutoMipMap) { + + /* Note: useAutoMipMap is not use for SubImage in the jogl pipe */ + + if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DSubImage()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + int format = 0; + int internalFormat = 0; + int type = GL2.GL_UNSIGNED_INT_8_8_8_8; + int numBytes = 0; + boolean forceAlphaToOne = false; + boolean pixelStore = false; + + if (imgXOffset > 0 || (width < tilew)) { + pixelStore = true; + gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, tilew); + } + + switch (textureFormat) { + case Texture.INTENSITY: + internalFormat = GL2.GL_INTENSITY; + break; + case Texture.LUMINANCE: + internalFormat = GL.GL_LUMINANCE; + break; + case Texture.ALPHA: + internalFormat = GL.GL_ALPHA; + break; + case Texture.LUMINANCE_ALPHA: + internalFormat = GL.GL_LUMINANCE_ALPHA; + break; + case Texture.RGB: + internalFormat = GL.GL_RGB; + break; + case Texture.RGBA: + internalFormat = GL.GL_RGBA; + break; + default: + assert false; + } + + if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) || + (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) { + + switch (imageFormat) { + case ImageComponentRetained.TYPE_BYTE_BGR: + format = GL2.GL_BGR; + numBytes = 3; + break; + case ImageComponentRetained.TYPE_BYTE_RGB: + format = GL.GL_RGB; + numBytes = 3; + break; + case ImageComponentRetained.TYPE_BYTE_ABGR: + if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here! + format = GL2.GL_ABGR_EXT; + numBytes = 4; + } else { + assert false; + return; + } + break; + case ImageComponentRetained.TYPE_BYTE_RGBA: + // all RGB types are stored as RGBA + format = GL.GL_RGBA; + numBytes = 4; + break; + case ImageComponentRetained.TYPE_BYTE_LA: + // all LA types are stored as LA8 + format = GL.GL_LUMINANCE_ALPHA; + numBytes = 2; + break; + case ImageComponentRetained.TYPE_BYTE_GRAY: + if (internalFormat == GL.GL_ALPHA) { + format = GL.GL_ALPHA; + numBytes = 1; + } else { + format = GL.GL_LUMINANCE; + numBytes = 1; + } + break; + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_INT_BGR: + case ImageComponentRetained.TYPE_INT_RGB: + case ImageComponentRetained.TYPE_INT_ARGB: + default: + assert false; + return; + } + + ByteBuffer buf = null; + if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) { + buf = ByteBuffer.wrap((byte[]) data); + } + else { + buf = (ByteBuffer) data; + } + + int offset = (tilew * tileh * imgZOffset + + tilew * imgYOffset + imgXOffset) * numBytes; + buf.position(offset); + gl.glTexSubImage3D(GL2.GL_TEXTURE_3D, + level, xoffset, yoffset, zoffset, + width, height, depth, + format, GL.GL_UNSIGNED_BYTE, + buf); + + } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) || + (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) { + + switch (imageFormat) { + /* GL_BGR */ + case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ + format = GL.GL_RGBA; + type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + forceAlphaToOne = true; + break; + case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ + forceAlphaToOne = true; + /* Fall through to next case */ + case ImageComponentRetained.TYPE_INT_ARGB: + format = GL2.GL_BGRA; + type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + break; + /* This method only supports 3 and 4 components formats and INT types. */ + case ImageComponentRetained.TYPE_BYTE_LA: + case ImageComponentRetained.TYPE_BYTE_GRAY: + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_BYTE_BGR: + case ImageComponentRetained.TYPE_BYTE_RGB: + case ImageComponentRetained.TYPE_BYTE_RGBA: + case ImageComponentRetained.TYPE_BYTE_ABGR: + default: + assert false; + return; + } + + /* Force Alpha to 1.0 if needed */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); + } + + IntBuffer buf = null; + if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) { + buf = IntBuffer.wrap((int[]) data); + } + else { + buf = (IntBuffer) data; + } + + int offset = tilew * tileh * imgZOffset + + tilew * imgYOffset + imgXOffset; + buf.position(offset); + gl.glTexSubImage3D(GL2.GL_TEXTURE_3D, + level, xoffset, yoffset, zoffset, + width, height, depth, + format, type, + buf); + + /* Restore Alpha scale and bias */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); + } + } else { + assert false; + return; + } + + if (pixelStore) { + gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, 0); + } + + } + + + void updateTexture3DLodRange(Context ctx, + int baseLevel, int maximumLevel, + float minimumLod, float maximumLod) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DLodRange()"); + + updateTextureLodRange(ctx, GL2.GL_TEXTURE_3D, + baseLevel, maximumLevel, + minimumLod, maximumLod); + } + + void updateTexture3DLodOffset(Context ctx, + float lodOffsetS, float lodOffsetT, + float lodOffsetR) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DLodOffset()"); + + updateTextureLodOffset(ctx, GL2.GL_TEXTURE_3D, + lodOffsetS, lodOffsetT, lodOffsetR); + } + + void updateTexture3DBoundary(Context ctx, + int boundaryModeS, int boundaryModeT, + int boundaryModeR, float boundaryRed, + float boundaryGreen, float boundaryBlue, + float boundaryAlpha) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DBoundary()"); + + updateTextureBoundary(ctx, GL.GL_TEXTURE_2D, + boundaryModeS, boundaryModeT, boundaryModeR, + boundaryRed, boundaryGreen, + boundaryBlue, boundaryAlpha); + } + + void updateTexture3DFilterModes(Context ctx, + int minFilter, int magFilter) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DFilterModes()"); + + updateTextureFilterModes(ctx, GL2.GL_TEXTURE_3D, + minFilter, magFilter); + } + + void updateTexture3DSharpenFunc(Context ctx, + int numSharpenTextureFuncPts, + float[] sharpenTextureFuncPts) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DSharpenFunc()"); + + updateTextureSharpenFunc(ctx, GL2.GL_TEXTURE_3D, + numSharpenTextureFuncPts, sharpenTextureFuncPts); + } + + void updateTexture3DFilter4Func(Context ctx, + int numFilter4FuncPts, + float[] filter4FuncPts) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DFilter4Func()"); + + updateTextureFilter4Func(ctx, GL2.GL_TEXTURE_3D, + numFilter4FuncPts, filter4FuncPts); + } + + void updateTexture3DAnisotropicFilter(Context ctx, float degree) { + if (VERBOSE) System.err.println("JoglPipeline.updateTexture3DAnisotropicFilter()"); + + updateTextureAnisotropicFilter(ctx, GL2.GL_TEXTURE_3D, degree); + } + + + // --------------------------------------------------------------------- + + // + // TextureCubeMapRetained methods + // + + void bindTextureCubeMap(Context ctx, int objectId, boolean enable) { + if (VERBOSE) System.err.println("JoglPipeline.bindTextureCubeMap()"); + + GL gl = context(ctx).getGL(); + // TextureCubeMap will take precedure over 3D Texture so + // there is no need to disable 3D Texture here. + if (!enable) { + gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); + } else { + gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, objectId); + gl.glEnable(GL.GL_TEXTURE_CUBE_MAP); + } + } + + void updateTextureCubeMapImage(Context ctx, + int face, int numLevels, int level, + int textureFormat, int imageFormat, + int width, int height, + int boundaryWidth, + int dataType, Object data, boolean useAutoMipMap) { + if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapImage()"); + + updateTexture2DImage(ctx, _gl_textureCubeMapFace[face], + numLevels, level, textureFormat, imageFormat, + width, height, boundaryWidth, dataType, data, useAutoMipMap); + } + + void updateTextureCubeMapSubImage(Context ctx, + int face, int level, int xoffset, int yoffset, + int textureFormat,int imageFormat, + int imgXOffset, int imgYOffset, + int tilew, int width, int height, + int dataType, Object data, boolean useAutoMipMap) { + + /* Note: useAutoMipMap is not use for SubImage in the jogl pipe */ + + if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapSubImage()"); + + updateTexture2DSubImage(ctx, _gl_textureCubeMapFace[face], + level, xoffset, yoffset, textureFormat, + imageFormat, imgXOffset, imgYOffset, tilew, + width, height, dataType, data); + } + + void updateTextureCubeMapLodRange(Context ctx, + int baseLevel, int maximumLevel, + float minimumLod, float maximumLod) { + if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapLodRange()"); + + updateTextureLodRange(ctx, + GL.GL_TEXTURE_CUBE_MAP, + baseLevel, maximumLevel, + minimumLod, maximumLod); + } + + void updateTextureCubeMapLodOffset(Context ctx, + float lodOffsetS, float lodOffsetT, + float lodOffsetR) { + if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapLodOffset()"); + + updateTextureLodOffset(ctx, + GL.GL_TEXTURE_CUBE_MAP, + lodOffsetS, lodOffsetT, lodOffsetR); + } + + void updateTextureCubeMapBoundary(Context ctx, + int boundaryModeS, int boundaryModeT, + float boundaryRed, float boundaryGreen, + float boundaryBlue, float boundaryAlpha) { + if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapBoundary()"); + + updateTextureBoundary(ctx, + GL.GL_TEXTURE_CUBE_MAP, + boundaryModeS, boundaryModeT, -1, + boundaryRed, boundaryGreen, + boundaryBlue, boundaryAlpha); + } + + void updateTextureCubeMapFilterModes(Context ctx, + int minFilter, int magFilter) { + if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapFilterModes()"); + + updateTextureFilterModes(ctx, + GL.GL_TEXTURE_CUBE_MAP, + minFilter, magFilter); + } + + void updateTextureCubeMapSharpenFunc(Context ctx, + int numSharpenTextureFuncPts, + float[] sharpenTextureFuncPts) { + if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapSharpenFunc()"); + + updateTextureSharpenFunc(ctx, + GL.GL_TEXTURE_CUBE_MAP, + numSharpenTextureFuncPts, sharpenTextureFuncPts); + } + + void updateTextureCubeMapFilter4Func(Context ctx, + int numFilter4FuncPts, + float[] filter4FuncPts) { + if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapFilter4Func()"); + + updateTextureFilter4Func(ctx, + GL.GL_TEXTURE_CUBE_MAP, + numFilter4FuncPts, filter4FuncPts); + } + + void updateTextureCubeMapAnisotropicFilter(Context ctx, float degree) { + if (VERBOSE) System.err.println("JoglPipeline.updateTextureCubeMapAnisotropicFilter()"); + + updateTextureAnisotropicFilter(ctx, + GL.GL_TEXTURE_CUBE_MAP, + degree); + } + + //---------------------------------------------------------------------- + // + // Helper routines for above texture methods + // + + private void updateTexture2DImage(Context ctx, + int target, + int numLevels, + int level, + int textureFormat, + int imageFormat, + int width, + int height, + int boundaryWidth, + int dataType, + Object data, + boolean useAutoMipMap) { + GL2 gl = context(ctx).getGL().getGL2(); + + int format = 0, internalFormat = 0; + int type = GL2.GL_UNSIGNED_INT_8_8_8_8; + boolean forceAlphaToOne = false; + + switch (textureFormat) { + case Texture.INTENSITY: + internalFormat = GL2.GL_INTENSITY; + break; + case Texture.LUMINANCE: + internalFormat = GL.GL_LUMINANCE; + break; + case Texture.ALPHA: + internalFormat = GL.GL_ALPHA; + break; + case Texture.LUMINANCE_ALPHA: + internalFormat = GL.GL_LUMINANCE_ALPHA; + break; + case Texture.RGB: + internalFormat = GL.GL_RGB; + break; + case Texture.RGBA: + internalFormat = GL.GL_RGBA; + break; + default: + assert false; + } + + if (useAutoMipMap) { + gl.glTexParameteri(target, GL2.GL_GENERATE_MIPMAP, GL.GL_TRUE); + } + else { + gl.glTexParameteri(target, GL2.GL_GENERATE_MIPMAP, GL.GL_FALSE); + } + + if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) || + (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) { + + switch (imageFormat) { + case ImageComponentRetained.TYPE_BYTE_BGR: + format = GL2.GL_BGR; + break; + case ImageComponentRetained.TYPE_BYTE_RGB: + format = GL.GL_RGB; + break; + case ImageComponentRetained.TYPE_BYTE_ABGR: + if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here! + format = GL2.GL_ABGR_EXT; + } else { + assert false; + return; + } + break; + case ImageComponentRetained.TYPE_BYTE_RGBA: + // all RGB types are stored as RGBA + format = GL.GL_RGBA; + break; + case ImageComponentRetained.TYPE_BYTE_LA: + // all LA types are stored as LA8 + format = GL.GL_LUMINANCE_ALPHA; + break; + case ImageComponentRetained.TYPE_BYTE_GRAY: + if (internalFormat == GL.GL_ALPHA) { + format = GL.GL_ALPHA; + } else { + format = GL.GL_LUMINANCE; + } + break; + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_INT_BGR: + case ImageComponentRetained.TYPE_INT_RGB: + case ImageComponentRetained.TYPE_INT_ARGB: + default: + assert false; + return; + } + + if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) { + + gl.glTexImage2D(target, level, internalFormat, + width, height, boundaryWidth, + format, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[])data)); + } else { + gl.glTexImage2D(target, level, internalFormat, + width, height, boundaryWidth, + format, GL.GL_UNSIGNED_BYTE, (Buffer) data); + } + + } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) || + (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) { + + switch (imageFormat) { + /* GL_BGR */ + case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ + format = GL.GL_RGBA; + type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + forceAlphaToOne = true; + break; + case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ + forceAlphaToOne = true; + /* Fall through to next case */ + case ImageComponentRetained.TYPE_INT_ARGB: + format = GL2.GL_BGRA; + type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + break; + /* This method only supports 3 and 4 components formats and INT types. */ + case ImageComponentRetained.TYPE_BYTE_LA: + case ImageComponentRetained.TYPE_BYTE_GRAY: + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_BYTE_BGR: + case ImageComponentRetained.TYPE_BYTE_RGB: + case ImageComponentRetained.TYPE_BYTE_RGBA: + case ImageComponentRetained.TYPE_BYTE_ABGR: + default: + assert false; + return; + } + + /* Force Alpha to 1.0 if needed */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); + } + + if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) { + gl.glTexImage2D(target, level, internalFormat, + width, height, boundaryWidth, + format, type, IntBuffer.wrap((int[])data)); + } else { + gl.glTexImage2D(target, level, internalFormat, + width, height, boundaryWidth, + format, type, (Buffer) data); + } + + /* Restore Alpha scale and bias */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); + } + } else { + assert false; + } + } + + private void updateTexture2DSubImage(Context ctx, + int target, + int level, int xoffset, int yoffset, + int textureFormat, int imageFormat, + int imgXOffset, int imgYOffset, + int tilew, int width, int height, + int dataType, Object data) { + GL2 gl = context(ctx).getGL().getGL2(); + + int format = 0, internalFormat=0; + int numBytes = 0; + int type = GL2.GL_UNSIGNED_INT_8_8_8_8; + boolean forceAlphaToOne = false; + boolean pixelStore = false; + + if (imgXOffset > 0 || (width < tilew)) { + pixelStore = true; + gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, tilew); + } + + switch (textureFormat) { + case Texture.INTENSITY: + internalFormat = GL2.GL_INTENSITY; + break; + case Texture.LUMINANCE: + internalFormat = GL.GL_LUMINANCE; + break; + case Texture.ALPHA: + internalFormat = GL.GL_ALPHA; + break; + case Texture.LUMINANCE_ALPHA: + internalFormat = GL.GL_LUMINANCE_ALPHA; + break; + case Texture.RGB: + internalFormat = GL.GL_RGB; + break; + case Texture.RGBA: + internalFormat = GL.GL_RGBA; + break; + default: + assert false; + } + + if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) || + (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) { + + switch (imageFormat) { + case ImageComponentRetained.TYPE_BYTE_BGR: + format = GL2.GL_BGR; + numBytes = 3; + break; + case ImageComponentRetained.TYPE_BYTE_RGB: + format = GL.GL_RGB; + numBytes = 3; + break; + case ImageComponentRetained.TYPE_BYTE_ABGR: + if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If its zero, should never come here! + format = GL2.GL_ABGR_EXT; + numBytes = 4; + } else { + assert false; + return; + } + break; + case ImageComponentRetained.TYPE_BYTE_RGBA: + // all RGB types are stored as RGBA + format = GL.GL_RGBA; + numBytes = 4; + break; + case ImageComponentRetained.TYPE_BYTE_LA: + // all LA types are stored as LA8 + format = GL.GL_LUMINANCE_ALPHA; + numBytes = 2; + break; + case ImageComponentRetained.TYPE_BYTE_GRAY: + if (internalFormat == GL.GL_ALPHA) { + format = GL.GL_ALPHA; + numBytes = 1; + } else { + format = GL.GL_LUMINANCE; + numBytes = 1; + } + break; + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_INT_BGR: + case ImageComponentRetained.TYPE_INT_RGB: + case ImageComponentRetained.TYPE_INT_ARGB: + default: + assert false; + return; + } + + ByteBuffer buf = null; + if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) { + buf = ByteBuffer.wrap((byte[]) data); + } + else { + buf = (ByteBuffer) data; + } + + // offset by the imageOffset + buf.position((tilew * imgYOffset + imgXOffset) * numBytes); + gl.glTexSubImage2D(target, level, xoffset, yoffset, width, height, + format, GL.GL_UNSIGNED_BYTE, buf); + + } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) || + (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) { + + switch (imageFormat) { + /* GL_BGR */ + case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ + format = GL.GL_RGBA; + type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + forceAlphaToOne = true; + break; + case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ + forceAlphaToOne = true; + /* Fall through to next case */ + case ImageComponentRetained.TYPE_INT_ARGB: + format = GL2.GL_BGRA; + type = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + break; + /* This method only supports 3 and 4 components formats and INT types. */ + case ImageComponentRetained.TYPE_BYTE_LA: + case ImageComponentRetained.TYPE_BYTE_GRAY: + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_BYTE_BGR: + case ImageComponentRetained.TYPE_BYTE_RGB: + case ImageComponentRetained.TYPE_BYTE_RGBA: + case ImageComponentRetained.TYPE_BYTE_ABGR: + default: + assert false; + return; + } + /* Force Alpha to 1.0 if needed */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); + } + + IntBuffer buf = null; + if(dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) { + buf = IntBuffer.wrap((int[]) data); + } + else { + buf = (IntBuffer) data; + } + + // offset by the imageOffset + buf.position(tilew * imgYOffset + imgXOffset); + gl.glTexSubImage2D(target, level, xoffset, yoffset, width, height, + format, type, buf); + + /* Restore Alpha scale and bias */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); + } + } else { + assert false; + return; + } + + if (pixelStore) { + gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, 0); + } + + } + + void updateTextureFilterModes(Context ctx, + int target, + int minFilter, + int magFilter) { + GL gl = context(ctx).getGL(); + + if (EXTRA_DEBUGGING) { + System.err.println("minFilter: " + getFilterName(minFilter) + + " magFilter: " + getFilterName(magFilter)); + } + + // FIXME: unclear whether we really need to set up the enum values + // in the JoglContext as is done in the native code depending on + // extension availability; maybe this is the defined fallback + // behavior of the various Java3D modes + + // set texture min filter + switch (minFilter) { + case Texture.FASTEST: + case Texture.BASE_LEVEL_POINT: + gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); + break; + case Texture.BASE_LEVEL_LINEAR: + gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); + break; + case Texture.MULTI_LEVEL_POINT: + gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, + GL.GL_NEAREST_MIPMAP_NEAREST); + break; + case Texture.NICEST: + case Texture.MULTI_LEVEL_LINEAR: + gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, + GL.GL_LINEAR_MIPMAP_LINEAR); + break; + case Texture.FILTER4: +// We should never get here as we've disabled the FILTER4 feature +// gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, +// GL.GL_FILTER4_SGIS); + break; + } + + // set texture mag filter + switch (magFilter) { + case Texture.FASTEST: + case Texture.BASE_LEVEL_POINT: + gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); + break; + case Texture.NICEST: + case Texture.BASE_LEVEL_LINEAR: + gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); + break; + case Texture.LINEAR_SHARPEN: +// We should never get here as we've disabled the TEXTURE_SHARPEN feature +// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, +// GL.GL_LINEAR_SHARPEN_SGIS); + break; + case Texture.LINEAR_SHARPEN_RGB: +// We should never get here as we've disabled the TEXTURE_SHARPEN feature +// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, +// GL.GL_LINEAR_SHARPEN_COLOR_SGIS); + break; + case Texture.LINEAR_SHARPEN_ALPHA: +// We should never get here as we've disabled the TEXTURE_SHARPEN feature +// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, +// GL.GL_LINEAR_SHARPEN_ALPHA_SGIS); + break; + case Texture2D.LINEAR_DETAIL: +// We should never get here as we've disabled the TEXTURE_DETAIL feature +// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, +// GL.GL_LINEAR_DETAIL_SGIS); + break; + case Texture2D.LINEAR_DETAIL_RGB: +// We should never get here as we've disabled the TEXTURE_DETAIL feature +// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, +// GL.GL_LINEAR_DETAIL_COLOR_SGIS); + break; + case Texture2D.LINEAR_DETAIL_ALPHA: +// We should never get here as we've disabled the TEXTURE_DETAIL feature +// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, +// GL.GL_LINEAR_DETAIL_ALPHA_SGIS); + break; + case Texture.FILTER4: +// We should never get here as we've disabled the FILTER4 feature +// gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, +// GL.GL_FILTER4_SGIS); + break; + } + } + + void updateTextureBoundary(Context ctx, + int target, + int boundaryModeS, + int boundaryModeT, + int boundaryModeR, + float boundaryRed, + float boundaryGreen, + float boundaryBlue, + float boundaryAlpha) { + GL gl = context(ctx).getGL(); + + // set texture wrap parameter + switch (boundaryModeS) { + case Texture.WRAP: + gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT); + break; + case Texture.CLAMP: + gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP); + break; + case Texture.CLAMP_TO_EDGE: + gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, + GL.GL_CLAMP_TO_EDGE); + break; + case Texture.CLAMP_TO_BOUNDARY: + gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, + GL2.GL_CLAMP_TO_BORDER); + break; + } + + switch (boundaryModeT) { + case Texture.WRAP: + gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT); + break; + case Texture.CLAMP: + gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP); + break; + case Texture.CLAMP_TO_EDGE: + gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, + GL.GL_CLAMP_TO_EDGE); + break; + case Texture.CLAMP_TO_BOUNDARY: + gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_T, + GL2.GL_CLAMP_TO_BORDER); + break; + } + + // applies to Texture3D only + if (boundaryModeR != -1) { + switch (boundaryModeR) { + case Texture.WRAP: + gl.glTexParameteri(target, + GL2.GL_TEXTURE_WRAP_R, GL.GL_REPEAT); + break; + + case Texture.CLAMP: + gl.glTexParameteri(target, + GL2.GL_TEXTURE_WRAP_R, GL2.GL_CLAMP); + break; + case Texture.CLAMP_TO_EDGE: + gl.glTexParameteri(target, + GL2.GL_TEXTURE_WRAP_R, + GL.GL_CLAMP_TO_EDGE); + break; + case Texture.CLAMP_TO_BOUNDARY: + gl.glTexParameteri(target, + GL2.GL_TEXTURE_WRAP_R, + GL2.GL_CLAMP_TO_BORDER); + break; + } + } + + if (boundaryModeS == Texture.CLAMP || + boundaryModeT == Texture.CLAMP || + boundaryModeR == Texture.CLAMP) { + // set texture border color + float[] color = new float[4]; + color[0] = boundaryRed; + color[1] = boundaryGreen; + color[2] = boundaryBlue; + color[3] = boundaryAlpha; + gl.glTexParameterfv(target, GL2.GL_TEXTURE_BORDER_COLOR, color, 0); + } + } + + private static final String getFilterName(int filter) { + switch (filter) { + case Texture.FASTEST: + return "Texture.FASTEST"; + case Texture.NICEST: + return "Texture.NICEST"; + case Texture.BASE_LEVEL_POINT: + return "Texture.BASE_LEVEL_POINT"; + case Texture.BASE_LEVEL_LINEAR: + return "Texture.BASE_LEVEL_LINEAR"; + case Texture.MULTI_LEVEL_POINT: + return "Texture.MULTI_LEVEL_POINT"; + case Texture.MULTI_LEVEL_LINEAR: + return "Texture.MULTI_LEVEL_LINEAR"; + case Texture.FILTER4: + return "Texture.FILTER4"; + case Texture.LINEAR_SHARPEN: + return "Texture.LINEAR_SHARPEN"; + case Texture.LINEAR_SHARPEN_RGB: + return "Texture.LINEAR_SHARPEN_RGB"; + case Texture.LINEAR_SHARPEN_ALPHA: + return "Texture.LINEAR_SHARPEN_ALPHA"; + case Texture2D.LINEAR_DETAIL: + return "Texture.LINEAR_DETAIL"; + case Texture2D.LINEAR_DETAIL_RGB: + return "Texture.LINEAR_DETAIL_RGB"; + case Texture2D.LINEAR_DETAIL_ALPHA: + return "Texture.LINEAR_DETAIL_ALPHA"; + default: + return "(unknown)"; + } + } + + private void updateTextureSharpenFunc(Context ctx, + int target, + int numPts, + float[] pts) { + // checking of the availability of sharpen texture functionality + // is already done in shared code +// FIXME: GL_SGIS_sharpen_texture +// GL gl = context(ctx).getGL(); +// gl.glSharpenTexFuncSGIS(target, numPts, pts, 0); + } + + private void updateTextureFilter4Func(Context ctx, + int target, + int numPts, + float[] pts) { + // checking of the availability of filter4 functionality + // is already done in shared code +// FIXME: GL_SGIS_texture_filter4 +// GL gl = context(ctx).getGL(); +// gl.glTexFilterFuncSGIS(target, GL.GL_FILTER4_SGIS, +// numPts, pts, 0); + } + + // mapping from java enum to gl enum + private static final int[] _gl_textureCubeMapFace = { + GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + }; + + // --------------------------------------------------------------------- + + // + // MasterControl methods + // + + // Method to return the AWT object + long getAWT() { + if (VERBOSE) System.err.println("JoglPipeline.getAWT()"); + + // FIXME: probably completely unneeded in this implementation, + // but should probably remove this dependence in the shared code + return 0; + } + + // Method to initialize the native J3D library + boolean initializeJ3D(boolean disableXinerama) { + // Dummy method in JOGL pipeline + return true; + } + + // Maximum lights supported by the native API + int getMaximumLights() { + if (VERBOSE) System.err.println("JoglPipeline.getMaximumLights()"); + + // FIXME: this isn't quite what the NativePipeline returns but + // is probably close enough + return 8; + } + + + // --------------------------------------------------------------------- + + // + // Canvas3D methods - native wrappers + // + + // This is the native method for creating the underlying graphics context. + Context createNewContext(Canvas3D cv, long display, Drawable drawable, + long fbConfig, Context shareCtx, boolean isSharedCtx, + boolean offScreen, + boolean glslLibraryAvailable) { + if (VERBOSE) System.err.println("JoglPipeline.createNewContext()"); + GLDrawable draw = null; + GLCapabilitiesChooser indexChooser = null; + JoglGraphicsConfiguration config = (JoglGraphicsConfiguration) cv.graphicsConfiguration; + if (config.getChosenIndex() >= 0) { + indexChooser = new IndexCapabilitiesChooser(config.getChosenIndex()); + } + if (cv.drawable == null) { + AWTGraphicsScreen awtGraphicsScreen = new AWTGraphicsScreen(config.getAwtGraphicsDevice()); + GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(config.getAwtGraphicsDevice()); + AWTGraphicsConfiguration awtGraphicsConfiguration = (AWTGraphicsConfiguration)factory.chooseGraphicsConfiguration(config.getGLCapabilities(), + config.getGLCapabilities(), + indexChooser, awtGraphicsScreen); + NativeWindow nativeWindow = NativeWindowFactory.getNativeWindow(cv, awtGraphicsConfiguration); + draw = GLDrawableFactory.getFactory(getDefaultProfile()).createGLDrawable(nativeWindow); + cv.drawable = new JoglDrawable(draw); + } else { + draw = drawable(cv.drawable); + } + + // FIXME: assuming that this only gets called after addNotify has been called + draw.setRealized(true); + GLContext context = draw.createContext(context(shareCtx)); + + // Apparently we are supposed to make the context current at + // this point and set up a bunch of properties + + // Work around for some low end graphics driver bug, such as Intel Chipset. + // Issue 324 : Lockup Java3D program and throw exception using JOGL renderer + boolean failed = false; + int failCount = 0; + int MAX_FAIL_COUNT = 5; + do { + failed = false; + int res = context.makeCurrent(); + if (res == GLContext.CONTEXT_NOT_CURRENT) { + // System.err.println("makeCurrent fail : " + failCount); + failed = true; + ++failCount; + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + } + } while (failed && (failCount < MAX_FAIL_COUNT)); + if (failCount == MAX_FAIL_COUNT) { + throw new IllegalRenderingStateException("Unable to make new context current after " + failCount + "tries"); + } + + GL2 gl = context.getGL().getGL2(); + JoglContext ctx = new JoglContext(context); + + try { + if (!getPropertiesFromCurrentContext(ctx)) { + throw new IllegalRenderingStateException("Unable to fetch properties from current OpenGL context"); + } + + if(!isSharedCtx){ + // Set up fields in Canvas3D + setupCanvasProperties(cv, ctx, gl, glslLibraryAvailable); + } + + // Enable rescale normal + gl.glEnable(GL2.GL_RESCALE_NORMAL); + + gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL2.GL_DIFFUSE); + gl.glDepthFunc(GL.GL_LEQUAL); + gl.glEnable(GL2.GL_COLOR_MATERIAL); + gl.glReadBuffer(GL.GL_FRONT); + + // Issue 417: JOGL: Mip-mapped NPOT textures rendered incorrectly + // Java 3D images are aligned to 1 byte + gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); + + // Workaround for issue 400: Enable separate specular by default + gl.glLightModeli(GL2.GL_LIGHT_MODEL_COLOR_CONTROL, GL2.GL_SEPARATE_SPECULAR_COLOR); + } finally { + context.release(); + } + + return ctx; + } + + private GLProfile getDefaultProfile() { + return GLProfile.getMaxFixedFunc(true); + } + + void createQueryContext(Canvas3D cv, long display, Drawable drawable, + long fbConfig, boolean offScreen, int width, int height, + boolean glslLibraryAvailable) { + if (VERBOSE) System.err.println("JoglPipeline.createQueryContext()"); + + // FIXME: for now, ignoring the "offscreen" flag -- unclear how + // to create an offscreen buffer at this point -- very likely + // need Canvas3D.offScreenBufferInfo promoted to an Object -- + // this logic will need to be revisited to make sure we capture + // all of the functionality of the NativePipeline + + Frame f = new Frame(); + f.setUndecorated(true); + f.setLayout(new BorderLayout()); + GLCapabilities caps = new GLCapabilities(getDefaultProfile()); + ContextQuerier querier = new ContextQuerier(cv, glslLibraryAvailable); + // FIXME: should know what GraphicsDevice on which to create + // this Canvas / Frame, and this should probably be known from + // the incoming "display" parameter + + JoglGraphicsConfiguration joglGraphicsConfiguration = (JoglGraphicsConfiguration) cv.graphicsConfiguration; + AWTGraphicsDevice awtGraphicsDevice = joglGraphicsConfiguration.getAwtGraphicsDevice(); + AWTGraphicsConfiguration awtGraphicsConfiguration = createAwtGraphicsConfiguration(caps, querier, awtGraphicsDevice/*null*/); + + QueryCanvas canvas = new QueryCanvas(awtGraphicsConfiguration, querier); + f.add(canvas, BorderLayout.CENTER); + f.setSize(MIN_FRAME_SIZE, MIN_FRAME_SIZE); + f.setVisible(true); + canvas.doQuery(); + // Attempt to wait for the frame to become visible, but don't block the EDT + if (!EventQueue.isDispatchThread()) { + synchronized(querier) { + if (!querier.done()) { + try { + querier.wait(WAIT_TIME); + } catch (InterruptedException e) { + } + } + } + } + + disposeOnEDT(f); + } + + // This is the native for creating an offscreen buffer + Drawable createOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, int width, int height) { + if (VERBOSE) System.err.println("JoglPipeline.createOffScreenBuffer()"); + + // Note 1: when this is called, the incoming Context argument is + // null because (obviously) no drawable or context has been + // created for the Canvas3D yet. + + // Note 2: we ignore the global j3d.usePbuffer flag; JOGL + // doesn't expose pixmap/bitmap surfaces in its public API. + + // First pick up the JoglGraphicsConfiguration and from there + // the GLCapabilities from the Canvas3D + JoglGraphicsConfiguration jcfg = (JoglGraphicsConfiguration) cv.graphicsConfiguration; + // Note that we ignore any chosen index from a prior call to getBestConfiguration(); + // those only enumerate the on-screen visuals, and we need to find one which is + // pbuffer capable + GLCapabilities caps = jcfg.getGLCapabilities(); + + //FIXME use the real AWTGraphicsDevice + GLPbuffer pbuffer = GLDrawableFactory.getFactory(getDefaultProfile()).createGLPbuffer(GLDrawableFactory.getDesktopFactory().getDefaultDevice() ,caps, null,width, height, GLContext.getCurrent()); + + return new JoglDrawable(pbuffer); + } + + void destroyOffScreenBuffer(Canvas3D cv, Context ctx, long display, long fbConfig, Drawable drawable) { + if (VERBOSE) System.err.println("JoglPipeline.destroyOffScreenBuffer()"); + + JoglDrawable jdraw = (JoglDrawable) drawable; + GLPbuffer pbuffer = (GLPbuffer) jdraw.getGLDrawable(); + pbuffer.destroy(); + } + + // This is the native for reading the image from the offscreen buffer + void readOffScreenBuffer(Canvas3D cv, Context ctx, int format, int dataType, Object data, int width, int height) { + if (VERBOSE) System.err.println("JoglPipeline.readOffScreenBuffer()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, width); + gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1); + + int type = 0; + if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_ARRAY) || + (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_BYTE_BUFFER)) { + + switch (format) { + // GL_BGR + case ImageComponentRetained.TYPE_BYTE_BGR: + type = GL2.GL_BGR; + break; + case ImageComponentRetained.TYPE_BYTE_RGB: + type = GL.GL_RGB; + break; + // GL_ABGR_EXT + case ImageComponentRetained.TYPE_BYTE_ABGR: + if (gl.isExtensionAvailable("GL_EXT_abgr")) { // If false, should never come here! + type = GL2.GL_ABGR_EXT; + } else { + assert false; + return; + } + break; + case ImageComponentRetained.TYPE_BYTE_RGBA: + type = GL.GL_RGBA; + break; + + /* This method only supports 3 and 4 components formats and BYTE types. */ + case ImageComponentRetained.TYPE_BYTE_LA: + case ImageComponentRetained.TYPE_BYTE_GRAY: + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_INT_BGR: + case ImageComponentRetained.TYPE_INT_RGB: + case ImageComponentRetained.TYPE_INT_ARGB: + default: + throw new AssertionError("illegal format " + format); + } + + gl.glReadPixels(0, 0, width, height, type, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap((byte[]) data)); + + } else if((dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_ARRAY) || + (dataType == ImageComponentRetained.IMAGE_DATA_TYPE_INT_BUFFER)) { + + int intType = GL2.GL_UNSIGNED_INT_8_8_8_8; + boolean forceAlphaToOne = false; + + switch (format) { + /* GL_BGR */ + case ImageComponentRetained.TYPE_INT_BGR: /* Assume XBGR format */ + type = GL.GL_RGBA; + intType = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + forceAlphaToOne = true; + break; + case ImageComponentRetained.TYPE_INT_RGB: /* Assume XRGB format */ + forceAlphaToOne = true; + /* Fall through to next case */ + case ImageComponentRetained.TYPE_INT_ARGB: + type = GL2.GL_BGRA; + intType = GL2.GL_UNSIGNED_INT_8_8_8_8_REV; + break; + /* This method only supports 3 and 4 components formats and BYTE types. */ + case ImageComponentRetained.TYPE_BYTE_LA: + case ImageComponentRetained.TYPE_BYTE_GRAY: + case ImageComponentRetained.TYPE_USHORT_GRAY: + case ImageComponentRetained.TYPE_BYTE_BGR: + case ImageComponentRetained.TYPE_BYTE_RGB: + case ImageComponentRetained.TYPE_BYTE_RGBA: + case ImageComponentRetained.TYPE_BYTE_ABGR: + default: + throw new AssertionError("illegal format " + format); + } + + /* Force Alpha to 1.0 if needed */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 0.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 1.0f); + } + + gl.glReadPixels(0, 0, width, height, type, intType, IntBuffer.wrap((int[]) data)); + + /* Restore Alpha scale and bias */ + if(forceAlphaToOne) { + gl.glPixelTransferf(GL2.GL_ALPHA_SCALE, 1.0f); + gl.glPixelTransferf(GL2.GL_ALPHA_BIAS, 0.0f); + } + + } else { + throw new AssertionError("illegal image data type " + dataType); + + } + } + + // The native method for swapBuffers + int swapBuffers(Canvas3D cv, Context ctx, long dpy, Drawable drawable) { + if (VERBOSE) System.err.println("JoglPipeline.swapBuffers()"); + GLDrawable draw = drawable(drawable); + draw.swapBuffers(); + return 0; + } + + // native method for setting Material when no material is present + void updateMaterialColor(Context ctx, float r, float g, float b, float a) { + if (VERBOSE) System.err.println("JoglPipeline.updateMaterialColor()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glColor4f(r, g, b, a); + gl.glDisable(GL2.GL_LIGHTING); + } + + void destroyContext(long display, Drawable drawable, Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.destroyContext()"); + GLDrawable draw = drawable(drawable); + GLContext context = context(ctx); + if (GLContext.getCurrent() == context) { + context.release(); + } + context.destroy(); + // FIXME: assuming this is the right point at which to make this call + draw.setRealized(false); + } + + // This is the native method for doing accumulation. + void accum(Context ctx, float value) { + if (VERBOSE) System.err.println("JoglPipeline.accum()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glReadBuffer(GL.GL_BACK); + gl.glAccum(GL2.GL_ACCUM, value); + gl.glReadBuffer(GL.GL_FRONT); + } + + // This is the native method for doing accumulation return. + void accumReturn(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.accumReturn()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glAccum(GL2.GL_RETURN, 1.0f); + } + + // This is the native method for clearing the accumulation buffer. + void clearAccum(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.clearAccum()"); + + GL gl = context(ctx).getGL(); + gl.glClear(GL2.GL_ACCUM_BUFFER_BIT); + } + + // This is the native method for getting the number of lights the underlying + // native library can support. + int getNumCtxLights(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.getNumCtxLights()"); + + GL gl = context(ctx).getGL(); + int[] res = new int[1]; + gl.glGetIntegerv(GL2.GL_MAX_LIGHTS, res, 0); + return res[0]; + } + + // Native method for decal 1st child setup + boolean decal1stChildSetup(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.decal1stChildSetup()"); + + GL gl = context(ctx).getGL(); + gl.glEnable(GL.GL_STENCIL_TEST); + gl.glClearStencil(0x0); + gl.glClear(GL.GL_STENCIL_BUFFER_BIT); + gl.glStencilFunc(GL.GL_ALWAYS, 0x1, 0x1); + gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_REPLACE); + if (gl.glIsEnabled(GL.GL_DEPTH_TEST)) + return true; + else + return false; + } + + // Native method for decal nth child setup + void decalNthChildSetup(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.decalNthChildSetup()"); + + GL gl = context(ctx).getGL(); + gl.glDisable(GL.GL_DEPTH_TEST); + gl.glStencilFunc(GL.GL_EQUAL, 0x1, 0x1); + gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); + } + + // Native method for decal reset + void decalReset(Context ctx, boolean depthBufferEnable) { + if (VERBOSE) System.err.println("JoglPipeline.decalReset()"); + + GL gl = context(ctx).getGL(); + gl.glDisable(GL.GL_STENCIL_TEST); + if (depthBufferEnable) + gl.glEnable(GL.GL_DEPTH_TEST); + } + + // Native method for eye lighting + void ctxUpdateEyeLightingEnable(Context ctx, boolean localEyeLightingEnable) { + if (VERBOSE) System.err.println("JoglPipeline.ctxUpdateEyeLightingEnable()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + if (localEyeLightingEnable) { + gl.glLightModeli(GL2.GL_LIGHT_MODEL_LOCAL_VIEWER, GL.GL_TRUE); + } else { + gl.glLightModeli(GL2.GL_LIGHT_MODEL_LOCAL_VIEWER, GL.GL_FALSE); + } + } + + // The following three methods are used in multi-pass case + + // native method for setting blend color + void setBlendColor(Context ctx, float red, float green, + float blue, float alpha) { + if (VERBOSE) System.err.println("JoglPipeline.setBlendColor()"); + + GL2 gl = context(ctx).getGL().getGL2(); + if (gl.isExtensionAvailable("GL_ARB_imaging")) { + gl.glBlendColor(red, green, blue, alpha); + } + } + + // native method for setting blend func + void setBlendFunc(Context ctx, int srcBlendFunction, int dstBlendFunction) { + if (VERBOSE) System.err.println("JoglPipeline.setBlendFunc()"); + + GL gl = context(ctx).getGL(); + gl.glEnable(GL.GL_BLEND); + gl.glBlendFunc(blendFunctionTable[srcBlendFunction], + blendFunctionTable[dstBlendFunction]); + } + + // native method for setting fog enable flag + void setFogEnableFlag(Context ctx, boolean enable) { + if (VERBOSE) System.err.println("JoglPipeline.setFogEnableFlag()"); + + GL gl = context(ctx).getGL(); + + if (enable) + gl.glEnable(GL2.GL_FOG); + else + gl.glDisable(GL2.GL_FOG); + } + + // Setup the full scene antialising in D3D and ogl when GL_ARB_multisamle supported + void setFullSceneAntialiasing(Context absCtx, boolean enable) { + if (VERBOSE) System.err.println("JoglPipeline.setFullSceneAntialiasing()"); + + JoglContext ctx = (JoglContext) absCtx; + GL gl = context(ctx).getGL(); + if (ctx.getHasMultisample() && !VirtualUniverse.mc.implicitAntialiasing) { + if (enable) { + gl.glEnable(GL.GL_MULTISAMPLE); + } else { + gl.glDisable(GL.GL_MULTISAMPLE); + } + } + } + + void setGlobalAlpha(Context ctx, float alpha) { + if (VERBOSE) System.err.println("JoglPipeline.setGlobalAlpha()"); +// FIXME: SUN_global_alpha +// GL gl = context(ctx).getGL(); +// if (gl.isExtensionAvailable("GL_SUN_global_alpha")) { +// gl.glEnable(GL.GL_GLOBAL_ALPHA_SUN); +// gl.glGlobalAlphaFactorfSUN(alpha); +// } + } + + // Native method to update separate specular color control + void updateSeparateSpecularColorEnable(Context ctx, boolean enable) { + if (VERBOSE) System.err.println("JoglPipeline.updateSeparateSpecularColorEnable()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + if (enable) { + gl.glLightModeli(GL2.GL_LIGHT_MODEL_COLOR_CONTROL, GL2.GL_SEPARATE_SPECULAR_COLOR); + } else { + gl.glLightModeli(GL2.GL_LIGHT_MODEL_COLOR_CONTROL, GL2.GL_SINGLE_COLOR); + } + } + + // True under Solaris, + // False under windows when display mode <= 8 bit + boolean validGraphicsMode() { + if (VERBOSE) System.err.println("JoglPipeline.validGraphicsMode()"); + + // FIXME: believe this should do exactly what the native code + // used to, but not 100% sure (also in theory should only run + // this code on the Windows platform? What about Mac OS X?) + DisplayMode currentMode = + GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode(); + // Note: on X11 platforms, a bit depth < 0 simply indicates that + // multiple visuals are supported on the current display mode + + if (VERBOSE) System.err.println(" Returning " + (currentMode.getBitDepth() < 0 || + currentMode.getBitDepth() > 8)); + + return (currentMode.getBitDepth() < 0 || + currentMode.getBitDepth() > 8); + } + + // native method for setting light enables + void setLightEnables(Context ctx, long enableMask, int maxLights) { + if (VERBOSE) System.err.println("JoglPipeline.setLightEnables()"); + + GL gl = context(ctx).getGL(); + + for (int i = 0; i < maxLights; i++) { + if ((enableMask & (1 << i)) != 0) { + gl.glEnable(GL2.GL_LIGHT0 + i); + } else { + gl.glDisable(GL2.GL_LIGHT0 + i); + } + } + } + + // native method for setting scene ambient + void setSceneAmbient(Context ctx, float red, float green, float blue) { + if (VERBOSE) System.err.println("JoglPipeline.setSceneAmbient()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + float[] color = new float[4]; + color[0] = red; + color[1] = green; + color[2] = blue; + color[3] = 1.0f; + gl.glLightModelfv(GL2.GL_LIGHT_MODEL_AMBIENT, color, 0); + } + + // native method for disabling fog + void disableFog(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.disableFog()"); + + GL gl = context(ctx).getGL(); + gl.glDisable(GL2.GL_FOG); + } + + // native method for disabling modelClip + void disableModelClip(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.disableModelClip()"); + + GL gl = context(ctx).getGL(); + + gl.glDisable(GL2.GL_CLIP_PLANE0); + gl.glDisable(GL2.GL_CLIP_PLANE1); + gl.glDisable(GL2.GL_CLIP_PLANE2); + gl.glDisable(GL2.GL_CLIP_PLANE3); + gl.glDisable(GL2.GL_CLIP_PLANE4); + gl.glDisable(GL2.GL_CLIP_PLANE5); + } + + // native method for setting default RenderingAttributes + void resetRenderingAttributes(Context ctx, + boolean depthBufferWriteEnableOverride, + boolean depthBufferEnableOverride) { + if (VERBOSE) System.err.println("JoglPipeline.resetRenderingAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + if (!depthBufferWriteEnableOverride) { + gl.glDepthMask(true); + } + if (!depthBufferEnableOverride) { + gl.glEnable(GL.GL_DEPTH_TEST); + } + gl.glAlphaFunc(GL.GL_ALWAYS, 0.0f); + gl.glDepthFunc(GL.GL_LEQUAL); + gl.glEnable(GL2.GL_COLOR_MATERIAL); + gl.glDisable(GL.GL_COLOR_LOGIC_OP); + } + + // native method for setting default texture + void resetTextureNative(Context ctx, int texUnitIndex) { + if (VERBOSE) System.err.println("JoglPipeline.resetTextureNative()"); + + GL2 gl = context(ctx).getGL().getGL2(); + if (texUnitIndex >= 0 && + gl.isExtensionAvailable("GL_VERSION_1_3")) { + gl.glActiveTexture(texUnitIndex + GL.GL_TEXTURE0); + gl.glClientActiveTexture(texUnitIndex + GL.GL_TEXTURE0); + } + + gl.glDisable(GL2.GL_TEXTURE_1D); + gl.glDisable(GL.GL_TEXTURE_2D); + gl.glDisable(GL2.GL_TEXTURE_3D); + gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); + } + + // native method for activating a particular texture unit + void activeTextureUnit(Context ctx, int texUnitIndex) { + if (VERBOSE) System.err.println("JoglPipeline.activeTextureUnit()"); + + GL2 gl = context(ctx).getGL().getGL2(); + if (gl.isExtensionAvailable("GL_VERSION_1_3")) { + gl.glActiveTexture(texUnitIndex + GL.GL_TEXTURE0); + gl.glClientActiveTexture(texUnitIndex + GL.GL_TEXTURE0); + } + } + + // native method for setting default TexCoordGeneration + void resetTexCoordGeneration(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.resetTexCoordGeneration()"); + + GL gl = context(ctx).getGL(); + gl.glDisable(GL2.GL_TEXTURE_GEN_S); + gl.glDisable(GL2.GL_TEXTURE_GEN_T); + gl.glDisable(GL2.GL_TEXTURE_GEN_R); + gl.glDisable(GL2.GL_TEXTURE_GEN_Q); + } + + // native method for setting default TextureAttributes + void resetTextureAttributes(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.resetTextureAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + float[] color = new float[4]; + + gl.glPushAttrib(GL2.GL_TRANSFORM_BIT); + gl.glMatrixMode(GL.GL_TEXTURE); + gl.glLoadIdentity(); + gl.glPopAttrib(); + gl.glTexEnvfv(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_COLOR, color, 0); + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); + gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST); + +// FIXME: GL_NV_register_combiners +// if (gl.isExtensionAvailable("GL_NV_register_combiners")) { +// gl.glDisable(GL.GL_REGISTER_COMBINERS_NV); +// } + +// FIXME: GL_SGI_texture_color_table +// if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) { +// gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI); +// } + } + + // native method for setting default PolygonAttributes + void resetPolygonAttributes(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.resetPolygonAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + gl.glCullFace(GL.GL_BACK); + gl.glEnable(GL.GL_CULL_FACE); + + gl.glLightModeli(GL2.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_FALSE); + + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL); + + gl.glPolygonOffset(0.0f, 0.0f); + gl.glDisable(GL2.GL_POLYGON_OFFSET_POINT); + gl.glDisable(GL2.GL_POLYGON_OFFSET_LINE); + gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); + } + + // native method for setting default LineAttributes + void resetLineAttributes(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.resetLineAttributes()"); + + GL gl = context(ctx).getGL(); + gl.glLineWidth(1.0f); + gl.glDisable(GL2.GL_LINE_STIPPLE); + + // XXXX: Polygon Mode check, blend enable + gl.glDisable(GL.GL_LINE_SMOOTH); + } + + // native method for setting default PointAttributes + void resetPointAttributes(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.resetPointAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glPointSize(1.0f); + + // XXXX: Polygon Mode check, blend enable + gl.glDisable(GL2.GL_POINT_SMOOTH); + } + + // native method for setting default TransparencyAttributes + void resetTransparency(Context ctx, int geometryType, + int polygonMode, boolean lineAA, + boolean pointAA) { + if (VERBOSE) System.err.println("JoglPipeline.resetTransparency()"); + + GL gl = context(ctx).getGL(); + + if (((((geometryType & RenderMolecule.LINE) != 0) || + (polygonMode == PolygonAttributes.POLYGON_LINE)) + && lineAA) || + ((((geometryType & RenderMolecule.POINT) != 0) || + (polygonMode == PolygonAttributes.POLYGON_POINT)) + && pointAA)) { + gl.glEnable(GL.GL_BLEND); + gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); + } else { + gl.glDisable(GL.GL_BLEND); + } + gl.glDisable(GL2.GL_POLYGON_STIPPLE); + } + + // native method for setting default ColoringAttributes + void resetColoringAttributes(Context ctx, + float r, float g, + float b, float a, + boolean enableLight) { + if (VERBOSE) System.err.println("JoglPipeline.resetColoringAttributes()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + if (!enableLight) { + gl.glColor4f(r, g, b, a); + } + gl.glShadeModel(GL2.GL_SMOOTH); + } + + /** + * This native method makes sure that the rendering for this canvas + * gets done now. + */ + void syncRender(Context ctx, boolean wait) { + if (VERBOSE) System.err.println("JoglPipeline.syncRender()"); + + GL gl = context(ctx).getGL(); + + if (wait) + gl.glFinish(); + else + gl.glFlush(); + } + + // The native method that sets this ctx to be the current one + boolean useCtx(Context ctx, long display, Drawable drawable) { + if (VERBOSE) System.err.println("JoglPipeline.useCtx()"); + GLContext context = context(ctx); + int res = context.makeCurrent(); + return (res != GLContext.CONTEXT_NOT_CURRENT); + } + + // Optionally release the context. Returns true if the context was released. + boolean releaseCtx(Context ctx, long dpy) { + if (VERBOSE) System.err.println("JoglPipeline.releaseCtx()"); + GLContext context = context(ctx); + context.release(); + return true; + } + + void clear(Context ctx, float r, float g, float b, boolean clearStencil) { + if (VERBOSE) System.err.println("JoglPipeline.clear()"); + + JoglContext jctx = (JoglContext) ctx; + GLContext context = context(ctx); + GL2 gl = context.getGL().getGL2(); + + // OBSOLETE CLEAR CODE + /* + gl.glClearColor(r, g, b, jctx.getAlphaClearValue()); + gl.glClear(GL.GL_COLOR_BUFFER_BIT); + + // Java 3D always clears the Z-buffer + gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT); + gl.glDepthMask(true); + gl.glClear(GL.GL_DEPTH_BUFFER_BIT); + gl.glPopAttrib(); + + // Issue 239 - clear stencil if specified + if (clearStencil) { + gl.glPushAttrib(GL.GL_STENCIL_BUFFER_BIT); + gl.glClearStencil(0); + gl.glStencilMask(~0); + gl.glClear(GL.GL_STENCIL_BUFFER_BIT); + gl.glPopAttrib(); + } + */ + + // Mask of which buffers to clear, this always includes color & depth + int clearMask = GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT; + + // Issue 239 - clear stencil if specified + if (clearStencil) { + gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT); + + gl.glClearStencil(0); + gl.glStencilMask(~0); + clearMask |= GL.GL_STENCIL_BUFFER_BIT; + } else { + gl.glPushAttrib(GL.GL_DEPTH_BUFFER_BIT); + } + + gl.glDepthMask(true); + gl.glClearColor(r, g, b, jctx.getAlphaClearValue()); + gl.glClear(clearMask); + gl.glPopAttrib(); + + } + + void textureFillBackground(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV, + float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, boolean useBilinearFilter) { + if (VERBOSE) System.err.println("JoglPipeline.textureFillBackground()"); + + GLContext context = context(ctx); + GL2 gl = context.getGL().getGL2(); + + // Temporarily disable fragment and most 3D operations + gl.glPushAttrib(GL2.GL_ENABLE_BIT | GL2.GL_TEXTURE_BIT | GL2.GL_POLYGON_BIT); + + disableAttribFor2D(gl); + gl.glDepthMask(false); + gl.glEnable(GL.GL_TEXTURE_2D); + + /* Setup filter mode if needed */ + if(useBilinearFilter) { + // System.err.println("JoglPipeline - Background : use bilinear filter\n"); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); + } + + // reset the polygon mode + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL); + + gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); + + // load identity modelview and projection matrix + gl.glMatrixMode(GL2.GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + gl.glMatrixMode(GL2.GL_MODELVIEW); + gl.glLoadIdentity(); + gl.glMatrixMode(GL.GL_TEXTURE); + gl.glPushMatrix(); + gl.glLoadIdentity(); + + gl.glBegin(GL2.GL_QUADS); + gl.glTexCoord2f(texMinU, texMinV); gl.glVertex2f(mapMinX,mapMinY); + gl.glTexCoord2f(texMaxU, texMinV); gl.glVertex2f(mapMaxX,mapMinY); + gl.glTexCoord2f(texMaxU, texMaxV); gl.glVertex2f(mapMaxX,mapMaxY); + gl.glTexCoord2f(texMinU, texMaxV); gl.glVertex2f(mapMinX,mapMaxY); + gl.glEnd(); + + // Restore texture Matrix transform + gl.glPopMatrix(); + + gl.glMatrixMode(GL2.GL_MODELVIEW); + // Restore attributes + gl.glPopAttrib(); + + } + + void textureFillRaster(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV, + float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, float mapZ, float alpha, + boolean useBilinearFilter) { + + if (VERBOSE) System.err.println("JoglPipeline.textureFillRaster()"); + + GLContext context = context(ctx); + GL2 gl = context.getGL().getGL2(); + + // Temporarily disable fragment and most 3D operations + gl.glPushAttrib(GL2.GL_ENABLE_BIT | GL2.GL_TEXTURE_BIT | GL2.GL_POLYGON_BIT | + GL2.GL_CURRENT_BIT ); + + disableAttribForRaster(gl); + + /* Setup filter mode if needed */ + if(useBilinearFilter) { + // System.err.println("JoglPipeline - Raster : use bilinear filter\n"); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); + } + + gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE); + gl.glColor4f(1.0f, 1.0f, 1.0f, alpha); + + // reset the polygon mode + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL); + + gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); + + // load identity modelview and projection matrix + gl.glMatrixMode(GL2.GL_MODELVIEW); + gl.glPushMatrix(); + gl.glLoadIdentity(); + gl.glMatrixMode(GL2.GL_PROJECTION); + gl.glPushMatrix(); + gl.glLoadIdentity(); + gl.glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0); + + gl.glBegin(GL2.GL_QUADS); + gl.glTexCoord2f(texMinU, texMinV); gl.glVertex3f(mapMinX,mapMinY, mapZ); + gl.glTexCoord2f(texMaxU, texMinV); gl.glVertex3f(mapMaxX,mapMinY, mapZ); + gl.glTexCoord2f(texMaxU, texMaxV); gl.glVertex3f(mapMaxX,mapMaxY, mapZ); + gl.glTexCoord2f(texMinU, texMaxV); gl.glVertex3f(mapMinX,mapMaxY, mapZ); + gl.glEnd(); + + // Restore matrices + gl.glPopMatrix(); + gl.glMatrixMode(GL2.GL_MODELVIEW); + gl.glPopMatrix(); + // Restore attributes + gl.glPopAttrib(); + + } + + void executeRasterDepth(Context ctx, float posX, float posY, float posZ, + int srcOffsetX, int srcOffsetY, int rasterWidth, int rasterHeight, + int depthWidth, int depthHeight, int depthFormat, Object depthData) { + if (VERBOSE) System.err.println("JoglPipeline.executeRasterDepth()"); + GLContext context = context(ctx); + GL2 gl = context.getGL().getGL2(); + + + gl.glRasterPos3f(posX, posY, posZ); + + int[] drawBuf = new int[1]; + gl.glGetIntegerv(GL2.GL_DRAW_BUFFER, drawBuf, 0); + /* disable draw buffer */ + gl.glDrawBuffer(GL.GL_NONE); + + /* + * raster position is upper left corner, default for Java3D + * ImageComponent currently has the data reverse in Y + */ + gl.glPixelZoom(1.0f, -1.0f); + gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, depthWidth); + if (srcOffsetX >= 0) { + gl.glPixelStorei(GL2.GL_UNPACK_SKIP_PIXELS, srcOffsetX); + if (srcOffsetX + rasterWidth > depthWidth) { + rasterWidth = depthWidth - srcOffsetX; + } + } else { + rasterWidth += srcOffsetX; + if (rasterWidth > depthWidth) { + rasterWidth = depthWidth; + } + } + if (srcOffsetY >= 0) { + gl.glPixelStorei(GL2.GL_UNPACK_SKIP_ROWS, srcOffsetY); + if (srcOffsetY + rasterHeight > depthHeight) { + rasterHeight = depthHeight - srcOffsetY; + } + } else { + rasterHeight += srcOffsetY; + if (rasterHeight > depthHeight) { + rasterHeight = depthHeight; + } + } + + + if (depthFormat == DepthComponentRetained.DEPTH_COMPONENT_TYPE_INT) { + gl.glDrawPixels(rasterWidth, rasterHeight, GL2.GL_DEPTH_COMPONENT, + GL.GL_UNSIGNED_INT, IntBuffer.wrap((int[]) depthData)); + } else { /* DepthComponentRetained.DEPTH_COMPONENT_TYPE_FLOAT */ + gl.glDrawPixels(rasterWidth, rasterHeight, GL2.GL_DEPTH_COMPONENT, + GL.GL_FLOAT, FloatBuffer.wrap((float[]) depthData)); + } + + /* re-enable draw buffer */ + gl.glDrawBuffer(drawBuf[0]); + + gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, 0); + gl.glPixelStorei(GL2.GL_UNPACK_SKIP_PIXELS, 0); + gl.glPixelStorei(GL2.GL_UNPACK_SKIP_ROWS, 0); + + } + + // The native method for setting the ModelView matrix. + void setModelViewMatrix(Context ctx, double[] viewMatrix, double[] modelMatrix) { + if (VERBOSE) System.err.println("JoglPipeline.setModelViewMatrix()"); + GLContext context = context(ctx); + GL2 gl = context.getGL().getGL2(); + + gl.glMatrixMode(GL2.GL_MODELVIEW); + + if (gl.isExtensionAvailable("GL_VERSION_1_3")) { + gl.glLoadTransposeMatrixd(viewMatrix, 0); + gl.glMultTransposeMatrixd(modelMatrix, 0); + } else { + double[] v = new double[16]; + double[] m = new double[16]; + copyTranspose(viewMatrix, v); + copyTranspose(modelMatrix, m); + gl.glLoadMatrixd(v, 0); + gl.glMultMatrixd(m, 0); + } + } + + // The native method for setting the Projection matrix. + void setProjectionMatrix(Context ctx, double[] projMatrix) { + if (VERBOSE) System.err.println("JoglPipeline.setProjectionMatrix()"); + GLContext context = context(ctx); + GL2 gl = context.getGL().getGL2(); + + gl.glMatrixMode(GL2.GL_PROJECTION); + + if (gl.isExtensionAvailable("GL_VERSION_1_3")) { + // Invert the Z value in clipping coordinates because OpenGL uses + // left-handed clipping coordinates, while Java3D defines right-handed + // coordinates everywhere. + projMatrix[8] *= -1.0; + projMatrix[9] *= -1.0; + projMatrix[10] *= -1.0; + projMatrix[11] *= -1.0; + gl.glLoadTransposeMatrixd(projMatrix, 0); + projMatrix[8] *= -1.0; + projMatrix[9] *= -1.0; + projMatrix[10] *= -1.0; + projMatrix[11] *= -1.0; + } else { + double[] p = new double[16]; + copyTranspose(projMatrix, p); + // Invert the Z value in clipping coordinates because OpenGL uses + // left-handed clipping coordinates, while Java3D defines right-handed + // coordinates everywhere. + p[2] *= -1.0; + p[6] *= -1.0; + p[10] *= -1.0; + p[14] *= -1.0; + gl.glLoadMatrixd(p, 0); + } + } + + // The native method for setting the Viewport. + void setViewport(Context ctx, int x, int y, int width, int height) { + if (VERBOSE) System.err.println("JoglPipeline.setViewport()"); + GL gl = context(ctx).getGL(); + gl.glViewport(x, y, width, height); + } + + // used for display Lists + void newDisplayList(Context ctx, int displayListId) { + if (VERBOSE) System.err.println("JoglPipeline.newDisplayList()"); + if (displayListId <= 0) { + System.err.println("JAVA 3D ERROR : glNewList(" + displayListId + ") -- IGNORED"); + } + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glNewList(displayListId, GL2.GL_COMPILE); + } + + void endDisplayList(Context ctx) { + if (VERBOSE) System.err.println("JoglPipeline.endDisplayList()"); + GL2 gl = context(ctx).getGL().getGL2(); + gl.glEndList(); + } + + int numInvalidLists = 0; + void callDisplayList(Context ctx, int id, boolean isNonUniformScale) { + if (VERBOSE) System.err.println("JoglPipeline.callDisplayList()"); + if (id <= 0) { + if (numInvalidLists < 3) { + ++numInvalidLists; + System.err.println("JAVA 3D ERROR : glCallList(" + id + ") -- IGNORED"); + } else if (numInvalidLists == 3) { + ++numInvalidLists; + System.err.println("JAVA 3D : further glCallList error messages discarded"); + } + return; + } + + GL2 gl = context(ctx).getGL().getGL2(); + // Set normalization if non-uniform scale + if (isNonUniformScale) { + gl.glEnable(GL2.GL_NORMALIZE); + } + + gl.glCallList(id); + + // Turn normalization back off + if (isNonUniformScale) { + gl.glDisable(GL2.GL_NORMALIZE); + } + } + + void freeDisplayList(Context ctx, int id) { + if (VERBOSE) System.err.println("JoglPipeline.freeDisplayList()"); + if (id <= 0) { + System.err.println("JAVA 3D ERROR : glDeleteLists(" + id + ",1) -- IGNORED"); + } + + GL2 gl = context(ctx).getGL().getGL2(); + gl.glDeleteLists(id, 1); + } + void freeTexture(Context ctx, int id) { + if (VERBOSE) System.err.println("JoglPipeline.freeTexture()"); + + GL gl = context(ctx).getGL(); + + if (id > 0) { + int[] tmp = new int[1]; + tmp[0] = id; + gl.glDeleteTextures(1, tmp, 0); + } else { + System.err.println("tried to delete tex with texid <= 0"); + } + } + + + void texturemapping(Context ctx, + int px, int py, + int minX, int minY, int maxX, int maxY, + int texWidth, int texHeight, + int rasWidth, + int format, int objectId, + byte[] imageYdown, + int winWidth, int winHeight) { + if (VERBOSE) System.err.println("JoglPipeline.texturemapping()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + int glType = GL.GL_RGBA; + + // Temporarily disable fragment and most 3D operations + gl.glPushAttrib(GL2.GL_ENABLE_BIT | GL2.GL_TEXTURE_BIT | GL.GL_DEPTH_BUFFER_BIT | GL2.GL_POLYGON_BIT); + disableAttribFor2D(gl); + + // Reset the polygon mode + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL); + + gl.glDepthMask(false); + gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); + gl.glBindTexture(GL.GL_TEXTURE_2D, objectId); + // set up texture parameter + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT); + + gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); + gl.glEnable(GL.GL_BLEND); + gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); + + gl.glEnable(GL.GL_TEXTURE_2D); + + // loaded identity modelview and projection matrix + gl.glMatrixMode(GL2.GL_PROJECTION); + gl.glLoadIdentity(); + + gl.glOrtho(0.0, winWidth, 0.0, winHeight, 0.0, 0.0); + + gl.glMatrixMode(GL2.GL_MODELVIEW); + gl.glLoadIdentity(); + + if (gl.isExtensionAvailable("GL_EXT_abgr")) { + glType = GL2.GL_ABGR_EXT; + } else { + switch (format) { + case ImageComponentRetained.TYPE_BYTE_RGBA: + glType = GL.GL_RGBA; + break; + case ImageComponentRetained.TYPE_BYTE_RGB: + glType = GL.GL_RGB; + break; + } + } + gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, rasWidth); + gl.glPixelStorei(GL2.GL_UNPACK_SKIP_PIXELS, minX); + gl.glPixelStorei(GL2.GL_UNPACK_SKIP_ROWS, minY); + gl.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, minX, minY, + maxX - minX, maxY - minY, + glType, GL.GL_UNSIGNED_BYTE, + ByteBuffer.wrap(imageYdown)); + gl.glPixelStorei(GL2.GL_UNPACK_ROW_LENGTH, 0); + gl.glPixelStorei(GL2.GL_UNPACK_SKIP_PIXELS, 0); + gl.glPixelStorei(GL2.GL_UNPACK_SKIP_ROWS, 0); + + float texMinU = (float) minX/ (float) texWidth; + float texMinV = (float) minY/ (float) texHeight; + float texMaxU = (float) maxX/ (float) texWidth; + float texMaxV = (float) maxY/ (float) texHeight; + float halfWidth = (float)winWidth/2.0f; + float halfHeight = (float)winHeight/2.0f; + + float mapMinX = (float) (((px + minX)- halfWidth)/halfWidth); + float mapMinY = (float) ((halfHeight - (py + maxY))/halfHeight); + float mapMaxX = (float) ((px + maxX - halfWidth)/halfWidth); + float mapMaxY = (float) ((halfHeight - (py + minY))/halfHeight); + + gl.glBegin(GL2.GL_QUADS); + + gl.glTexCoord2f(texMinU, texMaxV); gl.glVertex2f(mapMinX,mapMinY); + gl.glTexCoord2f(texMaxU, texMaxV); gl.glVertex2f(mapMaxX,mapMinY); + gl.glTexCoord2f(texMaxU, texMinV); gl.glVertex2f(mapMaxX,mapMaxY); + gl.glTexCoord2f(texMinU, texMinV); gl.glVertex2f(mapMinX,mapMaxY); + gl.glEnd(); + + // Java 3D always clears the Z-buffer + gl.glDepthMask(true); + gl.glClear(GL.GL_DEPTH_BUFFER_BIT); + gl.glPopAttrib(); + } + + boolean initTexturemapping(Context ctx, int texWidth, + int texHeight, int objectId) { + if (VERBOSE) System.err.println("JoglPipeline.initTexturemapping()"); + + GL2 gl = context(ctx).getGL().getGL2(); + + int glType = (gl.isExtensionAvailable("GL_EXT_abgr") ? GL2.GL_ABGR_EXT : GL.GL_RGBA); + + gl.glBindTexture(GL.GL_TEXTURE_2D, objectId); + + gl.glTexImage2D(GL2.GL_PROXY_TEXTURE_2D, 0, GL.GL_RGBA, texWidth, + texHeight, 0, glType, GL.GL_UNSIGNED_BYTE, null); + + int[] width = new int[1]; + gl.glGetTexLevelParameteriv(GL2.GL_PROXY_TEXTURE_2D, 0, + GL2.GL_TEXTURE_WIDTH, width, 0); + + if (width[0] <= 0) { + return false; + } + + // init texture size only without filling the pixels + gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, texWidth, + texHeight, 0, glType, GL.GL_UNSIGNED_BYTE, null); + + return true; + } + + + // Set internal render mode to one of FIELD_ALL, FIELD_LEFT or + // FIELD_RIGHT. Note that it is up to the caller to ensure that + // stereo is available before setting the mode to FIELD_LEFT or + // FIELD_RIGHT. The boolean isTRUE for double buffered mode, FALSE + // foe single buffering. + void setRenderMode(Context ctx, int mode, boolean doubleBuffer) { + if (VERBOSE) System.err.println("JoglPipeline.setRenderMode()"); + + GL2 gl = context(ctx).getGL().getGL2(); + int drawBuf = 0; + if (doubleBuffer) { + drawBuf = GL.GL_BACK; + switch (mode) { + case Canvas3D.FIELD_LEFT: + drawBuf = GL2.GL_BACK_LEFT; + break; + case Canvas3D.FIELD_RIGHT: + drawBuf = GL2.GL_BACK_RIGHT; + break; + case Canvas3D.FIELD_ALL: + drawBuf = GL.GL_BACK; + break; + } + } else { + drawBuf = GL.GL_FRONT; + switch (mode) { + case Canvas3D.FIELD_LEFT: + drawBuf = GL2.GL_FRONT_LEFT; + break; + case Canvas3D.FIELD_RIGHT: + drawBuf = GL2.GL_FRONT_RIGHT; + break; + case Canvas3D.FIELD_ALL: + drawBuf = GL.GL_FRONT; + break; + } + } + + gl.glDrawBuffer(drawBuf); + } + + // Set glDepthMask. + void setDepthBufferWriteEnable(Context ctx, boolean mode) { + if (VERBOSE) System.err.println("JoglPipeline.setDepthBufferWriteEnable()"); + + GL gl = context(ctx).getGL(); + if (mode) { + gl.glDepthMask(true); + } else { + gl.glDepthMask(false); + } + } + + //---------------------------------------------------------------------- + // Helper private functions for Canvas3D + // + + private boolean getPropertiesFromCurrentContext(JoglContext ctx) { + GL gl = GLU.getCurrentGL(); + // FIXME: this is a heavily abridged set of the stuff in Canvas3D.c; + // probably need to pull much more in + int[] tmp = new int[1]; + gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_UNITS, tmp, 0); + ctx.setMaxTexCoordSets(tmp[0]); + if (VirtualUniverse.mc.transparentOffScreen) { + ctx.setAlphaClearValue(0.0f); + } else { + ctx.setAlphaClearValue(1.0f); + } + if (gl.isExtensionAvailable("GL_ARB_vertex_shader")) { + gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_COORDS_ARB, tmp, 0); + ctx.setMaxTexCoordSets(tmp[0]); + } + return true; + } + + private int[] extractVersionInfo(String versionString) { + StringTokenizer tok = new StringTokenizer(versionString, ". "); + int major = Integer.valueOf(tok.nextToken()).intValue(); + int minor = Integer.valueOf(tok.nextToken()).intValue(); + + // See if there's vendor-specific information which might + // imply a more recent OpenGL version + tok = new StringTokenizer(versionString, " "); + if (tok.hasMoreTokens()) { + tok.nextToken(); + if (tok.hasMoreTokens()) { + Pattern p = Pattern.compile("\\D*(\\d+)\\.(\\d+)\\.?(\\d*).*"); + Matcher m = p.matcher(tok.nextToken()); + if (m.matches()) { + int altMajor = Integer.valueOf(m.group(1)).intValue(); + int altMinor = Integer.valueOf(m.group(2)).intValue(); + // Avoid possibly confusing situations by requiring + // major version to match + if (altMajor == major && + altMinor > minor) { + minor = altMinor; + } + } + } + } + return new int[] { major, minor }; + } + +// FIXME: GL_SGI_texture_color_table +// private int getTextureColorTableSize(GL gl) { +// if (!gl.isExtensionAvailable("GL_ARB_imaging")) { +// return 0; +// } +// +// gl.glColorTable(GL.GL_PROXY_TEXTURE_COLOR_TABLE_SGI, GL.GL_RGBA, 256, GL.GL_RGB, +// GL2.GL_INT, null); +// int[] tmp = new int[1]; +// gl.glGetColorTableParameteriv(GL.GL_PROXY_TEXTURE_COLOR_TABLE_SGI, +// GL2.GL_COLOR_TABLE_WIDTH, tmp, 0); +// return tmp[0]; +// } + + + private void checkTextureExtensions(Canvas3D cv, + JoglContext ctx, + GL gl, + boolean gl13) { + if (gl13) { + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_MULTI_TEXTURE; + cv.multiTexAccelerated = true; + int[] tmp = new int[1]; + gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_UNITS, tmp, 0); + cv.maxTextureUnits = tmp[0]; + cv.maxTexCoordSets = cv.maxTextureUnits; + if (gl.isExtensionAvailable("GL_ARB_vertex_shader")) { + gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_COORDS_ARB, tmp, 0); + cv.maxTexCoordSets = tmp[0]; + } + } +// FIXME: GL_SGI_texture_color_table +// if (gl.isExtensionAvailable("GL_SGI_texture_color_table") || +// gl.isExtensionAvailable("GL_ARB_imaging")) { +// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COLOR_TABLE; +// +// // get texture color table size +// // need to check later +// cv.textureColorTableSize = getTextureColorTableSize(gl); +// if (cv.textureColorTableSize <= 0) { +// cv.textureExtendedFeatures &= ~Canvas3D.TEXTURE_COLOR_TABLE; +// } +// if (cv.textureColorTableSize > 256) { +// cv.textureColorTableSize = 256; +// } +// } + + if (gl.isExtensionAvailable("GL_ARB_texture_env_combine")) { + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE; + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE_SUBTRACT; + } else if (gl.isExtensionAvailable("GL_EXT_texture_env_combine")) { + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE; + } + +// FIXME: GL_NV_register_combiners +// if (gl.isExtensionAvailable("GL_NV_register_combiners")) { +// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_REGISTER_COMBINERS; +// } + + if (gl.isExtensionAvailable("GL_ARB_texture_env_dot3") || + gl.isExtensionAvailable("GL_EXT_texture_env_dot3")) { + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_COMBINE_DOT3; + } + + if (gl13) { + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_CUBE_MAP; + } + +// FIXME: GL_SGIS_sharpen_texture +// if (gl.isExtensionAvailable("GL_SGIS_sharpen_texture")) { +// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_SHARPEN; +// } + +// FIXME: GL_SGIS_sharpen_texture +// if (gl.isExtensionAvailable("GL_SGIS_detail_texture")) { +// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_DETAIL; +// } + +// FIXME: GL_SGIS_texture_filter4 +// if (gl.isExtensionAvailable("GL_SGIS_texture_filter4")) { +// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_FILTER4; +// } + + if (gl.isExtensionAvailable("GL_EXT_texture_filter_anisotropic")) { + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_ANISOTROPIC_FILTER; + float[] tmp = new float[1]; + gl.glGetFloatv(GL. GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, tmp, 0); + cv.anisotropicDegreeMax = tmp[0]; + } + +// FIXME: GL_SGIX_texture_lod_bias +// if (gl.isExtensionAvailable("GL_SGIX_texture_lod_bias")) { +// cv.textureExtendedFeatures |= Canvas3D.TEXTURE_LOD_OFFSET; +// } + + if (!VirtualUniverse.mc.enforcePowerOfTwo && + gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two")) { + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_NON_POWER_OF_TWO; + } + + if (gl.isExtensionAvailable("GL_SGIS_generate_mipmap")) { + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_AUTO_MIPMAP_GENERATION; + } + + } + + + private void checkGLSLShaderExtensions(Canvas3D cv, + JoglContext ctx, + GL gl, + boolean glslLibraryAvailable) { + if (glslLibraryAvailable && + gl.isExtensionAvailable("GL_ARB_shader_objects") && + gl.isExtensionAvailable("GL_ARB_shading_language_100")) { + // Initialize shader vertex attribute function pointers + ctx.initGLSLVertexAttributeImpl(); + + // FIXME: this isn't complete and would need to set up the + // JoglContext for dispatch of various routines such as those + // related to vertex attributes + int[] tmp = new int[1]; + gl.glGetIntegerv(GL2.GL_MAX_TEXTURE_IMAGE_UNITS_ARB, tmp, 0); + cv.maxTextureImageUnits = tmp[0]; + gl.glGetIntegerv(GL2.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, tmp, 0); + cv.maxVertexTextureImageUnits = tmp[0]; + gl.glGetIntegerv(GL2.GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, tmp, 0); + cv.maxCombinedTextureImageUnits = tmp[0]; + int vertexAttrOffset = VirtualUniverse.mc.glslVertexAttrOffset; + ctx.setGLSLVertexAttrOffset(vertexAttrOffset); + gl.glGetIntegerv(GL2.GL_MAX_VERTEX_ATTRIBS_ARB, tmp, 0); + cv.maxVertexAttrs = tmp[0]; + // decr count to allow for reserved vertex attrs + cv.maxVertexAttrs -= vertexAttrOffset; + if (cv.maxVertexAttrs < 0) { + cv.maxVertexAttrs = 0; + } + cv.shadingLanguageGLSL = true; + } + } + + private void setupCanvasProperties(Canvas3D cv, + JoglContext ctx, + GL gl, + boolean glslLibraryAvailable) { + // Note: this includes relevant portions from both the + // NativePipeline's getPropertiesFromCurrentContext and setupCanvasProperties + + // Reset all fields + cv.multiTexAccelerated = false; + cv.maxTextureUnits = 1; + cv.maxTexCoordSets = 1; + cv.maxTextureImageUnits = 0; + cv.maxVertexTextureImageUnits = 0; + cv.maxCombinedTextureImageUnits = 0; + cv.maxVertexAttrs = 0; + cv.extensionsSupported = 0; + cv.textureExtendedFeatures = 0; + cv.textureColorTableSize = 0; + cv.anisotropicDegreeMax = 0; + cv.textureBoundaryWidthMax = 0; + cv.textureWidthMax = 0; + cv.textureHeightMax = 0; + cv.texture3DWidthMax = 0; + cv.texture3DHeightMax = 0; + cv.texture3DDepthMax = 0; + cv.shadingLanguageGLSL = false; + + // Now make queries and set up these fields + String glVersion = gl.glGetString(GL.GL_VERSION); + String glVendor = gl.glGetString(GL.GL_VENDOR); + String glRenderer = gl.glGetString(GL.GL_RENDERER); + cv.nativeGraphicsVersion = glVersion; + cv.nativeGraphicsVendor = glVendor; + cv.nativeGraphicsRenderer = glRenderer; + + // find out the version, major and minor version number + int[] versionNumbers = extractVersionInfo(glVersion); + int major = versionNumbers[0]; + int minor = versionNumbers[1]; + + /////////////////////////////////////////// + // setup the graphics context properties // + + // NOTE: Java 3D now requires OpenGL 1.3 for full functionality. + // For backwards compatibility with certain older graphics cards and + // drivers (e.g., the Linux DRI driver for older ATI cards), + // we will try to run on OpenGL 1.2 in an unsupported manner. However, + // we will not attempt to use OpenGL extensions for any features that + // are available in OpenGL 1.3, specifically multitexture, multisample, + // and cube map textures. + + if (major < 1 || (major == 1 && minor < 2)) { + throw new IllegalRenderingStateException( + "Java 3D ERROR : OpenGL 1.2 or better is required (GL_VERSION=" + + major + "." + minor + ")"); + } + + boolean gl20 = false; + boolean gl14 = false; + boolean gl13 = false; + + if (major == 1) { + if (minor == 2) { + System.err.println("JAVA 3D: OpenGL 1.2 detected; will run with reduced functionality"); + } + if (minor >= 3) { + gl13 = true; + } + if (minor >= 4) { + gl14 = true; + } + } else /* major >= 2 */ { + gl13 = true; + gl14 = true; + gl20 = true; + } + + if (gl20) { + assert gl13; + assert gl14; + assert gl.isExtensionAvailable("GL_VERSION_2_0"); + } + + if (gl14) { + assert gl13; + assert gl.isExtensionAvailable("GL_VERSION_1_4"); + } + + if (gl13) { + assert gl.isExtensionAvailable("GL_VERSION_1_3"); + } + + // Set up properties for OpenGL 1.3 + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_3D; + + // Note that we don't query for GL_ARB_imaging here + + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_LOD_RANGE; + + if (gl14) { + cv.textureExtendedFeatures |= Canvas3D.TEXTURE_AUTO_MIPMAP_GENERATION; + } + + // look for OpenGL 2.0 features + // Fix to Issue 455 : Need to disable NPOT textures for older cards that claim to support it. + // Some older cards (e.g., Nvidia fx500 and ATI 9800) claim to support OpenGL 2.0. + // This means that these cards have to support non-power-of-two (NPOT) texture, + // but their lack the necessary HW force the vendors the emulate this feature in software. + // The result is a ~100x slower down compare to power-of-two textures. + // Do not check for gl20 but instead check of GL_ARB_texture_non_power_of_two extension string + // if (gl20) { + // if(!VirtualUniverse.mc.enforcePowerOfTwo) { + // cv.textureExtendedFeatures |= Canvas3D.TEXTURE_NON_POWER_OF_TWO; + // } + // } + + + // Setup GL_EXT_abgr + if (gl.isExtensionAvailable("GL_EXT_abgr")) { + cv.extensionsSupported |= Canvas3D.EXT_ABGR; + } + + // GL_BGR is always supported + cv.extensionsSupported |= Canvas3D.EXT_BGR; + + // Setup multisample + // FIXME: this is not correct for the Windows platform yet + if (gl13) { + cv.extensionsSupported |= Canvas3D.MULTISAMPLE; + ctx.setHasMultisample(true); + } + + if ((cv.extensionsSupported & Canvas3D.MULTISAMPLE) != 0 && + !VirtualUniverse.mc.implicitAntialiasing) { + gl.glDisable(GL.GL_MULTISAMPLE); + } + + // Check texture extensions + checkTextureExtensions(cv, ctx, gl, gl13); + + // Check shader extensions + if (gl13) { + checkGLSLShaderExtensions(cv, ctx, gl, glslLibraryAvailable); + } else { + // Force shaders to be disabled, since no multitexture support + checkGLSLShaderExtensions(cv, ctx, gl, false); + } + + // Setup GL_SUN_gloabl_alpha +// FIXME: SUN_global_alpha +// if (gl.isExtensionAvailable("GL_SUN_gloabl_alpha")) { +// cv.extensionsSupported |= Canvas3D.SUN_GLOBAL_ALPHA; +// } + + cv.textureBoundaryWidthMax = 1; + { + int[] tmp = new int[1]; + gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, tmp, 0); + cv.textureWidthMax = tmp[0]; + cv.textureHeightMax = tmp[0]; + + tmp[0] = -1; + gl.glGetIntegerv(GL2.GL_MAX_3D_TEXTURE_SIZE, tmp, 0); + cv.texture3DWidthMax = tmp[0]; + cv.texture3DHeightMax = tmp[0]; + cv.texture3DDepthMax = tmp[0]; + } + } + + /* + * Function to disable most rendering attributes when doing a 2D + * clear, image copy, or image composite operation. Note that the + * caller must save/restore the attributes with + * pushAttrib(GL_ENABLE_BIT|...) and popAttrib() + */ + private void disableAttribFor2D(GL gl) { + gl.glDisable(GL2.GL_ALPHA_TEST); + gl.glDisable(GL.GL_BLEND); + gl.glDisable(GL.GL_COLOR_LOGIC_OP); + gl.glDisable(GL2.GL_COLOR_MATERIAL); + gl.glDisable(GL.GL_CULL_FACE); + gl.glDisable(GL.GL_DEPTH_TEST); + gl.glDisable(GL2.GL_FOG); + gl.glDisable(GL2.GL_LIGHTING); + gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); + gl.glDisable(GL2.GL_POLYGON_STIPPLE); + gl.glDisable(GL.GL_STENCIL_TEST); + gl.glDisable(GL.GL_TEXTURE_2D); + gl.glDisable(GL2.GL_TEXTURE_GEN_Q); + gl.glDisable(GL2.GL_TEXTURE_GEN_R); + gl.glDisable(GL2.GL_TEXTURE_GEN_S); + gl.glDisable(GL2.GL_TEXTURE_GEN_T); + + + for (int i = 0; i < 6; i++) { + gl.glDisable(GL2.GL_CLIP_PLANE0 + i); + } + + gl.glDisable(GL2.GL_TEXTURE_3D); + gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); + +// FIXME: GL_NV_register_combiners +// if (gl.isExtensionAvailable("GL_NV_register_combiners")) { +// gl.glDisable(GL.GL_REGISTER_COMBINERS_NV); +// } +// FIXME: GL_SGI_texture_color_table +// if (gl.isExtensionAvailable("GL_SGI_texture_color_table")) { +// gl.glDisable(GL.GL_TEXTURE_COLOR_TABLE_SGI); +// } +// FIXME: SUN_global_alpha +// if (gl.isExtensionAvailable("GL_SUN_global_alpha")) { +// gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN); +// } + + } + + private void disableAttribForRaster(GL gl) { + + gl.glDisable(GL2.GL_COLOR_MATERIAL); + gl.glDisable(GL.GL_CULL_FACE); + gl.glDisable(GL2.GL_LIGHTING); + gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); + gl.glDisable(GL2.GL_POLYGON_STIPPLE); + + // TODO: Disable if Raster.CLIP_POSITION is true +// for (int i = 0; i < 6; i++) { +// gl.glDisable(GL2.GL_CLIP_PLANE0 + i); +// } + +// FIXME: SUN_global_alpha +// if (gl.isExtensionAvailable("GL_SUN_global_alpha")) { +// gl.glDisable(GL.GL_GLOBAL_ALPHA_SUN); +// } + } + + private void copyTranspose(double[] src, double[] dst) { + dst[0] = src[0]; + dst[1] = src[4]; + dst[2] = src[8]; + dst[3] = src[12]; + dst[4] = src[1]; + dst[5] = src[5]; + dst[6] = src[9]; + dst[7] = src[13]; + dst[8] = src[2]; + dst[9] = src[6]; + dst[10] = src[10]; + dst[11] = src[14]; + dst[12] = src[3]; + dst[13] = src[7]; + dst[14] = src[11]; + dst[15] = src[15]; + } + + // --------------------------------------------------------------------- + + // + // Canvas3D / GraphicsConfigTemplate3D methods - logic dealing with + // native graphics configuration or drawing surface + // + + // Return a graphics config based on the one passed in. Note that we can + // assert that the input config is non-null and was created from a + // GraphicsConfigTemplate3D. + // This method must return a valid GraphicsConfig, or else it must throw + // an exception if one cannot be returned. + GraphicsConfiguration getGraphicsConfig(GraphicsConfiguration gconfig) { + if (VERBOSE) System.err.println("JoglPipeline.getGraphicsConfig()"); + JoglGraphicsConfiguration config = (JoglGraphicsConfiguration) gconfig; + GLCapabilitiesChooser indexChooser = null; + if (config.getChosenIndex() >= 0) { + indexChooser = new IndexCapabilitiesChooser(config.getChosenIndex()); + } + + AWTGraphicsDevice awtGraphicsDevice = ((JoglGraphicsConfiguration)gconfig).getAwtGraphicsDevice()/*new AWTGraphicsDevice(config.getDevice(), 0)*/; + GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtGraphicsDevice); + + AbstractGraphicsConfiguration absConfig = + factory.chooseGraphicsConfiguration(config.getGLCapabilities(), config.getGLCapabilities(), + indexChooser, new AWTGraphicsScreen(awtGraphicsDevice)); + if (absConfig == null) { + return null; + } + return ((AWTGraphicsConfiguration) absConfig).getAWTGraphicsConfiguration(); + + /* + + System.err.println("JoglPipeline.getGraphicsConfig()"); + // Just return the input graphics config for now. eventually, we will + // use the input graphics config to get the GraphicsConfigTemplate3D + // parameters, which we will use to create a new graphics config with JOGL. + return gconfig; + */ + } + + // Get the native FBconfig pointer + long getFbConfig(GraphicsConfigInfo gcInfo) { + if (VERBOSE) System.err.println("JoglPipeline.getFbConfig()"); + return 0L; // Dummy method in JOGL + } + + + private static final int DISABLE_STEREO = 1; + private static final int DISABLE_AA = 2; + private static final int DISABLE_DOUBLE_BUFFER = 3; + + // Get best graphics config from pipeline + GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate3D gct, + GraphicsConfiguration[] gc) { + if (VERBOSE) System.err.println("JoglPipeline.getBestConfiguration()"); + /* + System.err.println("gct.getDoubleBuffer(): " + gct.getDoubleBuffer()); + System.err.println("gct.getStereo(): " + gct.getStereo()); + System.err.println("gct.getDepthBits(): " + gct.getDepthSize()); + System.err.println("gct.getRedSize(): " + gct.getRedSize()); + System.err.println("gct.getGreenSize(): " + gct.getGreenSize()); + System.err.println("gct.getBlueSize(): " + gct.getBlueSize()); + System.err.println("gct.getSceneAntialiasing(): " + gct.getSceneAntialiasing()); + */ + + // Create a GLCapabilities based on the GraphicsConfigTemplate3D + GLCapabilities caps = new GLCapabilities(getDefaultProfile()); + caps.setDoubleBuffered(gct.getDoubleBuffer() <= GraphicsConfigTemplate.PREFERRED); + caps.setStereo (gct.getStereo() <= GraphicsConfigTemplate.PREFERRED); + caps.setDepthBits (gct.getDepthSize()); + caps.setStencilBits (gct.getStencilSize()); + caps.setRedBits (Math.max(5, gct.getRedSize())); + caps.setGreenBits (Math.max(5, gct.getGreenSize())); + caps.setBlueBits (Math.max(5, gct.getBlueSize())); + caps.setSampleBuffers(gct.getSceneAntialiasing() <= GraphicsConfigTemplate.PREFERRED); + // FIXME: should be smarter about choosing the number of samples + // (Java3D's native code has a loop trying 8, 6, 4, 3, and 2 samples) + caps.setNumSamples(4); + + // Issue 399: Request alpha buffer if transparentOffScreen is set + if (VirtualUniverse.mc.transparentOffScreen) { + caps.setAlphaBits(1); + } + + java.util.List capsToDisable = new ArrayList(); + // Add PREFERRED capabilities in order we will try disabling them + if (gct.getStereo() == GraphicsConfigTemplate.PREFERRED) { + capsToDisable.add(new Integer(DISABLE_STEREO)); + } + if (gct.getSceneAntialiasing() == GraphicsConfigTemplate.PREFERRED) { + capsToDisable.add(new Integer(DISABLE_AA)); + } + if (gct.getDoubleBuffer() == GraphicsConfigTemplate.PREFERRED) { + capsToDisable.add(new Integer(DISABLE_DOUBLE_BUFFER)); + } + + // Pick the GraphicsDevice from a random configuration + GraphicsDevice dev = gc[0].getDevice(); + + // Create a Frame and dummy GLCanvas to perform eager pixel format selection + + // Note that we loop in similar fashion to the NativePipeline's + // native code in the situation where we need to disable certain + // capabilities which aren't required + boolean tryAgain = true; + CapabilitiesCapturer capturer = null; + while (tryAgain) { + Frame f = new Frame(dev.getDefaultConfiguration()); + f.setUndecorated(true); + f.setLayout(new BorderLayout()); + capturer = new CapabilitiesCapturer(); + try { + AWTGraphicsConfiguration awtGraphicsConfiguration = createAwtGraphicsConfiguration(caps, capturer, dev/*null*/); + QueryCanvas canvas = new QueryCanvas(awtGraphicsConfiguration, capturer); + f.add(canvas, BorderLayout.CENTER); + f.setSize(MIN_FRAME_SIZE, MIN_FRAME_SIZE); + f.setVisible(true); + canvas.doQuery(); + if (DEBUG_CONFIG) { + System.err.println("Waiting for CapabilitiesCapturer"); + } + // Try to wait for result without blocking EDT + if (!EventQueue.isDispatchThread()) { + synchronized(capturer) { + if (!capturer.done()) { + try { + capturer.wait(WAIT_TIME); + } catch (InterruptedException e) { + } + } + } + } + disposeOnEDT(f); + tryAgain = false; + } catch (GLException e) { + // Failure to select a pixel format; try switching off one + // of the only-preferred capabilities + if (capsToDisable.size() == 0) { + tryAgain = false; + } else { + int whichToDisable = capsToDisable.remove(0).intValue(); + switch (whichToDisable) { + case DISABLE_STEREO: + caps.setStereo(false); + break; + + case DISABLE_AA: + caps.setSampleBuffers(false); + break; + + case DISABLE_DOUBLE_BUFFER: + caps.setDoubleBuffered(false); + break; + + default: + throw new AssertionError("missing case statement"); + } + } + } + } + int chosenIndex = capturer.getChosenIndex(); + GLCapabilities chosenCaps = null; + if (chosenIndex < 0) { + if (DEBUG_CONFIG) { + System.err.println("CapabilitiesCapturer returned invalid index"); + } + // It's possible some platforms or implementations might not + // support the GLCapabilitiesChooser mechanism; feed in the + // same GLCapabilities later which we gave to the selector + chosenCaps = caps; + } else { + if (DEBUG_CONFIG) { + System.err.println("CapabilitiesCapturer returned index=" + chosenIndex); + } + chosenCaps = capturer.getCapabilities(); + } + + JoglGraphicsConfiguration config = new JoglGraphicsConfiguration(chosenCaps, chosenIndex, dev); + + // FIXME: because of the fact that JoglGraphicsConfiguration + // doesn't override hashCode() or equals(), we will basically be + // creating a new one each time getBestConfiguration() is + // called; in theory, we should probably map the same + // GLCapabilities on the same GraphicsDevice to the same + // JoglGraphicsConfiguration object + + // Cache the GraphicsTemplate3D + synchronized (Canvas3D.graphicsConfigTable) { + GraphicsConfigInfo gcInfo = new GraphicsConfigInfo(gct); + // We don't need this + // gcInfo.setPrivateData(privateData); + Canvas3D.graphicsConfigTable.put(config, gcInfo); + } + + return config; + + /* + + // TODO: implement this + + // TODO: construct a unique GraphicsConfiguration object that will be + // used the key in the hashmap so we can lookup the GraphicsTemplate3D + GraphicsConfiguration gc1 = GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(); + + // Cache the GraphicsTemplate3D + synchronized (Canvas3D.graphicsConfigTable) { + if (Canvas3D.graphicsConfigTable.get(gc1) == null) { + GraphicsConfigInfo gcInfo = new GraphicsConfigInfo(gct); + // gcInfo.setPrivateData(privateData); + Canvas3D.graphicsConfigTable.put(gc1, gcInfo); + } + } + return gc1; + + */ + } + + // Determine whether specified graphics config is supported by pipeline + boolean isGraphicsConfigSupported(GraphicsConfigTemplate3D gct, + GraphicsConfiguration gc) { + if (VERBOSE) System.err.println("JoglPipeline.isGraphicsConfigSupported()"); + + // FIXME: it looks like this method is implemented incorrectly + // in the existing NativePipeline in both the Windows and X11 + // ports. According to the semantics of the javadoc, it looks + // like this method is supposed to figure out the OpenGL + // capabilities which would be requested by the passed + // GraphicsConfiguration object were it to be used, and see + // whether it is possible to create a context with them. + // Instead, on both platforms, the implementations basically set + // up a query based on the contents of the + // GraphicsConfigTemplate3D object, using the + // GraphicsConfiguration object only to figure out on which + // GraphicsDevice and screen we're making the request, and see + // whether it's possible to choose an OpenGL pixel format based + // on that information. This makes this method less useful and + // we can probably just safely return true here uniformly + // without breaking anything. + return true; + } + + // Methods to get actual capabilities from Canvas3D + boolean hasDoubleBuffer(Canvas3D cv) { + if (VERBOSE) System.err.println("JoglPipeline.hasDoubleBuffer()"); + if (VERBOSE) System.err.println(" Returning " + caps(cv).getDoubleBuffered()); + return caps(cv).getDoubleBuffered(); + } + + boolean hasStereo(Canvas3D cv) { + if (VERBOSE) System.err.println("JoglPipeline.hasStereo()"); + if (VERBOSE) System.err.println(" Returning " + caps(cv).getStereo()); + return caps(cv).getStereo(); + } + + int getStencilSize(Canvas3D cv) { + if (VERBOSE) System.err.println("JoglPipeline.getStencilSize()"); + if (VERBOSE) System.err.println(" Returning " + caps(cv).getStencilBits()); + return caps(cv).getStencilBits(); + } + + boolean hasSceneAntialiasingMultisample(Canvas3D cv) { + if (VERBOSE) System.err.println("JoglPipeline.hasSceneAntialiasingMultisample()"); + if (VERBOSE) System.err.println(" Returning " + caps(cv).getSampleBuffers()); + + return caps(cv).getSampleBuffers(); + } + + boolean hasSceneAntialiasingAccum(Canvas3D cv) { + if (VERBOSE) System.err.println("JoglPipeline.hasSceneAntialiasingAccum()"); + GLCapabilities caps = caps(cv); + if (VERBOSE) System.err.println(" Returning " + (caps.getAccumRedBits() > 0 && + caps.getAccumGreenBits() > 0 && + caps.getAccumBlueBits() > 0)); + return (caps.getAccumRedBits() > 0 && + caps.getAccumGreenBits() > 0 && + caps.getAccumBlueBits() > 0); + } + + // Methods to get native WS display and screen + long getDisplay() { + if (VERBOSE) System.err.println("JoglPipeline.getDisplay()"); + return 0L; // Dummy method in JOGL + } + + private boolean checkedForGetScreenMethod = false; + private Method getScreenMethod = null; + int getScreen(final GraphicsDevice graphicsDevice) { + if (VERBOSE) System.err.println("JoglPipeline.getScreen()"); + + if (!checkedForGetScreenMethod) { + // All of the Sun GraphicsDevice implementations have a method + // int getScreen(); + // which we want to call reflectively if it's available. + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + getScreenMethod = graphicsDevice.getClass().getDeclaredMethod("getScreen", new Class[] {}); + getScreenMethod.setAccessible(true); + } catch (Exception e) { + } + checkedForGetScreenMethod = true; + return null; + } + }); + } + + if (getScreenMethod != null) { + try { + return ((Integer) getScreenMethod.invoke(graphicsDevice, (Object[]) null)).intValue(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + return 0; + } + + //---------------------------------------------------------------------- + // Helper classes and methods to support query context functionality + // and pixel format selection + + interface ExtendedCapabilitiesChooser extends GLCapabilitiesChooser { + public void init(GLContext context); + } + + // Canvas subclass to help with various query operations such as the + // "query context" mechanism and pixel format selection. + // Must defeat and simplify the single-threading behavior of JOGL's + // GLCanvas in order to be able to set up a temporary pixel format + // and OpenGL context. Apparently simply turning off the + // single-threaded mode isn't enough to do this. + class QueryCanvas extends Canvas { + private GLDrawable drawable; + private ExtendedCapabilitiesChooser chooser; + private boolean alreadyRan; + + public QueryCanvas(AWTGraphicsConfiguration awtGraphicsConfiguration, ExtendedCapabilitiesChooser chooser) { + // The platform-specific GLDrawableFactory will only provide a + // non-null GraphicsConfiguration on platforms where this is + // necessary (currently only X11, as Windows allows the pixel + // format of the window to be set later and Mac OS X seems to + // handle this very differently than all other platforms). On + // other platforms this method returns null; it is the case (at + // least in the Sun AWT implementation) that this will result in + // equivalent behavior to calling the no-arg super() constructor + // for Canvas. + super(unwrap(awtGraphicsConfiguration)); + NativeWindow nativeWindow = NativeWindowFactory.getNativeWindow(this, awtGraphicsConfiguration); + drawable = GLDrawableFactory.getFactory(getDefaultProfile()).createGLDrawable(nativeWindow); + this.chooser = chooser; + } + + public void addNotify() { + super.addNotify(); + drawable.setRealized(true); + } + + // It seems that at least on Mac OS X we need to do the OpenGL + // context-related work outside of the addNotify call because the + // Canvas hasn't been resized to a non-zero size by that point + public void doQuery() { + if (alreadyRan) + return; + GLContext context = drawable.createContext(null); + int res = context.makeCurrent(); + if (res != GLContext.CONTEXT_NOT_CURRENT) { + try { + chooser.init(context); + } finally { + context.release(); + } + } + context.destroy(); + alreadyRan = true; + } + } + + private static AWTGraphicsConfiguration createAwtGraphicsConfiguration(GLCapabilities capabilities, + CapabilitiesChooser chooser, + GraphicsDevice device) { + //FIXME unit id? + AWTGraphicsDevice awtGraphicsDevice = new AWTGraphicsDevice(device, 0); + GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtGraphicsDevice); + AWTGraphicsConfiguration awtGraphicsConfiguration = (AWTGraphicsConfiguration) factory.chooseGraphicsConfiguration(capabilities, capabilities, + chooser, new AWTGraphicsScreen(awtGraphicsDevice)); + return awtGraphicsConfiguration; + } + + private static AWTGraphicsConfiguration createAwtGraphicsConfiguration(GLCapabilities capabilities, + CapabilitiesChooser chooser, + AWTGraphicsDevice awtGraphicsDevice) { + GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtGraphicsDevice); + AWTGraphicsConfiguration awtGraphicsConfiguration = (AWTGraphicsConfiguration) factory.chooseGraphicsConfiguration(capabilities, capabilities, + chooser, new AWTGraphicsScreen(awtGraphicsDevice)); + return awtGraphicsConfiguration; + } + + private static GraphicsConfiguration unwrap(AWTGraphicsConfiguration config) { + if (config == null) { + return null; + } + return config.getAWTGraphicsConfiguration(); + } + + // Used in conjunction with IndexCapabilitiesChooser in pixel format + // selection -- see getBestConfiguration + class CapabilitiesCapturer extends DefaultGLCapabilitiesChooser implements ExtendedCapabilitiesChooser { + private boolean done; + private GLCapabilities capabilities; + private int chosenIndex = -1; + + public boolean done() { + return done; + } + + public GLCapabilities getCapabilities() { + return capabilities; + } + + public int getChosenIndex() { + return chosenIndex; + } + + public int chooseCapabilities(GLCapabilities desired, + GLCapabilities[] available, + int windowSystemRecommendedChoice) { + int res = super.chooseCapabilities(desired, Arrays.asList(available), windowSystemRecommendedChoice); + capabilities = available[res]; + chosenIndex = res; + markDone(); + return res; + } + + public void init(GLContext context) { + // Avoid hanging things up for several seconds + kick(); + } + + private void markDone() { + synchronized (this) { + done = true; + notifyAll(); + } + } + + private void kick() { + synchronized (this) { + notifyAll(); + } + } + } + + // Used to support the query context mechanism -- needs to be more + // than just a GLCapabilitiesChooser + class ContextQuerier extends DefaultGLCapabilitiesChooser implements ExtendedCapabilitiesChooser { + private Canvas3D canvas; + private boolean glslLibraryAvailable; + private boolean done; + + public ContextQuerier(Canvas3D canvas, + boolean glslLibraryAvailable) { + this.canvas = canvas; + this.glslLibraryAvailable = glslLibraryAvailable; + } + + public boolean done() { + return done; + } + + public void init(GLContext context) { + // This is basically a temporary + JoglContext jctx = new JoglContext(context); + // Set up various properties + if (getPropertiesFromCurrentContext(jctx)) { + setupCanvasProperties(canvas, jctx, context.getGL(), + glslLibraryAvailable); + } + markDone(); + } + + private void markDone() { + synchronized (this) { + done = true; + notifyAll(); + } + } + } + + // Used in two phases of pixel format selection: transforming the + // JoglGraphicsConfiguration to a real AWT GraphicsConfiguration and + // during context creation to select exactly the same graphics + // configuration as was done during getBestConfiguration. + class IndexCapabilitiesChooser implements GLCapabilitiesChooser { + private int indexToChoose; + + IndexCapabilitiesChooser(int indexToChoose) { + this.indexToChoose = indexToChoose; + } + + public int chooseCapabilities(CapabilitiesImmutable desired, + List available, + int windowSystemRecommendedChoice) { + if (DEBUG_CONFIG) { + System.err.println("IndexCapabilitiesChooser returning index=" + indexToChoose); + } + return indexToChoose; + } + } + + private void disposeOnEDT(final Frame f) { + Runnable r = new Runnable() { + public void run() { + f.setVisible(false); + f.dispose(); + } + }; + if (!EventQueue.isDispatchThread()) { + EventQueue.invokeLater(r); + } else { + r.run(); + } + } + + + // --------------------------------------------------------------------- + + // + // DrawingSurfaceObject methods + // + + // Method to construct a new DrawingSurfaceObject + DrawingSurfaceObject createDrawingSurfaceObject(Canvas3D cv) { + if (VERBOSE) System.err.println("JoglPipeline.createDrawingSurfaceObject()"); + return new JoglDrawingSurfaceObject(cv); + } + + // Method to free the drawing surface object + void freeDrawingSurface(Canvas3D cv, DrawingSurfaceObject drawingSurfaceObject) { + if (VERBOSE) System.err.println("JoglPipeline.freeDrawingSurface()"); + // This method is a no-op + } + + // Method to free the native drawing surface object + void freeDrawingSurfaceNative(Object o) { + if (VERBOSE) System.err.println("JoglPipeline.freeDrawingSurfaceNative()"); + // This method is a no-op + } + + //---------------------------------------------------------------------- + // Context-related routines + // + + // Helper used everywhere + GLContext context(Context ctx) { + if (ctx == null) + return null; + return ((JoglContext) ctx).getGLContext(); + } + + // Helper used everywhere + GLDrawable drawable(Drawable drawable) { + if (drawable == null) + return null; + return ((JoglDrawable) drawable).getGLDrawable(); + } + + GLCapabilities caps(Canvas3D ctx) { + return ((JoglGraphicsConfiguration) ctx.graphicsConfiguration).getGLCapabilities(); + } + + //---------------------------------------------------------------------- + // General helper routines + // + + private static ThreadLocal nioVertexTemp = new ThreadLocal(); + private static ThreadLocal nioVertexDoubleTemp = new ThreadLocal(); + private static ThreadLocal nioColorTemp = new ThreadLocal(); + private static ThreadLocal nioColorByteTemp = new ThreadLocal(); + private static ThreadLocal nioNormalTemp = new ThreadLocal(); + private static ThreadLocal nioTexCoordSetTemp = new ThreadLocal(); + private static ThreadLocal nioVertexAttrSetTemp = new ThreadLocal(); + + private static FloatBuffer getVertexArrayBuffer(float[] vertexArray) { + return getVertexArrayBuffer(vertexArray, true); + } + + private static FloatBuffer getVertexArrayBuffer(float[] vertexArray, boolean copyData) { + return getNIOBuffer(vertexArray, nioVertexTemp, copyData); + } + + private static DoubleBuffer getVertexArrayBuffer(double[] vertexArray) { + return getVertexArrayBuffer(vertexArray, true); + } + + private static DoubleBuffer getVertexArrayBuffer(double[] vertexArray, boolean copyData) { + return getNIOBuffer(vertexArray, nioVertexDoubleTemp, true); + } + + private static FloatBuffer getColorArrayBuffer(float[] colorArray) { + return getColorArrayBuffer(colorArray, true); + } + + private static FloatBuffer getColorArrayBuffer(float[] colorArray, boolean copyData) { + return getNIOBuffer(colorArray, nioColorTemp, true); + } + + private static ByteBuffer getColorArrayBuffer(byte[] colorArray) { + return getColorArrayBuffer(colorArray, true); + } + + private static ByteBuffer getColorArrayBuffer(byte[] colorArray, boolean copyData) { + return getNIOBuffer(colorArray, nioColorByteTemp, true); + } + + private static FloatBuffer getNormalArrayBuffer(float[] normalArray) { + return getNormalArrayBuffer(normalArray, true); + } + + private static FloatBuffer getNormalArrayBuffer(float[] normalArray, boolean copyData) { + return getNIOBuffer(normalArray, nioNormalTemp, true); + } + + private static FloatBuffer[] getTexCoordSetBuffer(Object[] texCoordSet) { + return getNIOBuffer(texCoordSet, nioTexCoordSetTemp); + } + + private static FloatBuffer[] getVertexAttrSetBuffer(Object[] vertexAttrSet) { + return getNIOBuffer(vertexAttrSet, nioVertexAttrSetTemp); + } + + private static FloatBuffer getNIOBuffer(float[] array, ThreadLocal threadLocal, boolean copyData) { + if (array == null) { + return null; + } + FloatBuffer buf = threadLocal.get(); + if (buf == null) { + buf = Buffers.newDirectFloatBuffer(array.length); + threadLocal.set(buf); + } else { + buf.rewind(); + if (buf.remaining() < array.length) { + int newSize = Math.max(2 * buf.remaining(), array.length); + buf = Buffers.newDirectFloatBuffer(newSize); + threadLocal.set(buf); + } + } + if (copyData) { + buf.put(array); + buf.rewind(); + } + return buf; + } + + private static DoubleBuffer getNIOBuffer(double[] array, ThreadLocal threadLocal, boolean copyData) { + if (array == null) { + return null; + } + DoubleBuffer buf = threadLocal.get(); + if (buf == null) { + buf = Buffers.newDirectDoubleBuffer(array.length); + threadLocal.set(buf); + } else { + buf.rewind(); + if (buf.remaining() < array.length) { + int newSize = Math.max(2 * buf.remaining(), array.length); + buf = Buffers.newDirectDoubleBuffer(newSize); + threadLocal.set(buf); + } + } + if (copyData) { + buf.put(array); + buf.rewind(); + } + return buf; + } + + private static ByteBuffer getNIOBuffer(byte[] array, ThreadLocal threadLocal, boolean copyData) { + if (array == null) { + return null; + } + ByteBuffer buf = threadLocal.get(); + if (buf == null) { + buf = Buffers.newDirectByteBuffer(array.length); + threadLocal.set(buf); + } else { + buf.rewind(); + if (buf.remaining() < array.length) { + int newSize = Math.max(2 * buf.remaining(), array.length); + buf = Buffers.newDirectByteBuffer(newSize); + threadLocal.set(buf); + } + } + if (copyData) { + buf.put(array); + buf.rewind(); + } + return buf; + } + + private static FloatBuffer[] getNIOBuffer(Object[] array, ThreadLocal threadLocal) { + if (array == null) { + return null; + } + FloatBuffer[] bufs = threadLocal.get(); + + // First resize array of FloatBuffers + if (bufs == null) { + bufs = new FloatBuffer[array.length]; + threadLocal.set(bufs); + } else if (bufs.length < array.length) { + FloatBuffer[] newBufs = new FloatBuffer[array.length]; + System.arraycopy(bufs, 0, newBufs, 0, bufs.length); + bufs = newBufs; + threadLocal.set(bufs); + } + + // Now go down array of arrays, converting each into a direct FloatBuffer + for (int i = 0; i < array.length; i++) { + float[] cur = (float[]) array[i]; + FloatBuffer buf = bufs[i]; + if (buf == null) { + buf = Buffers.newDirectFloatBuffer(cur.length); + bufs[i] = buf; + } else { + buf.rewind(); + if (buf.remaining() < cur.length) { + int newSize = Math.max(2 * buf.remaining(), cur.length); + buf = Buffers.newDirectFloatBuffer(newSize); + bufs[i] = buf; + } + } + buf.put(cur); + buf.rewind(); + } + + return bufs; + } +} diff --git a/src/classes/share/javax/media/j3d/JoglShaderObject.java b/src/classes/share/javax/media/j3d/JoglShaderObject.java new file mode 100644 index 0000000..da4b77c --- /dev/null +++ b/src/classes/share/javax/media/j3d/JoglShaderObject.java @@ -0,0 +1,44 @@ +/* + * $RCSfile$ + * + * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + * $Revision$ + * $Date$ + * $State$ + */ + +package javax.media.j3d; + +class JoglShaderObject implements ShaderProgramId, ShaderId, ShaderAttrLoc { + private int val; + + JoglShaderObject(int val) { + this.val = val; + } + + int getValue() { + return val; + } +} -- cgit v1.2.3