aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/javax
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2009-03-16 15:10:57 +0000
committerSven Gothel <[email protected]>2009-03-16 15:10:57 +0000
commit3b83ea25d64ab2c92822265f2eb74b35eddab722 (patch)
treea041ed8697b747fec0e198578df1c6cfbfc6adda /src/jogl/classes/javax
parentaf88a8948eb945fdf97d8553f339effc2349fd24 (diff)
repair
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1872 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/jogl/classes/javax')
-rw-r--r--src/jogl/classes/javax/media/opengl/GLArrayData.java114
-rw-r--r--src/jogl/classes/javax/media/opengl/GLAutoDrawable.java128
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java291
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawable.java163
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java272
-rw-r--r--src/jogl/classes/javax/media/opengl/GLEventListener.java112
-rw-r--r--src/jogl/classes/javax/media/opengl/GLException.java68
-rw-r--r--src/jogl/classes/javax/media/opengl/GLPbuffer.java91
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java555
-rw-r--r--src/jogl/classes/javax/media/opengl/GLUniformData.java159
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/Threading.java327
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java52
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/ComponentEvents.java75
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java630
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java1487
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/glu/GLUnurbs.java8
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/glu/GLUquadric.java33
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/glu/GLUtessellator.java66
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallback.java356
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallbackAdapter.java84
-rw-r--r--src/jogl/classes/javax/media/opengl/sub/GLObject.java75
-rw-r--r--src/jogl/classes/javax/media/opengl/sub/fixed/GLFixedFuncUtil.java61
-rw-r--r--src/jogl/classes/javax/media/opengl/sub/fixed/GLLightingIf.java50
-rw-r--r--src/jogl/classes/javax/media/opengl/sub/fixed/GLMatrixIf.java77
-rw-r--r--src/jogl/classes/javax/media/opengl/sub/fixed/GLPointerIf.java39
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/util/BufferUtil.java.javame_cdc_fp453
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/util/BufferUtil.java.javase503
-rw-r--r--src/jogl/classes/javax/media/opengl/util/FixedPoint.java29
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/util/Gamma.java106
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/util/PMVMatrix.java656
30 files changed, 7120 insertions, 0 deletions
diff --git a/src/jogl/classes/javax/media/opengl/GLArrayData.java b/src/jogl/classes/javax/media/opengl/GLArrayData.java
new file mode 100644
index 000000000..d17ee6a06
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLArrayData.java
@@ -0,0 +1,114 @@
+
+package javax.media.opengl;
+
+import java.nio.*;
+
+/**
+ *
+ * The total number of bytes hold by the referenced buffer is:
+ * getComponentSize()* getComponentNumber() * getElementNumber()
+ *
+ */
+public interface GLArrayData {
+
+ /**
+ * Returns true if this data set is intended for a GLSL vertex shader attribute,
+ * otherwise false, ie intended for fixed function vertex pointer
+ */
+ public boolean isVertexAttribute();
+
+ /**
+ * The index of the predefined array index, see list below,
+ * or -1 in case of a shader attribute array.
+ *
+ * @see javax.media.opengl.GL#GL_VERTEX_ARRAY
+ * @see javax.media.opengl.GL#GL_NORMAL_ARRAY
+ * @see javax.media.opengl.GL#GL_COLOR_ARRAY
+ * @see javax.media.opengl.GL#GL_TEXTURE_COORD_ARRAY
+ */
+ public int getIndex();
+
+ /**
+ * The name of the reflecting shader array attribute.
+ */
+ public String getName();
+
+ /**
+ * Set a new name for this array.
+ */
+ public void setName(String newName);
+
+
+ /**
+ * Returns the shader attribute location for this name,
+ * -1 if not yet determined
+ */
+ public int getLocation();
+
+ /**
+ * Sets the determined location of the shader attribute
+ * This is usually done within ShaderState.
+ *
+ * @see javax.media.opengl.glsl.ShaderState#glVertexAttribPointer(GL2ES2, GLArrayData)
+ */
+ public void setLocation(int v);
+
+ /**
+ * Determines wheather the data is server side (VBO),
+ * or a client side array (false).
+ */
+ public boolean isVBO();
+
+ /**
+ * The offset, if it's an VBO, otherwise -1
+ */
+ public long getOffset();
+
+ /**
+ * The VBO name, if it's an VBO, otherwise -1
+ */
+ public int getVBOName();
+
+ /**
+ * The Buffer holding the data, may be null in case of VBO
+ */
+ public Buffer getBuffer();
+
+ /**
+ * The number of components per element
+ */
+ public int getComponentNumber();
+
+ /**
+ * The component's GL data type, ie. GL_FLOAT
+ */
+ public int getComponentType();
+
+ /**
+ * The components size in bytes
+ */
+ public int getComponentSize();
+
+ /**
+ * Return the number of elements.
+ */
+ public int getElementNumber();
+
+ /**
+ * True, if GL shall normalize fixed point data while converting
+ * them into float
+ */
+ public boolean getNormalized();
+
+ /**
+ * The distance to the next payload,
+ * allowing interleaved arrays.
+ */
+ public int getStride();
+
+ public String toString();
+
+ public void destroy(GL gl);
+
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
new file mode 100644
index 000000000..629142f64
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl;
+
+import javax.media.opengl.glu.*;
+
+/** A higher-level abstraction than {@link GLDrawable} which supplies
+ an event based mechanism ({@link GLEventListener}) for performing
+ OpenGL rendering. A GLAutoDrawable automatically creates a primary
+ rendering context which is associated with the GLAutoDrawable for
+ the lifetime of the object. This context has the {@link
+ GLContext#setSynchronized synchronized} property enabled so that
+ calls to {@link GLContext#makeCurrent makeCurrent} will block if
+ the context is current on another thread. This allows the internal
+ GLContext for the GLAutoDrawable to be used both by the event
+ based rendering mechanism as well by end users directly. */
+
+public interface GLAutoDrawable extends GLDrawable {
+ /**
+ * Returns the context associated with this drawable. The returned
+ * context will be synchronized.
+ * Don't rely on it's identity, the context may change.
+ */
+ public GLContext getContext();
+
+ /**
+ * Associate a new context to this drawable.
+ */
+ public void setContext(GLContext context);
+
+ /** Adds a {@link GLEventListener} to this drawable. If multiple
+ listeners are added to a given drawable, they are notified of
+ events in an arbitrary order. */
+ public void addGLEventListener(GLEventListener listener);
+
+ /** Removes a {@link GLEventListener} from this drawable. Note that
+ if this is done from within a particular drawable's {@link
+ GLEventListener} handler (reshape, display, etc.) that it is not
+ guaranteed that all other listeners will be evaluated properly
+ during this update cycle. */
+ public void removeGLEventListener(GLEventListener listener);
+
+ /** Destroys all resources associated with this GLAutoDrawable.
+ If a window is attached to it's implementation, it shall be closed.
+ Causes disposing of all OpenGL resources
+ by calling {@link GLEventListener#dispose dispose} for all
+ registered {@link GLEventListener}s. Called automatically by the
+ window system toolkit upon receiving a destroy notification. This
+ routine may be called manually. */
+ public void destroy();
+
+ /** Causes OpenGL rendering to be performed for this GLAutoDrawable
+ by calling {@link GLEventListener#display display} for all
+ registered {@link GLEventListener}s. Called automatically by the
+ window system toolkit upon receiving a repaint() request. this
+ routine may be called manually for better control over the
+ rendering process. It is legal to call another GLAutoDrawable's
+ display method from within the {@link GLEventListener#display
+ display} callback. */
+ public void display();
+
+ /** Enables or disables automatic buffer swapping for this drawable.
+ By default this property is set to true; when true, after all
+ GLEventListeners have been called for a display() event, the
+ front and back buffers are swapped, displaying the results of
+ the render. When disabled, the user is responsible for calling
+ {@link #swapBuffers} manually. */
+ public void setAutoSwapBufferMode(boolean onOrOff);
+
+ /** Indicates whether automatic buffer swapping is enabled for this
+ drawable. See {@link #setAutoSwapBufferMode}. */
+ public boolean getAutoSwapBufferMode();
+
+ /** Returns the {@link GL} pipeline object this GLAutoDrawable uses.
+ If this method is called outside of the {@link
+ GLEventListener}'s callback methods (init, display, etc.) it may
+ return null. Users should not rely on the identity of the
+ returned GL object; for example, users should not maintain a
+ hash table with the GL object as the key. Additionally, the GL
+ object should not be cached in client code, but should be
+ re-fetched from the GLAutoDrawable at the beginning of each call
+ to init, display, etc. */
+ public GL getGL();
+
+ /** Sets the {@link GL} pipeline object this GLAutoDrawable uses.
+ This should only be called from within the GLEventListener's
+ callback methods, and usually only from within the init()
+ method, in order to install a composable pipeline. See the JOGL
+ demos for examples. */
+ public void setGL(GL gl);
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
new file mode 100644
index 000000000..78252b4e8
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl;
+
+import com.sun.opengl.impl.Debug;
+import javax.media.opengl.sub.fixed.*;
+import java.util.HashMap;
+
+/** Abstraction for an OpenGL rendering context. In order to perform
+ OpenGL rendering, a context must be "made current" on the current
+ thread. OpenGL rendering semantics specify that only one context
+ may be current on the current thread at any given time, and also
+ that a given context may be current on only one thread at any
+ given time. Because components can be added to and removed from
+ the component hierarchy at any time, it is possible that the
+ underlying OpenGL context may need to be destroyed and recreated
+ multiple times over the lifetime of a given component. This
+ process is handled by the implementation, and the GLContext
+ abstraction provides a stable object which clients can use to
+ refer to a given context. */
+
+public abstract class GLContext {
+ protected static final boolean DEBUG = Debug.debug("GLContext");
+
+ /** Indicates that the context was not made current during the last call to {@link #makeCurrent makeCurrent}. */
+ public static final int CONTEXT_NOT_CURRENT = 0;
+ /** Indicates that the context was made current during the last call to {@link #makeCurrent makeCurrent}. */
+ public static final int CONTEXT_CURRENT = 1;
+ /** Indicates that a newly-created context was made current during the last call to {@link #makeCurrent makeCurrent}. */
+ public static final int CONTEXT_CURRENT_NEW = 2;
+
+ private static ThreadLocal currentContext = new ThreadLocal();
+
+ private HashMap/*<int, Object>*/ attachedObjects = new HashMap();
+
+ /**
+ * Returns the GLDrawable to which this context may be used to
+ * draw.
+ */
+ public abstract GLDrawable getGLDrawable();
+
+ /**
+ * Makes this GLContext current on the calling thread.
+ *
+ * There are two return values that indicate success and one that
+ * indicates failure. A return value of CONTEXT_CURRENT_NEW
+ * indicates that that context has been made current, and that
+ * this is the first time this context has been made current, or
+ * that the state of the underlying context or drawable may have
+ * changed since the last time this context was made current. In
+ * this case, the application may wish to initialize the state. A
+ * return value of CONTEXT_CURRENT indicates that the context has
+ * been made currrent, with its previous state restored.
+ *
+ * If the context could not be made current (for example, because
+ * the underlying drawable has not ben realized on the display) ,
+ * a value of CONTEXT_NOT_CURRENT is returned.
+ *
+ * If the context is in use by another thread at the time of the
+ * call, then if isSynchronized() is true the call will
+ * block. If isSynchronized() is false, an exception will be
+ * thrown and the context will remain current on the other thread.
+ *
+ * @return CONTEXT_CURRENT if the context was successfully made current
+ * @return CONTEXT_CURRENT_NEW if the context was successfully made
+ * current, but need to be initialized.
+ *
+ * @return CONTEXT_NOT_CURRENT if the context could not be made current.
+ *
+ * @throws GLException if synchronization is disabled and the
+ * context is current on another thread, or because the context
+ * could not be created or made current due to non-recoverable,
+ * window system-specific errors.
+ */
+ public abstract int makeCurrent() throws GLException;
+
+ /**
+ * Releases control of this GLContext from the current thread.
+ *
+ * @throws GLException if the context had not previously been made
+ * current on the current thread
+ */
+ public abstract void release() throws GLException;
+
+ /**
+ * Copies selected groups of OpenGL state variables from the
+ * supplied source context into this one. The <code>mask</code>
+ * parameter indicates which groups of state variables are to be
+ * copied. <code>mask</code> contains the bitwise OR of the same
+ * symbolic names that are passed to the GL command {@link
+ * GL#glPushAttrib glPushAttrib}. The single symbolic constant
+ * {@link GL#GL_ALL_ATTRIB_BITS GL_ALL_ATTRIB_BITS} can be used to
+ * copy the maximum possible portion of rendering state. <P>
+ *
+ * Not all values for GL state can be copied. For example, pixel
+ * pack and unpack state, render mode state, and select and feedback
+ * state are not copied. The state that can be copied is exactly the
+ * state that is manipulated by the GL command {@link
+ * GL#glPushAttrib glPushAttrib}. <P>
+ *
+ * On most platforms, this context may not be current to any thread,
+ * including the calling thread, when this method is called. Some
+ * platforms have additional requirements such as whether this
+ * context or the source context must occasionally be made current
+ * in order for the results of the copy to be seen; these
+ * requirements are beyond the scope of this specification.
+ *
+ * @param source the source OpenGL context from which to copy state
+ * @param mask a mask of symbolic names indicating which groups of state to copy
+
+ * @throws GLException if an OpenGL-related error occurred
+ */
+ public abstract void copy(GLContext source, int mask) throws GLException;
+
+ /**
+ * Returns the context which is current on the current thread. If no
+ * context is current, returns null.
+ *
+ * @return the context current on this thread, or null if no context
+ * is current.
+ */
+ public static GLContext getCurrent() {
+ return (GLContext) currentContext.get();
+ }
+
+ /**
+ * Sets the thread-local variable returned by {@link #getCurrent}
+ * and has no other side-effects. For use by third parties adding
+ * new GLContext implementations; not for use by end users.
+ */
+ protected static void setCurrent(GLContext cur) {
+ if(DEBUG) {
+ Exception e = new Exception("setCurrent: "+Thread.currentThread()+", "+currentContext.get()+" -> "+cur);
+ e.printStackTrace();
+ }
+
+ currentContext.set(cur);
+ }
+
+ /**
+ * Destroys this OpenGL context and frees its associated
+ * resources. The context should have been released before this
+ * method is called.
+ */
+ public abstract void destroy();
+
+ /**
+ * Returns true if 'makeCurrent' will exhibit synchronized behavior.
+ */
+ public abstract boolean isSynchronized();
+
+ /**
+ * Determines whether 'makeCurrent' will exhibit synchronized behavior.
+ */
+ public abstract void setSynchronized(boolean isSynchronized);
+
+ /**
+ * Returns the GL pipeline object for this GLContext.
+ */
+ public abstract GL getGL();
+
+ /**
+ * Sets the GL pipeline object for this GLContext.
+ */
+ public abstract void setGL(GL gl);
+
+ /**
+ * Returns the attached user object for the given name to this GLContext/GL.
+ */
+ public Object getAttachedObject(int name) {
+ return attachedObjects.get(new Integer(name));
+ }
+
+ /**
+ * Sets the attached user object for the given name to this GLContext/GL.
+ * Returns the previous set object or null.
+ */
+ public Object putAttachedObject(int name, Object obj) {
+ return attachedObjects.put(new Integer(name), obj);
+ }
+
+ /**
+ * Classname, GL, GLDrawable
+ */
+ public final String toString() {
+ return getClass().getName()+" ["+getGL()+","+
+ " Drawable: "+ getGLDrawable()+"] ";
+ }
+
+ /** Returns a non-null (but possibly empty) string containing the
+ space-separated list of available platform-dependent (e.g., WGL,
+ GLX) extensions. Can only be called while this context is
+ current. */
+ public abstract String getPlatformExtensionsString();
+
+ /**
+ * Mapping fixed function (client) array indices to
+ * GLSL array attribute names.
+ *
+ * Useful for uniq mapping of canonical array index names as listed.
+ *
+ * @see #mgl_Vertex
+ * @see javax.media.opengl.sub.fixed.GLPointerIf#GL_VERTEX_ARRAY
+ * @see #mgl_Normal
+ * @see javax.media.opengl.sub.fixed.GLPointerIf#GL_NORMAL_ARRAY
+ * @see #mgl_Color
+ * @see javax.media.opengl.sub.fixed.GLPointerIf#GL_COLOR_ARRAY
+ * @see #mgl_MultiTexCoord
+ * @see javax.media.opengl.sub.fixed.GLPointerIf#GL_TEXTURE_COORD_ARRAY
+ * @see javax.media.opengl.sub.fixed.GLPointerIf#glEnableClientState
+ * @see javax.media.opengl.sub.fixed.GLPointerIf#glVertexPointer
+ * @see javax.media.opengl.sub.fixed.GLPointerIf#glColorPointer
+ * @see javax.media.opengl.sub.fixed.GLPointerIf#glNormalPointer
+ * @see javax.media.opengl.sub.fixed.GLPointerIf#glTexCoordPointer
+ */
+ public static String getPredefinedArrayIndexName(int glArrayIndex) {
+ switch(glArrayIndex) {
+ case GLPointerIf.GL_VERTEX_ARRAY:
+ return mgl_Vertex;
+ case GLPointerIf.GL_NORMAL_ARRAY:
+ return mgl_Normal;
+ case GLPointerIf.GL_COLOR_ARRAY:
+ return mgl_Color;
+ case GLPointerIf.GL_TEXTURE_COORD_ARRAY:
+ return mgl_MultiTexCoord;
+ }
+ return null;
+ }
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL#GL_VERTEX_ARRAY
+ */
+ public static final String mgl_Vertex = "mgl_Vertex";
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL#GL_NORMAL_ARRAY
+ */
+ public static final String mgl_Normal = "mgl_Normal";
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL#GL_COLOR_ARRAY
+ */
+ public static final String mgl_Color = "mgl_Color";
+
+ /**
+ * String name for
+ * @see javax.media.opengl.GL#GL_TEXTURE_COORD_ARRAY
+ */
+ public static final String mgl_MultiTexCoord = "mgl_MultiTexCoord" ;
+
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawable.java b/src/jogl/classes/javax/media/opengl/GLDrawable.java
new file mode 100644
index 000000000..c2bbcb860
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLDrawable.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl;
+
+import javax.media.nwi.*;
+
+// FIXME: We need some way to tell when the device upon which the canvas is
+// being displayed has changed (e.g., the user drags the canvas's parent
+// window from one screen on multi-screen environment to another, when the
+// user changes the display bit depth or screen resolution, etc). When this
+// occurs, we need the canvas to reset the gl function pointer tables for the
+// canvas, because the new device may have different capabilities (e.g.,
+// doesn't support as many opengl extensions) from the original device. This
+// hook would also be useful in other GLDrawables (for example, offscreen
+// buffers such as pbuffers, whose contents may or may not be invalidated when
+// the display mode changes, depending on the vendor's GL implementation).
+//
+// Right now I'm not sure how hook into when this change occurs. There isn't
+// any AWT event corresponding to a device change (as far as I can
+// tell). We could constantly check the GraphicsConfiguration of the canvas's top-level
+// parent to see if it has changed, but this would be very slow (we'd have to
+// do it every time the context is made current). There has got to be a better
+// solution, but I'm not sure what it is.
+
+// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
+// context whenever the displayChanged() function is called on our
+// GLEventListeners
+
+/** An abstraction for an OpenGL rendering target. A GLDrawable's
+ primary functionality is to create OpenGL contexts which can be
+ used to perform rendering. A GLDrawable does not automatically
+ create an OpenGL context, but all implementations of {@link
+ GLAutoDrawable} do so upon creation. */
+
+public interface GLDrawable {
+ /**
+ * Creates a new context for drawing to this drawable that will
+ * optionally share display lists and other server-side OpenGL
+ * objects with the specified GLContext. <P>
+ *
+ * The GLContext <code>share</code> need not be associated with this
+ * GLDrawable and may be null if sharing of display lists and other
+ * objects is not desired. See the note in the overview
+ * documentation on
+ * <a href="../../../overview-summary.html#SHARING">context sharing</a>.
+ */
+ public GLContext createContext(GLContext shareWith);
+
+ /**
+ * Indicates to on-screen GLDrawable implementations whether the
+ * underlying window has been created and can be drawn into. End
+ * users do not need to call this method; it is not necessary to
+ * call <code>setRealized</code> on a GLCanvas, a GLJPanel, or a
+ * GLPbuffer, as these perform the appropriate calls on their
+ * underlying GLDrawables internally.
+ *
+ * <P>
+ *
+ * Developers implementing new OpenGL components for various window
+ * toolkits need to call this method against GLDrawables obtained
+ * from the GLDrawableFactory via the {@link
+ * GLDrawableFactory#getGLDrawable
+ * GLDrawableFactory.getGLDrawable()} method. It must typically be
+ * called with an argument of <code>true</code> when the component
+ * associated with the GLDrawable is realized and with an argument
+ * of <code>false</code> just before the component is unrealized.
+ * For the AWT, this means calling <code>setRealized(true)</code> in
+ * the <code>addNotify</code> method and with an argument of
+ * <code>false</code> in the <code>removeNotify</code> method.
+ *
+ * <P>
+ *
+ * <code>GLDrawable</code> implementations should handle multiple
+ * cycles of <code>setRealized(true)</code> /
+ * <code>setRealized(false)</code> calls. Most, if not all, Java
+ * window toolkits have a persistent object associated with a given
+ * component, regardless of whether that component is currently
+ * realized. The <CODE>GLDrawable</CODE> object associated with a
+ * particular component is intended to be similarly persistent. A
+ * <CODE>GLDrawable</CODE> is intended to be created for a given
+ * component when it is constructed and live as long as that
+ * component. <code>setRealized</code> allows the
+ * <code>GLDrawable</code> to re-initialize and destroy any
+ * associated resources as the component becomes realized and
+ * unrealized, respectively.
+ *
+ * <P>
+ *
+ * Calling this method has no other effects. For example, if
+ * <code>removeNotify</code> is called on a Canvas implementation
+ * for which a GLDrawable has been created, it is also necessary to
+ * destroy all OpenGL contexts associated with that GLDrawable. This
+ * is not done automatically by the implementation.
+ */
+ public void setRealized(boolean realized);
+
+ /** Returns the current width of this GLDrawable. */
+ public int getWidth();
+
+ /** Returns the current height of this GLDrawable. */
+ public int getHeight();
+
+ /** Swaps the front and back buffers of this drawable. For {@link
+ GLAutoDrawable} implementations, when automatic buffer swapping
+ is enabled (as is the default), this method is called
+ automatically and should not be called by the end user. */
+ public void swapBuffers() throws GLException;
+
+ /** Fetches the {@link NWCapabilities} corresponding to the chosen
+ OpenGL capabilities (pixel format / visual) for this drawable.
+ Some drawables, in particular on-screen drawables, may be
+ created lazily; null is returned if the drawable is not
+ currently created or if its pixel format has not been set yet.
+ On some platforms, the pixel format is not directly associated
+ with the drawable; a best attempt is made to return a reasonable
+ value in this case.
+ Returns a copy of the passed object.
+ */
+ public NWCapabilities getChosenNWCapabilities();
+
+ public NativeWindow getNativeWindow();
+
+ public GLDrawableFactory getFactory();
+
+ public String toString();
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
new file mode 100644
index 000000000..60399afce
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl;
+
+import javax.media.nwi.*;
+
+import java.lang.reflect.*;
+import java.security.*;
+import com.sun.opengl.impl.*;
+import com.sun.nwi.impl.NWReflection;
+
+/** <P> Provides a virtual machine- and operating system-independent
+ mechanism for creating {@link GLDrawable}s. </P>
+
+ <P> The {@link javax.media.opengl.NWCapabilities} objects passed
+ in to the various factory methods are used as a hint for the
+ properties of the returned drawable. The default capabilities
+ selection algorithm (equivalent to passing in a null {@link
+ NWCapabilitiesChooser}) is described in {@link
+ DefaultNWCapabilitiesChooser}. Sophisticated applications needing
+ to change the selection algorithm may pass in their own {@link
+ NWCapabilitiesChooser} which can select from the available pixel
+ formats. The NWCapabilitiesChooser mechanism may not be supported
+ by all implementations or on all platforms, in which case any
+ passed NWCapabilitiesChooser will be ignored. </P>
+
+ <P> Because of the multithreaded nature of the Java platform's
+ Abstract Window Toolkit, it is typically not possible to immediately
+ reject a given {@link NWCapabilities} as being unsupportable by
+ either returning <code>null</code> from the creation routines or
+ raising a {@link GLException}. The semantics of the rejection
+ process are (unfortunately) left unspecified for now. The current
+ implementation will cause a {@link GLException} to be raised
+ during the first repaint of the {@link GLCanvas} or {@link
+ GLJPanel} if the capabilities can not be met. Pbuffers are always
+ created immediately and their creation will fail with a {@link
+ GLException} if errors occur. </P>
+
+ <P> The concrete GLDrawableFactory subclass instantiated by {@link
+ #getFactory getFactory} can be changed by setting the system
+ property <code>opengl.factory.class.name</code> to the
+ fully-qualified name of the desired class. </P>
+*/
+
+public abstract class GLDrawableFactory {
+ private static GLDrawableFactory factory;
+
+ /** Creates a new GLDrawableFactory instance. End users do not need
+ to call this method. */
+ protected GLDrawableFactory() {
+ }
+
+ /** Returns the sole GLDrawableFactory instance. The {@link
+ GLProfile GLProfile} must be configured before calling this
+ method. */
+ public static GLDrawableFactory getFactory() throws GLException {
+ if (null == factory) {
+ if (null == GLProfile.getProfile()) {
+ throw new GLException("GLProfile was not properly initialized");
+ }
+
+ // See if the user is requesting one of the embedded profiles,
+ // and if so, try to instantiate the EGLDrawableFactory
+ if (GLProfile.isGLES()) {
+ try {
+ factory = (GLDrawableFactory) NWReflection.createInstance("com.sun.opengl.impl.egl.EGLDrawableFactory");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else if (!GLProfile.isGL2() && !GLProfile.isGL2ES12()) {
+ // We require that the user passes in one of the known profiles
+ throw new GLException("Unknown or unsupported profile \"" + GLProfile.getProfile() + "\"");
+ }
+
+ if (null == factory) {
+ // Use the desktop OpenGL as the fallback always
+ try {
+ String factoryClassName =
+ (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty("opengl.factory.class.name");
+ }
+ });
+ String osName = System.getProperty("os.name");
+ String osNameLowerCase = osName.toLowerCase();
+
+ if (factoryClassName == null) {
+ if (osNameLowerCase.startsWith("windows")) {
+ factoryClassName = "com.sun.opengl.impl.windows.wgl.WindowsWGLDrawableFactory";
+ } else if (osNameLowerCase.startsWith("mac os x") ||
+ osNameLowerCase.startsWith("darwin")) {
+ // FIXME: remove this residual dependence on the AWT
+ factoryClassName = "com.sun.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory";
+ } else {
+ // Assume Linux, Solaris, etc. Should probably test for these explicitly.
+ factoryClassName = "com.sun.opengl.impl.x11.glx.X11GLXDrawableFactory";
+ }
+ }
+
+ factory = (GLDrawableFactory) NWReflection.createInstance(factoryClassName);
+ } catch (Exception e) {
+ throw new GLException(e);
+ }
+ }
+ }
+
+ return factory;
+ }
+
+ /** Shuts down this GLDrawableFactory, releasing resources
+ associated with it. Before calling this method you should first
+ destroy any GLContexts and GLDrawables that have been created
+ and are still in use. No further OpenGL calls may be made after
+ shutting down the GLDrawableFactory. */
+ public void shutdown() {
+ }
+
+ /**
+ * Returns a GLDrawable that wraps a platform-specific window system
+ * object, such as an AWT or LCDUI Canvas. On platforms which
+ * support it, selects a pixel format compatible with the supplied
+ * NWCapabilities, or if the passed NWCapabilities object is null,
+ * uses a default set of capabilities. On these platforms, uses
+ * either the supplied NWCapabilitiesChooser object, or if the
+ * passed NWCapabilitiesChooser object is null, uses a
+ * DefaultNWCapabilitiesChooser instance.
+ *
+ * @throws IllegalArgumentException if the passed target is null
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the GLDrawable to fail.
+ */
+ public abstract GLDrawable createGLDrawable(NativeWindow target,
+ NWCapabilities capabilities,
+ NWCapabilitiesChooser chooser)
+ throws IllegalArgumentException, GLException;
+
+ //----------------------------------------------------------------------
+ // Methods to create high-level objects
+
+ /**
+ * Returns true if it is possible to create a GLPbuffer. Some older
+ * graphics cards do not have this capability.
+ */
+ public abstract boolean canCreateGLPbuffer();
+
+ /**
+ * Creates a GLPbuffer with the given capabilites and dimensions. <P>
+ *
+ * See the note in the overview documentation on
+ * <a href="../../../overview-summary.html#SHARING">context sharing</a>.
+ *
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the GLPbuffer to fail.
+ */
+ public abstract GLPbuffer createGLPbuffer(NWCapabilities capabilities,
+ NWCapabilitiesChooser chooser,
+ int initialWidth,
+ int initialHeight,
+ GLContext shareWith)
+ throws GLException;
+
+ //----------------------------------------------------------------------
+ // Methods for interacting with third-party OpenGL libraries
+
+ /**
+ * <P> Creates a GLContext object representing an existing OpenGL
+ * context in an external (third-party) OpenGL-based library. This
+ * GLContext object may be used to draw into this preexisting
+ * context using its {@link GL} and {@link
+ * javax.media.opengl.glu.GLU} objects. New contexts created through
+ * {@link GLDrawable}s may share textures and display lists with
+ * this external context. </P>
+ *
+ * <P> The underlying OpenGL context must be current on the current
+ * thread at the time this method is called. The user is responsible
+ * for the maintenance of the underlying OpenGL context; calls to
+ * <code>makeCurrent</code> and <code>release</code> on the returned
+ * GLContext object have no effect. If the underlying OpenGL context
+ * is destroyed, the <code>destroy</code> method should be called on
+ * the <code>GLContext</code>. A new <code>GLContext</code> object
+ * should be created for each newly-created underlying OpenGL
+ * context.
+ *
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the external GLContext to fail.
+ */
+ public abstract GLContext createExternalGLContext()
+ throws GLException;
+
+ /**
+ * Returns true if it is possible to create an external GLDrawable
+ * object via {@link #createExternalGLDrawable}.
+ */
+ public abstract boolean canCreateExternalGLDrawable();
+
+ /**
+ * <P> Creates a {@link GLDrawable} object representing an existing
+ * OpenGL drawable in an external (third-party) OpenGL-based
+ * library. This GLDrawable object may be used to create new,
+ * fully-functional {@link GLContext}s on the OpenGL drawable. This
+ * is useful when interoperating with a third-party OpenGL-based
+ * library and it is essential to not perturb the state of the
+ * library's existing context, even to the point of not sharing
+ * textures or display lists with that context. </P>
+ *
+ * <P> An underlying OpenGL context must be current on the desired
+ * drawable and the current thread at the time this method is
+ * called. The user is responsible for the maintenance of the
+ * underlying drawable. If one or more contexts are created on the
+ * drawable using {@link GLDrawable#createContext}, and the drawable
+ * is deleted by the third-party library, the user is responsible
+ * for calling {@link GLContext#destroy} on these contexts. </P>
+ *
+ * <P> Calls to <code>setSize</code>, <code>getWidth</code> and
+ * <code>getHeight</code> are illegal on the returned GLDrawable. If
+ * these operations are required by the user, they must be performed
+ * by the third-party library. </P>
+ *
+ * <P> It is legal to create both an external GLContext and
+ * GLDrawable representing the same third-party OpenGL entities.
+ * This can be used, for example, to query current state information
+ * using the external GLContext and then create and set up new
+ * GLContexts using the external GLDrawable. </P>
+ *
+ * <P> This functionality may not be available on all platforms and
+ * {@link #canCreateExternalGLDrawable} should be called first to
+ * see if it is present. For example, on X11 platforms, this API
+ * requires the presence of GLX 1.3 or later.
+ *
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the external GLDrawable to fail.
+ */
+ public abstract GLDrawable createExternalGLDrawable()
+ throws GLException;
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLEventListener.java b/src/jogl/classes/javax/media/opengl/GLEventListener.java
new file mode 100644
index 000000000..d2c851a69
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLEventListener.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl;
+
+import java.util.EventListener;
+
+/** Declares events which client code can use to manage OpenGL
+ rendering into a {@link GLAutoDrawable}. At the time any of these
+ methods is called, the drawable has made its associated OpenGL
+ context current, so it is valid to make OpenGL calls. */
+
+public interface GLEventListener extends EventListener {
+ /** Called by the drawable immediately after the OpenGL context is
+ initialized. Can be used to perform one-time OpenGL
+ initialization such as setup of lights and display lists. Note
+ that this method may be called more than once if the underlying
+ OpenGL context for the GLAutoDrawable is destroyed and
+ recreated, for example if a GLCanvas is removed from the widget
+ hierarchy and later added again.
+ */
+ public void init(GLAutoDrawable drawable);
+
+ /** Called by the drawable before the OpenGL context is
+ destroyed by an external event.
+ This happens through notification by the
+ native window manager, ie window close, but also
+ manually by calling {@link GLAutoDrawable#destroy destroy}.
+ Shall be used to perform final release of all OpenGL
+ resources, such as memory buffers and GLSL programs.
+ You might also want to exit your application after receiving this signal.
+ */
+ public void dispose(GLAutoDrawable drawable);
+
+ /** Called by the drawable to initiate OpenGL rendering by the
+ client. After all GLEventListeners have been notified of a
+ display event, the drawable will swap its buffers if {@link
+ GLAutoDrawable#setAutoSwapBufferMode setAutoSwapBufferMode} is
+ enabled. */
+ public void display(GLAutoDrawable drawable);
+
+ /** Called by the drawable during the first repaint after the
+ component has been resized. The client can update the viewport
+ and view volume of the window appropriately, for example by a
+ call to {@link javax.media.opengl.GL#glViewport}; note that for
+ convenience the component has already called <code>glViewport(x,
+ y, width, height)</code> when this method is called, so the
+ client may not have to do anything in this method.
+ */
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height);
+
+ /** Called by the drawable when the display mode or the display device
+ associated with the GLAutoDrawable has changed. The two boolean parameters
+ indicate the types of change(s) that have occurred.
+ <P>
+
+ An example of a display <i>mode</i> change is when the bit depth changes (e.g.,
+ from 32-bit to 16-bit color) on monitor upon which the GLAutoDrawable is
+ currently being displayed. <p>
+
+ An example of a display <i>device</i> change is when the user drags the
+ window containing the GLAutoDrawable from one monitor to another in a
+ multiple-monitor setup. <p>
+
+ The reason that this function handles both types of changes (instead of
+ handling mode and device changes in separate methods) is so that
+ applications have the opportunity to respond to display changes in the most
+ efficient manner. For example, the application may need make fewer
+ adjustments to compensate for a device change if it knows that the mode
+ on the new device is identical the previous mode.<p>
+
+ <b>NOTE: Implementations are not required to implement this method. The
+ Reference Implementation DOES NOT IMPLEMENT this method.</b>
+ */
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged);
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLException.java b/src/jogl/classes/javax/media/opengl/GLException.java
new file mode 100644
index 000000000..644042e15
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl;
+
+/** A generic exception for OpenGL errors used throughout the binding
+ as a substitute for {@link RuntimeException}. */
+
+public class GLException extends RuntimeException {
+ /** Constructs a GLException object. */
+ public GLException() {
+ super();
+ }
+
+ /** Constructs a GLException object with the specified detail
+ message. */
+ public GLException(String message) {
+ super(message);
+ }
+
+ /** Constructs a GLException object with the specified detail
+ message and root cause. */
+ public GLException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /** Constructs a GLException object with the specified root
+ cause. */
+ public GLException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLPbuffer.java b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
new file mode 100644
index 000000000..0250365b0
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl;
+
+/** Provides offscreen rendering support via pbuffers. The principal
+ addition of this interface is a {@link #destroy} method to
+ deallocate the pbuffer and its associated resources. It also
+ contains experimental methods for accessing the pbuffer's contents
+ as a texture map and enabling rendering to floating-point frame
+ buffers. These methods are not guaranteed to be supported on all
+ platforms and may be deprecated in a future release. */
+
+public interface GLPbuffer extends GLAutoDrawable {
+ /** Indicates the GL_APPLE_float_pixels extension is being used for this pbuffer. */
+ public static final int APPLE_FLOAT = 1;
+
+ /** Indicates the GL_ATI_texture_float extension is being used for this pbuffer. */
+ public static final int ATI_FLOAT = 2;
+
+ /** Indicates the GL_NV_float_buffer extension is being used for this pbuffer. */
+ public static final int NV_FLOAT = 3;
+
+ /** Binds this pbuffer to its internal texture target. Only valid to
+ call if offscreen render-to-texture has been specified in the
+ NWCapabilities for this GLPbuffer. If the
+ render-to-texture-rectangle capability has also been specified,
+ this will use e.g. wglBindTexImageARB as its implementation and
+ cause the texture to be bound to e.g. the
+ GL_TEXTURE_RECTANGLE_NV state; otherwise, during the display()
+ phase the pixels will have been copied into an internal texture
+ target and this will cause that to be bound to the GL_TEXTURE_2D
+ state. */
+ public void bindTexture();
+
+ /** Unbinds the pbuffer from its internal texture target. */
+ public void releaseTexture();
+
+ /** Destroys the native resources associated with this pbuffer. It
+ is not valid to call display() or any other routines on this
+ pbuffer after it has been destroyed. Before destroying the
+ pbuffer, the application must destroy any additional OpenGL
+ contexts which have been created for the pbuffer via {@link
+ #createContext}. */
+ public void destroy();
+
+ /** Indicates which vendor's extension is being used to support
+ floating point channels in this pbuffer if that capability was
+ requested in the NWCapabilities during pbuffer creation. Returns
+ one of NV_FLOAT, ATI_FLOAT or APPLE_FLOAT, or throws GLException
+ if floating-point channels were not requested for this pbuffer.
+ This function may only be called once the init method for this
+ pbuffer's GLEventListener has been called. */
+ public int getFloatingPointMode();
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
new file mode 100644
index 000000000..687027dec
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -0,0 +1,555 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package javax.media.opengl;
+
+import javax.media.opengl.sub.fixed.*;
+import java.lang.reflect.*;
+import java.security.*;
+import com.sun.opengl.impl.*;
+import com.sun.nwi.impl.NWReflection;
+
+public class GLProfile {
+ /** The desktop (OpenGL 2.0) profile */
+ public static final String GL2 = "GL2";
+
+ /** The desktop short profile, intersecting: GL2+GLES1+GLES2 */
+ public static final String GL2ES12 = "GL2ES12";
+
+ /** The OpenGL ES 1 (really, 1.1) profile */
+ public static final String GLES1 = "GLES1";
+
+ /** The OpenGL ES 2 (really, 2.0) profile */
+ public static final String GLES2 = "GLES2";
+
+ /** The JVM/process wide chosen GL profile **/
+ private static String profile = null;
+
+ private static final void tryLibrary()
+ {
+ try {
+ Class clazz = Class.forName(getGLImplBaseClassName()+"Impl");
+ if(GL2.equals(profile)) {
+ // See DRIHack.java for an explanation of why this is necessary
+ DRIHack.begin();
+ NativeLibLoader.loadGL2();
+ DRIHack.end();
+ } if(GL2ES12.equals(profile)) {
+ // See DRIHack.java for an explanation of why this is necessary
+ DRIHack.begin();
+ NativeLibLoader.loadGL2ES12();
+ DRIHack.end();
+ } else if(GLES1.equals(profile) || GLES2.equals(profile)) {
+ Object eGLDrawableFactory = NWReflection.createInstance("com.sun.opengl.impl.egl.EGLDrawableFactory");
+ if(null==eGLDrawableFactory) {
+ throw new GLException("com.sun.opengl.impl.egl.EGLDrawableFactory not available");
+ }
+ }
+ System.out.println("Successfully loaded profile " + profile);
+ } catch (Throwable e) {
+ if (Debug.debug("GLProfile")) {
+ e.printStackTrace();
+ }
+ profile=null;
+ }
+ }
+
+ public static synchronized final void setProfile(String profile)
+ throws GLException
+ {
+ if(null==GLProfile.profile) {
+ GLProfile.profile = profile;
+ tryLibrary();
+ if (profile == null) {
+ throw new GLException("Profile " + profile + " not available");
+ }
+ } else {
+ if(!GLProfile.profile.equals(profile)) {
+ throw new GLException("Chosen profile ("+profile+") doesn't match preset one: "+GLProfile.profile);
+ }
+ }
+ }
+
+ public static synchronized final void setProfile(String[] profiles)
+ throws GLException
+ {
+ for(int i=0; profile==null && i<profiles.length; i++) {
+ profile = profiles[i];
+ tryLibrary();
+ }
+ if(null==profile) {
+ StringBuffer msg = new StringBuffer();
+ msg.append("[");
+ for (int i = 0; i < profiles.length; i++) {
+ if (i > 0)
+ msg.append(", ");
+ msg.append(profiles[i]);
+ }
+ msg.append("]");
+ throw new GLException("Profiles "+msg.toString()+" not available");
+ }
+ }
+
+ /**
+ * Selects a profile, implementing the interface GL2ES1.
+ * Order: GL2, GL2ES12, GLES1
+ */
+ public static synchronized final void setProfileGL2ES1() {
+ setProfile(new String[] { GL2, GL2ES12, GLES1 });
+ }
+
+ /**
+ * Selects a profile, implementing the interface GL2ES2.
+ * Order: GL2, GL2ES12, GLES2
+ */
+ public static synchronized final void setProfileGL2ES2() {
+ setProfile(new String[] { GL2, GL2ES12, GLES2 });
+ }
+
+ /**
+ * Selects a profile, implementing the interface GL
+ * Order: GL2, GL2ES12, GLES2, GLES1
+ */
+ public static synchronized final void setProfileGLAny() {
+ setProfile(new String[] { GL2, GL2ES12, GLES2, GLES1 });
+ }
+
+ public static final String getProfile() {
+ return profile;
+ }
+
+ /* true profile GL2ES12 */
+ public static final boolean isGL2ES12() {
+ return GL2ES12.equals(profile);
+ }
+
+ /* true profile GL2 */
+ public static final boolean isGL2() {
+ return GL2.equals(profile);
+ }
+
+ /* true profile GLES1 */
+ public static final boolean isGLES1() {
+ return GLES1.equals(profile);
+ }
+
+ /* true profile GLES2 */
+ public static final boolean isGLES2() {
+ return GLES2.equals(profile);
+ }
+
+ /* abstract profile GL2ES12, GL2, GLES1 */
+ public static final boolean isGL2ES1() {
+ return isGL2ES12() || isGL2() || isGLES1();
+ }
+
+ /* abstract profile GL2ES12, GL2, GLES2 */
+ public static final boolean isGL2ES2() {
+ return isGL2ES12() || isGL2() || isGLES2();
+ }
+
+ /* abstract profile GLES1, GLES2 */
+ public static final boolean isGLES() {
+ return isGLES2() || isGLES1();
+ }
+
+ public static final boolean matches(String test_profile) {
+ return (null==test_profile)?false:test_profile.equals(profile);
+ }
+
+ public static final boolean implementationOfGL2(Object obj) {
+ return NWReflection.implementationOf(obj, "javax.media.opengl.GL2");
+ }
+
+ public static final boolean implementationOfGLES1(Object obj) {
+ return NWReflection.implementationOf(obj, "javax.media.opengl.GLES1");
+ }
+
+ public static final boolean implementationOfGLES2(Object obj) {
+ return NWReflection.implementationOf(obj, "javax.media.opengl.GLES2");
+ }
+
+ public static final boolean implementationOfGLES(Object obj) {
+ return implementationOfGLES1(obj) || implementationOfGLES2(obj);
+ }
+
+ public static final boolean implementationOfGL2ES1(Object obj) {
+ return NWReflection.implementationOf(obj, "javax.media.opengl.GL2ES1");
+ }
+
+ public static final boolean implementationOfGL2ES2(Object obj) {
+ return NWReflection.implementationOf(obj, "javax.media.opengl.GL2ES2");
+ }
+
+ public static final String getGLImplBaseClassName() {
+ if(isGL2()) {
+ return "com.sun.opengl.impl.gl2.GL2";
+ } else if(isGL2ES12()) {
+ return "com.sun.opengl.impl.gl2es12.GL2ES12";
+ } else if(isGLES1()) {
+ return "com.sun.opengl.impl.es1.GLES1";
+ } else if(isGLES2()) {
+ return "com.sun.opengl.impl.es2.GLES2";
+ } else {
+ throw new GLException("unsupported profile \"" + profile + "\"");
+ }
+ }
+
+ public static String getGLTypeName(int type) {
+ switch (type) {
+ case GL.GL_UNSIGNED_BYTE:
+ return "GL_UNSIGNED_BYTE";
+ case GL.GL_BYTE:
+ return "GL_BYTE";
+ case GL.GL_UNSIGNED_SHORT:
+ return "GL_UNSIGNED_SHORT";
+ case GL.GL_SHORT:
+ return "GL_SHORT";
+ case GL.GL_FLOAT:
+ return "GL_FLOAT";
+ case GL.GL_FIXED:
+ return "GL_FIXED";
+ case javax.media.opengl.GL2ES2.GL_INT:
+ return "GL_INT";
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ return "GL_UNSIGNED_INT";
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ return "GL_DOUBLE";
+ case javax.media.opengl.GL2.GL_2_BYTES:
+ return "GL_2_BYTES";
+ case javax.media.opengl.GL2.GL_3_BYTES:
+ return "GL_3_BYTES";
+ case javax.media.opengl.GL2.GL_4_BYTES:
+ return "GL_4_BYTES";
+ }
+ return null;
+ }
+
+ /**
+ * General validation if type is a valid GL data type
+ * for the current profile
+ */
+ public static boolean isValidDataType(int type, boolean throwException) {
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case GL.GL_FIXED:
+ return true;
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ if( isGL2ES2() ) {
+ return true;
+ }
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ case javax.media.opengl.GL2.GL_2_BYTES:
+ case javax.media.opengl.GL2.GL_3_BYTES:
+ case javax.media.opengl.GL2.GL_4_BYTES:
+ if( isGL2ES12() || isGL2() ) {
+ return true;
+ }
+ }
+ if(throwException) {
+ throw new GLException("Illegal data type on profile "+GLProfile.getProfile()+": "+type);
+ }
+ return false;
+ }
+
+ public static boolean isValidateArrayDataType(int index, int comps, int type,
+ boolean isVertexAttribPointer, boolean throwException) {
+ String indexName = GLContext.getPredefinedArrayIndexName(index);
+ if(GLProfile.isGLES1()) {
+ if(isVertexAttribPointer) {
+ if(throwException) {
+ throw new GLException("Illegal array type for "+indexName+" on profile GLES1: VertexAttribPointer");
+ }
+ return false;
+ }
+ switch(index) {
+ case GLPointerIf.GL_VERTEX_ARRAY:
+ case GLPointerIf.GL_TEXTURE_COORD_ARRAY:
+ switch(type) {
+ case GL.GL_BYTE:
+ case GL.GL_SHORT:
+ case GL.GL_FIXED:
+ case GL.GL_FLOAT:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GLES1: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GLPointerIf.GL_NORMAL_ARRAY:
+ switch(type) {
+ case GL.GL_BYTE:
+ case GL.GL_SHORT:
+ case GL.GL_FIXED:
+ case GL.GL_FLOAT:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GLES1: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 3:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GLPointerIf.GL_COLOR_ARRAY:
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_FIXED:
+ case GL.GL_FLOAT:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GLES1: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ }
+ } else if(GLProfile.isGLES2()) {
+ // simply ignore !isVertexAttribPointer case, since it is simulated anyway ..
+
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case GL.GL_FIXED:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GLES2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ } else if(GLProfile.isGL2ES12() || GLProfile.isGL2()) {
+ if(isVertexAttribPointer) {
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ } else {
+ switch(index) {
+ case GLPointerIf.GL_VERTEX_ARRAY:
+ switch(type) {
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GLPointerIf.GL_NORMAL_ARRAY:
+ switch(type) {
+ case GL.GL_BYTE:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 3:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GLPointerIf.GL_COLOR_ARRAY:
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GLPointerIf.GL_TEXTURE_COORD_ARRAY:
+ switch(type) {
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+indexName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+indexName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLUniformData.java b/src/jogl/classes/javax/media/opengl/GLUniformData.java
new file mode 100644
index 000000000..40368e4e7
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLUniformData.java
@@ -0,0 +1,159 @@
+
+package javax.media.opengl;
+
+import java.nio.*;
+
+public class GLUniformData {
+
+ /**
+ * int atom
+ *
+ * Number of objects is 1
+ *
+ * @arg components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, int val) {
+ init(name, 1, new Integer(val));
+ }
+
+ /**
+ * float atom
+ *
+ * Number of objects is 1
+ *
+ * @arg components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, float val) {
+ init(name, 1, new Float(val));
+ }
+
+ /**
+ * Multiple IntBuffer Vector
+ *
+ * Number of objects is calculated by data.limit()/components
+ *
+ * @arg components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, int components, IntBuffer data) {
+ init(name, components, data);
+ }
+
+ /**
+ * Multiple FloatBuffer Vector
+ *
+ * Number of objects is calculated by data.limit()/components
+ *
+ * @arg components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, int components, FloatBuffer data) {
+ init(name, components, data);
+ }
+
+ /**
+ * Multiple FloatBuffer Matrix
+ *
+ * Number of objects is calculated by data.limit()/(rows*columns)
+ *
+ * @arg rows the matrix rows
+ * @arg column the matrix column
+ */
+ public GLUniformData(String name, int rows, int columns, FloatBuffer data) {
+ init(name, rows, columns, data);
+ }
+
+ public void setData(int data) { init(new Integer(data)); }
+ public void setData(float data) { init(new Float(data)); }
+ public void setData(IntBuffer data) { init(data); }
+ public void setData(FloatBuffer data) { init(data); }
+
+ public int intValue() { return ((Integer)data).intValue(); };
+ public float floatValue() { return ((Float)data).floatValue(); };
+ public IntBuffer intBufferValue() { return (IntBuffer)data; };
+ public FloatBuffer floatBufferValue() { return (FloatBuffer)data; };
+
+ public String toString() {
+ return "GLUniformData[name "+name+
+ ", location "+location+
+ ", size "+rows+"*"+columns+
+ ", count "+count+
+ ", matrix "+isMatrix+
+ ", data "+data+
+ "]";
+ }
+
+ private void init(String name, int rows, int columns, Object data) {
+ if( 2>rows || rows>4 || 2>columns || columns>4 ) {
+ throw new GLException("rowsXcolumns must be within [2..4]X[2..4], is: "+rows+"X"+columns);
+ }
+ this.name=name;
+ this.rows=rows;
+ this.columns=columns;
+ this.isMatrix=true;
+ this.location=-1;
+ init(data);
+ }
+
+ private void init(String name, int components, Object data) {
+ if( 1>components || components>4 ) {
+ throw new GLException("components must be within [1..4], is: "+components);
+ }
+ this.name=name;
+ this.columns=components;
+ this.rows=1;
+ this.isMatrix=false;
+ this.location=-1;
+ init(data);
+ }
+
+ private void init(Object data) {
+ if(data instanceof Buffer) {
+ int sz = rows*columns;
+ Buffer buffer = (Buffer)data;
+ if(buffer.limit()<sz || 0!=buffer.limit()%sz) {
+ throw new GLException("data buffer size invalid: new buffer limit: "+buffer.limit()+"\n\t"+this);
+ }
+ this.count=buffer.limit()/(rows*columns);
+ } else {
+ if(isMatrix) {
+ throw new GLException("Atom type not allowed for matrix : "+this);
+ }
+ this.count=1;
+ }
+ this.data=data;
+ }
+
+ public String getName() { return name; }
+
+ public int getLocation() { return location; }
+
+ /**
+ * Sets the determined location of the shader uniform
+ * This is usually done within ShaderState.
+ *
+ * @see javax.media.opengl.glsl.ShaderState#glUniform(GL2ES2, GLUniformData)
+ */
+ public void setLocation(int location) { this.location=location; }
+
+ public Object getObject() {
+ return data;
+ }
+ public Buffer getBuffer() {
+ return (data instanceof Buffer)?(Buffer)data:null;
+ }
+ public boolean isBuffer() {
+ return (data instanceof Buffer);
+ }
+ public boolean isMatrix() { return isMatrix; }
+
+ public int count() { return count; }
+ public int components() { return rows*columns; }
+ public int rows() { return rows; }
+ public int columns() { return columns; }
+
+ private String name;
+ private int location;
+ private int rows, columns;
+ private int count;
+ private Object data;
+ private boolean isMatrix;
+}
diff --git a/src/jogl/classes/javax/media/opengl/Threading.java b/src/jogl/classes/javax/media/opengl/Threading.java
new file mode 100755
index 000000000..763389aca
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/Threading.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl;
+
+// FIXME: refactor Java SE dependencies
+//import java.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import com.sun.opengl.impl.*;
+
+/** This API provides access to the threading model for the implementation of
+ the classes in this package.
+
+ <P>
+
+ OpenGL is specified as a thread-safe API, but in practice there
+ are multithreading-related issues on most, if not all, of the
+ platforms which support it. For example, some OpenGL
+ implementations do not behave well when one context is made
+ current first on one thread, released, and then made current on a
+ second thread, although this is legal according to the OpenGL
+ specification. On other platforms there are other problems.
+
+ <P>
+
+ Due to these limitations, and due to the inherent multithreading
+ in the Java platform (in particular, in the Abstract Window
+ Toolkit), it is often necessary to limit the multithreading
+ occurring in the typical application using the OpenGL API.
+
+ <P>
+
+ In the current reference implementation, for instance, multithreading
+ has been limited by
+ forcing all OpenGL-related work for GLAutoDrawables on to a single
+ thread. In other words, if an application uses only the
+ GLAutoDrawable and GLEventListener callback mechanism, it is
+ guaranteed to have the most correct single-threaded behavior on
+ all platforms.
+
+ <P>
+
+ Applications using the GLContext makeCurrent/release API directly
+ will inherently break this single-threaded model, as these methods
+ require that the OpenGL context be made current on the current
+ thread immediately. For applications wishing to integrate better
+ with an implementation that uses the single-threaded model, this
+ class provides public access to the mechanism used by the implementation.
+
+ <P>
+
+ Users can execute Runnables on the
+ internal thread used for performing OpenGL work, and query whether
+ the current thread is already this thread. Using these mechanisms
+ the user can move work from the current thread on to the internal
+ OpenGL thread if desired.
+
+ <P>
+
+ This class also provides mechanisms for querying whether this
+ internal serialization of OpenGL work is in effect, and a
+ programmatic way of disabling it. In the current reference
+ implementation it is enabled by default, although it could be
+ disabled in the future if OpenGL drivers become more robust on
+ all platforms.
+
+ <P>
+
+ In addition to specifying programmatically whether the single
+ thread for OpenGL work is enabled, users may switch it on and off
+ using the system property <code>opengl.1thread</code>. Valid values
+ for this system property are:
+
+ <PRE>
+ -Dopengl.1thread=false Disable single-threading of OpenGL work
+ -Dopengl.1thread=true Enable single-threading of OpenGL work (default -- on a newly-created worker thread)
+ -Dopengl.1thread=auto Select default single-threading behavior (currently on)
+ -Dopengl.1thread=awt Enable single-threading of OpenGL work on AWT event dispatch thread (current default on all
+ platforms, and also the default behavior older releases)
+ -Dopengl.1thread=worker Enable single-threading of OpenGL work on newly-created worker thread (not suitable for Mac
+ OS X or X11 platforms, and risky on Windows in applet environments)
+ </PRE>
+*/
+
+public class Threading {
+ private static boolean singleThreaded = true;
+ private static final int AWT = 1;
+ private static final int WORKER = 2;
+ private static int mode;
+ /* FIXME: refactor Java SE dependencies
+ // We need to know whether we're running on X11 platforms to change
+ // our behavior when the Java2D/JOGL bridge is active
+ private static boolean isX11;
+ */
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String workaround = System.getProperty("opengl.1thread");
+ /* FIXME: refactor Java SE dependencies
+ // Default to using the AWT thread on all platforms except
+ // Windows. On OS X there is instability apparently due to
+ // using the JAWT on non-AWT threads. On X11 platforms there
+ // are potential deadlocks which can be caused if the AWT
+ // EventQueue thread hands work off to the GLWorkerThread
+ // while holding the AWT lock. The optimization of
+ // makeCurrent / release calls isn't worth these stability
+ // problems.
+ String osName = System.getProperty("os.name");
+ boolean isWindows = osName.startsWith("Windows");
+ isX11 = !(isWindows || osName.startsWith("Mac OS"));
+ */
+ // int defaultMode = (isWindows ? WORKER : AWT);
+ int defaultMode = AWT;
+ mode = defaultMode;
+ if (workaround != null) {
+ workaround = workaround.toLowerCase();
+ if (workaround.equals("true") ||
+ workaround.equals("auto")) {
+ // Nothing to do; singleThreaded and mode already set up
+ } else if (workaround.equals("worker")) {
+ singleThreaded = true;
+ mode = WORKER;
+ } else if (workaround.equals("awt")) {
+ singleThreaded = true;
+ mode = AWT;
+ } else {
+ singleThreaded = false;
+ }
+ }
+ printWorkaroundNotice();
+ return null;
+ }
+ });
+ }
+
+ /** No reason to ever instantiate this class */
+ private Threading() {}
+
+ /** If an implementation of the javax.media.opengl APIs offers a
+ multithreading option but the default behavior is single-threading,
+ this API provides a mechanism for end users to disable single-threading
+ in this implementation. Users are strongly discouraged from
+ calling this method unless they are aware of all of the
+ consequences and are prepared to enforce some amount of
+ threading restrictions in their applications. Disabling
+ single-threading, for example, may have unintended consequences
+ on GLAutoDrawable implementations such as GLCanvas, GLJPanel and
+ GLPbuffer. Currently there is no supported way to re-enable it
+ once disabled, partly to discourage careless use of this
+ method. This method should be called as early as possible in an
+ application. */
+ public static void disableSingleThreading() {
+ singleThreaded = false;
+ if (Debug.verbose()) {
+ System.err.println("Application forced disabling of single-threading of javax.media.opengl implementation");
+ }
+ }
+
+ /** Indicates whether OpenGL work is being automatically forced to a
+ single thread in this implementation. */
+ public static boolean isSingleThreaded() {
+ return singleThreaded;
+ }
+
+ /** Indicates whether the current thread is the single thread on
+ which this implementation of the javax.media.opengl APIs
+ performs all of its OpenGL-related work. This method should only
+ be called if the single-thread model is in effect. */
+ public static boolean isOpenGLThread() throws GLException {
+ if (!isSingleThreaded()) {
+ throw new GLException("Should only call this in single-threaded mode");
+ }
+
+ switch (mode) {
+ case AWT:
+ /* FIXME: refactor Java SE dependencies
+ if (Java2D.isOGLPipelineActive()) {
+ // FIXME: ideally only the QFT would be considered to be the
+ // "OpenGL thread", but we can not currently run all of
+ // JOGL's OpenGL work on that thread. See the FIXME in
+ // invokeOnOpenGLThread.
+ return (Java2D.isQueueFlusherThread() ||
+ (isX11 && EventQueue.isDispatchThread()));
+ } else {
+ return EventQueue.isDispatchThread();
+ }
+ */
+ return true;
+ case WORKER:
+ /* FIXME: refactor Java SE dependencies
+ if (Java2D.isOGLPipelineActive()) {
+ // FIXME: ideally only the QFT would be considered to be the
+ // "OpenGL thread", but we can not currently run all of
+ // JOGL's OpenGL work on that thread. See the FIXME in
+ // invokeOnOpenGLThread.
+ return (Java2D.isQueueFlusherThread() ||
+ (isX11 && GLWorkerThread.isWorkerThread()));
+ } else {
+ return GLWorkerThread.isWorkerThread();
+ }
+ */
+ return GLWorkerThread.isWorkerThread();
+ default:
+ throw new InternalError("Illegal single-threading mode " + mode);
+ }
+ }
+
+ /** Executes the passed Runnable on the single thread used for all
+ OpenGL work in this javax.media.opengl API implementation. It is
+ not specified exactly which thread is used for this
+ purpose. This method should only be called if the single-thread
+ model is in use and if the current thread is not the OpenGL
+ thread (i.e., if <code>isOpenGLThread()</code> returns
+ false). It is up to the end user to check to see whether the
+ current thread is the OpenGL thread and either execute the
+ Runnable directly or perform the work inside it. */
+ public static void invokeOnOpenGLThread(Runnable r) throws GLException {
+ if (!isSingleThreaded()) {
+ throw new GLException ("Should only call this in single-threaded mode");
+ }
+
+ if (isOpenGLThread()) {
+ throw new GLException ("Should only call this from other threads than the OpenGL thread");
+ }
+
+ switch (mode) {
+ case AWT:
+ /* FIXME: refactor Java SE dependencies
+ // FIXME: ideally should run all OpenGL work on the Java2D QFT
+ // thread when it's enabled, but unfortunately there are
+ // deadlock issues on X11 platforms when making our
+ // heavyweight OpenGL contexts current on the QFT because we
+ // perform the JAWT lock inside the makeCurrent()
+ // implementation, which attempts to grab the AWT lock on the
+ // QFT which is not allowed. For now, on X11 platforms,
+ // continue to perform this work on the EDT.
+ if (Java2D.isOGLPipelineActive() && !isX11) {
+ Java2D.invokeWithOGLContextCurrent(null, r);
+ } else {
+ try {
+ EventQueue.invokeAndWait(r);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ }
+ */
+ r.run();
+ break;
+
+ case WORKER:
+ if (!GLWorkerThread.isStarted()) {
+ synchronized (GLWorkerThread.class) {
+ if (!GLWorkerThread.isStarted()) {
+ GLWorkerThread.start();
+ }
+ }
+ }
+ try {
+ GLWorkerThread.invokeAndWait(r);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ break;
+
+ default:
+ throw new InternalError("Illegal single-threading mode " + mode);
+ }
+ }
+
+ /** This is a workaround for AWT-related deadlocks which only seem
+ to show up in the context of applets */
+ public static boolean isAWTMode() {
+ return (mode == AWT);
+ }
+
+ private static void printWorkaroundNotice() {
+ if (singleThreaded && Debug.verbose()) {
+ System.err.println("Using " +
+ (mode == AWT ? "AWT" : "OpenGL worker") +
+ " thread for performing OpenGL work in javax.media.opengl implementation");
+ }
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java
new file mode 100644
index 000000000..d92cec389
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl.awt;
+
+import javax.media.opengl.*;
+import javax.media.opengl.glu.*;
+
+public interface AWTGLAutoDrawable extends GLAutoDrawable, ComponentEvents {
+ /** Requests a new width and height for this AWTGLAutoDrawable. */
+ public void setSize(int width, int height);
+
+ /** Schedules a repaint of the component at some point in the
+ future. */
+ public void repaint();
+}
diff --git a/src/jogl/classes/javax/media/opengl/awt/ComponentEvents.java b/src/jogl/classes/javax/media/opengl/awt/ComponentEvents.java
new file mode 100644
index 000000000..0c4f63c2d
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/awt/ComponentEvents.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl.awt;
+
+import javax.media.opengl.*;
+import java.awt.event.*;
+import java.beans.PropertyChangeListener;
+
+/** Factors out the listener manipulation for the events supported by
+ all of the {@link GLDrawable} implementations. Provided to reduce
+ clutter in the documentation for GLDrawable. */
+
+public interface ComponentEvents {
+ public void addComponentListener(ComponentListener l);
+ public void removeComponentListener(ComponentListener l);
+ public void addFocusListener(FocusListener l);
+ public void removeFocusListener(FocusListener l);
+ public void addHierarchyBoundsListener(HierarchyBoundsListener l);
+ public void removeHierarchyBoundsListener(HierarchyBoundsListener l);
+ public void addHierarchyListener(HierarchyListener l);
+ public void removeHierarchyListener(HierarchyListener l);
+ public void addInputMethodListener(InputMethodListener l);
+ public void removeInputMethodListener(InputMethodListener l);
+ public void addKeyListener(KeyListener l);
+ public void removeKeyListener(KeyListener l);
+ public void addMouseListener(MouseListener l);
+ public void removeMouseListener(MouseListener l);
+ public void addMouseMotionListener(MouseMotionListener l);
+ public void removeMouseMotionListener(MouseMotionListener l);
+ public void addMouseWheelListener(MouseWheelListener l);
+ public void removeMouseWheelListener(MouseWheelListener l);
+ public void addPropertyChangeListener(PropertyChangeListener listener);
+ public void removePropertyChangeListener(PropertyChangeListener listener);
+ public void addPropertyChangeListener(String propertyName,
+ PropertyChangeListener listener);
+ public void removePropertyChangeListener(String propertyName,
+ PropertyChangeListener listener);
+}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
new file mode 100644
index 000000000..031c5f854
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -0,0 +1,630 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl.awt;
+
+import javax.media.opengl.*;
+import javax.media.nwi.*;
+import javax.media.nwi.awt.AWTGraphicsDevice;
+import javax.media.nwi.awt.AWTGraphicsConfiguration;
+
+import com.sun.opengl.impl.*;
+
+import java.awt.Canvas;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.EventQueue;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.Container;
+import java.awt.Window;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.geom.*;
+import java.beans.*;
+import java.lang.reflect.*;
+import java.security.*;
+
+// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
+// context whenever the displayChanged() function is called on our
+// GLEventListeners
+
+/** A heavyweight AWT component which provides OpenGL rendering
+ support. This is the primary implementation of {@link GLDrawable};
+ {@link GLJPanel} is provided for compatibility with Swing user
+ interfaces when adding a heavyweight doesn't work either because
+ of Z-ordering or LayoutManager problems. */
+
+public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
+
+ private static final boolean DEBUG = Debug.debug("GLCanvas");
+
+ private GLDrawableHelper drawableHelper = new GLDrawableHelper();
+ private GLDrawable drawable;
+ private GLContextImpl context;
+ private boolean autoSwapBufferMode = true;
+ private boolean sendReshape = false;
+
+ private GraphicsConfiguration chosen;
+ private NWCapabilities glCaps;
+ private NWCapabilitiesChooser glCapChooser;
+
+ static {
+ // Default to the GL2 profile, which is the default on the desktop
+ if (GLProfile.getProfile() == null) {
+ GLProfile.setProfile(GLProfile.GL2);
+ }
+ }
+
+ /** Creates a new GLCanvas component with a default set of OpenGL
+ capabilities, using the default OpenGL capabilities selection
+ mechanism, on the default screen device. */
+ public GLCanvas() {
+ this(null);
+ }
+
+ /** Creates a new GLCanvas component with the requested set of
+ OpenGL capabilities, using the default OpenGL capabilities
+ selection mechanism, on the default screen device. */
+ public GLCanvas(NWCapabilities capabilities) {
+ this(capabilities, null, null, null);
+ }
+
+ /** Creates a new GLCanvas component. The passed NWCapabilities
+ specifies the OpenGL capabilities for the component; if null, a
+ default set of capabilities is used. The NWCapabilitiesChooser
+ specifies the algorithm for selecting one of the available
+ NWCapabilities for the component; a DefaultGLCapabilitesChooser
+ is used if null is passed for this argument. The passed
+ GLContext specifies an OpenGL context with which to share
+ textures, display lists and other OpenGL state, and may be null
+ if sharing is not desired. See the note in the overview
+ documentation on <a
+ href="../../../overview-summary.html#SHARING">context
+ sharing</a>. The passed GraphicsDevice indicates the screen on
+ which to create the GLCanvas; the GLDrawableFactory uses the
+ default screen device of the local GraphicsEnvironment if null
+ is passed for this argument. */
+ public GLCanvas(NWCapabilities capabilities,
+ NWCapabilitiesChooser chooser,
+ GLContext shareWith,
+ GraphicsDevice device) {
+ // 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.
+ /*
+ * Workaround for Xinerama, always pass null so we can detect whether
+ * super.getGraphicsConfiguration() is returning the Canvas' GC (null),
+ * or an ancestor component's GC (non-null) in the overridden version
+ * below.
+ */
+ super();
+ /*
+ * Save the chosen capabilities for use in getGraphicsConfiguration().
+ */
+ chosen = chooseGraphicsConfiguration(capabilities, chooser, device);
+ if (chosen != null) {
+ /*
+ * If we are running on a platform that
+ * must select a GraphicsConfiguration now,
+ * save these for later use in getGraphicsConfiguration().
+ */
+ this.glCapChooser = chooser;
+ this.glCaps = capabilities;
+ }
+ if (!Beans.isDesignTime()) {
+ drawable = GLDrawableFactory.getFactory().createGLDrawable(NativeWindowFactory.getFactory(getClass()).getNativeWindow(this),
+ capabilities, chooser);
+ context = (GLContextImpl) drawable.createContext(shareWith);
+ context.setSynchronized(true);
+ }
+ }
+
+ protected interface DestroyMethod {
+ public void destroyMethod();
+ }
+
+ protected final static Object addClosingListener(Component c, final DestroyMethod d) {
+ WindowAdapter cl = null;
+ Window w = getWindow(c);
+ if(null!=w) {
+ cl = new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ // we have to issue this call rigth away,
+ // otherwise the window gets destroyed
+ d.destroyMethod();
+ }
+ };
+ w.addWindowListener(cl);
+ }
+ return cl;
+ }
+
+ protected final static Window getWindow(Component c) {
+ while ( c!=null && ! ( c instanceof Window ) ) {
+ c = c.getParent();
+ }
+ return (Window)c;
+ }
+
+ /**
+ * Overridden to choose a GraphicsConfiguration on a parent container's
+ * GraphicsDevice because both devices
+ */
+ public GraphicsConfiguration getGraphicsConfiguration() {
+ /*
+ * Workaround for problems with Xinerama and java.awt.Component.checkGD
+ * when adding to a container on a different graphics device than the
+ * one that this Canvas is associated with.
+ *
+ * GC will be null unless:
+ * - A native peer has assigned it. This means we have a native
+ * peer, and are already comitted to a graphics configuration.
+ * - This canvas has been added to a component hierarchy and has
+ * an ancestor with a non-null GC, but the native peer has not
+ * yet been created. This means we can still choose the GC on
+ * all platforms since the peer hasn't been created.
+ */
+ final GraphicsConfiguration gc = super.getGraphicsConfiguration();
+ /*
+ * chosen is only non-null on platforms where the GLDrawableFactory
+ * returns a non-null GraphicsConfiguration (in the GLCanvas
+ * constructor).
+ *
+ * if gc is from this Canvas' native peer then it should equal chosen,
+ * otherwise it is from an ancestor component that this Canvas is being
+ * added to, and we go into this block.
+ */
+ if (gc != null && chosen != null && !chosen.equals(gc)) {
+ /*
+ * Check for compatibility with gc. If they differ by only the
+ * device then return a new GCconfig with the super-class' GDevice
+ * (and presumably the same visual ID in Xinerama).
+ *
+ */
+ if (!chosen.getDevice().getIDstring().equals(gc.getDevice().getIDstring())) {
+ /*
+ * Here we select a GraphicsConfiguration on the alternate
+ * device that is presumably identical to the chosen
+ * configuration, but on the other device.
+ *
+ * Should really check to ensure that we select a configuration
+ * with the same X visual ID for Xinerama screens, otherwise the
+ * GLDrawable may have the wrong visual ID (I don't think this
+ * ever gets updated). May need to add a method to
+ * X11GLDrawableFactory to do this in a platform specific
+ * manner.
+ *
+ * However, on platforms where we can actually get into this
+ * block, both devices should have the same visual list, and the
+ * same configuration should be selected here.
+ */
+ final GraphicsConfiguration compatible = chooseGraphicsConfiguration(glCaps, glCapChooser, gc.getDevice());
+
+ if (compatible != null) {
+ /*
+ * Save the new GC for equals test above, and to return to
+ * any outside callers of this method.
+ */
+ chosen = compatible;
+ }
+ }
+
+ /*
+ * If a compatible GC was not found in the block above, this will
+ * return the GC that was selected in the constructor (and might
+ * cause an exception in Component.checkGD when adding to a
+ * container, but in this case that would be the desired behavior).
+ *
+ */
+ return chosen;
+ } else if (gc == null) {
+ /*
+ * The GC is null, which means we have no native peer, and are not
+ * part of a (realized) component hierarchy. So we return the
+ * desired visual that was selected in the constructor (possibly
+ * null).
+ */
+ return chosen;
+ }
+
+ /*
+ * Otherwise we have not explicitly selected a GC in the constructor, so
+ * just return what Canvas would have.
+ */
+ return gc;
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return drawable.createContext(shareWith);
+ }
+
+ public void setRealized(boolean realized) {
+ }
+
+ private Object closingListener = null;
+ private Object closingListenerLock = new Object();
+
+ public void display() {
+ maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction,
+ displayAction);
+ if(null==closingListener) {
+ synchronized(closingListenerLock) {
+ if(null==closingListener) {
+ closingListener=addClosingListener(this, new DestroyMethod() {
+ public void destroyMethod() { destroy(); } });
+ }
+ }
+ }
+ }
+
+ /**
+ * Just an alias for removeNotify
+ */
+ public void destroy() {
+ removeNotify();
+ }
+
+ /** Overridden to cause OpenGL rendering to be performed during
+ repaint cycles. Subclasses which override this method must call
+ super.paint() in their paint() method in order to function
+ properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>paint</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ public void paint(Graphics g) {
+ if (Beans.isDesignTime()) {
+ // Make GLCanvas behave better in NetBeans GUI builder
+ g.setColor(Color.BLACK);
+ g.fillRect(0, 0, getWidth(), getHeight());
+ FontMetrics fm = g.getFontMetrics();
+ String name = getName();
+ if (name == null) {
+ name = getClass().getName();
+ int idx = name.lastIndexOf('.');
+ if (idx >= 0) {
+ name = name.substring(idx + 1);
+ }
+ }
+ Rectangle2D bounds = fm.getStringBounds(name, g);
+ g.setColor(Color.WHITE);
+ g.drawString(name,
+ (int) ((getWidth() - bounds.getWidth()) / 2),
+ (int) ((getHeight() + bounds.getHeight()) / 2));
+ return;
+ }
+
+ display();
+ }
+
+ /** Overridden to track when this component is added to a container.
+ Subclasses which override this method must call
+ super.addNotify() in their addNotify() method in order to
+ function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>addNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ public void addNotify() {
+ super.addNotify();
+ if (!Beans.isDesignTime()) {
+ disableBackgroundErase();
+ drawable.setRealized(true);
+ }
+ }
+
+ /** Overridden to track when this component is removed from a
+ container. Subclasses which override this method must call
+ super.removeNotify() in their removeNotify() method in order to
+ function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ public void removeNotify() {
+ if(DEBUG) {
+ Exception ex1 = new Exception("removeNotify - start");
+ ex1.printStackTrace();
+ }
+ drawableHelper.invokeGL(drawable, context, disposeAction, null);
+
+ if (Beans.isDesignTime()) {
+ super.removeNotify();
+ } else {
+ try {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ // Workaround for termination issues with applets --
+ // sun.applet.AppletPanel should probably be performing the
+ // remove() call on the EDT rather than on its own thread
+ if (Threading.isAWTMode() &&
+ Thread.holdsLock(getTreeLock())) {
+ // The user really should not be invoking remove() from this
+ // thread -- but since he/she is, we can not go over to the
+ // EDT at this point. Try to destroy the context from here.
+ destroyAction.run();
+ } else {
+ Threading.invokeOnOpenGLThread(destroyAction);
+ }
+ } else {
+ destroyAction.run();
+ }
+ } finally {
+ if(null!=drawable) {
+ drawable.setRealized(false);
+ }
+ drawable=null;
+ super.removeNotify();
+ }
+ }
+ if(DEBUG) {
+ System.out.println("removeNotify - end");
+ }
+ }
+
+ /** Overridden to cause {@link GLDrawableHelper#reshape} to be
+ called on all registered {@link GLEventListener}s. Subclasses
+ which override this method must call super.reshape() in
+ their reshape() method in order to function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>reshape</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ public void reshape(int x, int y, int width, int height) {
+ super.reshape(x, y, width, height);
+ sendReshape = true;
+ }
+
+ /** <B>Overrides:</B>
+ <DL><DD><CODE>update</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ // Overridden from Canvas to prevent the AWT's clearing of the
+ // canvas from interfering with the OpenGL rendering.
+ public void update(Graphics g) {
+ paint(g);
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ drawableHelper.addGLEventListener(listener);
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ drawableHelper.removeGLEventListener(listener);
+ }
+
+ public void setContext(GLContext ctx) {
+ context=(GLContextImpl)ctx;
+ }
+
+ public GLContext getContext() {
+ return context;
+ }
+
+ public GL getGL() {
+ if (Beans.isDesignTime()) {
+ return null;
+ }
+
+ return getContext().getGL();
+ }
+
+ public void setGL(GL gl) {
+ if (!Beans.isDesignTime()) {
+ getContext().setGL(gl);
+ }
+ }
+
+ public void setAutoSwapBufferMode(boolean onOrOff) {
+ drawableHelper.setAutoSwapBufferMode(onOrOff);
+ }
+
+ public boolean getAutoSwapBufferMode() {
+ return drawableHelper.getAutoSwapBufferMode();
+ }
+
+ public void swapBuffers() {
+ maybeDoSingleThreadedWorkaround(swapBuffersOnEventDispatchThreadAction, swapBuffersAction);
+ }
+
+ public NWCapabilities getChosenNWCapabilities() {
+ if (drawable == null)
+ return null;
+
+ return drawable.getChosenNWCapabilities();
+ }
+
+ public NativeWindow getNativeWindow() {
+ return drawable.getNativeWindow();
+ }
+
+ public GLDrawableFactory getFactory() {
+ return drawable.getFactory();
+ }
+
+ public String toString() {
+ return "AWT-GLCanvas[ "+((null!=drawable)?drawable.getClass().getName():"null-drawable")+", "+drawableHelper+"]";
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ class DisposeAction implements Runnable {
+ public void run() {
+ drawableHelper.dispose(GLCanvas.this);
+ }
+ }
+ private DisposeAction disposeAction = new DisposeAction();
+
+ private void maybeDoSingleThreadedWorkaround(Runnable eventDispatchThreadAction,
+ Runnable invokeGLAction) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ Threading.invokeOnOpenGLThread(eventDispatchThreadAction);
+ } else {
+ drawableHelper.invokeGL(drawable, context, invokeGLAction, initAction);
+ }
+ }
+
+ class InitAction implements Runnable {
+ public void run() {
+ drawableHelper.init(GLCanvas.this);
+ }
+ }
+ private InitAction initAction = new InitAction();
+
+ class DisplayAction implements Runnable {
+ public void run() {
+ if (sendReshape) {
+ // Note: we ignore the given x and y within the parent component
+ // since we are drawing directly into this heavyweight component.
+ int width = getWidth();
+ int height = getHeight();
+ getGL().glViewport(0, 0, width, height);
+ drawableHelper.reshape(GLCanvas.this, 0, 0, width, height);
+ sendReshape = false;
+ }
+
+ drawableHelper.display(GLCanvas.this);
+ }
+ }
+ private DisplayAction displayAction = new DisplayAction();
+
+ class SwapBuffersAction implements Runnable {
+ public void run() {
+ drawable.swapBuffers();
+ }
+ }
+ private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
+
+ // Workaround for ATI driver bugs related to multithreading issues
+ // like simultaneous rendering via Animators to canvases that are
+ // being resized on the AWT event dispatch thread
+ class DisplayOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ drawableHelper.invokeGL(drawable, context, displayAction, initAction);
+ }
+ }
+ private DisplayOnEventDispatchThreadAction displayOnEventDispatchThreadAction =
+ new DisplayOnEventDispatchThreadAction();
+ class SwapBuffersOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ drawableHelper.invokeGL(drawable, context, swapBuffersAction, initAction);
+ }
+ }
+ private SwapBuffersOnEventDispatchThreadAction swapBuffersOnEventDispatchThreadAction =
+ new SwapBuffersOnEventDispatchThreadAction();
+
+ class DestroyAction implements Runnable {
+ public void run() {
+ if(DEBUG) {
+ Exception ex1 = new Exception("DestroyAction - start");
+ ex1.printStackTrace();
+ }
+ GLContext current = GLContext.getCurrent();
+ if(null!=current) {
+ context.destroy();
+ context = null;
+ }
+ if(DEBUG) {
+ System.out.println("DestroyAction - end");
+ }
+ }
+ }
+ private DestroyAction destroyAction = new DestroyAction();
+
+ // Disables the AWT's erasing of this Canvas's background on Windows
+ // in Java SE 6. This internal API is not available in previous
+ // releases, but the system property
+ // -Dsun.awt.noerasebackground=true can be specified to get similar
+ // results globally in previous releases.
+ private static boolean disableBackgroundEraseInitialized;
+ private static Method disableBackgroundEraseMethod;
+ private void disableBackgroundErase() {
+ if (!disableBackgroundEraseInitialized) {
+ try {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ disableBackgroundEraseMethod =
+ getToolkit().getClass().getDeclaredMethod("disableBackgroundErase",
+ new Class[] { Canvas.class });
+ disableBackgroundEraseMethod.setAccessible(true);
+ } catch (Exception e) {
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ }
+ disableBackgroundEraseInitialized = true;
+ }
+ if (disableBackgroundEraseMethod != null) {
+ try {
+ disableBackgroundEraseMethod.invoke(getToolkit(), new Object[] { this });
+ } catch (Exception e) {
+ // FIXME: workaround for 6504460 (incorrect backport of 6333613 in 5.0u10)
+ // throw new GLException(e);
+ }
+ }
+ }
+
+ private static GraphicsConfiguration chooseGraphicsConfiguration(NWCapabilities capabilities,
+ NWCapabilitiesChooser chooser,
+ GraphicsDevice device) {
+ // Make GLCanvas behave better in NetBeans GUI builder
+ if (Beans.isDesignTime()) {
+ return null;
+ }
+
+ AWTGraphicsConfiguration config = (AWTGraphicsConfiguration)
+ NativeWindowFactory.getFactory(Component.class).chooseGraphicsConfiguration(capabilities,
+ chooser,
+ new AWTGraphicsDevice(device));
+ if (config == null) {
+ return null;
+ }
+
+ return config.getGraphicsConfiguration();
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
new file mode 100644
index 000000000..2efae7e96
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -0,0 +1,1487 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl.awt;
+
+import javax.media.opengl.*;
+import javax.media.nwi.*;
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.image.*;
+import java.beans.*;
+import javax.swing.*;
+import java.nio.*;
+import java.security.*;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import com.sun.opengl.impl.*;
+import com.sun.opengl.impl.awt.*;
+
+// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
+// context whenever the displayChanged() function is called on their
+// GLEventListeners
+
+/** A lightweight Swing component which provides OpenGL rendering
+ support. Provided for compatibility with Swing user interfaces
+ when adding a heavyweight doesn't work either because of
+ Z-ordering or LayoutManager problems. <P>
+
+ The GLJPanel can be made transparent by creating it with a
+ NWCapabilities object with alpha bits specified and calling {@link
+ #setOpaque}(false). Pixels with resulting OpenGL alpha values less
+ than 1.0 will be overlaid on any underlying Swing rendering. <P>
+
+ Notes specific to the Reference Implementation: This component
+ attempts to use hardware-accelerated rendering via pbuffers and
+ falls back on to software rendering if problems occur.
+ Note that because this component attempts to use pbuffers for
+ rendering, and because pbuffers can not be resized, somewhat
+ surprising behavior may occur during resize operations; the {@link
+ GLEventListener#init} method may be called multiple times as the
+ pbuffer is resized to be able to cover the size of the GLJPanel.
+ This behavior is correct, as the textures and display lists for
+ the GLJPanel will have been lost during the resize operation. The
+ application should attempt to make its GLEventListener.init()
+ methods as side-effect-free as possible. <P>
+
+*/
+
+public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
+ private static final boolean DEBUG = Debug.debug("GLJPanel");
+ private static final boolean VERBOSE = Debug.verbose();
+
+ private GLDrawableHelper drawableHelper = new GLDrawableHelper();
+ private volatile boolean isInitialized;
+
+ // Data used for either pbuffers or pixmap-based offscreen surfaces
+ private NWCapabilities offscreenCaps;
+ private NWCapabilitiesChooser chooser;
+ private GLContext shareWith;
+ // Width of the actual GLJPanel
+ private int panelWidth = 0;
+ private int panelHeight = 0;
+ // Lazy reshape notification
+ private boolean handleReshape = false;
+ private boolean sendReshape = true;
+
+ private static GLDrawableFactoryImpl factory;
+
+ // The backend in use
+ private Backend backend;
+
+ // Used by all backends either directly or indirectly to hook up callbacks
+ private Updater updater = new Updater();
+
+ // Turns off the pbuffer-based backend (used by default, unless the
+ // Java 2D / OpenGL pipeline is in use)
+ private static boolean hardwareAccelerationDisabled =
+ Debug.isPropertyDefined("jogl.gljpanel.nohw");
+
+ // Turns off the fallback to software-based rendering from
+ // pbuffer-based rendering
+ private static boolean softwareRenderingDisabled =
+ Debug.isPropertyDefined("jogl.gljpanel.nosw");
+
+ // Indicates whether the Java 2D OpenGL pipeline is enabled
+ private boolean oglPipelineEnabled =
+ Java2D.isOGLPipelineActive() &&
+ !Debug.isPropertyDefined("jogl.gljpanel.noogl");
+
+ // For handling reshape events lazily
+ private int reshapeX;
+ private int reshapeY;
+ private int reshapeWidth;
+ private int reshapeHeight;
+
+ // These are always set to (0, 0) except when the Java2D / OpenGL
+ // pipeline is active
+ private int viewportX;
+ private int viewportY;
+
+ static {
+ // Force eager initialization of part of the Java2D class since
+ // otherwise it's likely it will try to be initialized while on
+ // the Queue Flusher Thread, which is not allowed
+ if (Java2D.isOGLPipelineActive() && Java2D.isFBOEnabled()) {
+ Java2D.getShareContext(GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().
+ getDefaultConfiguration());
+ }
+ GLProfile.setProfile(GLProfile.GL2);
+ factory = GLDrawableFactoryImpl.getFactoryImpl();
+ }
+
+ /** Creates a new GLJPanel component with a default set of OpenGL
+ capabilities and using the default OpenGL capabilities selection
+ mechanism. */
+ public GLJPanel() {
+ this(null);
+ }
+
+ /** Creates a new GLJPanel component with the requested set of
+ OpenGL capabilities, using the default OpenGL capabilities
+ selection mechanism. */
+ public GLJPanel(NWCapabilities capabilities) {
+ this(capabilities, null, null);
+ }
+
+ /** Creates a new GLJPanel component. The passed NWCapabilities
+ specifies the OpenGL capabilities for the component; if null, a
+ default set of capabilities is used. The NWCapabilitiesChooser
+ specifies the algorithm for selecting one of the available
+ NWCapabilities for the component; a DefaultGLCapabilitesChooser
+ is used if null is passed for this argument. The passed
+ GLContext specifies an OpenGL context with which to share
+ textures, display lists and other OpenGL state, and may be null
+ if sharing is not desired. See the note in the overview documentation on
+ <a href="../../../overview-summary.html#SHARING">context sharing</a>.
+ */
+ public GLJPanel(NWCapabilities capabilities, NWCapabilitiesChooser chooser, GLContext shareWith) {
+ super();
+
+ // Works around problems on many vendors' cards; we don't need a
+ // back buffer for the offscreen surface anyway
+ if (capabilities != null) {
+ offscreenCaps = (NWCapabilities) capabilities.clone();
+ } else {
+ offscreenCaps = new NWCapabilities();
+ }
+ offscreenCaps.setDoubleBuffered(false);
+ this.chooser = ((chooser != null) ? chooser : new DefaultNWCapabilitiesChooser());
+ this.shareWith = shareWith;
+ }
+
+ public void display() {
+ if (EventQueue.isDispatchThread()) {
+ // Want display() to be synchronous, so call paintImmediately()
+ paintImmediately(0, 0, getWidth(), getHeight());
+ } else {
+ // Multithreaded redrawing of Swing components is not allowed,
+ // so do everything on the event dispatch thread
+ try {
+ EventQueue.invokeAndWait(paintImmediatelyAction);
+ } catch (Exception e) {
+ throw new GLException(e);
+ }
+ }
+ }
+
+ /**
+ * Just an alias for removeNotify
+ */
+ public void destroy() {
+ removeNotify();
+ }
+
+ /** Overridden to cause OpenGL rendering to be performed during
+ repaint cycles. Subclasses which override this method must call
+ super.paintComponent() in their paintComponent() method in order
+ to function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>paintComponent</CODE> in class <CODE>javax.swing.JComponent</CODE></DD></DL> */
+ protected void paintComponent(final Graphics g) {
+ if (Beans.isDesignTime()) {
+ // Make GLJPanel behave better in NetBeans GUI builder
+ g.setColor(Color.BLACK);
+ g.fillRect(0, 0, getWidth(), getHeight());
+ FontMetrics fm = g.getFontMetrics();
+ String name = getName();
+ if (name == null) {
+ name = getClass().getName();
+ int idx = name.lastIndexOf('.');
+ if (idx >= 0) {
+ name = name.substring(idx + 1);
+ }
+ }
+ Rectangle2D bounds = fm.getStringBounds(name, g);
+ g.setColor(Color.WHITE);
+ g.drawString(name,
+ (int) ((getWidth() - bounds.getWidth()) / 2),
+ (int) ((getHeight() + bounds.getHeight()) / 2));
+ return;
+ }
+
+ if (backend == null || !isInitialized) {
+ createAndInitializeBackend();
+ }
+
+ if (!isInitialized) {
+ return;
+ }
+
+ // NOTE: must do this when the context is not current as it may
+ // involve destroying the pbuffer (current context) and
+ // re-creating it -- tricky to do properly while the context is
+ // current
+ if (handleReshape) {
+ handleReshape();
+ }
+
+ updater.setGraphics(g);
+ backend.doPaintComponent(g);
+ }
+
+ /** Overridden to track when this component is added to a container.
+ Subclasses which override this method must call
+ super.addNotify() in their addNotify() method in order to
+ function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>addNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ public void addNotify() {
+ super.addNotify();
+ if (DEBUG) {
+ System.err.println("GLJPanel.addNotify()");
+ }
+ }
+
+ /** Overridden to track when this component is removed from a
+ container. Subclasses which override this method must call
+ super.removeNotify() in their removeNotify() method in order to
+ function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ public void removeNotify() {
+ if(DEBUG) {
+ Exception ex1 = new Exception("removeNotify - start");
+ ex1.printStackTrace();
+ }
+ if (backend != null) {
+ drawableHelper.invokeGL(backend.getDrawable(), backend.getContext(), disposeAction, null);
+ backend.destroy();
+ backend = null;
+ }
+ isInitialized = false;
+ super.removeNotify();
+ if(DEBUG) {
+ System.out.println("removeNotify - end");
+ }
+ }
+
+ /** Overridden to cause {@link GLDrawableHelper#reshape} to be
+ called on all registered {@link GLEventListener}s. Subclasses
+ which override this method must call super.reshape() in
+ their reshape() method in order to function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>reshape</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ public void reshape(int x, int y, int width, int height) {
+ super.reshape(x, y, width, height);
+
+ reshapeX = x;
+ reshapeY = y;
+ reshapeWidth = width;
+ reshapeHeight = height;
+ handleReshape = true;
+ }
+
+ public void setOpaque(boolean opaque) {
+ if (backend != null) {
+ backend.setOpaque(opaque);
+ }
+ super.setOpaque(opaque);
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ drawableHelper.addGLEventListener(listener);
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ drawableHelper.removeGLEventListener(listener);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return backend.createContext(shareWith);
+ }
+
+ public void setRealized(boolean realized) {
+ }
+
+ public void setContext(GLContext ctx) {
+ if (backend == null) {
+ return;
+ }
+ backend.setContext(ctx);
+ }
+
+ public GLContext getContext() {
+ if (backend == null) {
+ return null;
+ }
+ return backend.getContext();
+ }
+
+ public GL getGL() {
+ GLContext context = getContext();
+ return (context == null) ? null : context.getGL();
+ }
+
+ public void setGL(GL gl) {
+ GLContext context = getContext();
+ if (context != null) {
+ context.setGL(gl);
+ }
+ }
+
+ public void setAutoSwapBufferMode(boolean onOrOff) {
+ // In the current implementation this is a no-op. Both the pbuffer
+ // and pixmap based rendering paths use a single-buffered surface
+ // so swapping the buffers doesn't do anything. We also don't
+ // currently have the provision to skip copying the data to the
+ // Swing portion of the GLJPanel in any of the rendering paths.
+ }
+
+ public boolean getAutoSwapBufferMode() {
+ // In the current implementation this is a no-op. Both the pbuffer
+ // and pixmap based rendering paths use a single-buffered surface
+ // so swapping the buffers doesn't do anything. We also don't
+ // currently have the provision to skip copying the data to the
+ // Swing portion of the GLJPanel in any of the rendering paths.
+ return true;
+ }
+
+ public void swapBuffers() {
+ // In the current implementation this is a no-op. Both the pbuffer
+ // and pixmap based rendering paths use a single-buffered surface
+ // so swapping the buffers doesn't do anything. We also don't
+ // currently have the provision to skip copying the data to the
+ // Swing portion of the GLJPanel in any of the rendering paths.
+ }
+
+ /** For a translucent GLJPanel (one for which {@link #setOpaque
+ setOpaque}(false) has been called), indicates whether the
+ application should preserve the OpenGL color buffer
+ (GL_COLOR_BUFFER_BIT) for correct rendering of the GLJPanel and
+ underlying widgets which may show through portions of the
+ GLJPanel with alpha values less than 1. Most Swing
+ implementations currently expect the GLJPanel to be completely
+ cleared (e.g., by <code>glClear(GL_COLOR_BUFFER_BIT |
+ GL_DEPTH_BUFFER_BIT)</code>), but for certain optimized Swing
+ implementations which use OpenGL internally, it may be possible
+ to perform OpenGL rendering using the GLJPanel into the same
+ OpenGL drawable as the Swing implementation uses. */
+ public boolean shouldPreserveColorBufferIfTranslucent() {
+ return oglPipelineEnabled;
+ }
+
+ public NWCapabilities getChosenNWCapabilities() {
+ return backend.getChosenNWCapabilities();
+ }
+
+ public NativeWindow getNativeWindow() {
+ throw new GLException("FIXME");
+ }
+
+ public GLDrawableFactory getFactory() {
+ return factory;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private void createAndInitializeBackend() {
+ if (panelWidth == 0 ||
+ panelHeight == 0) {
+ // See whether we have a non-zero size yet and can go ahead with
+ // initialization
+ if (reshapeWidth == 0 ||
+ reshapeHeight == 0) {
+ return;
+ }
+
+ // Pull down reshapeWidth and reshapeHeight into panelWidth and
+ // panelHeight eagerly in order to complete initialization, and
+ // force a reshape later
+ panelWidth = reshapeWidth;
+ panelHeight = reshapeHeight;
+ }
+
+ do {
+ if (backend == null) {
+ if (oglPipelineEnabled) {
+ backend = new J2DOGLBackend();
+ } else {
+ if (!hardwareAccelerationDisabled &&
+ factory.canCreateGLPbuffer()) {
+ backend = new PbufferBackend();
+ } else {
+ if (softwareRenderingDisabled) {
+ throw new GLException("Fallback to software rendering disabled by user");
+ }
+ backend = new SoftwareBackend();
+ }
+ }
+ }
+
+ if (!isInitialized) {
+ backend.initialize();
+ }
+ // The backend might set itself to null, indicating it punted to
+ // a different implementation -- try again
+ } while (backend == null);
+
+ if(null==closingListener) {
+ synchronized(closingListenerLock) {
+ if(null==closingListener) {
+ closingListener=GLCanvas.addClosingListener(this, new GLCanvas.DestroyMethod() {
+ public void destroyMethod() { destroy(); } });
+ }
+ }
+ }
+ }
+ private Object closingListener = null;
+ private Object closingListenerLock = new Object();
+
+ private void handleReshape() {
+ panelWidth = reshapeWidth;
+ panelHeight = reshapeHeight;
+
+ if (DEBUG) {
+ System.err.println("GLJPanel.handleReshape: (w,h) = (" +
+ panelWidth + "," + panelHeight + ")");
+ }
+
+ sendReshape = true;
+ backend.handleReshape();
+ handleReshape = false;
+ }
+
+ // This is used as the GLEventListener for the pbuffer-based backend
+ // as well as the callback mechanism for the other backends
+ class Updater implements GLEventListener {
+ private Graphics g;
+
+ public void setGraphics(Graphics g) {
+ this.g = g;
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ if (!backend.preGL(g)) {
+ return;
+ }
+ drawableHelper.init(GLJPanel.this);
+ backend.postGL(g, false);
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ drawableHelper.dispose(GLJPanel.this);
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ if (!backend.preGL(g)) {
+ return;
+ }
+ if (sendReshape) {
+ if (DEBUG) {
+ System.err.println("glViewport(" + viewportX + ", " + viewportY + ", " + panelWidth + ", " + panelHeight + ")");
+ }
+ getGL().getGL2().glViewport(viewportX, viewportY, panelWidth, panelHeight);
+ drawableHelper.reshape(GLJPanel.this, viewportX, viewportY, panelWidth, panelHeight);
+ sendReshape = false;
+ }
+
+ drawableHelper.display(GLJPanel.this);
+ backend.postGL(g, true);
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ // This is handled above and dispatched directly to the appropriate context
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
+ }
+ }
+
+ public String toString() {
+ return "AWT-GLJPanel[ "+((null!=backend)?backend.getDrawable().getClass().getName():"null-drawable")+", "+drawableHelper+"]";
+ }
+
+ class DisposeAction implements Runnable {
+ public void run() {
+ updater.dispose(GLJPanel.this);
+ }
+ }
+ private DisposeAction disposeAction = new DisposeAction();
+
+ class InitAction implements Runnable {
+ public void run() {
+ updater.init(GLJPanel.this);
+ }
+ }
+ private InitAction initAction = new InitAction();
+
+ class DisplayAction implements Runnable {
+ public void run() {
+ updater.display(GLJPanel.this);
+ }
+ }
+ private DisplayAction displayAction = new DisplayAction();
+
+ class PaintImmediatelyAction implements Runnable {
+ public void run() {
+ paintImmediately(0, 0, getWidth(), getHeight());
+ }
+ }
+ private PaintImmediatelyAction paintImmediatelyAction = new PaintImmediatelyAction();
+
+ private int getNextPowerOf2(int number) {
+ // Workaround for problems where 0 width or height are transiently
+ // seen during layout
+ if (number == 0) {
+ return 2;
+ }
+
+ if (((number-1) & number) == 0) {
+ //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
+ return number;
+ }
+ int power = 0;
+ while (number > 0) {
+ number = number>>1;
+ power++;
+ }
+ return (1<<power);
+ }
+
+ private int getGLInteger(GL gl, int which) {
+ int[] tmp = new int[1];
+ gl.glGetIntegerv(which, tmp, 0);
+ return tmp[0];
+ }
+
+ //----------------------------------------------------------------------
+ // Implementations of the various backends
+ //
+
+ // Abstraction of the different rendering backends: i.e., pure
+ // software / pixmap rendering, pbuffer-based acceleration, Java 2D
+ // / JOGL bridge
+ static interface Backend {
+ // Called each time the backend needs to initialize itself
+ public void initialize();
+
+ // Called when the backend should clean up its resources
+ public void destroy();
+
+ // Called when the opacity of the GLJPanel is changed
+ public void setOpaque(boolean opaque);
+
+ // Called to manually create an additional OpenGL context against
+ // this GLJPanel
+ public GLContext createContext(GLContext shareWith);
+
+ // Called to set the current backend's GLContext
+ public void setContext(GLContext ctx);
+
+ // Called to get the current backend's GLContext
+ public GLContext getContext();
+
+ // Called to get the current backend's GLDrawable
+ public GLDrawable getDrawable();
+
+ // Called to fetch the "real" chosen NWCapabilities for the backend
+ public NWCapabilities getChosenNWCapabilities();
+
+ // Called to handle a reshape event. When this is called, the
+ // OpenGL context associated with the backend is not current, to
+ // make it easier to destroy and re-create pbuffers if necessary.
+ public void handleReshape();
+
+ // Called before the OpenGL work is done in init() and display().
+ // If false is returned, this render is aborted.
+ public boolean preGL(Graphics g);
+
+ // Called after the OpenGL work is done in init() and display().
+ // The isDisplay argument indicates whether this was called on
+ // behalf of a call to display() rather than init().
+ public void postGL(Graphics g, boolean isDisplay);
+
+ // Called from within paintComponent() to initiate the render
+ public void doPaintComponent(Graphics g);
+ }
+
+ // Base class used by both the software (pixmap) and pbuffer
+ // backends, both of which rely on reading back the OpenGL frame
+ // buffer and drawing it with a BufferedImage
+ abstract class AbstractReadbackBackend implements Backend {
+ // This image is exactly the correct size to render into the panel
+ protected BufferedImage offscreenImage;
+ // One of these is used to store the read back pixels before storing
+ // in the BufferedImage
+ protected ByteBuffer readBackBytes;
+ protected IntBuffer readBackInts;
+ protected int readBackWidthInPixels;
+ protected int readBackHeightInPixels;
+
+ private int awtFormat;
+ private int glFormat;
+ private int glType;
+
+ // For saving/restoring of OpenGL state during ReadPixels
+ private int[] swapbytes = new int[1];
+ private int[] rowlength = new int[1];
+ private int[] skiprows = new int[1];
+ private int[] skippixels = new int[1];
+ private int[] alignment = new int[1];
+
+ public void setOpaque(boolean opaque) {
+ if (opaque != isOpaque()) {
+ if (offscreenImage != null) {
+ offscreenImage.flush();
+ offscreenImage = null;
+ }
+ }
+ }
+
+ public boolean preGL(Graphics g) {
+ // Empty in this implementation
+ return true;
+ }
+
+ public void postGL(Graphics g, boolean isDisplay) {
+ if (isDisplay) {
+ // Must now copy pixels from offscreen context into surface
+ if (offscreenImage == null) {
+ if (panelWidth > 0 && panelHeight > 0) {
+ // It looks like NVidia's drivers (at least the ones on my
+ // notebook) are buggy and don't allow a sub-rectangle to be
+ // read from a pbuffer...this doesn't really matter because
+ // it's the Graphics.drawImage() calls that are the
+ // bottleneck
+
+ int awtFormat = 0;
+
+ // Should be more flexible in these BufferedImage formats;
+ // perhaps see what the preferred image types are on the
+ // given platform
+ if (isOpaque()) {
+ awtFormat = BufferedImage.TYPE_INT_RGB;
+ } else {
+ awtFormat = BufferedImage.TYPE_INT_ARGB;
+ }
+
+ offscreenImage = new BufferedImage(panelWidth,
+ panelHeight,
+ awtFormat);
+ switch (awtFormat) {
+ case BufferedImage.TYPE_3BYTE_BGR:
+ glFormat = GL2.GL_BGR;
+ glType = GL2.GL_UNSIGNED_BYTE;
+ readBackBytes = ByteBuffer.allocate(readBackWidthInPixels * readBackHeightInPixels * 3);
+ break;
+
+ case BufferedImage.TYPE_INT_RGB:
+ case BufferedImage.TYPE_INT_ARGB:
+ glFormat = GL2.GL_BGRA;
+ glType = getGLPixelType();
+ readBackInts = IntBuffer.allocate(readBackWidthInPixels * readBackHeightInPixels);
+ break;
+
+ default:
+ // FIXME: Support more off-screen image types (current
+ // offscreen context implementations don't use others, and
+ // some of the OpenGL formats aren't supported in the 1.1
+ // headers, which we're currently using)
+ throw new GLException("Unsupported offscreen image type " + awtFormat);
+ }
+ }
+ }
+
+ if (offscreenImage != null) {
+ GL2 gl = getGL().getGL2();
+ // Save current modes
+ gl.glGetIntegerv(GL2.GL_PACK_SWAP_BYTES, swapbytes, 0);
+ gl.glGetIntegerv(GL2.GL_PACK_ROW_LENGTH, rowlength, 0);
+ gl.glGetIntegerv(GL2.GL_PACK_SKIP_ROWS, skiprows, 0);
+ gl.glGetIntegerv(GL2.GL_PACK_SKIP_PIXELS, skippixels, 0);
+ gl.glGetIntegerv(GL2.GL_PACK_ALIGNMENT, alignment, 0);
+
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, GL.GL_FALSE);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, readBackWidthInPixels);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_ALIGNMENT, 1);
+
+ // Actually read the pixels.
+ gl.glReadBuffer(GL2.GL_FRONT);
+ if (readBackBytes != null) {
+ gl.glReadPixels(0, 0, readBackWidthInPixels, readBackHeightInPixels, glFormat, glType, readBackBytes);
+ } else if (readBackInts != null) {
+ gl.glReadPixels(0, 0, readBackWidthInPixels, readBackHeightInPixels, glFormat, glType, readBackInts);
+ }
+
+ // Restore saved modes.
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, swapbytes[0]);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, rowlength[0]);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, skiprows[0]);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, skippixels[0]);
+ gl.glPixelStorei(GL2.GL_PACK_ALIGNMENT, alignment[0]);
+
+ if (readBackBytes != null || readBackInts != null) {
+ // Copy temporary data into raster of BufferedImage for faster
+ // blitting Note that we could avoid this copy in the cases
+ // where !offscreenContext.offscreenImageNeedsVerticalFlip(),
+ // but that's the software rendering path which is very slow
+ // anyway
+ Object src = null;
+ Object dest = null;
+ int srcIncr = 0;
+ int destIncr = 0;
+
+ if (readBackBytes != null) {
+ src = readBackBytes.array();
+ dest = ((DataBufferByte) offscreenImage.getRaster().getDataBuffer()).getData();
+ srcIncr = readBackWidthInPixels * 3;
+ destIncr = offscreenImage.getWidth() * 3;
+ } else {
+ src = readBackInts.array();
+ dest = ((DataBufferInt) offscreenImage.getRaster().getDataBuffer()).getData();
+ srcIncr = readBackWidthInPixels;
+ destIncr = offscreenImage.getWidth();
+ }
+
+ if (flipVertically()) {
+ int srcPos = 0;
+ int destPos = (offscreenImage.getHeight() - 1) * destIncr;
+ for (; destPos >= 0; srcPos += srcIncr, destPos -= destIncr) {
+ System.arraycopy(src, srcPos, dest, destPos, destIncr);
+ }
+ } else {
+ int srcPos = 0;
+ int destEnd = destIncr * offscreenImage.getHeight();
+ for (int destPos = 0; destPos < destEnd; srcPos += srcIncr, destPos += destIncr) {
+ System.arraycopy(src, srcPos, dest, destPos, destIncr);
+ }
+ }
+
+ // Note: image will be drawn back in paintComponent() for
+ // correctness on all platforms
+ }
+ }
+ }
+ }
+
+ public void doPaintComponent(Graphics g) {
+ doPaintComponentImpl();
+ if (offscreenImage != null) {
+ // Draw resulting image in one shot
+ g.drawImage(offscreenImage, 0, 0,
+ offscreenImage.getWidth(),
+ offscreenImage.getHeight(),
+ GLJPanel.this);
+ }
+ }
+
+ protected abstract void doPaintComponentImpl();
+ protected abstract int getGLPixelType();
+ protected abstract boolean flipVertically();
+ }
+
+ class SoftwareBackend extends AbstractReadbackBackend {
+ // Implementation using software rendering
+ private GLDrawableImpl offscreenDrawable;
+ private GLContextImpl offscreenContext;
+
+ public void initialize() {
+ // Fall-through path: create an offscreen context instead
+ offscreenDrawable = factory.createOffscreenDrawable(offscreenCaps,
+ chooser,
+ Math.max(1, panelWidth),
+ Math.max(1, panelHeight));
+ offscreenContext = (GLContextImpl) offscreenDrawable.createContext(shareWith);
+ offscreenContext.setSynchronized(true);
+ isInitialized = true;
+ }
+
+ public void destroy() {
+ if (offscreenContext != null) {
+ offscreenContext.destroy();
+ offscreenContext = null;
+ }
+ if (offscreenDrawable != null) {
+ offscreenDrawable.destroy();
+ offscreenDrawable = null;
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return offscreenDrawable.createContext(shareWith);
+ }
+
+ public void setContext(GLContext ctx) {
+ offscreenContext=(GLContextImpl)ctx;
+ }
+
+ public GLContext getContext() {
+ return offscreenContext;
+ }
+
+ public GLDrawable getDrawable() {
+ return offscreenDrawable;
+ }
+
+ public NWCapabilities getChosenNWCapabilities() {
+ if (offscreenDrawable == null) {
+ return null;
+ }
+ return offscreenDrawable.getChosenNWCapabilities();
+ }
+
+ public void handleReshape() {
+ destroy();
+ initialize();
+ readBackWidthInPixels = Math.max(1, panelWidth);
+ readBackHeightInPixels = Math.max(1, panelHeight);
+
+ if (offscreenImage != null) {
+ offscreenImage.flush();
+ offscreenImage = null;
+ }
+ }
+
+ protected void doPaintComponentImpl() {
+ drawableHelper.invokeGL(offscreenDrawable, offscreenContext, displayAction, initAction);
+ }
+
+ protected int getGLPixelType() {
+ return offscreenContext.getOffscreenContextPixelDataType();
+ }
+
+ protected boolean flipVertically() {
+ return offscreenContext.offscreenImageNeedsVerticalFlip();
+ }
+ }
+
+ class PbufferBackend extends AbstractReadbackBackend {
+ private GLPbuffer pbuffer;
+ private int pbufferWidth = 256;
+ private int pbufferHeight = 256;
+
+ public void initialize() {
+ if (pbuffer != null) {
+ throw new InternalError("Creating pbuffer twice without destroying it (memory leak / correctness bug)");
+ }
+ try {
+ pbuffer = factory.createGLPbuffer(offscreenCaps,
+ null,
+ pbufferWidth,
+ pbufferHeight,
+ shareWith);
+ pbuffer.addGLEventListener(updater);
+ isInitialized = true;
+ } catch (GLException e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ System.err.println("GLJPanel: Falling back on software rendering because of problems creating pbuffer");
+ }
+ hardwareAccelerationDisabled = true;
+ backend = null;
+ isInitialized = false;
+ createAndInitializeBackend();
+ }
+ }
+
+ public void destroy() {
+ if (pbuffer != null) {
+ pbuffer.destroy();
+ pbuffer = null;
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return pbuffer.createContext(shareWith);
+ }
+
+ public void setContext(GLContext ctx) {
+ if (pbuffer == null && Beans.isDesignTime()) {
+ return;
+ }
+ pbuffer.setContext(ctx);
+ }
+
+ public GLContext getContext() {
+ // Workaround for crashes in NetBeans GUI builder
+ if (pbuffer == null && Beans.isDesignTime()) {
+ return null;
+ }
+ return pbuffer.getContext();
+ }
+
+ public GLDrawable getDrawable() {
+ return pbuffer;
+ }
+
+ public NWCapabilities getChosenNWCapabilities() {
+ if (pbuffer == null) {
+ return null;
+ }
+ return pbuffer.getChosenNWCapabilities();
+ }
+
+ public void handleReshape() {
+ // Use factor larger than 2 during shrinks for some hysteresis
+ float shrinkFactor = 2.5f;
+ if ((panelWidth > pbufferWidth) || (panelHeight > pbufferHeight) ||
+ (panelWidth < (pbufferWidth / shrinkFactor)) || (panelHeight < (pbufferHeight / shrinkFactor))) {
+ if (DEBUG) {
+ System.err.println("Resizing pbuffer from (" + pbufferWidth + ", " + pbufferHeight + ") " +
+ " to fit (" + panelWidth + ", " + panelHeight + ")");
+ }
+ // Must destroy and recreate pbuffer to fit
+ if (pbuffer != null) {
+ // Watch for errors during pbuffer destruction (due to
+ // buggy / bad OpenGL drivers, in particular SiS) and fall
+ // back to software rendering
+ try {
+ pbuffer.destroy();
+ } catch (GLException e) {
+ hardwareAccelerationDisabled = true;
+ backend = null;
+ isInitialized = false;
+ // Just disabled hardware acceleration during this resize operation; do a fixup
+ readBackWidthInPixels = Math.max(1, panelWidth);
+ readBackHeightInPixels = Math.max(1, panelHeight);
+ if (DEBUG) {
+ System.err.println("WARNING: falling back to software rendering due to bugs in OpenGL drivers");
+ e.printStackTrace();
+ }
+ createAndInitializeBackend();
+ return;
+ }
+ }
+ pbuffer = null;
+ isInitialized = false;
+ pbufferWidth = getNextPowerOf2(panelWidth);
+ pbufferHeight = getNextPowerOf2(panelHeight);
+ if (DEBUG && !hardwareAccelerationDisabled) {
+ System.err.println("New pbuffer size is (" + pbufferWidth + ", " + pbufferHeight + ")");
+ }
+ initialize();
+ }
+
+ // It looks like NVidia's drivers (at least the ones on my
+ // notebook) are buggy and don't allow a rectangle of less than
+ // the pbuffer's width to be read...this doesn't really matter
+ // because it's the Graphics.drawImage() calls that are the
+ // bottleneck. Should probably make the size of the offscreen
+ // image be the exact size of the pbuffer to save some work on
+ // resize operations...
+ readBackWidthInPixels = pbufferWidth;
+ readBackHeightInPixels = panelHeight;
+
+ if (offscreenImage != null) {
+ offscreenImage.flush();
+ offscreenImage = null;
+ }
+ }
+
+ protected void doPaintComponentImpl() {
+ pbuffer.display();
+ }
+
+ protected int getGLPixelType() {
+ // This seems to be a good choice on all platforms
+ return GL2.GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+
+ protected boolean flipVertically() {
+ return true;
+ }
+ }
+
+ class J2DOGLBackend implements Backend {
+ // Opaque Object identifier representing the Java2D surface we are
+ // drawing to; used to determine when to destroy and recreate JOGL
+ // context
+ private Object j2dSurface;
+ // Graphics object being used during Java2D update action
+ // (absolutely essential to cache this)
+ private Graphics cached2DGraphics;
+ // No-op context representing the Java2D OpenGL context
+ private GLContext j2dContext;
+ // Context associated with no-op drawable representing the JOGL
+ // OpenGL context
+ private GLDrawable joglDrawable;
+ // The real OpenGL context JOGL uses to render
+ private GLContext joglContext;
+ // State captured from Java2D OpenGL context necessary in order to
+ // properly render into Java2D back buffer
+ private int[] drawBuffer = new int[1];
+ private int[] readBuffer = new int[1];
+ // This is required when the FBO option of the Java2D / OpenGL
+ // pipeline is active
+ private int[] frameBuffer = new int[1];
+ // Current (as of this writing) NVidia drivers have a couple of bugs
+ // relating to the sharing of framebuffer and renderbuffer objects
+ // between contexts. It appears we have to (a) reattach the color
+ // attachment and (b) actually create new depth buffer storage and
+ // attach it in order for the FBO to behave properly in our context.
+ private boolean checkedForFBObjectWorkarounds;
+ private boolean fbObjectWorkarounds;
+ private int[] frameBufferDepthBuffer;
+ private int[] frameBufferTexture;
+ private boolean createNewDepthBuffer;
+ // Current (as of this writing) ATI drivers have problems when the
+ // same FBO is bound in two different contexts. Here we check for
+ // this case and explicitly release the FBO from Java2D's context
+ // before switching to ours. Java2D will re-bind the FBO when it
+ // makes its context current the next time. Interestingly, if we run
+ // this code path on NVidia hardware, it breaks the rendering
+ // results -- no output is generated. This doesn't appear to be an
+ // interaction with the abovementioned NVidia-specific workarounds,
+ // as even if we disable that code the FBO is still reported as
+ // incomplete in our context.
+ private boolean checkedGLVendor;
+ private boolean vendorIsATI;
+
+ // Holding on to this GraphicsConfiguration is a workaround for a
+ // problem in the Java 2D / JOGL bridge when FBOs are enabled; see
+ // comment related to Issue 274 below
+ private GraphicsConfiguration workaroundConfig;
+
+ public void initialize() {
+ // No-op in this implementation; everything is done lazily
+ isInitialized = true;
+ }
+
+ public void destroy() {
+ Java2D.invokeWithOGLContextCurrent(null, new Runnable() {
+ public void run() {
+ if (joglContext != null) {
+ joglContext.destroy();
+ joglContext = null;
+ }
+ joglDrawable = null;
+ if (j2dContext != null) {
+ j2dContext.destroy();
+ j2dContext = null;
+ }
+ }
+ });
+ }
+
+ public void setOpaque(boolean opaque) {
+ // Empty in this implementation
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ // FIXME: should implement this, but it was not properly
+ // implemented before the refactoring anyway
+ throw new GLException("Not yet implemented");
+ }
+
+ public void setContext(GLContext ctx) {
+ joglContext=ctx;
+ }
+
+ public GLContext getContext() {
+ return joglContext;
+ }
+
+ public GLDrawable getDrawable() {
+ return joglDrawable;
+ }
+
+ public NWCapabilities getChosenNWCapabilities() {
+ // FIXME: should do better than this; is it possible to using only platform-independent code?
+ return new NWCapabilities();
+ }
+
+ public void handleReshape() {
+ // Empty in this implementation
+ }
+
+ public boolean preGL(Graphics g) {
+ GL2 gl = joglContext.getGL().getGL2();
+ // Set up needed state in JOGL context from Java2D context
+ gl.glEnable(GL2.GL_SCISSOR_TEST);
+ Rectangle r = Java2D.getOGLScissorBox(g);
+
+ if (r == null) {
+ if (DEBUG && VERBOSE) {
+ System.err.println("Java2D.getOGLScissorBox() returned null");
+ }
+ return false;
+ }
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: gl.glScissor(" + r.x + ", " + r.y + ", " + r.width + ", " + r.height + ")");
+ }
+
+ gl.glScissor(r.x, r.y, r.width, r.height);
+ Rectangle oglViewport = Java2D.getOGLViewport(g, panelWidth, panelHeight);
+ // If the viewport X or Y changes, in addition to the panel's
+ // width or height, we need to send a reshape operation to the
+ // client
+ if ((viewportX != oglViewport.x) ||
+ (viewportY != oglViewport.y)) {
+ sendReshape = true;
+ if (DEBUG) {
+ System.err.println("Sending reshape because viewport changed");
+ System.err.println(" viewportX (" + viewportX + ") ?= oglViewport.x (" + oglViewport.x + ")");
+ System.err.println(" viewportY (" + viewportY + ") ?= oglViewport.y (" + oglViewport.y + ")");
+ }
+ }
+ viewportX = oglViewport.x;
+ viewportY = oglViewport.y;
+
+ // If the FBO option is active, bind to the FBO from the Java2D
+ // context.
+ // Note that all of the plumbing in the context sharing stuff will
+ // allow us to bind to this object since it's in our namespace.
+ if (Java2D.isFBOEnabled() &&
+ Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) {
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: Binding to framebuffer object " + frameBuffer[0]);
+ }
+
+ // The texture target for Java2D's OpenGL pipeline when using FBOs
+ // -- either GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB
+ int fboTextureTarget = Java2D.getOGLTextureType(g);
+
+ if (!checkedForFBObjectWorkarounds) {
+ checkedForFBObjectWorkarounds = true;
+ gl.glBindTexture(fboTextureTarget, 0);
+ gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBuffer[0]);
+ if (gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER) !=
+ GL2.GL_FRAMEBUFFER_COMPLETE) {
+ // Need to do workarounds
+ fbObjectWorkarounds = true;
+ createNewDepthBuffer = true;
+ if (DEBUG) {
+ System.err.println("-- GLJPanel: discovered frame_buffer_object workarounds to be necessary");
+ }
+ } else {
+ // Don't need the frameBufferTexture temporary any more
+ frameBufferTexture = null;
+ }
+ }
+
+ if (fbObjectWorkarounds && createNewDepthBuffer) {
+ if (frameBufferDepthBuffer == null)
+ frameBufferDepthBuffer = new int[1];
+
+ // Create our own depth renderbuffer and associated storage
+ // If we have an old one, delete it
+ if (frameBufferDepthBuffer[0] != 0) {
+ gl.glDeleteRenderbuffers(1, frameBufferDepthBuffer, 0);
+ frameBufferDepthBuffer[0] = 0;
+ }
+
+ gl.glBindTexture(fboTextureTarget, frameBufferTexture[0]);
+ int[] width = new int[1];
+ int[] height = new int[1];
+ gl.glGetTexLevelParameteriv(fboTextureTarget, 0, GL2.GL_TEXTURE_WIDTH, width, 0);
+ gl.glGetTexLevelParameteriv(fboTextureTarget, 0, GL2.GL_TEXTURE_HEIGHT, height, 0);
+
+ gl.glGenRenderbuffers(1, frameBufferDepthBuffer, 0);
+ if (DEBUG) {
+ System.err.println("GLJPanel: Generated frameBufferDepthBuffer " + frameBufferDepthBuffer[0] +
+ " with width " + width[0] + ", height " + height[0]);
+ }
+
+ gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, frameBufferDepthBuffer[0]);
+ // FIXME: may need a loop here like in Java2D
+ gl.glRenderbufferStorage(GL2.GL_RENDERBUFFER, GL2.GL_DEPTH_COMPONENT24, width[0], height[0]);
+
+ gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, 0);
+ createNewDepthBuffer = false;
+ }
+
+ gl.glBindTexture(fboTextureTarget, 0);
+ gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBuffer[0]);
+
+ if (fbObjectWorkarounds) {
+ // Hook up the color and depth buffer attachment points for this framebuffer
+ gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER,
+ GL2.GL_COLOR_ATTACHMENT0,
+ fboTextureTarget,
+ frameBufferTexture[0],
+ 0);
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: frameBufferDepthBuffer: " + frameBufferDepthBuffer[0]);
+ }
+ gl.glFramebufferRenderbuffer(GL2.GL_FRAMEBUFFER,
+ GL2.GL_DEPTH_ATTACHMENT,
+ GL2.GL_RENDERBUFFER,
+ frameBufferDepthBuffer[0]);
+ }
+
+ if (DEBUG) {
+ int status = gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER);
+ if (status != GL2.GL_FRAMEBUFFER_COMPLETE) {
+ throw new GLException("Error: framebuffer was incomplete: status = 0x" +
+ Integer.toHexString(status));
+ }
+ }
+ } else {
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: Setting up drawBuffer " + drawBuffer[0] +
+ " and readBuffer " + readBuffer[0]);
+ }
+
+ gl.glDrawBuffer(drawBuffer[0]);
+ gl.glReadBuffer(readBuffer[0]);
+ }
+
+ return true;
+ }
+
+ public void postGL(Graphics g, boolean isDisplay) {
+ // Cause OpenGL pipeline to flush its results because
+ // otherwise it's possible we will buffer up multiple frames'
+ // rendering results, resulting in apparent mouse lag
+ GL gl = getGL();
+ gl.glFinish();
+
+ if (Java2D.isFBOEnabled() &&
+ Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) {
+ // Unbind the framebuffer from our context to work around
+ // apparent driver bugs or at least unspecified behavior causing
+ // OpenGL to run out of memory with certain cards and drivers
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0);
+ }
+ }
+
+ public void doPaintComponent(final Graphics g) {
+ // This is a workaround for an issue in the Java 2D / JOGL
+ // bridge (reported by an end user as JOGL Issue 274) where Java
+ // 2D can occasionally leave its internal OpenGL context current
+ // to the on-screen window rather than its internal "scratch"
+ // pbuffer surface to which the FBO is attached. JOGL expects to
+ // find a stable OpenGL drawable (on Windows, an HDC) upon which
+ // it can create another OpenGL context. It turns out that, on
+ // Windows, when Java 2D makes its internal OpenGL context
+ // current against the window in order to put pixels on the
+ // screen, it gets the device context for the window, makes its
+ // context current, and releases the device context. This means
+ // that when JOGL's Runnable gets to run below, the HDC is
+ // already invalid. The workaround for this is to force Java 2D
+ // to make its context current to the scratch surface, which we
+ // can do by executing an empty Runnable with the "shared"
+ // context current. This will be fixed in a Java SE 6 update
+ // release, hopefully 6u2.
+ if (Java2D.isFBOEnabled()) {
+ if (workaroundConfig == null) {
+ workaroundConfig = GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().
+ getDefaultConfiguration();
+ }
+ Java2D.invokeWithOGLSharedContextCurrent(workaroundConfig, new Runnable() { public void run() {}});
+ }
+
+ Java2D.invokeWithOGLContextCurrent(g, new Runnable() {
+ public void run() {
+ if (DEBUG && VERBOSE) {
+ System.err.println("-- In invokeWithOGLContextCurrent");
+ }
+
+ // Create no-op context representing Java2D context
+ if (j2dContext == null) {
+ j2dContext = factory.createExternalGLContext();
+ if (DEBUG) {
+ j2dContext.setGL(new DebugGL2(j2dContext.getGL().getGL2()));
+ }
+
+ // Check to see whether we can support the requested
+ // capabilities or need to fall back to a pbuffer
+ // FIXME: add more checks?
+
+ j2dContext.makeCurrent();
+ GL gl = j2dContext.getGL();
+ if ((getGLInteger(gl, GL2.GL_RED_BITS) < offscreenCaps.getRedBits()) ||
+ (getGLInteger(gl, GL2.GL_GREEN_BITS) < offscreenCaps.getGreenBits()) ||
+ (getGLInteger(gl, GL2.GL_BLUE_BITS) < offscreenCaps.getBlueBits()) ||
+ // (getGLInteger(gl, GL2.GL_ALPHA_BITS) < offscreenCaps.getAlphaBits()) ||
+ (getGLInteger(gl, GL2.GL_ACCUM_RED_BITS) < offscreenCaps.getAccumRedBits()) ||
+ (getGLInteger(gl, GL2.GL_ACCUM_GREEN_BITS) < offscreenCaps.getAccumGreenBits()) ||
+ (getGLInteger(gl, GL2.GL_ACCUM_BLUE_BITS) < offscreenCaps.getAccumBlueBits()) ||
+ (getGLInteger(gl, GL2.GL_ACCUM_ALPHA_BITS) < offscreenCaps.getAccumAlphaBits()) ||
+ // (getGLInteger(gl, GL2.GL_DEPTH_BITS) < offscreenCaps.getDepthBits()) ||
+ (getGLInteger(gl, GL2.GL_STENCIL_BITS) < offscreenCaps.getStencilBits())) {
+ if (DEBUG) {
+ System.err.println("GLJPanel: Falling back to pbuffer-based support because Java2D context insufficient");
+ System.err.println(" Available Required");
+ System.err.println("GL_RED_BITS " + getGLInteger(gl, GL2.GL_RED_BITS) + " " + offscreenCaps.getRedBits());
+ System.err.println("GL_GREEN_BITS " + getGLInteger(gl, GL2.GL_GREEN_BITS) + " " + offscreenCaps.getGreenBits());
+ System.err.println("GL_BLUE_BITS " + getGLInteger(gl, GL2.GL_BLUE_BITS) + " " + offscreenCaps.getBlueBits());
+ System.err.println("GL_ALPHA_BITS " + getGLInteger(gl, GL2.GL_ALPHA_BITS) + " " + offscreenCaps.getAlphaBits());
+ System.err.println("GL_ACCUM_RED_BITS " + getGLInteger(gl, GL2.GL_ACCUM_RED_BITS) + " " + offscreenCaps.getAccumRedBits());
+ System.err.println("GL_ACCUM_GREEN_BITS " + getGLInteger(gl, GL2.GL_ACCUM_GREEN_BITS) + " " + offscreenCaps.getAccumGreenBits());
+ System.err.println("GL_ACCUM_BLUE_BITS " + getGLInteger(gl, GL2.GL_ACCUM_BLUE_BITS) + " " + offscreenCaps.getAccumBlueBits());
+ System.err.println("GL_ACCUM_ALPHA_BITS " + getGLInteger(gl, GL2.GL_ACCUM_ALPHA_BITS) + " " + offscreenCaps.getAccumAlphaBits());
+ System.err.println("GL_DEPTH_BITS " + getGLInteger(gl, GL2.GL_DEPTH_BITS) + " " + offscreenCaps.getDepthBits());
+ System.err.println("GL_STENCIL_BITS " + getGLInteger(gl, GL2.GL_STENCIL_BITS) + " " + offscreenCaps.getStencilBits());
+ }
+ isInitialized = false;
+ backend = null;
+ oglPipelineEnabled = false;
+ handleReshape = true;
+ j2dContext.release();
+ j2dContext.destroy();
+ j2dContext = null;
+ return;
+ }
+ j2dContext.release();
+ }
+
+ j2dContext.makeCurrent();
+ try {
+ captureJ2DState(j2dContext.getGL(), g);
+ Object curSurface = Java2D.getOGLSurfaceIdentifier(g);
+ if (curSurface != null) {
+ if (j2dSurface != curSurface) {
+ if (joglContext != null) {
+ joglContext.destroy();
+ joglContext = null;
+ joglDrawable = null;
+ sendReshape = true;
+ if (DEBUG) {
+ System.err.println("Sending reshape because surface changed");
+ System.err.println("New surface = " + curSurface);
+ }
+ }
+ j2dSurface = curSurface;
+ }
+ if (joglContext == null) {
+ if (factory.canCreateExternalGLDrawable()) {
+ joglDrawable = factory.createExternalGLDrawable();
+ joglContext = joglDrawable.createContext(shareWith);
+ } else if (((GLDrawableFactoryImpl) factory).canCreateContextOnJava2DSurface()) {
+ // Mac OS X code path
+ joglContext = ((GLDrawableFactoryImpl) factory).createContextOnJava2DSurface(g, shareWith);
+ }
+ if (DEBUG) {
+ joglContext.setGL(new DebugGL2(joglContext.getGL().getGL2()));
+ }
+
+ if (Java2D.isFBOEnabled() &&
+ Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT &&
+ fbObjectWorkarounds) {
+ createNewDepthBuffer = true;
+ }
+ }
+ if (joglContext instanceof Java2DGLContext) {
+ // Mac OS X code path
+ ((Java2DGLContext) joglContext).setGraphics(g);
+ }
+
+ if (DEBUG && VERBOSE && Java2D.isFBOEnabled()) {
+ System.err.print("-- Surface type: ");
+ int surfaceType = Java2D.getOGLSurfaceType(g);
+ if (surfaceType == Java2D.UNDEFINED) {
+ System.err.println("UNDEFINED");
+ } else if (surfaceType == Java2D.WINDOW) {
+ System.err.println("WINDOW");
+ } else if (surfaceType == Java2D.PBUFFER) {
+ System.err.println("PBUFFER");
+ } else if (surfaceType == Java2D.TEXTURE) {
+ System.err.println("TEXTURE");
+ } else if (surfaceType == Java2D.FLIP_BACKBUFFER) {
+ System.err.println("FLIP_BACKBUFFER");
+ } else if (surfaceType == Java2D.FBOBJECT) {
+ System.err.println("FBOBJECT");
+ } else {
+ System.err.println("(Unknown surface type " + surfaceType + ")");
+ }
+ }
+
+ drawableHelper.invokeGL(joglDrawable, joglContext, displayAction, initAction);
+ }
+ } finally {
+ j2dContext.release();
+ }
+ }
+ });
+ }
+
+ private void captureJ2DState(GL gl, Graphics g) {
+ gl.glGetIntegerv(GL2.GL_DRAW_BUFFER, drawBuffer, 0);
+ gl.glGetIntegerv(GL2.GL_READ_BUFFER, readBuffer, 0);
+ if (Java2D.isFBOEnabled() &&
+ Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) {
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: Fetching GL_FRAMEBUFFER_BINDING_EXT");
+ }
+ gl.glGetIntegerv(GL2.GL_FRAMEBUFFER_BINDING, frameBuffer, 0);
+
+ if (fbObjectWorkarounds ||
+ !checkedForFBObjectWorkarounds) {
+ // See above for description of what we are doing here
+ if (frameBufferTexture == null)
+ frameBufferTexture = new int[1];
+
+ // Query the framebuffer for its color buffer so we can hook
+ // it back up in our context (should not be necessary)
+ gl.glGetFramebufferAttachmentParameteriv(GL2.GL_FRAMEBUFFER,
+ GL2.GL_COLOR_ATTACHMENT0,
+ GL2.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
+ frameBufferTexture, 0);
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: FBO COLOR_ATTACHMENT0: " + frameBufferTexture[0]);
+ }
+ }
+
+ if (!checkedGLVendor) {
+ checkedGLVendor = true;
+ String vendor = gl.glGetString(GL2.GL_VENDOR);
+
+ if ((vendor != null) &&
+ vendor.startsWith("ATI")) {
+ vendorIsATI = true;
+ }
+ }
+
+ if (vendorIsATI) {
+ // Unbind the FBO from Java2D's context as it appears that
+ // driver bugs on ATI's side are causing problems if the FBO is
+ // simultaneously bound to more than one context. Java2D will
+ // re-bind the FBO during the next validation of its context.
+ // Note: this breaks rendering at least on NVidia hardware
+ gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);
+ }
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/glu/GLUnurbs.java b/src/jogl/classes/javax/media/opengl/glu/GLUnurbs.java
new file mode 100755
index 000000000..2641115d0
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/glu/GLUnurbs.java
@@ -0,0 +1,8 @@
+package javax.media.opengl.glu;
+
+/**
+ * Wrapper for a GLU NURBS object.
+ */
+
+public interface GLUnurbs {
+}
diff --git a/src/jogl/classes/javax/media/opengl/glu/GLUquadric.java b/src/jogl/classes/javax/media/opengl/glu/GLUquadric.java
new file mode 100755
index 000000000..d5a7a11f3
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/glu/GLUquadric.java
@@ -0,0 +1,33 @@
+package javax.media.opengl.glu;
+
+import javax.media.opengl.GL;
+import com.sun.opengl.util.ImmModeSink;
+
+/**
+ * Wrapper for a GLU quadric object.
+ */
+
+public interface GLUquadric {
+ // enable/disables the Immediate Mode Sink module.
+ // This defaults to false for GLUgl2,
+ // and is always true for GLUes1.
+ public void enableImmModeSink(boolean val);
+
+ public boolean isImmModeSinkEnabled();
+
+ // set Immediate Mode usage.
+ // This defaults to false at GLU creation time.
+ // If enabled rendering will happen immediately,
+ // otherwise rendering will be hold in the ImmModeSink
+ // object, to be rendered deferred.
+ public void setImmMode(boolean val);
+
+ public boolean getImmMode();
+
+ // creates a new ImmModeSink (VBO Buffers) and
+ // returns the old vbo buffer with it's rendering result
+ public ImmModeSink replaceImmModeSink();
+
+ // gl may be null, then the GL client states are not disabled
+ public void resetImmModeSink(GL gl);
+}
diff --git a/src/jogl/classes/javax/media/opengl/glu/GLUtessellator.java b/src/jogl/classes/javax/media/opengl/glu/GLUtessellator.java
new file mode 100755
index 000000000..cb7bd9d76
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/glu/GLUtessellator.java
@@ -0,0 +1,66 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package javax.media.opengl.glu;
+
+/**
+ * The <b>GLUtessellator</b> object is used to hold the data, such as the
+ * vertices, edges and callback objects, to describe and tessellate complex
+ * polygons. A <b>GLUtessellator</b> object is used with the
+ * {@link GLU GLU} tessellator methods and
+ * {@link GLUtessellatorCallback GLU callbacks}.
+ *
+ * @author Eric Veach, July 1994
+ * @author Java Port: Pepijn Van Eechhoudt, July 2003
+ * @author Java Port: Nathan Parker Burg, August 2003
+ */
+public interface GLUtessellator {}
diff --git a/src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallback.java b/src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallback.java
new file mode 100755
index 000000000..4b5ec63b7
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallback.java
@@ -0,0 +1,356 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package javax.media.opengl.glu;
+
+/**
+ * <b>GLUtessellatorCallback</b> interface provides methods that the user will
+ * override to define the callbacks for a tessellation object.
+ *
+ * @author Eric Veach, July 1994
+ * @author Java Port: Pepijn Van Eeckhoudt, July 2003
+ * @author Java Port: Nathan Parker Burg, August 2003
+ */
+public interface GLUtessellatorCallback {
+ /**
+ * The <b>begin</b> callback method is invoked like
+ * {@link javax.media.opengl.GL#glBegin glBegin} to indicate the start of a
+ * (triangle) primitive. The method takes a single argument of type int. If
+ * the <b>GLU_TESS_BOUNDARY_ONLY</b> property is set to <b>GL_FALSE</b>, then
+ * the argument is set to either <b>GL_TRIANGLE_FAN</b>,
+ * <b>GL_TRIANGLE_STRIP</b>, or <b>GL_TRIANGLES</b>. If the
+ * <b>GLU_TESS_BOUNDARY_ONLY</b> property is set to <b>GL_TRUE</b>, then the
+ * argument will be set to <b>GL_LINE_LOOP</b>.
+ *
+ * @param type
+ * Specifics the type of begin/end pair being defined. The following
+ * values are valid: <b>GL_TRIANGLE_FAN</b>, <b>GL_TRIANGLE_STRIP</b>,
+ * <b>GL_TRIANGLES</b> or <b>GL_LINE_LOOP</b>.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #end end
+ * @see #begin begin
+ */
+ public void begin(int type);
+
+ /**
+ * The same as the {@link #begin begin} callback method except that
+ * it takes an additional reference argument. This reference is
+ * identical to the opaque reference provided when {@link
+ * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called.
+ *
+ * @param type
+ * Specifics the type of begin/end pair being defined. The following
+ * values are valid: <b>GL_TRIANGLE_FAN</b>, <b>GL_TRIANGLE_STRIP</b>,
+ * <b>GL_TRIANGLES</b> or <b>GL_LINE_LOOP</b>.
+ * @param polygonData
+ * Specifics a reference to user-defined data.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #endData endData
+ * @see #begin begin
+ */
+ public void beginData(int type, Object polygonData);
+
+
+ /**
+ * The <b>edgeFlag</b> callback method is similar to
+ * {@link javax.media.opengl.GL#glEdgeFlag glEdgeFlag}. The method takes
+ * a single boolean boundaryEdge that indicates which edges lie on the
+ * polygon boundary. If the boundaryEdge is <b>GL_TRUE</b>, then each vertex
+ * that follows begins an edge that lies on the polygon boundary, that is,
+ * an edge that separates an interior region from an exterior one. If the
+ * boundaryEdge is <b>GL_FALSE</b>, then each vertex that follows begins an
+ * edge that lies in the polygon interior. The edge flag callback (if
+ * defined) is invoked before the first vertex callback.<P>
+ *
+ * Since triangle fans and triangle strips do not support edge flags, the
+ * begin callback is not called with <b>GL_TRIANGLE_FAN</b> or
+ * <b>GL_TRIANGLE_STRIP</b> if a non-null edge flag callback is provided.
+ * (If the callback is initialized to null, there is no impact on
+ * performance). Instead, the fans and strips are converted to independent
+ * triangles.
+ *
+ * @param boundaryEdge
+ * Specifics which edges lie on the polygon boundary.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #edgeFlagData edgeFlagData
+ */
+ public void edgeFlag(boolean boundaryEdge);
+
+
+ /**
+ * The same as the {@link #edgeFlag edgeFlage} callback method
+ * except that it takes an additional reference argument. This
+ * reference is identical to the opaque reference provided when
+ * {@link GLU#gluTessBeginPolygon gluTessBeginPolygon} was called.
+ *
+ * @param boundaryEdge
+ * Specifics which edges lie on the polygon boundary.
+ * @param polygonData
+ * Specifics a reference to user-defined data.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #edgeFlag edgeFlag
+ */
+ public void edgeFlagData(boolean boundaryEdge, Object polygonData);
+
+
+ /**
+ * The <b>vertex</b> callback method is invoked between the {@link
+ * #begin begin} and {@link #end end} callback methods. It is
+ * similar to {@link javax.media.opengl.GL#glVertex3f glVertex3f},
+ * and it defines the vertices of the triangles created by the
+ * tessellation process. The method takes a reference as its only
+ * argument. This reference is identical to the opaque reference
+ * provided by the user when the vertex was described (see {@link
+ * GLU#gluTessVertex gluTessVertex}).
+ *
+ * @param vertexData
+ * Specifics a reference to the vertices of the triangles created
+ * by the tessellation process.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #vertexData vertexData
+ */
+ public void vertex(Object vertexData);
+
+
+ /**
+ * The same as the {@link #vertex vertex} callback method except
+ * that it takes an additional reference argument. This reference is
+ * identical to the opaque reference provided when {@link
+ * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called.
+ *
+ * @param vertexData
+ * Specifics a reference to the vertices of the triangles created
+ * by the tessellation process.
+ * @param polygonData
+ * Specifics a reference to user-defined data.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #vertex vertex
+ */
+ public void vertexData(Object vertexData, Object polygonData);
+
+
+ /**
+ * The end callback serves the same purpose as
+ * {@link javax.media.opengl.GL#glEnd glEnd}. It indicates the end of a
+ * primitive and it takes no arguments.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #begin begin
+ * @see #endData endData
+ */
+ public void end();
+
+
+ /**
+ * The same as the {@link #end end} callback method except that it
+ * takes an additional reference argument. This reference is
+ * identical to the opaque reference provided when {@link
+ * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called.
+ *
+ * @param polygonData
+ * Specifics a reference to user-defined data.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #beginData beginData
+ * @see #end end
+ */
+ public void endData(Object polygonData);
+
+
+ /**
+ * The <b>combine</b> callback method is called to create a new vertex when
+ * the tessellation detects an intersection, or wishes to merge features. The
+ * method takes four arguments: an array of three elements each of type
+ * double, an array of four references, an array of four elements each of
+ * type float, and a reference to a reference.<P>
+ *
+ * The vertex is defined as a linear combination of up to four existing
+ * vertices, stored in <i>data</i>. The coefficients of the linear combination
+ * are given by <i>weight</i>; these weights always add up to 1. All vertex
+ * pointers are valid even when some of the weights are 0. <i>coords</i> gives
+ * the location of the new vertex.<P>
+ *
+ * The user must allocate another vertex, interpolate parameters using
+ * <i>data</i> and <i>weight</i>, and return the new vertex pointer in
+ * <i>outData</i>. This handle is supplied during rendering callbacks. The
+ * user is responsible for freeing the memory some time after
+ * {@link GLU#gluTessEndPolygon gluTessEndPolygon} is
+ * called.<P>
+ *
+ * For example, if the polygon lies in an arbitrary plane in 3-space, and a
+ * color is associated with each vertex, the <b>GLU_TESS_COMBINE</b>
+ * callback might look like this:
+ * </UL>
+ * <PRE>
+ * void myCombine(double[] coords, Object[] data,
+ * float[] weight, Object[] outData)
+ * {
+ * MyVertex newVertex = new MyVertex();
+ *
+ * newVertex.x = coords[0];
+ * newVertex.y = coords[1];
+ * newVertex.z = coords[2];
+ * newVertex.r = weight[0]*data[0].r +
+ * weight[1]*data[1].r +
+ * weight[2]*data[2].r +
+ * weight[3]*data[3].r;
+ * newVertex.g = weight[0]*data[0].g +
+ * weight[1]*data[1].g +
+ * weight[2]*data[2].g +
+ * weight[3]*data[3].g;
+ * newVertex.b = weight[0]*data[0].b +
+ * weight[1]*data[1].b +
+ * weight[2]*data[2].b +
+ * weight[3]*data[3].b;
+ * newVertex.a = weight[0]*data[0].a +
+ * weight[1]*data[1].a +
+ * weight[2]*data[2].a +
+ * weight[3]*data[3].a;
+ * outData = newVertex;
+ * }</PRE>
+ *
+ * @param coords
+ * Specifics the location of the new vertex.
+ * @param data
+ * Specifics the vertices used to create the new vertex.
+ * @param weight
+ * Specifics the weights used to create the new vertex.
+ * @param outData
+ * Reference user the put the coodinates of the new vertex.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #combineData combineData
+ */
+ public void combine(double[] coords, Object[] data,
+ float[] weight, Object[] outData);
+
+
+ /**
+ * The same as the {@link #combine combine} callback method except
+ * that it takes an additional reference argument. This reference is
+ * identical to the opaque reference provided when {@link
+ * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called.
+ *
+ * @param coords
+ * Specifics the location of the new vertex.
+ * @param data
+ * Specifics the vertices used to create the new vertex.
+ * @param weight
+ * Specifics the weights used to create the new vertex.
+ * @param outData
+ * Reference user the put the coodinates of the new vertex.
+ * @param polygonData
+ * Specifics a reference to user-defined data.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #combine combine
+ */
+ public void combineData(double[] coords, Object[] data,
+ float[] weight, Object[] outData,
+ Object polygonData);
+
+
+ /**
+ * The <b>error</b> callback method is called when an error is encountered.
+ * The one argument is of type int; it indicates the specific error that
+ * occurred and will be set to one of <b>GLU_TESS_MISSING_BEGIN_POLYGON</b>,
+ * <b>GLU_TESS_MISSING_END_POLYGON</b>, <b>GLU_TESS_MISSING_BEGIN_CONTOUR</b>,
+ * <b>GLU_TESS_MISSING_END_CONTOUR</b>, <b>GLU_TESS_COORD_TOO_LARGE</b>,
+ * <b>GLU_TESS_NEED_COMBINE_CALLBACK</b> or <b>GLU_OUT_OF_MEMORY</b>.
+ * Character strings describing these errors can be retrieved with the
+ * {@link GLU#gluErrorString gluErrorString} call.<P>
+ *
+ * The GLU library will recover from the first four errors by inserting the
+ * missing call(s). <b>GLU_TESS_COORD_TOO_LARGE</b> indicates that some
+ * vertex coordinate exceeded the predefined constant
+ * <b>GLU_TESS_MAX_COORD</b> in absolute value, and that the value has been
+ * clamped. (Coordinate values must be small enough so that two can be
+ * multiplied together without overflow.)
+ * <b>GLU_TESS_NEED_COMBINE_CALLBACK</b> indicates that the tessellation
+ * detected an intersection between two edges in the input data, and the
+ * <b>GLU_TESS_COMBINE</b> or <b>GLU_TESS_COMBINE_DATA</b> callback was not
+ * provided. No output is generated. <b>GLU_OUT_OF_MEMORY</b> indicates that
+ * there is not enough memory so no output is generated.
+ *
+ * @param errnum
+ * Specifics the error number code.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #errorData errorData
+ */
+ public void error(int errnum);
+
+
+ /**
+ * The same as the {@link #error error} callback method except that
+ * it takes an additional reference argument. This reference is
+ * identical to the opaque reference provided when {@link
+ * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called.
+ *
+ * @param errnum
+ * Specifics the error number code.
+ * @param polygonData
+ * Specifics a reference to user-defined data.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #error error
+ */
+ public void errorData(int errnum, Object polygonData);
+
+ //void mesh(com.sun.opengl.impl.tessellator.GLUmesh mesh);
+}
diff --git a/src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallbackAdapter.java b/src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallbackAdapter.java
new file mode 100755
index 000000000..bf6f2d29a
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallbackAdapter.java
@@ -0,0 +1,84 @@
+/*
+* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc.
+* All rights reserved.
+*/
+
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 1.1 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+**
+** http://oss.sgi.com/projects/FreeB
+**
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE: The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License"). Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License"). This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted. Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+**
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+**
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** Author: Eric Veach, July 1994
+** Java Port: Pepijn Van Eeckhoudt, July 2003
+** Java Port: Nathan Parker Burg, August 2003
+*/
+package javax.media.opengl.glu;
+
+/**
+ * The <b>GLUtessellatorCallbackAdapter</b> provides a default implementation of
+ * {@link GLUtessellatorCallback GLUtessellatorCallback}
+ * with empty callback methods. This class can be extended to provide user
+ * defined callback methods.
+ *
+ * @author Eric Veach, July 1994
+ * @author Java Port: Pepijn Van Eechhoudt, July 2003
+ * @author Java Port: Nathan Parker Burg, August 2003
+ */
+
+public class GLUtessellatorCallbackAdapter implements GLUtessellatorCallback {
+ public void begin(int type) {}
+ public void edgeFlag(boolean boundaryEdge) {}
+ public void vertex(Object vertexData) {}
+ public void end() {}
+// public void mesh(com.sun.opengl.impl.tessellator.GLUmesh mesh) {}
+ public void error(int errnum) {}
+ public void combine(double[] coords, Object[] data,
+ float[] weight, Object[] outData) {}
+ public void beginData(int type, Object polygonData) {}
+ public void edgeFlagData(boolean boundaryEdge,
+ Object polygonData) {}
+ public void vertexData(Object vertexData, Object polygonData) {}
+ public void endData(Object polygonData) {}
+ public void errorData(int errnum, Object polygonData) {}
+ public void combineData(double[] coords, Object[] data,
+ float[] weight, Object[] outData,
+ Object polygonData) {}
+}
diff --git a/src/jogl/classes/javax/media/opengl/sub/GLObject.java b/src/jogl/classes/javax/media/opengl/sub/GLObject.java
new file mode 100644
index 000000000..1426f75d1
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/sub/GLObject.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package javax.media.opengl.sub;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+
+/**
+ * GLObject specifies the GL profile related implementations
+ * and it's composition with GLContext, which is a lifetime one.
+ */
+public interface GLObject {
+
+ public boolean isGL();
+
+ public boolean isGL2();
+
+ public boolean isGLES1();
+
+ public boolean isGLES2();
+
+ public boolean isGLES();
+
+ public boolean isGL2ES1();
+
+ public boolean isGL2ES2();
+
+ /**
+ * @return This object cast to GL
+ * @throws GLException is this GLObject is not a GL implementation
+ */
+ public GL getGL() throws GLException;
+
+ /**
+ * @return This object cast to GL2
+ * @throws GLException is this GLObject is not a GL2 implementation
+ */
+ public GL2 getGL2() throws GLException;
+
+ /**
+ * @return This object cast to GLES1
+ * @throws GLException is this GLObject is not a GLES1 implementation
+ */
+ public GLES1 getGLES1() throws GLException;
+
+ /**
+ * @return This object cast to GLES2
+ * @throws GLException is this GLObject is not a GLES2 implementation
+ */
+ public GLES2 getGLES2() throws GLException;
+
+ /**
+ * @return This object cast to GL2ES1
+ * @throws GLException is this GLObject is not a GL2ES1 implementation
+ */
+ public GL2ES1 getGL2ES1() throws GLException;
+
+ /**
+ * @return This object cast to GL2ES2
+ * @throws GLException is this GLObject is not a GL2ES2 implementation
+ */
+ public GL2ES2 getGL2ES2() throws GLException;
+
+ public String toString();
+
+ /**
+ * @return This GL object's bound GLContext
+ */
+ public GLContext getContext();
+
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/sub/fixed/GLFixedFuncUtil.java b/src/jogl/classes/javax/media/opengl/sub/fixed/GLFixedFuncUtil.java
new file mode 100644
index 000000000..9c384e934
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/sub/fixed/GLFixedFuncUtil.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package javax.media.opengl.sub.fixed;
+
+import javax.media.opengl.*;
+import javax.media.opengl.sub.*;
+
+import com.sun.nwi.impl.NWReflection;
+import java.lang.reflect.*;
+
+/**
+ * Tool to pipeline GL2ES2 into a fixed function emulation,
+ * implementing GL2ES1.
+ * The implementation is retrieved by reflection.
+ */
+public class GLFixedFuncUtil {
+ static final Constructor fFuncHookCstr;
+ static final Constructor fFuncImplCstr;
+
+ static {
+ if(NWReflection.isClassAvailable("com.sun.opengl.util.glsl.fixed.FixedFuncHook") &&
+ NWReflection.isClassAvailable("com.sun.opengl.util.glsl.fixed.FixedFuncImpl")) {
+ Class argsHook[] = { javax.media.opengl.GL2ES2.class };
+ Class argsImpl[] = { javax.media.opengl.GL2ES2.class, NWReflection.getClass("com.sun.opengl.util.glsl.fixed.FixedFuncHook") };
+ fFuncHookCstr = NWReflection.getConstructor("com.sun.opengl.util.glsl.fixed.FixedFuncHook", argsHook);
+ fFuncImplCstr = NWReflection.getConstructor("com.sun.opengl.util.glsl.fixed.FixedFuncImpl", argsImpl);
+ } else {
+ fFuncHookCstr=null;
+ fFuncImplCstr=null;
+ }
+ }
+
+ /**
+ * @return If gl is a GL2ES1, return the type cast object,
+ * otherwise create a FixedFuncImpl pipeline with the GL2ES2 impl.
+ * @throws GLException If this GL Object is neither GL2ES1 nor GL2ES2
+ */
+ public static final GL2ES1 getFixedFuncImpl(GL gl) {
+ if(gl instanceof GL2ES1) {
+ return (GL2ES1)gl;
+ } else if(gl instanceof GL2ES2) {
+ if(null!=fFuncImplCstr) {
+ try {
+ GL2ES2 es2 = (GL2ES2)gl;
+ Object fFuncHook = fFuncHookCstr.newInstance( new Object[] { es2 } );
+ GL2ES1 fFuncImpl = (GL2ES1) fFuncImplCstr.newInstance( new Object[] { es2, fFuncHook } );
+ gl.getContext().setGL(fFuncImpl);
+ return fFuncImpl;
+ } catch (Exception e) {
+ throw new GLException(e);
+ }
+ } else {
+ throw new GLException("GL Object is GL2ES2, but no fixed function impl. available");
+ }
+ }
+ throw new GLException("GL Object is neither GL2ES1 nor GL2ES2");
+ }
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/sub/fixed/GLLightingIf.java b/src/jogl/classes/javax/media/opengl/sub/fixed/GLLightingIf.java
new file mode 100644
index 000000000..1f3aa9ab7
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/sub/fixed/GLLightingIf.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package javax.media.opengl.sub.fixed;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.sub.*;
+
+public interface GLLightingIf {
+ public static final int GL_LIGHT0 = 0x4000;
+ public static final int GL_LIGHT1 = 0x4001;
+ public static final int GL_LIGHT2 = 0x4002;
+ public static final int GL_LIGHT3 = 0x4003;
+ public static final int GL_LIGHT4 = 0x4004;
+ public static final int GL_LIGHT5 = 0x4005;
+ public static final int GL_LIGHT6 = 0x4006;
+ public static final int GL_LIGHT7 = 0x4007;
+ public static final int GL_LIGHTING = 0xB50;
+ public static final int GL_AMBIENT = 0x1200;
+ public static final int GL_DIFFUSE = 0x1201;
+ public static final int GL_SPECULAR = 0x1202;
+ public static final int GL_POSITION = 0x1203;
+ public static final int GL_SPOT_DIRECTION = 0x1204;
+ public static final int GL_SPOT_EXPONENT = 0x1205;
+ public static final int GL_SPOT_CUTOFF = 0x1206;
+ public static final int GL_CONSTANT_ATTENUATION = 0x1207;
+ public static final int GL_LINEAR_ATTENUATION = 0x1208;
+ public static final int GL_QUADRATIC_ATTENUATION = 0x1209;
+ public static final int GL_EMISSION = 0x1600;
+ public static final int GL_SHININESS = 0x1601;
+ public static final int GL_AMBIENT_AND_DIFFUSE = 0x1602;
+ public static final int GL_COLOR_MATERIAL = 0xB57;
+ public static final int GL_NORMALIZE = 0xBA1;
+
+ public static final int GL_FLAT = 0x1D00;
+ public static final int GL_SMOOTH = 0x1D01;
+
+ public void glLightfv(int light, int pname, java.nio.FloatBuffer params);
+ public void glLightfv(int light, int pname, float[] params, int params_offset);
+ public void glMaterialf(int face, int pname, float param);
+ public void glMaterialfv(int face, int pname, java.nio.FloatBuffer params);
+ public void glMaterialfv(int face, int pname, float[] params, int params_offset);
+ public void glColor4f(float red, float green, float blue, float alpha);
+ public void glShadeModel(int mode);
+
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/sub/fixed/GLMatrixIf.java b/src/jogl/classes/javax/media/opengl/sub/fixed/GLMatrixIf.java
new file mode 100644
index 000000000..834731b98
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/sub/fixed/GLMatrixIf.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package javax.media.opengl.sub.fixed;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.sub.*;
+
+public interface GLMatrixIf {
+
+ public static final int GL_MATRIX_MODE = 0x0BA0;
+ public static final int GL_MODELVIEW = 0x1700;
+ public static final int GL_PROJECTION = 0x1701;
+ // public static final int GL_TEXTURE = 0x1702; // Use GL.GL_TEXTURE due to ambiguous GL usage
+ public static final int GL_MODELVIEW_MATRIX = 0x0BA6;
+ public static final int GL_PROJECTION_MATRIX = 0x0BA7;
+ public static final int GL_TEXTURE_MATRIX = 0x0BA8;
+
+ /**
+ * glGetFloatv
+ * @param pname GL_MODELVIEW_MATRIX, GL_PROJECTION_MATRIX or GL_TEXTURE_MATRIX
+ * @param params the FloatBuffer's position remains unchanged,
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glGetFloatv(int pname, java.nio.FloatBuffer params);
+ public void glGetFloatv(int pname, float[] params, int params_offset);
+ /**
+ * glGetIntegerv
+ * @param pname GL_MATRIX_MODE
+ * @param params the FloatBuffer's position remains unchanged
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glGetIntegerv(int pname, IntBuffer params);
+ public void glGetIntegerv(int pname, int[] params, int params_offset);
+
+ /**
+ * sets the current matrix
+ * @param pname GL_MODELVIEW, GL_PROJECTION or GL.GL_TEXTURE
+ */
+ public void glMatrixMode(int mode) ;
+
+ public void glPushMatrix();
+ public void glPopMatrix();
+
+ public void glLoadIdentity() ;
+
+ /**
+ * glLoadMatrixf
+ * @param params the FloatBuffer's position remains unchanged,
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glLoadMatrixf(java.nio.FloatBuffer m) ;
+ public void glLoadMatrixf(float[] m, int m_offset);
+
+ /**
+ * glMultMatrixf
+ * @param params the FloatBuffer's position remains unchanged,
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glMultMatrixf(java.nio.FloatBuffer m) ;
+ public void glMultMatrixf(float[] m, int m_offset);
+
+ public void glTranslatef(float x, float y, float z) ;
+
+ public void glRotatef(float angle, float x, float y, float z);
+
+ public void glScalef(float x, float y, float z) ;
+
+ public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) ;
+
+ public void glFrustumf(float left, float right, float bottom, float top, float zNear, float zFar);
+
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/sub/fixed/GLPointerIf.java b/src/jogl/classes/javax/media/opengl/sub/fixed/GLPointerIf.java
new file mode 100644
index 000000000..2f4cda1aa
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/sub/fixed/GLPointerIf.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package javax.media.opengl.sub.fixed;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+import javax.media.opengl.sub.*;
+
+public interface GLPointerIf {
+ public static final int GL_VERTEX_ARRAY = 0x8074;
+ public static final int GL_NORMAL_ARRAY = 0x8075;
+ public static final int GL_COLOR_ARRAY = 0x8076;
+ public static final int GL_TEXTURE_COORD_ARRAY = 0x8078;
+
+ public void glEnableClientState(int arrayName);
+ public void glDisableClientState(int arrayName);
+
+ public void glVertexPointer(GLArrayData array);
+ public void glVertexPointer(int size, int type, int stride, java.nio.Buffer pointer);
+ public void glVertexPointer(int size, int type, int stride, long pointer_buffer_offset);
+
+ public void glColorPointer(GLArrayData array);
+ public void glColorPointer(int size, int type, int stride, java.nio.Buffer pointer);
+ public void glColorPointer(int size, int type, int stride, long pointer_buffer_offset);
+ public void glColor4f(float red, float green, float blue, float alpha);
+
+ public void glNormalPointer(GLArrayData array);
+ public void glNormalPointer(int type, int stride, java.nio.Buffer pointer);
+ public void glNormalPointer(int type, int stride, long pointer_buffer_offset);
+
+ public void glTexCoordPointer(GLArrayData array);
+ public void glTexCoordPointer(int size, int type, int stride, java.nio.Buffer pointer);
+ public void glTexCoordPointer(int size, int type, int stride, long pointer_buffer_offset);
+
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/util/BufferUtil.java.javame_cdc_fp b/src/jogl/classes/javax/media/opengl/util/BufferUtil.java.javame_cdc_fp
new file mode 100755
index 000000000..116b337d4
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/util/BufferUtil.java.javame_cdc_fp
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl.util;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import com.sun.nwi.impl.NWReflection;
+
+import java.nio.*;
+import java.util.*;
+
+import java.lang.reflect.*;
+
+/** Utility routines for dealing with direct buffers. */
+
+public class BufferUtil {
+ public static final int SIZEOF_BYTE = 1;
+ public static final int SIZEOF_SHORT = 2;
+ public static final int SIZEOF_INT = 4;
+ public static final int SIZEOF_FLOAT = 4;
+ public static final int SIZEOF_LONG = -1; // not supported
+ public static final int SIZEOF_DOUBLE = -1; // not supported
+
+ public static final int sizeOfGLType(int glType) {
+ switch (glType) {
+ case GL.GL_UNSIGNED_BYTE:
+ return SIZEOF_BYTE;
+ case GL.GL_BYTE:
+ return SIZEOF_BYTE;
+ case GL.GL_UNSIGNED_SHORT:
+ return SIZEOF_SHORT;
+ case GL.GL_SHORT:
+ return SIZEOF_SHORT;
+ case GL.GL_FLOAT:
+ return SIZEOF_FLOAT;
+ case GL.GL_FIXED:
+ return SIZEOF_INT;
+ case GL2ES2.GL_INT:
+ return SIZEOF_INT;
+ case GL2ES2.GL_UNSIGNED_INT:
+ return SIZEOF_INT;
+ case GL2.GL_DOUBLE:
+ return SIZEOF_DOUBLE;
+ }
+ return -1;
+ }
+
+ public static final int sizeOfBufferElem(Buffer buffer) {
+ if (buffer == null) {
+ return 0;
+ }
+ if (buffer instanceof ByteBuffer) {
+ return BufferUtil.SIZEOF_BYTE;
+ } else if (buffer instanceof IntBuffer) {
+ return BufferUtil.SIZEOF_INT;
+ } else if (buffer instanceof ShortBuffer) {
+ return BufferUtil.SIZEOF_SHORT;
+ } else if (buffer instanceof FloatBuffer) {
+ return BufferUtil.SIZEOF_FLOAT;
+ }
+ throw new RuntimeException("Unexpected buffer type " +
+ buffer.getClass().getName());
+ }
+
+ private BufferUtil() {}
+
+ //----------------------------------------------------------------------
+ // Allocation routines
+ //
+
+ public static final Buffer newGLBuffer(int glType, int numElements) {
+ switch (glType) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ return newByteBuffer(numElements);
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ return newShortBuffer(numElements);
+ case GL.GL_FLOAT:
+ return newFloatBuffer(numElements);
+ case GL.GL_FIXED:
+ case GL2ES2.GL_INT:
+ case GL2ES2.GL_UNSIGNED_INT:
+ return newIntBuffer(numElements);
+ }
+ return null;
+ }
+
+ public static final Buffer sliceGLBuffer(ByteBuffer parent, int bytePos, int byteLen, int glType) {
+ if(parent==null || byteLen==0) return null;
+ parent.position(bytePos);
+ parent.limit(bytePos + byteLen);
+
+ switch (glType) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ return parent.slice();
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ return parent.asShortBuffer();
+ case GL.GL_FLOAT:
+ return parent.asFloatBuffer();
+ case GL.GL_FIXED:
+ case GL2ES2.GL_INT:
+ case GL2ES2.GL_UNSIGNED_INT:
+ return parent.asIntBuffer();
+ }
+ return null;
+ }
+
+ /** Allocates a new direct ByteBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ByteBuffer newByteBuffer(int numElements) {
+ ByteBuffer bb = ByteBuffer.allocateDirect(numElements);
+ nativeOrder(bb);
+ return bb;
+ }
+
+ public static ByteBuffer newByteBuffer(byte[] values, int offset, int len) {
+ ByteBuffer bb = newByteBuffer(len);
+ bb.put(values, offset, len);
+ bb.rewind();
+ return bb;
+ }
+
+ public static ByteBuffer newByteBuffer(byte[] values, int offset) {
+ return newByteBuffer(values, offset, values.length-offset);
+ }
+
+ public static ByteBuffer newByteBuffer(byte[] values) {
+ return newByteBuffer(values, 0);
+ }
+
+ /** Allocates a new direct FloatBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static FloatBuffer newFloatBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT);
+ return bb.asFloatBuffer();
+ }
+
+ public static FloatBuffer newFloatBuffer(float[] values, int offset, int len) {
+ FloatBuffer bb = newFloatBuffer(len);
+ bb.put(values, offset, len);
+ bb.rewind();
+ return bb;
+ }
+
+ public static FloatBuffer newFloatBuffer(float[] values, int offset) {
+ return newFloatBuffer(values, 0, values.length-offset);
+ }
+
+ public static FloatBuffer newFloatBuffer(float[] values) {
+ return newFloatBuffer(values, 0);
+ }
+
+ /** Allocates a new direct IntBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static IntBuffer newIntBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT);
+ return bb.asIntBuffer();
+ }
+
+ public static IntBuffer newIntBuffer(int[] values, int offset, int len) {
+ IntBuffer bb = newIntBuffer(len);
+ bb.put(values, offset, len);
+ bb.rewind();
+ return bb;
+ }
+
+ public static IntBuffer newIntBuffer(int[] values, int offset) {
+ return newIntBuffer(values, 0, values.length-offset);
+ }
+
+ public static IntBuffer newIntBuffer(int[] values) {
+ return newIntBuffer(values, 0);
+ }
+
+
+ /** Allocates a new direct ShortBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ShortBuffer newShortBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_SHORT);
+ return bb.asShortBuffer();
+ }
+
+ public static ShortBuffer newShortBuffer(short[] values, int offset, int len) {
+ ShortBuffer bb = newShortBuffer(len);
+ bb.put(values, offset, len);
+ bb.rewind();
+ return bb;
+ }
+
+ public static ShortBuffer newShortBuffer(short[] values, int offset) {
+ return newShortBuffer(values, 0, values.length-offset);
+ }
+
+ public static ShortBuffer newShortBuffer(short[] values) {
+ return newShortBuffer(values, 0);
+ }
+
+
+ //----------------------------------------------------------------------
+ // Copy routines (type-to-type)
+ //
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ByteBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyByteBuffer(ByteBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining());
+ dest.put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed FloatBuffer
+ into a newly-allocated direct FloatBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static FloatBuffer copyFloatBuffer(FloatBuffer orig) {
+ return copyFloatBufferAsByteBuffer(orig).asFloatBuffer();
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed IntBuffer
+ into a newly-allocated direct IntBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static IntBuffer copyIntBuffer(IntBuffer orig) {
+ return copyIntBufferAsByteBuffer(orig).asIntBuffer();
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ShortBuffer
+ into a newly-allocated direct ShortBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ShortBuffer copyShortBuffer(ShortBuffer orig) {
+ return copyShortBufferAsByteBuffer(orig).asShortBuffer();
+ }
+
+ //----------------------------------------------------------------------
+ // Copy routines (type-to-ByteBuffer)
+ //
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed FloatBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyFloatBufferAsByteBuffer(FloatBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_FLOAT);
+ dest.asFloatBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed IntBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyIntBufferAsByteBuffer(IntBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_INT);
+ dest.asIntBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ShortBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyShortBufferAsByteBuffer(ShortBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_SHORT);
+ dest.asShortBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ //----------------------------------------------------------------------
+ // Conversion routines
+ //
+
+ public final static float[] getFloatArray(double[] source) {
+ int i=source.length;
+ float[] dest = new float[i--];
+ while(i>=0) { dest[i]=(float)source[i]; i--; }
+ return dest;
+ }
+
+ public static ByteBuffer nativeOrder(ByteBuffer buf) {
+ if (!isCDCFP) {
+ try {
+ if (byteOrderClass == null) {
+ byteOrderClass = Class.forName("java.nio.ByteOrder");
+ orderMethod = ByteBuffer.class.getMethod("order", new Class[] { byteOrderClass });
+ Method nativeOrderMethod = byteOrderClass.getMethod("nativeOrder", null);
+ nativeOrderObject = nativeOrderMethod.invoke(null, null);
+ }
+ } catch (Throwable t) {
+ // Must be running on CDC / FP
+ isCDCFP = true;
+ }
+
+ if (!isCDCFP) {
+ try {
+ orderMethod.invoke(buf, new Object[] { nativeOrderObject });
+ } catch (Throwable t) {
+ }
+ }
+ }
+ return buf;
+ }
+
+ //----------------------------------------------------------------------
+ // Convenient GL put methods with generic target Buffer
+ //
+ public static void put(Buffer dest, Buffer v) {
+ Class dClazz = dest.getClass();
+ Class vClazz = v.getClass();
+ if(!NWReflection.instanceOf(vClazz, dClazz.getName())) {
+ throw new GLException("This array's dest class "+dClazz+" doesn't match the argument's Class: "+vClazz);
+ }
+ if(dest instanceof ByteBuffer) {
+ ((ByteBuffer)dest).put((ByteBuffer)v);
+ } else if(dest instanceof ShortBuffer) {
+ ((ShortBuffer)dest).put((ShortBuffer)v);
+ } else if(dest instanceof IntBuffer) {
+ ((IntBuffer)dest).put((IntBuffer)v);
+ } else if(dest instanceof FloatBuffer) {
+ ((FloatBuffer)dest).put((FloatBuffer)v);
+ }
+ }
+
+ public static void putb(Buffer dest, byte v) {
+ if(dest instanceof ByteBuffer) {
+ ((ByteBuffer)dest).put(v);
+ } else if(dest instanceof ShortBuffer) {
+ ((ShortBuffer)dest).put((short)v);
+ } else if(dest instanceof IntBuffer) {
+ ((IntBuffer)dest).put((int)v);
+ } else {
+ throw new GLException("Byte doesn't match Buffer Class: "+dest);
+ }
+ }
+
+ public static void puts(Buffer dest, short v) {
+ if(dest instanceof ShortBuffer) {
+ ((ShortBuffer)dest).put(v);
+ } else if(dest instanceof IntBuffer) {
+ ((IntBuffer)dest).put((int)v);
+ } else {
+ throw new GLException("Short doesn't match Buffer Class: "+dest);
+ }
+ }
+
+ public static void puti(Buffer dest, int v) {
+ if(dest instanceof IntBuffer) {
+ ((IntBuffer)dest).put(v);
+ } else {
+ throw new GLException("Integer doesn't match Buffer Class: "+dest);
+ }
+ }
+
+ public static void putx(Buffer dest, int v) {
+ puti(dest, v);
+ }
+
+ public static void putf(Buffer dest, float v) {
+ if(dest instanceof FloatBuffer) {
+ ((FloatBuffer)dest).put(v);
+ } else if(dest instanceof IntBuffer) {
+ ((IntBuffer)dest).put(FixedPoint.toFixed(v));
+ } else {
+ throw new GLException("Float doesn't match Buffer Class: "+dest);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // NOTE that this work must be done reflectively at the present time
+ // because this code must compile and run correctly on both CDC/FP and J2SE
+ private static boolean isCDCFP;
+ private static Class byteOrderClass;
+ private static Object nativeOrderObject;
+ private static Method orderMethod;
+
+}
diff --git a/src/jogl/classes/javax/media/opengl/util/BufferUtil.java.javase b/src/jogl/classes/javax/media/opengl/util/BufferUtil.java.javase
new file mode 100755
index 000000000..a27c136c3
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/util/BufferUtil.java.javase
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl.util;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2ES2;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import com.sun.nwi.impl.NWReflection;
+
+import java.nio.*;
+import java.util.*;
+
+import java.lang.reflect.*;
+
+/** Utility routines for dealing with direct buffers. */
+
+public class BufferUtil {
+ public static final int SIZEOF_BYTE = 1;
+ public static final int SIZEOF_SHORT = 2;
+ public static final int SIZEOF_INT = 4;
+ public static final int SIZEOF_FLOAT = 4;
+ public static final int SIZEOF_LONG = 8;
+ public static final int SIZEOF_DOUBLE = 8;
+
+ public static final int sizeOfGLType(int glType) {
+ switch (glType) {
+ case GL.GL_UNSIGNED_BYTE:
+ return SIZEOF_BYTE;
+ case GL.GL_BYTE:
+ return SIZEOF_BYTE;
+ case GL.GL_UNSIGNED_SHORT:
+ return SIZEOF_SHORT;
+ case GL.GL_SHORT:
+ return SIZEOF_SHORT;
+ case GL.GL_FLOAT:
+ return SIZEOF_FLOAT;
+ case GL.GL_FIXED:
+ return SIZEOF_INT;
+ case GL2ES2.GL_INT:
+ return SIZEOF_INT;
+ case GL2ES2.GL_UNSIGNED_INT:
+ return SIZEOF_INT;
+ case GL2.GL_DOUBLE:
+ return SIZEOF_DOUBLE;
+ }
+ return -1;
+ }
+
+ public static final int sizeOfBufferElem(Buffer buffer) {
+ if (buffer == null) {
+ return 0;
+ }
+ if (buffer instanceof ByteBuffer) {
+ return BufferUtil.SIZEOF_BYTE;
+ } else if (buffer instanceof IntBuffer) {
+ return BufferUtil.SIZEOF_INT;
+ } else if (buffer instanceof ShortBuffer) {
+ return BufferUtil.SIZEOF_SHORT;
+ } else if (buffer instanceof FloatBuffer) {
+ return BufferUtil.SIZEOF_FLOAT;
+ } else if (buffer instanceof DoubleBuffer) {
+ return BufferUtil.SIZEOF_DOUBLE;
+ }
+ throw new RuntimeException("Unexpected buffer type " +
+ buffer.getClass().getName());
+ }
+
+ private BufferUtil() {}
+
+ //----------------------------------------------------------------------
+ // Allocation routines
+ //
+
+ public static final Buffer newGLBuffer(int glType, int numElements) {
+ switch (glType) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ return newByteBuffer(numElements);
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ return newShortBuffer(numElements);
+ case GL.GL_FLOAT:
+ return newFloatBuffer(numElements);
+ case GL.GL_FIXED:
+ case GL2ES2.GL_INT:
+ case GL2ES2.GL_UNSIGNED_INT:
+ return newIntBuffer(numElements);
+ case GL2.GL_DOUBLE:
+ return newDoubleBuffer(numElements);
+ }
+ return null;
+ }
+
+ public static final Buffer sliceGLBuffer(ByteBuffer parent, int bytePos, int byteLen, int glType) {
+ if(parent==null || byteLen==0) return null;
+ parent.position(bytePos);
+ parent.limit(bytePos + byteLen);
+
+ switch (glType) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ return parent.slice();
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ return parent.asShortBuffer();
+ case GL.GL_FLOAT:
+ return parent.asFloatBuffer();
+ case GL.GL_FIXED:
+ case GL2ES2.GL_INT:
+ case GL2ES2.GL_UNSIGNED_INT:
+ return parent.asIntBuffer();
+ case GL2.GL_DOUBLE:
+ return parent.asDoubleBuffer();
+ }
+ return null;
+ }
+
+ /** Allocates a new direct ByteBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ByteBuffer newByteBuffer(int numElements) {
+ ByteBuffer bb = ByteBuffer.allocateDirect(numElements);
+ nativeOrder(bb);
+ return bb;
+ }
+
+ public static ByteBuffer newByteBuffer(byte[] values, int offset, int len) {
+ ByteBuffer bb = newByteBuffer(len);
+ bb.put(values, offset, len);
+ bb.rewind();
+ return bb;
+ }
+
+ public static ByteBuffer newByteBuffer(byte[] values, int offset) {
+ return newByteBuffer(values, offset, values.length-offset);
+ }
+
+ public static ByteBuffer newByteBuffer(byte[] values) {
+ return newByteBuffer(values, 0);
+ }
+
+
+ /** Allocates a new direct DoubleBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static DoubleBuffer newDoubleBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_DOUBLE);
+ return bb.asDoubleBuffer();
+ }
+
+ public static DoubleBuffer newDoubleBuffer(double[] values, int offset) {
+ int len = values.length-offset;
+ DoubleBuffer bb = newDoubleBuffer(len);
+ bb.put(values, offset, len);
+ bb.rewind();
+ return bb;
+ }
+
+ public static DoubleBuffer newDoubleBuffer(double[] values) {
+ return newDoubleBuffer(values, 0);
+ }
+
+
+ /** Allocates a new direct FloatBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static FloatBuffer newFloatBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_FLOAT);
+ return bb.asFloatBuffer();
+ }
+
+ public static FloatBuffer newFloatBuffer(float[] values, int offset, int len) {
+ FloatBuffer bb = newFloatBuffer(len);
+ bb.put(values, offset, len);
+ bb.rewind();
+ return bb;
+ }
+
+ public static FloatBuffer newFloatBuffer(float[] values, int offset) {
+ return newFloatBuffer(values, 0, values.length-offset);
+ }
+
+ public static FloatBuffer newFloatBuffer(float[] values) {
+ return newFloatBuffer(values, 0);
+ }
+
+
+ /** Allocates a new direct IntBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static IntBuffer newIntBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_INT);
+ return bb.asIntBuffer();
+ }
+
+ public static IntBuffer newIntBuffer(int[] values, int offset, int len) {
+ IntBuffer bb = newIntBuffer(len);
+ bb.put(values, offset, len);
+ bb.rewind();
+ return bb;
+ }
+
+ public static IntBuffer newIntBuffer(int[] values, int offset) {
+ return newIntBuffer(values, 0, values.length-offset);
+ }
+
+ public static IntBuffer newIntBuffer(int[] values) {
+ return newIntBuffer(values, 0);
+ }
+
+ /** Allocates a new direct LongBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static LongBuffer newLongBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_LONG);
+ return bb.asLongBuffer();
+ }
+
+ /** Allocates a new direct ShortBuffer with the specified number of
+ elements. The returned buffer will have its byte order set to
+ the host platform's native byte order. */
+ public static ShortBuffer newShortBuffer(int numElements) {
+ ByteBuffer bb = newByteBuffer(numElements * SIZEOF_SHORT);
+ return bb.asShortBuffer();
+ }
+
+ public static ShortBuffer newShortBuffer(short[] values, int offset, int len) {
+ ShortBuffer bb = newShortBuffer(len);
+ bb.put(values, offset, len);
+ bb.rewind();
+ return bb;
+ }
+
+ public static ShortBuffer newShortBuffer(short[] values, int offset) {
+ return newShortBuffer(values, 0, values.length-offset);
+ }
+
+ public static ShortBuffer newShortBuffer(short[] values) {
+ return newShortBuffer(values, 0);
+ }
+
+ //----------------------------------------------------------------------
+ // Copy routines (type-to-type)
+ //
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ByteBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyByteBuffer(ByteBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining());
+ dest.put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed FloatBuffer
+ into a newly-allocated direct FloatBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static FloatBuffer copyFloatBuffer(FloatBuffer orig) {
+ return copyFloatBufferAsByteBuffer(orig).asFloatBuffer();
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed IntBuffer
+ into a newly-allocated direct IntBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static IntBuffer copyIntBuffer(IntBuffer orig) {
+ return copyIntBufferAsByteBuffer(orig).asIntBuffer();
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ShortBuffer
+ into a newly-allocated direct ShortBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ShortBuffer copyShortBuffer(ShortBuffer orig) {
+ return copyShortBufferAsByteBuffer(orig).asShortBuffer();
+ }
+
+ //----------------------------------------------------------------------
+ // Copy routines (type-to-ByteBuffer)
+ //
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed FloatBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyFloatBufferAsByteBuffer(FloatBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_FLOAT);
+ dest.asFloatBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed IntBuffer into
+ a newly-allocated direct ByteBuffer. The returned buffer will
+ have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyIntBufferAsByteBuffer(IntBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_INT);
+ dest.asIntBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ /** Copies the <i>remaining</i> elements (as defined by
+ <code>limit() - position()</code>) in the passed ShortBuffer
+ into a newly-allocated direct ByteBuffer. The returned buffer
+ will have its byte order set to the host platform's native byte
+ order. The position of the newly-allocated buffer will be zero,
+ and the position of the passed buffer is unchanged (though its
+ mark is changed). */
+ public static ByteBuffer copyShortBufferAsByteBuffer(ShortBuffer orig) {
+ ByteBuffer dest = newByteBuffer(orig.remaining() * SIZEOF_SHORT);
+ dest.asShortBuffer().put(orig);
+ dest.rewind();
+ return dest;
+ }
+
+ //----------------------------------------------------------------------
+ // Conversion routines
+ //
+
+ public final static float[] getFloatArray(double[] source) {
+ int i=source.length;
+ float[] dest = new float[i--];
+ while(i>=0) { dest[i]=(float)source[i]; i--; }
+ return dest;
+ }
+
+ public final static FloatBuffer getFloatBuffer(DoubleBuffer source) {
+ source.rewind();
+ FloatBuffer dest = BufferUtil.newFloatBuffer(source.limit());
+ while(source.hasRemaining()) { dest.put((float)source.get()); }
+ return dest;
+ }
+
+ public static ByteBuffer nativeOrder(ByteBuffer buf) {
+ if (!isCDCFP) {
+ try {
+ if (byteOrderClass == null) {
+ byteOrderClass = Class.forName("java.nio.ByteOrder");
+ orderMethod = ByteBuffer.class.getMethod("order", new Class[] { byteOrderClass });
+ Method nativeOrderMethod = byteOrderClass.getMethod("nativeOrder", null);
+ nativeOrderObject = nativeOrderMethod.invoke(null, null);
+ }
+ } catch (Throwable t) {
+ // Must be running on CDC / FP
+ isCDCFP = true;
+ }
+
+ if (!isCDCFP) {
+ try {
+ orderMethod.invoke(buf, new Object[] { nativeOrderObject });
+ } catch (Throwable t) {
+ }
+ }
+ }
+ return buf;
+ }
+
+ //----------------------------------------------------------------------
+ // Convenient GL put methods with generic target Buffer
+ //
+ public static void put(Buffer dest, Buffer v) {
+ Class dClazz = dest.getClass();
+ Class vClazz = v.getClass();
+ if(!NWReflection.instanceOf(vClazz, dClazz.getName())) {
+ throw new GLException("This array's dest class "+dClazz+" doesn't match the argument's Class: "+vClazz);
+ }
+ if(dest instanceof ByteBuffer) {
+ ((ByteBuffer)dest).put((ByteBuffer)v);
+ } else if(dest instanceof ShortBuffer) {
+ ((ShortBuffer)dest).put((ShortBuffer)v);
+ } else if(dest instanceof IntBuffer) {
+ ((IntBuffer)dest).put((IntBuffer)v);
+ } else if(dest instanceof FloatBuffer) {
+ ((FloatBuffer)dest).put((FloatBuffer)v);
+ }
+ }
+
+ public static void putb(Buffer dest, byte v) {
+ if(dest instanceof ByteBuffer) {
+ ((ByteBuffer)dest).put(v);
+ } else if(dest instanceof ShortBuffer) {
+ ((ShortBuffer)dest).put((short)v);
+ } else if(dest instanceof IntBuffer) {
+ ((IntBuffer)dest).put((int)v);
+ } else {
+ throw new GLException("Byte doesn't match Buffer Class: "+dest);
+ }
+ }
+
+ public static void puts(Buffer dest, short v) {
+ if(dest instanceof ShortBuffer) {
+ ((ShortBuffer)dest).put(v);
+ } else if(dest instanceof IntBuffer) {
+ ((IntBuffer)dest).put((int)v);
+ } else {
+ throw new GLException("Short doesn't match Buffer Class: "+dest);
+ }
+ }
+
+ public static void puti(Buffer dest, int v) {
+ if(dest instanceof IntBuffer) {
+ ((IntBuffer)dest).put(v);
+ } else {
+ throw new GLException("Integer doesn't match Buffer Class: "+dest);
+ }
+ }
+
+ public static void putx(Buffer dest, int v) {
+ puti(dest, v);
+ }
+
+ public static void putf(Buffer dest, float v) {
+ if(dest instanceof FloatBuffer) {
+ ((FloatBuffer)dest).put(v);
+ } else if(dest instanceof IntBuffer) {
+ ((IntBuffer)dest).put(FixedPoint.toFixed(v));
+ } else {
+ throw new GLException("Float doesn't match Buffer Class: "+dest);
+ }
+ }
+
+ public static void putd(Buffer dest, double v) {
+ if(dest instanceof FloatBuffer) {
+ ((FloatBuffer)dest).put((float)v);
+ } else {
+ throw new GLException("Double doesn't match Buffer Class: "+dest);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // NOTE that this work must be done reflectively at the present time
+ // because this code must compile and run correctly on both CDC/FP and J2SE
+ private static boolean isCDCFP;
+ private static Class byteOrderClass;
+ private static Object nativeOrderObject;
+ private static Method orderMethod;
+
+}
diff --git a/src/jogl/classes/javax/media/opengl/util/FixedPoint.java b/src/jogl/classes/javax/media/opengl/util/FixedPoint.java
new file mode 100644
index 000000000..35e2aaaf4
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/util/FixedPoint.java
@@ -0,0 +1,29 @@
+
+package javax.media.opengl.util;
+
+public class FixedPoint {
+ public static final int toFixed(int value) {
+ if (value < -32768) value = -32768;
+ if (value > 32767) value = 32767;
+ return value * 65536;
+ }
+
+ public static final int toFixed(float value) {
+ if (value < -32768) value = -32768;
+ if (value > 32767) value = 32767;
+ return (int)(value * 65536.0f);
+ }
+
+ public static final float toFloat(int value) {
+ return (float)value/65536.0f;
+ }
+
+ public static final int mult(int x1, int x2) {
+ return (int) ( ((long)x1*(long)x2)/65536 );
+ }
+
+ public static final int div(int x1, int x2) {
+ return (int) ( (((long)x1)<<16)/x2 );
+ }
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/util/Gamma.java b/src/jogl/classes/javax/media/opengl/util/Gamma.java
new file mode 100755
index 000000000..ba7bc5a32
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/util/Gamma.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package javax.media.opengl.util;
+
+import com.sun.opengl.impl.*;
+
+/** Provides control over the primary display's gamma, brightness and
+ contrast controls via the hardware gamma ramp tables. Not
+ supported on all platforms or graphics hardware. <P>
+
+ Thanks to the LWJGL project for illustrating how to access gamma
+ control on the various platforms.
+*/
+
+public class Gamma {
+ private Gamma() {}
+
+ /**
+ * Sets the gamma, brightness, and contrast of the current main
+ * display. This functionality is not available on all platforms and
+ * graphics hardware. Returns true if the settings were successfully
+ * changed, false if not. This method may return false for some
+ * values of the incoming arguments even on hardware which does
+ * support the underlying functionality. <P>
+ *
+ * If this method returns true, the display settings will
+ * automatically be reset to their original values upon JVM exit
+ * (assuming the JVM does not crash); if the user wishes to change
+ * the display settings back to normal ahead of time, use {@link
+ * #resetDisplayGamma resetDisplayGamma}(). It is recommended to
+ * call {@link #resetDisplayGamma resetDisplayGamma} before calling
+ * e.g. <code>System.exit()</code> from the application rather than
+ * rely on the shutdown hook functionality due to inevitable race
+ * conditions and unspecified behavior during JVM teardown. <P>
+ *
+ * This method may be called multiple times during the application's
+ * execution, but calling {@link #resetDisplayGamma
+ * resetDisplayGamma} will only reset the settings to the values
+ * before the first call to this method. <P>
+ *
+ * @param gamma The gamma value, typically > 1.0 (default values
+ * vary, but typically roughly 1.0)
+ * @param brightness The brightness value between -1.0 and 1.0,
+ * inclusive (default values vary, but typically 0)
+ * @param contrast The contrast, greater than 0.0 (default values
+ * vary, but typically 1)
+ * @return true if gamma settings were successfully changed, false
+ * if not
+ * @throws IllegalArgumentException if any of the parameters were
+ * out-of-bounds
+ */
+ public static boolean setDisplayGamma(float gamma, float brightness, float contrast) throws IllegalArgumentException {
+ return GLDrawableFactoryImpl.getFactoryImpl().setDisplayGamma(gamma, brightness, contrast);
+ }
+
+ /**
+ * Resets the gamma, brightness and contrast values for the primary
+ * display to their original values before {@link #setDisplayGamma
+ * setDisplayGamma} was called the first time. {@link
+ * #setDisplayGamma setDisplayGamma} must be called before calling
+ * this method or an unspecified exception will be thrown. While it
+ * is not explicitly required that this method be called before
+ * exiting, calling it is recommended because of the inevitable
+ * unspecified behavior during JVM teardown.
+ */
+ public static void resetDisplayGamma() {
+ GLDrawableFactoryImpl.getFactoryImpl().resetDisplayGamma();
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/util/PMVMatrix.java b/src/jogl/classes/javax/media/opengl/util/PMVMatrix.java
new file mode 100755
index 000000000..4598993f1
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/util/PMVMatrix.java
@@ -0,0 +1,656 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package javax.media.opengl.util;
+
+import com.sun.opengl.impl.ProjectFloat;
+
+import java.nio.*;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.media.opengl.*;
+import javax.media.opengl.sub.fixed.GLMatrixIf;
+
+public class PMVMatrix implements GLMatrixIf {
+
+ public PMVMatrix() {
+ projectFloat = new ProjectFloat();
+
+ matrixIdent = BufferUtil.newFloatBuffer(1*16);
+ projectFloat.gluMakeIdentityf(matrixIdent);
+ matrixIdent.rewind();
+
+ // T Texture
+ // P Projection
+ // Mv ModelView
+ // Mvi Modelview-Inverse
+ // Mvit Modelview-Inverse-Transpose
+ // Pmv P * Mv
+ matrixTPMvMvitPmv = BufferUtil.newFloatBuffer(6*16); // grouping T + P + Mv + Mvi + Mvit + Pmv
+ matrixPMvMvitPmv = slice(matrixTPMvMvitPmv, 1*16, 5*16); // grouping P + Mv + Mvi + Mvit + Pmv
+ matrixT = slice(matrixTPMvMvitPmv, 0*16, 1*16); // T
+ matrixPMvMvit = slice(matrixTPMvMvitPmv, 1*16, 4*16); // grouping P + Mv + Mvi + Mvit
+ matrixPMvMvi = slice(matrixTPMvMvitPmv, 1*16, 3*16); // grouping P + Mv + Mvi
+ matrixPMv = slice(matrixTPMvMvitPmv, 1*16, 2*16); // grouping P + Mv
+ matrixP = slice(matrixTPMvMvitPmv, 1*16, 1*16); // P
+ matrixMv = slice(matrixTPMvMvitPmv, 2*16, 1*16); // Mv
+ matrixMvi = slice(matrixTPMvMvitPmv, 3*16, 1*16); // Mvi
+ matrixMvit = slice(matrixTPMvMvitPmv, 4*16, 1*16); // Mvit
+ matrixPmv = slice(matrixTPMvMvitPmv, 5*16, 1*16); // Pmv
+ matrixTPMvMvitPmv.rewind();
+
+ matrixMvit3 = BufferUtil.newFloatBuffer(3*3);
+
+ localBuf = BufferUtil.newFloatBuffer(6*16);
+
+ matrixMult=slice(localBuf, 0*16, 16);
+
+ matrixTrans=slice(localBuf, 1*16, 16);
+ projectFloat.gluMakeIdentityf(matrixTrans);
+
+ matrixRot=slice(localBuf, 2*16, 16);
+ projectFloat.gluMakeIdentityf(matrixRot);
+
+ matrixScale=slice(localBuf, 3*16, 16);
+ projectFloat.gluMakeIdentityf(matrixScale);
+
+ matrixOrtho=slice(localBuf, 4*16, 16);
+ projectFloat.gluMakeIdentityf(matrixOrtho);
+
+ matrixFrustum=slice(localBuf, 5*16, 16);
+ projectFloat.gluMakeZero(matrixFrustum);
+
+ vec3f=new float[3];
+
+ matrixPStack = new ArrayList();
+ matrixMvStack= new ArrayList();
+
+ // default values and mode
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glMatrixMode(GL.GL_TEXTURE);
+ glLoadIdentity();
+ setDirty();
+ }
+
+ public void destroy() {
+ if(null!=projectFloat) {
+ projectFloat.destroy(); projectFloat=null;
+ }
+
+ if(null!=matrixIdent) {
+ matrixIdent.clear(); matrixIdent=null;
+ }
+ if(null!=matrixTPMvMvitPmv) {
+ matrixTPMvMvitPmv.clear(); matrixTPMvMvitPmv=null;
+ }
+ if(null!=matrixMvit3) {
+ matrixMvit3.clear(); matrixMvit3=null;
+ }
+ if(null!=localBuf) {
+ localBuf.clear(); localBuf=null;
+ }
+
+ if(null!=matrixPStack) {
+ matrixPStack.clear(); matrixPStack=null;
+ }
+ vec3f=null;
+ if(null!=matrixMvStack) {
+ matrixMvStack.clear(); matrixMvStack=null;
+ }
+ if(null!=matrixPStack) {
+ matrixPStack.clear(); matrixPStack=null;
+ }
+ if(null!=matrixTStack) {
+ matrixTStack.clear(); matrixTStack=null;
+ }
+
+ matrixTPMvMvitPmv=null; matrixPMvMvit=null; matrixPMvMvitPmv=null; matrixPMvMvi=null; matrixPMv=null;
+ matrixP=null; matrixT=null; matrixMv=null; matrixMvi=null; matrixMvit=null; matrixPmv=null;
+ matrixMult=null; matrixTrans=null; matrixRot=null; matrixScale=null; matrixOrtho=null; matrixFrustum=null;
+ }
+
+ private static FloatBuffer slice(FloatBuffer buf, int pos, int len) {
+ buf.position(pos);
+ buf.limit(pos + len);
+ return buf.slice();
+ }
+
+ public static final boolean isMatrixModeName(final int matrixModeName) {
+ switch(matrixModeName) {
+ case GL_MODELVIEW_MATRIX:
+ case GL_PROJECTION_MATRIX:
+ case GL_TEXTURE_MATRIX:
+ return true;
+ }
+ return false;
+ }
+
+ public static final int matrixModeName2MatrixGetName(final int matrixModeName) {
+ switch(matrixModeName) {
+ case GL_MODELVIEW:
+ return GL_MODELVIEW_MATRIX;
+ case GL_PROJECTION:
+ return GL_PROJECTION_MATRIX;
+ case GL.GL_TEXTURE:
+ return GL_TEXTURE_MATRIX;
+ default:
+ throw new GLException("unsupported matrixName: "+matrixModeName);
+ }
+ }
+
+ public static final boolean isMatrixGetName(final int matrixGetName) {
+ switch(matrixGetName) {
+ case GL_MATRIX_MODE:
+ case GL_MODELVIEW_MATRIX:
+ case GL_PROJECTION_MATRIX:
+ case GL_TEXTURE_MATRIX:
+ return true;
+ }
+ return false;
+ }
+
+ public static final int matrixGetName2MatrixModeName(final int matrixGetName) {
+ switch(matrixGetName) {
+ case GL_MODELVIEW_MATRIX:
+ return GL_MODELVIEW;
+ case GL_PROJECTION_MATRIX:
+ return GL_PROJECTION;
+ case GL_TEXTURE_MATRIX:
+ return GL.GL_TEXTURE;
+ default:
+ throw new GLException("unsupported matrixGetName: "+matrixGetName);
+ }
+ }
+
+ public void setDirty() {
+ modified = DIRTY_MODELVIEW | DIRTY_PROJECTION | DIRTY_TEXTURE ;
+ matrixMode = GL_MODELVIEW;
+ }
+
+ public int getDirtyBits() {
+ return modified;
+ }
+
+ public boolean isDirty(final int matrixName) {
+ boolean res;
+ switch(matrixName) {
+ case GL_MODELVIEW:
+ res = (modified&DIRTY_MODELVIEW)!=0 ;
+ break;
+ case GL_PROJECTION:
+ res = (modified&DIRTY_PROJECTION)!=0 ;
+ break;
+ case GL.GL_TEXTURE:
+ res = (modified&DIRTY_TEXTURE)!=0 ;
+ break;
+ default:
+ throw new GLException("unsupported matrixName: "+matrixName);
+ }
+ return res;
+ }
+
+ public boolean isDirty() {
+ return modified!=0;
+ }
+
+ public boolean update() {
+ // if(0==modified) return false;
+
+ // int res = modified;
+ int res = DIRTY_MODELVIEW | DIRTY_PROJECTION ;
+ if( (res&DIRTY_MODELVIEW)!=0 ) {
+ setMviMvit();
+ }
+ if( (res&DIRTY_MODELVIEW)!=0 || (res&DIRTY_PROJECTION)!=0 ) {
+ glMultMatrixf(matrixP, matrixMv, matrixPmv);
+ }
+ modified=0;
+ return res!=0;
+ }
+
+ public final int glGetMatrixMode() {
+ return matrixMode;
+ }
+
+ public final FloatBuffer glGetTMatrixf() {
+ return matrixT;
+ }
+
+ public final FloatBuffer glGetPMatrixf() {
+ return matrixP;
+ }
+
+ public final FloatBuffer glGetMvMatrixf() {
+ return matrixMv;
+ }
+
+ public final FloatBuffer glGetPMvMvitPmvMatrixf() {
+ return matrixPMvMvitPmv;
+ }
+
+ public final FloatBuffer glGetPMvMvitMatrixf() {
+ return matrixPMvMvit;
+ }
+
+ public final FloatBuffer glGetPMvMviMatrixf() {
+ return matrixPMvMvi;
+ }
+
+ public final FloatBuffer glGetPMvMatrixf() {
+ return matrixPMv;
+ }
+
+ public final FloatBuffer glGetMviMatrixf() {
+ return matrixMvi;
+ }
+
+ public final FloatBuffer glGetPmvMatrixf() {
+ return matrixPmv;
+ }
+
+ public final FloatBuffer glGetNormalMatrixf() {
+ return matrixMvit3;
+ }
+
+ /*
+ * @return the current matrix
+ */
+ public final FloatBuffer glGetMatrixf() {
+ return glGetMatrixf(matrixMode);
+ }
+
+ /**
+ * @param pname GL_MODELVIEW, GL_PROJECTION or GL.GL_TEXTURE
+ * @return the given matrix
+ */
+ public final FloatBuffer glGetMatrixf(final int matrixName) {
+ if(matrixName==GL_MODELVIEW) {
+ return matrixMv;
+ } else if(matrixName==GL_PROJECTION) {
+ return matrixP;
+ } else if(matrixName==GL.GL_TEXTURE) {
+ return matrixT;
+ } else {
+ throw new GLException("unsupported matrixName: "+matrixName);
+ }
+ }
+
+ public final void gluPerspective(final float fovy, final float aspect, final float zNear, final float zFar) {
+ float top=(float)Math.tan(fovy*((float)Math.PI)/360.0f)*zNear;
+ float bottom=-1.0f*top;
+ float left=aspect*bottom;
+ float right=aspect*top;
+ glFrustumf(left, right, bottom, top, zNear, zFar);
+ }
+
+ public static final void glMultMatrixf(final FloatBuffer a, final FloatBuffer b, FloatBuffer p) {
+ for (int i = 0; i < 4; i++) {
+ final float ai0=a.get(i+0*4), ai1=a.get(i+1*4), ai2=a.get(i+2*4), ai3=a.get(i+3*4);
+ p.put(i+0*4 , ai0 * b.get(0+0*4) + ai1 * b.get(1+0*4) + ai2 * b.get(2+0*4) + ai3 * b.get(3+0*4) );
+ p.put(i+1*4 , ai0 * b.get(0+1*4) + ai1 * b.get(1+1*4) + ai2 * b.get(2+1*4) + ai3 * b.get(3+1*4) );
+ p.put(i+2*4 , ai0 * b.get(0+2*4) + ai1 * b.get(1+2*4) + ai2 * b.get(2+2*4) + ai3 * b.get(3+2*4) );
+ p.put(i+3*4 , ai0 * b.get(0+3*4) + ai1 * b.get(1+3*4) + ai2 * b.get(2+3*4) + ai3 * b.get(3+3*4) );
+ }
+ }
+ public static final void glMultMatrixf(final FloatBuffer a, final float[] b, int b_off, FloatBuffer p) {
+ for (int i = 0; i < 4; i++) {
+ final float ai0=a.get(i+0*4), ai1=a.get(i+1*4), ai2=a.get(i+2*4), ai3=a.get(i+3*4);
+ p.put(i+0*4 , ai0 * b[b_off+0+0*4] + ai1 * b[b_off+1+0*4] + ai2 * b[b_off+2+0*4] + ai3 * b[b_off+3+0*4] );
+ p.put(i+1*4 , ai0 * b[b_off+0+1*4] + ai1 * b[b_off+1+1*4] + ai2 * b[b_off+2+1*4] + ai3 * b[b_off+3+1*4] );
+ p.put(i+2*4 , ai0 * b[b_off+0+2*4] + ai1 * b[b_off+1+2*4] + ai2 * b[b_off+2+2*4] + ai3 * b[b_off+3+2*4] );
+ p.put(i+3*4 , ai0 * b[b_off+0+3*4] + ai1 * b[b_off+1+3*4] + ai2 * b[b_off+2+3*4] + ai3 * b[b_off+3+3*4] );
+ }
+ }
+
+ //
+ // MatrixIf
+ //
+
+ public void glMatrixMode(final int matrixName) {
+ switch(matrixName) {
+ case GL_MODELVIEW:
+ case GL_PROJECTION:
+ case GL.GL_TEXTURE:
+ break;
+ default:
+ throw new GLException("unsupported matrixName: "+matrixName);
+ }
+ matrixMode = matrixName;
+ }
+
+ public void glGetFloatv(int matrixGetName, FloatBuffer params) {
+ int pos = params.position();
+ if(matrixGetName==GL_MATRIX_MODE) {
+ params.put((float)matrixMode);
+ } else {
+ FloatBuffer matrix = glGetMatrixf(matrixGetName2MatrixModeName(matrixGetName));
+ params.put(matrix);
+ matrix.rewind();
+ }
+ params.position(pos);
+ }
+ public void glGetFloatv(int matrixGetName, float[] params, int params_offset) {
+ if(matrixGetName==GL_MATRIX_MODE) {
+ params[params_offset]=(float)matrixMode;
+ } else {
+ FloatBuffer matrix = glGetMatrixf(matrixGetName2MatrixModeName(matrixGetName));
+ matrix.get(params, params_offset, 16);
+ matrix.rewind();
+ }
+ }
+ public void glGetIntegerv(int pname, IntBuffer params) {
+ int pos = params.position();
+ if(pname==GL_MATRIX_MODE) {
+ params.put(matrixMode);
+ } else {
+ throw new GLException("unsupported pname: "+pname);
+ }
+ params.position(pos);
+ }
+ public void glGetIntegerv(int pname, int[] params, int params_offset) {
+ if(pname==GL_MATRIX_MODE) {
+ params[params_offset]=matrixMode;
+ } else {
+ throw new GLException("unsupported pname: "+pname);
+ }
+ }
+
+ public final void glLoadMatrixf(final float[] values, final int offset) {
+ int len = values.length-offset;
+ if(matrixMode==GL_MODELVIEW) {
+ matrixMv.clear();
+ matrixMv.put(values, offset, len);
+ matrixMv.rewind();
+ modified |= DIRTY_MODELVIEW ;
+ } else if(matrixMode==GL_PROJECTION) {
+ matrixP.clear();
+ matrixP.put(values, offset, len);
+ matrixP.rewind();
+ modified |= DIRTY_PROJECTION ;
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ matrixT.clear();
+ matrixT.put(values, offset, len);
+ matrixT.rewind();
+ modified |= DIRTY_TEXTURE ;
+ }
+ }
+
+ public final void glLoadMatrixf(java.nio.FloatBuffer m) {
+ int spos = m.position();
+ if(matrixMode==GL_MODELVIEW) {
+ matrixMv.clear();
+ matrixMv.put(m);
+ matrixMv.rewind();
+ modified |= DIRTY_MODELVIEW ;
+ } else if(matrixMode==GL_PROJECTION) {
+ matrixP.clear();
+ matrixP.put(m);
+ matrixP.rewind();
+ modified |= DIRTY_PROJECTION ;
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ matrixT.clear();
+ matrixT.put(m);
+ matrixT.rewind();
+ modified |= DIRTY_TEXTURE ;
+ }
+ m.position(spos);
+ }
+
+ public final void glPopMatrix() {
+ float[] stackEntry=null;
+ if(matrixMode==GL_MODELVIEW) {
+ stackEntry = (float[])matrixMvStack.remove(0);
+ } else if(matrixMode==GL_PROJECTION) {
+ stackEntry = (float[])matrixPStack.remove(0);
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ stackEntry = (float[])matrixTStack.remove(0);
+ }
+ glLoadMatrixf(stackEntry, 0);
+ }
+
+ public final void glPushMatrix() {
+ float[] stackEntry = new float[1*16];
+ if(matrixMode==GL_MODELVIEW) {
+ matrixMv.get(stackEntry);
+ matrixMv.rewind();
+ matrixMvStack.add(0, stackEntry);
+ } else if(matrixMode==GL_PROJECTION) {
+ matrixP.get(stackEntry);
+ matrixP.rewind();
+ matrixPStack.add(0, stackEntry);
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ matrixT.get(stackEntry);
+ matrixT.rewind();
+ matrixTStack.add(0, stackEntry);
+ }
+ }
+
+ public final void glLoadIdentity() {
+ if(matrixMode==GL_MODELVIEW) {
+ matrixMv.clear();
+ matrixMv.put(matrixIdent);
+ matrixMv.rewind();
+ matrixIdent.rewind();
+ modified |= DIRTY_MODELVIEW ;
+ } else if(matrixMode==GL_PROJECTION) {
+ matrixP.clear();
+ matrixP.put(matrixIdent);
+ matrixP.rewind();
+ matrixIdent.rewind();
+ modified |= DIRTY_PROJECTION ;
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ matrixT.clear();
+ matrixT.put(matrixIdent);
+ matrixT.rewind();
+ matrixIdent.rewind();
+ modified |= DIRTY_TEXTURE ;
+ }
+ }
+
+ public final void glMultMatrixf(final FloatBuffer m) {
+ if(matrixMode==GL_MODELVIEW) {
+ glMultMatrixf(matrixMv, m, matrixMult);
+ matrixMv.clear();
+ matrixMv.put(matrixMult);
+ matrixMv.rewind();
+ modified |= DIRTY_MODELVIEW ;
+ } else if(matrixMode==GL_PROJECTION) {
+ glMultMatrixf(matrixP, m, matrixMult);
+ matrixP.clear();
+ matrixP.put(matrixMult);
+ matrixP.rewind();
+ modified |= DIRTY_PROJECTION ;
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ glMultMatrixf(matrixT, m, matrixMult);
+ matrixT.clear();
+ matrixT.put(matrixMult);
+ matrixT.rewind();
+ modified |= DIRTY_TEXTURE ;
+ }
+ matrixMult.rewind();
+ }
+
+ public void glMultMatrixf(float[] m, int m_offset) {
+ if(matrixMode==GL_MODELVIEW) {
+ glMultMatrixf(matrixMv, m, m_offset, matrixMult);
+ matrixMv.clear();
+ matrixMv.put(matrixMult);
+ matrixMv.rewind();
+ modified |= DIRTY_MODELVIEW ;
+ } else if(matrixMode==GL_PROJECTION) {
+ glMultMatrixf(matrixP, m, m_offset, matrixMult);
+ matrixP.clear();
+ matrixP.put(matrixMult);
+ matrixP.rewind();
+ modified |= DIRTY_PROJECTION ;
+ } else if(matrixMode==GL.GL_TEXTURE) {
+ glMultMatrixf(matrixT, m, m_offset, matrixMult);
+ matrixT.clear();
+ matrixT.put(matrixMult);
+ matrixT.rewind();
+ modified |= DIRTY_TEXTURE ;
+ }
+ matrixMult.rewind();
+ }
+
+ public final void glTranslatef(final float x, final float y, final float z) {
+ // Translation matrix:
+ // 1 0 0 x
+ // 0 1 0 y
+ // 0 0 1 z
+ // 0 0 0 1
+ matrixTrans.put(0+4*3, x);
+ matrixTrans.put(1+4*3, y);
+ matrixTrans.put(2+4*3, z);
+ glMultMatrixf(matrixTrans);
+ }
+
+ public final void glRotatef(final float angdeg, float x, float y, float z) {
+ float angrad = angdeg * (float) Math.PI / 180;
+ float c = (float)Math.cos(angrad);
+ float ic= 1.0f - c;
+ float s = (float)Math.sin(angrad);
+
+ vec3f[0]=x; vec3f[1]=y; vec3f[2]=z;
+ projectFloat.normalize(vec3f);
+ x = vec3f[0]; y = vec3f[1]; z = vec3f[2];
+
+ // Rotation matrix:
+ // xx(1−c)+c xy(1−c)+zs xz(1−c)-ys 0
+ // xy(1−c)-zs yy(1−c)+c yz(1−c)+xs 0
+ // xz(1−c)+ys yz(1−c)-xs zz(1−c)+c 0
+ // 0 0 0 1
+ float xy = x*y;
+ float xz = x*z;
+ float xs = x*s;
+ float ys = y*s;
+ float yz = y*z;
+ float zs = z*s;
+ matrixRot.put(0*4+0, x*x*ic+c);
+ matrixRot.put(0*4+1, xy*ic+zs);
+ matrixRot.put(0*4+2, xz*ic-ys);
+
+ matrixRot.put(1*4+0, xy*ic-zs);
+ matrixRot.put(1*4+1, y*y*ic+c);
+ matrixRot.put(1*4+2, yz*ic+xs);
+
+ matrixRot.put(2*4+0, xz*ic+ys);
+ matrixRot.put(2*4+1, yz*ic-xs);
+ matrixRot.put(2*4+2, z*z*ic+c);
+
+ glMultMatrixf(matrixRot);
+ }
+
+ public final void glScalef(final float x, final float y, final float z) {
+ // Scale matrix:
+ // x 0 0 0
+ // 0 y 0 0
+ // 0 0 z 0
+ // 0 0 0 1
+ matrixScale.put(0+4*0, x);
+ matrixScale.put(1+4*1, y);
+ matrixScale.put(2+4*2, z);
+
+ glMultMatrixf(matrixScale);
+ }
+
+ public final void glOrthof(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) {
+ // Ortho matrix:
+ // 2/dx 0 0 tx
+ // 0 2/dy 0 ty
+ // 0 0 2/dz tz
+ // 0 0 0 1
+ float dx=right-left;
+ float dy=top-bottom;
+ float dz=zFar-zNear;
+ float tx=-1.0f*(right+left)/dx;
+ float ty=-1.0f*(top+bottom)/dy;
+ float tz=-1.0f*(zFar+zNear)/dz;
+
+ matrixOrtho.put(0+4*0, 2.0f/dx);
+ matrixOrtho.put(1+4*1, 2.0f/dy);
+ matrixOrtho.put(2+4*2, -2.0f/dz);
+ matrixOrtho.put(0+4*3, tx);
+ matrixOrtho.put(1+4*3, ty);
+ matrixOrtho.put(2+4*3, tz);
+
+ glMultMatrixf(matrixOrtho);
+ }
+
+ public final void glFrustumf(final float left, final float right, final float bottom, final float top, final float zNear, final float zFar) {
+ if(zNear<=0.0f||zFar<0.0f) {
+ throw new GLException("GL_INVALID_VALUE: zNear and zFar must be positive, and zNear>0");
+ }
+ if(left==right || top==bottom) {
+ throw new GLException("GL_INVALID_VALUE: top,bottom and left,right must not be equal");
+ }
+ // Frustum matrix:
+ // 2*zNear/dx 0 A 0
+ // 0 2*zNear/dy B 0
+ // 0 0 C D
+ // 0 0 −1 0
+ float zNear2 = 2.0f*zNear;
+ float dx=right-left;
+ float dy=top-bottom;
+ float dz=zFar-zNear;
+ float A=(right+left)/dx;
+ float B=(top+bottom)/dy;
+ float C=-1.0f*(zFar+zNear)/dz;
+ float D=-2.0f*(zFar*zNear)/dz;
+
+ matrixFrustum.put(0+4*0, zNear2/dx);
+ matrixFrustum.put(1+4*1, zNear2/dy);
+ matrixFrustum.put(2+4*2, C);
+
+ matrixFrustum.put(0+4*2, A);
+ matrixFrustum.put(1+4*2, B);
+
+ matrixFrustum.put(2+4*3, D);
+ matrixFrustum.put(3+4*2, -1.0f);
+
+ glMultMatrixf(matrixFrustum);
+ }
+
+ //
+ // private
+ //
+
+ private final void setMviMvit() {
+ if(!projectFloat.gluInvertMatrixf(matrixMv, matrixMvi)) {
+ throw new GLException("Invalid source Mv matrix, can't compute inverse");
+ }
+
+ // transpose matrix
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ matrixMvit.put(j+i*4, matrixMvi.get(i+j*4));
+ }
+ }
+
+ // fetch 3x3
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++) {
+ matrixMvit3.put(i+j*3, matrixMvit.get(i+j*4));
+ }
+ }
+ }
+
+ protected FloatBuffer matrixIdent;
+ protected FloatBuffer matrixTPMvMvitPmv, matrixPMvMvit, matrixPMvMvitPmv, matrixPMvMvi, matrixPMv, matrixP, matrixT, matrixMv, matrixMvi, matrixMvit, matrixPmv;
+ protected FloatBuffer matrixMvit3;
+ protected FloatBuffer localBuf, matrixMult, matrixTrans, matrixRot, matrixScale, matrixOrtho, matrixFrustum;
+ protected float[] vec3f;
+ protected List/*FloatBuffer*/ matrixTStack, matrixPStack, matrixMvStack;
+ protected int matrixMode = GL_MODELVIEW;
+ protected int modified = 0;
+ protected ProjectFloat projectFloat;
+
+ public static final int DIRTY_MODELVIEW = 1 << 0;
+ public static final int DIRTY_PROJECTION = 1 << 1;
+ public static final int DIRTY_TEXTURE = 1 << 2;
+}