summaryrefslogtreecommitdiffstats
path: root/src/net/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/java')
-rw-r--r--src/net/java/games/gluegen/CMethodBindingEmitter.java6
-rw-r--r--src/net/java/games/gluegen/GlueGen.java3
-rw-r--r--src/net/java/games/gluegen/StructLayout.java1
-rw-r--r--src/net/java/games/gluegen/cgram/types/CompoundType.java7
-rw-r--r--src/net/java/games/jogl/GLJPanel.java44
-rw-r--r--src/net/java/games/jogl/Version.java2
-rw-r--r--src/net/java/games/jogl/impl/GLContext.java7
-rwxr-xr-xsrc/net/java/games/jogl/impl/SingleThreadedWorkaround.java11
-rw-r--r--src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java7
-rw-r--r--src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java27
-rw-r--r--src/net/java/games/jogl/impl/tesselator/Sweep.java2
-rw-r--r--src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java7
-rw-r--r--src/net/java/games/jogl/util/GLUT.java344
13 files changed, 409 insertions, 59 deletions
diff --git a/src/net/java/games/gluegen/CMethodBindingEmitter.java b/src/net/java/games/gluegen/CMethodBindingEmitter.java
index b9cc0091e..8abcdcd78 100644
--- a/src/net/java/games/gluegen/CMethodBindingEmitter.java
+++ b/src/net/java/games/gluegen/CMethodBindingEmitter.java
@@ -609,7 +609,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
writer.print(" ");
emitGetStringUTFChars(writer,
"(jstring) _tmpObj",
- "(const char*)"+convName+"_copy[_copyIndex]");
+ convName+"_copy[_copyIndex]");
}
else if (isNIOBufferClass(subArrayElementJavaType))
{
@@ -781,7 +781,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
}
// free the main array
- writer.print(" free(");
+ writer.print(" free((void*) ");
writer.print(convName+"_copy");
writer.println(");");
} // end of cleaning up copied data
@@ -1251,7 +1251,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
Class elementType = javaType.getJavaClass().getComponentType();
if (javaType.isArray() &&
javaType.getJavaClass().getComponentType() == java.lang.String.class) {
- writer.print(" char **");
+ writer.print(" const char **");
} else {
writer.print(ptrTypeString);
}
diff --git a/src/net/java/games/gluegen/GlueGen.java b/src/net/java/games/gluegen/GlueGen.java
index 6c343a5ee..1197741cb 100644
--- a/src/net/java/games/gluegen/GlueGen.java
+++ b/src/net/java/games/gluegen/GlueGen.java
@@ -144,7 +144,8 @@ public class GlueGen implements GlueEmitterControls {
MachineDescription machDesc;
String os = System.getProperty("os.name").toLowerCase();
String cpu = System.getProperty("os.arch").toLowerCase();
- if (os.startsWith("linux") && cpu.equals("amd64")) {
+ if ((os.startsWith("linux") && cpu.equals("amd64")) ||
+ (os.startsWith("linux") && cpu.equals("ia64"))) {
machDesc = new MachineDescription64Bit();
} else {
machDesc = new MachineDescription32Bit();
diff --git a/src/net/java/games/gluegen/StructLayout.java b/src/net/java/games/gluegen/StructLayout.java
index ebbace6b5..df612c3b5 100644
--- a/src/net/java/games/gluegen/StructLayout.java
+++ b/src/net/java/games/gluegen/StructLayout.java
@@ -124,6 +124,7 @@ public class StructLayout {
if ((os.startsWith("windows") && cpu.equals("x86")) ||
(os.startsWith("linux") && cpu.equals("i386")) ||
(os.startsWith("linux") && cpu.equals("amd64")) ||
+ (os.startsWith("linux") && cpu.equals("ia64")) ||
(os.startsWith("sunos") && cpu.equals("sparc")) ||
(os.startsWith("sunos") && cpu.equals("x86")) ||
(os.startsWith("mac os") && cpu.equals("ppc")) ||
diff --git a/src/net/java/games/gluegen/cgram/types/CompoundType.java b/src/net/java/games/gluegen/cgram/types/CompoundType.java
index d86fa9148..e57400e33 100644
--- a/src/net/java/games/gluegen/cgram/types/CompoundType.java
+++ b/src/net/java/games/gluegen/cgram/types/CompoundType.java
@@ -76,7 +76,7 @@ public class CompoundType extends Type {
} else if (getName() != null) {
hashcode = getName().hashCode();
} else {
- hashcode = System.identityHashCode(this);
+ hashcode = 0;
}
computedHashcode = true;
@@ -90,8 +90,9 @@ public class CompoundType extends Type {
}
CompoundType t = (CompoundType) arg;
return (super.equals(arg) &&
- kind == t.kind &&
- listsEqual(fields, t.fields));
+ (structName == t.structName || (structName != null && structName.equals(t.structName))) &&
+ kind == t.kind &&
+ listsEqual(fields, t.fields));
}
/** Returns the struct name of this CompoundType, i.e. the "foo" in
diff --git a/src/net/java/games/jogl/GLJPanel.java b/src/net/java/games/jogl/GLJPanel.java
index 425160494..229cc3446 100644
--- a/src/net/java/games/jogl/GLJPanel.java
+++ b/src/net/java/games/jogl/GLJPanel.java
@@ -78,7 +78,6 @@ public final class GLJPanel extends JPanel implements GLDrawable {
private int neededOffscreenImageHeight;
private DataBufferByte dbByte;
private DataBufferInt dbInt;
- private Object semaphore = new Object();
private int panelWidth = 0;
private int panelHeight = 0;
private Updater updater;
@@ -127,26 +126,9 @@ public final class GLJPanel extends JPanel implements GLDrawable {
// Multithreaded redrawing of Swing components is not allowed,
// so do everything on the event dispatch thread
try {
- // Wait a reasonable period of time for the repaint to
- // complete, so that we don't swamp the AWT event queue thread
- // with repaint requests. We used to have an explicit flag to
- // detect when the repaint completed; unfortunately, under
- // some circumstances, the top-level window can be torn down
- // while we're waiting for the repaint to complete, which will
- // never happen. It doesn't look like there's enough
- // information in the EventQueue to figure out whether there
- // are pending events without posting to the queue, which we
- // don't want to do during shutdown, and adding a
- // HierarchyListener and watching for displayability events
- // might be fragile since we don't know exactly how this
- // component will be used in users' applications. For these
- // reasons we simply wait up to a brief period of time for the
- // repaint to complete.
- synchronized(semaphore) {
- repaint();
- semaphore.wait(100);
- }
- } catch (InterruptedException e) {
+ EventQueue.invokeAndWait(paintImmediatelyAction);
+ } catch (Exception e) {
+ throw new GLException(e);
}
}
}
@@ -177,9 +159,6 @@ public final class GLJPanel extends JPanel implements GLDrawable {
} else {
offscreenContext.invokeGL(displayAction, false, initAction);
}
- synchronized(semaphore) {
- semaphore.notifyAll();
- }
}
/** Overridden from Canvas; causes {@link GLDrawableHelper#reshape}
@@ -475,11 +454,7 @@ public final class GLJPanel extends JPanel implements GLDrawable {
// Should be more flexible in these BufferedImage formats;
// perhaps see what the preferred image types are on the
// given platform
- if (offscreenCaps.getAlphaBits() > 0) {
- awtFormat = BufferedImage.TYPE_INT_ARGB;
- } else {
- awtFormat = BufferedImage.TYPE_INT_RGB;
- }
+ awtFormat = BufferedImage.TYPE_INT_RGB;
// This seems to be a good choice on all platforms
hwGLFormat = GL.GL_UNSIGNED_INT_8_8_8_8_REV;
@@ -552,10 +527,10 @@ public final class GLJPanel extends JPanel implements GLDrawable {
// Should figure out if we need to set the image scaling
// preference to FAST since it doesn't require subsampling
// of pixels -- FIXME
- for (int i = 0; i < panelHeight - 1; i++) {
+ for (int i = 0; i < panelHeight; i++) {
g.drawImage(offscreenImage,
0, i, panelWidth, i+1,
- 0, panelHeight - i - 2, panelWidth, panelHeight - i - 1,
+ 0, panelHeight - i - 1, panelWidth, panelHeight - i,
GLJPanel.this);
}
} else {
@@ -594,6 +569,13 @@ public final class GLJPanel extends JPanel implements GLDrawable {
}
private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
+ class PaintImmediatelyAction implements Runnable {
+ public void run() {
+ paintImmediately(0, 0, getWidth(), getHeight());
+ }
+ }
+ private PaintImmediatelyAction paintImmediatelyAction = new PaintImmediatelyAction();
+
private int getNextPowerOf2(int number) {
if (((number-1) & number) == 0) {
//ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
diff --git a/src/net/java/games/jogl/Version.java b/src/net/java/games/jogl/Version.java
index a5e7f43eb..0d64614e2 100644
--- a/src/net/java/games/jogl/Version.java
+++ b/src/net/java/games/jogl/Version.java
@@ -89,7 +89,7 @@ public final class Version {
/**
* Version string of this build.
*/
- private static final String version = "1.1.0-b10";
+ private static final String version = "1.1.0-b11";
/**
* Returns the verison string and build number of
diff --git a/src/net/java/games/jogl/impl/GLContext.java b/src/net/java/games/jogl/impl/GLContext.java
index 17667fbce..318ff24a2 100644
--- a/src/net/java/games/jogl/impl/GLContext.java
+++ b/src/net/java/games/jogl/impl/GLContext.java
@@ -552,6 +552,13 @@ public abstract class GLContext {
*/
public abstract void releasePbufferFromTexture();
+ /*
+ * Sets the swap interval for onscreen OpenGL contexts. Has no
+ * effect for offscreen contexts.
+ */
+ public void setSwapInterval(final int interval) {
+ }
+
/** Maps the given "platform-independent" function name to a real function
name. Currently this is only used to map "glAllocateMemoryNV" and
associated routines to wglAllocateMemoryNV / glXAllocateMemoryNV. */
diff --git a/src/net/java/games/jogl/impl/SingleThreadedWorkaround.java b/src/net/java/games/jogl/impl/SingleThreadedWorkaround.java
index 7b9fa46c4..ff79b5c6e 100755
--- a/src/net/java/games/jogl/impl/SingleThreadedWorkaround.java
+++ b/src/net/java/games/jogl/impl/SingleThreadedWorkaround.java
@@ -85,6 +85,17 @@ public class SingleThreadedWorkaround {
});
}
+ /** Public method for users to disable the single-threaded
+ workaround in application code. Should perhaps eventually
+ promote this method to the public API. */
+ public static void disableWorkaround() {
+ systemPropertySpecified = true;
+ singleThreadedWorkaround = false;
+ if (Debug.verbose()) {
+ System.err.println("Application forced disabling of single-threaded workaround of dispatching display() on event thread");
+ }
+ }
+
public static void shouldDoWorkaround() {
if (!systemPropertySpecified) {
singleThreadedWorkaround = true;
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
index 3c8027e7c..cfa5c3d99 100644
--- a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
@@ -227,6 +227,13 @@ public abstract class MacOSXGLContext extends GLContext
return "";
}
+ public void setSwapInterval(int interval) {
+ if (nsContext == 0) {
+ throw new GLException("OpenGL context not current");
+ }
+ CGL.setSwapInterval(nsContext, interval);
+ }
+
//----------------------------------------------------------------------
// Internals only below this point
//
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java
index e957092ee..401a657fe 100644
--- a/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java
@@ -52,7 +52,6 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext {
private JAWT_DrawingSurface ds;
private JAWT_DrawingSurfaceInfo dsi;
private JAWT_MacOSXDrawingSurfaceInfo macosxdsi;
- private Runnable myDeferredReshapeAction;
// Variables for pbuffer support
List pbuffersToInstantiate = new ArrayList();
@@ -67,24 +66,6 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext {
super(component, capabilities, chooser, shareWith);
}
- // gznote: remove when updater is thread safe!
- public synchronized void invokeGL(final Runnable runnable, boolean isReshape, Runnable initAction) throws GLException {
- if (isReshape) {
- myDeferredReshapeAction = new Runnable() {
- public void run() {
- CGL.updateContext(nsContext, nsView);
- runnable.run();
- }
- };
- } else {
- if (myDeferredReshapeAction != null) {
- super.invokeGL(myDeferredReshapeAction, true, initAction);
- myDeferredReshapeAction = null;
- }
- super.invokeGL(runnable, isReshape, initAction);
- }
- }
-
protected boolean isOffscreen() {
return false;
}
@@ -136,6 +117,14 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext {
}
boolean ret = super.makeCurrent(initAction);
if (ret) {
+ // Assume the canvas might have been resized or moved and tell the OpenGL
+ // context to update itself. This used to be done only upon receiving a
+ // reshape event but that doesn't appear to be sufficient. An experiment
+ // was also done to add a HierarchyBoundsListener to the GLCanvas and
+ // do this updating only upon reshape of this component or reshape or movement
+ // of an ancestor, but this also wasn't sufficient and left garbage on the
+ // screen in some situations.
+ CGL.updateContext(nsContext, nsView);
// Instantiate any pending pbuffers
while (!pbuffersToInstantiate.isEmpty()) {
MacOSXPbufferGLContext ctx =
diff --git a/src/net/java/games/jogl/impl/tesselator/Sweep.java b/src/net/java/games/jogl/impl/tesselator/Sweep.java
index e7b77cd26..3674d12e1 100644
--- a/src/net/java/games/jogl/impl/tesselator/Sweep.java
+++ b/src/net/java/games/jogl/impl/tesselator/Sweep.java
@@ -404,7 +404,7 @@ class Sweep {
coords[1] = isect.coords[1];
coords[2] = isect.coords[2];
- double[][] outData = new double[1][];
+ Object[] outData = new Object[1];
tess.callCombineOrCombineData(coords, data, weights, outData);
isect.data = outData[0];
if (isect.data == null) {
diff --git a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
index 1b5f54979..241a45dc9 100644
--- a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
@@ -103,6 +103,13 @@ public class X11OnscreenGLContext extends X11GLContext {
throw new GLException("Should not call this");
}
+ public void setSwapInterval(int interval) {
+ GL gl = getGL();
+ if (gl.isExtensionAvailable("GLX_SGI_swap_control")) {
+ gl.glXSwapIntervalSGI(interval);
+ }
+ }
+
protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
try {
if (!lockSurface()) {
diff --git a/src/net/java/games/jogl/util/GLUT.java b/src/net/java/games/jogl/util/GLUT.java
index 36b54d6b1..70144d66e 100644
--- a/src/net/java/games/jogl/util/GLUT.java
+++ b/src/net/java/games/jogl/util/GLUT.java
@@ -204,6 +204,74 @@ public class GLUT {
tetrahedron(gl, GL.GL_TRIANGLES);
}
+/**
+ * Renders the teapot as a solid shape of the specified size. The teapot is
+ * created in a way that replicates the C GLUT implementation.
+ *
+ * @param gl
+ * the OpenGL context in which to render the teapot
+ * @param scale
+ * the factor by which to scale the teapot
+ */
+ public void glutSolidTeapot(GL gl, double scale) {
+ glutSolidTeapot(gl, scale, true);
+ }
+
+ /**
+ * Renders the teapot as a solid shape of the specified size. The teapot can
+ * either be created in a way that is backward-compatible with the standard
+ * C glut library (i.e. broken), or in a more pleasing way (i.e. with
+ * surfaces whose front-faces point outwards and standing on the z=0 plane,
+ * instead of the y=-1 plane). Both surface normals and texture coordinates
+ * for the teapot are generated. The teapot is generated with OpenGL
+ * evaluators.
+ *
+ * @param gl
+ * the OpenGL context in which to render the teapot
+ * @param scale
+ * the factor by which to scale the teapot
+ * @param cStyle
+ * whether to create the teapot in exactly the same way as in the C
+ * implementation of GLUT
+ */
+ public void glutSolidTeapot(GL gl, double scale, boolean cStyle) {
+ teapot(gl, 14, scale, GL.GL_FILL, cStyle);
+ }
+
+ /**
+ * Renders the teapot as a wireframe shape of the specified size. The teapot
+ * is created in a way that replicates the C GLUT implementation.
+ *
+ * @param gl
+ * the OpenGL context in which to render the teapot
+ * @param scale
+ * the factor by which to scale the teapot
+ */
+ public void glutWireTeapot(GL gl, double scale) {
+ glutWireTeapot(gl, scale, true);
+ }
+
+ /**
+ * Renders the teapot as a wireframe shape of the specified size. The teapot
+ * can either be created in a way that is backward-compatible with the
+ * standard C glut library (i.e. broken), or in a more pleasing way (i.e.
+ * with surfaces whose front-faces point outwards and standing on the z=0
+ * plane, instead of the y=-1 plane). Both surface normals and texture
+ * coordinates for the teapot are generated. The teapot is generated with
+ * OpenGL evaluators.
+ *
+ * @param gl
+ * the OpenGL context in which to render the teapot
+ * @param scale
+ * the factor by which to scale the teapot
+ * @param cStyle
+ * whether to create the teapot in exactly the same way as in the C
+ * implementation of GLUT
+ */
+ public void glutWireTeapot(GL gl, double scale, boolean cStyle) {
+ teapot(gl, 10, scale, GL.GL_LINE, cStyle);
+ }
+
//----------------------------------------------------------------------
// Fonts
//
@@ -736,6 +804,282 @@ public class GLUT {
drawtriangle(gl, i, tdata, tndex, shadeType);
}
+ // Teapot implementation (a modified port of glut_teapot.c)
+ //
+ // Rim, body, lid, and bottom data must be reflected in x and
+ // y; handle and spout data across the y axis only.
+ private static final int[][] teapotPatchData = {
+ /* rim */
+ {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
+ /* body */
+ {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27},
+ {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40},
+ /* lid */
+ {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3,},
+ {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117},
+ /* bottom */
+ {118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37},
+ /* handle */
+ {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56},
+ {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67},
+ /* spout */
+ {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83},
+ {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95}
+ };
+ private static final float[][] teapotCPData = {
+ {0.2f, 0f, 2.7f},
+ {0.2f, -0.112f, 2.7f},
+ {0.112f, -0.2f, 2.7f},
+ {0f, -0.2f, 2.7f},
+ {1.3375f, 0f, 2.53125f},
+ {1.3375f, -0.749f, 2.53125f},
+ {0.749f, -1.3375f, 2.53125f},
+ {0f, -1.3375f, 2.53125f},
+ {1.4375f, 0f, 2.53125f},
+ {1.4375f, -0.805f, 2.53125f},
+ {0.805f, -1.4375f, 2.53125f},
+ {0f, -1.4375f, 2.53125f},
+ {1.5f, 0f, 2.4f},
+ {1.5f, -0.84f, 2.4f},
+ {0.84f, -1.5f, 2.4f},
+ {0f, -1.5f, 2.4f},
+ {1.75f, 0f, 1.875f},
+ {1.75f, -0.98f, 1.875f},
+ {0.98f, -1.75f, 1.875f},
+ {0f, -1.75f, 1.875f},
+ {2f, 0f, 1.35f},
+ {2f, -1.12f, 1.35f},
+ {1.12f, -2f, 1.35f},
+ {0f, -2f, 1.35f},
+ {2f, 0f, 0.9f},
+ {2f, -1.12f, 0.9f},
+ {1.12f, -2f, 0.9f},
+ {0f, -2f, 0.9f},
+ {-2f, 0f, 0.9f},
+ {2f, 0f, 0.45f},
+ {2f, -1.12f, 0.45f},
+ {1.12f, -2f, 0.45f},
+ {0f, -2f, 0.45f},
+ {1.5f, 0f, 0.225f},
+ {1.5f, -0.84f, 0.225f},
+ {0.84f, -1.5f, 0.225f},
+ {0f, -1.5f, 0.225f},
+ {1.5f, 0f, 0.15f},
+ {1.5f, -0.84f, 0.15f},
+ {0.84f, -1.5f, 0.15f},
+ {0f, -1.5f, 0.15f},
+ {-1.6f, 0f, 2.025f},
+ {-1.6f, -0.3f, 2.025f},
+ {-1.5f, -0.3f, 2.25f},
+ {-1.5f, 0f, 2.25f},
+ {-2.3f, 0f, 2.025f},
+ {-2.3f, -0.3f, 2.025f},
+ {-2.5f, -0.3f, 2.25f},
+ {-2.5f, 0f, 2.25f},
+ {-2.7f, 0f, 2.025f},
+ {-2.7f, -0.3f, 2.025f},
+ {-3f, -0.3f, 2.25f},
+ {-3f, 0f, 2.25f},
+ {-2.7f, 0f, 1.8f},
+ {-2.7f, -0.3f, 1.8f},
+ {-3f, -0.3f, 1.8f},
+ {-3f, 0f, 1.8f},
+ {-2.7f, 0f, 1.575f},
+ {-2.7f, -0.3f, 1.575f},
+ {-3f, -0.3f, 1.35f},
+ {-3f, 0f, 1.35f},
+ {-2.5f, 0f, 1.125f},
+ {-2.5f, -0.3f, 1.125f},
+ {-2.65f, -0.3f, 0.9375f},
+ {-2.65f, 0f, 0.9375f},
+ {-2f, -0.3f, 0.9f},
+ {-1.9f, -0.3f, 0.6f},
+ {-1.9f, 0f, 0.6f},
+ {1.7f, 0f, 1.425f},
+ {1.7f, -0.66f, 1.425f},
+ {1.7f, -0.66f, 0.6f},
+ {1.7f, 0f, 0.6f},
+ {2.6f, 0f, 1.425f},
+ {2.6f, -0.66f, 1.425f},
+ {3.1f, -0.66f, 0.825f},
+ {3.1f, 0f, 0.825f},
+ {2.3f, 0f, 2.1f},
+ {2.3f, -0.25f, 2.1f},
+ {2.4f, -0.25f, 2.025f},
+ {2.4f, 0f, 2.025f},
+ {2.7f, 0f, 2.4f},
+ {2.7f, -0.25f, 2.4f},
+ {3.3f, -0.25f, 2.4f},
+ {3.3f, 0f, 2.4f},
+ {2.8f, 0f, 2.475f},
+ {2.8f, -0.25f, 2.475f},
+ {3.525f, -0.25f, 2.49375f},
+ {3.525f, 0f, 2.49375f},
+ {2.9f, 0f, 2.475f},
+ {2.9f, -0.15f, 2.475f},
+ {3.45f, -0.15f, 2.5125f},
+ {3.45f, 0f, 2.5125f},
+ {2.8f, 0f, 2.4f},
+ {2.8f, -0.15f, 2.4f},
+ {3.2f, -0.15f, 2.4f},
+ {3.2f, 0f, 2.4f},
+ {0f, 0f, 3.15f},
+ {0.8f, 0f, 3.15f},
+ {0.8f, -0.45f, 3.15f},
+ {0.45f, -0.8f, 3.15f},
+ {0f, -0.8f, 3.15f},
+ {0f, 0f, 2.85f},
+ {1.4f, 0f, 2.4f},
+ {1.4f, -0.784f, 2.4f},
+ {0.784f, -1.4f, 2.4f},
+ {0f, -1.4f, 2.4f},
+ {0.4f, 0f, 2.55f},
+ {0.4f, -0.224f, 2.55f},
+ {0.224f, -0.4f, 2.55f},
+ {0f, -0.4f, 2.55f},
+ {1.3f, 0f, 2.55f},
+ {1.3f, -0.728f, 2.55f},
+ {0.728f, -1.3f, 2.55f},
+ {0f, -1.3f, 2.55f},
+ {1.3f, 0f, 2.4f},
+ {1.3f, -0.728f, 2.4f},
+ {0.728f, -1.3f, 2.4f},
+ {0f, -1.3f, 2.4f},
+ {0f, 0f, 0f},
+ {1.425f, -0.798f, 0f},
+ {1.5f, 0f, 0.075f},
+ {1.425f, 0f, 0f},
+ {0.798f, -1.425f, 0f},
+ {0f, -1.5f, 0.075f},
+ {0f, -1.425f, 0f},
+ {1.5f, -0.84f, 0.075f},
+ {0.84f, -1.5f, 0.075f}
+ };
+ // Since GL.glMap2f expects a packed array of floats, we must convert
+ // from a 3-dimensional array to a 1-dimensional array
+ private static final float[] teapotTex = {
+ 0, 0, 1, 0, 0, 1, 1, 1
+ };
+
+ private static void teapot(GL gl,
+ int grid,
+ double scale,
+ int type,
+ boolean backCompatible)
+ {
+ // As mentioned above, GL.glMap2f expects a packed array of floats
+ float[] p = new float[4*4*3];
+ float[] q = new float[4*4*3];
+ float[] r = new float[4*4*3];
+ float[] s = new float[4*4*3];
+ int i, j, k, l;
+
+ gl.glPushAttrib(GL.GL_ENABLE_BIT | GL.GL_EVAL_BIT | GL.GL_POLYGON_BIT);
+ gl.glEnable(GL.GL_AUTO_NORMAL);
+ gl.glEnable(GL.GL_NORMALIZE);
+ gl.glEnable(GL.GL_MAP2_VERTEX_3);
+ gl.glEnable(GL.GL_MAP2_TEXTURE_COORD_2);
+ if (!backCompatible) {
+ // The time has come to have the teapot no longer be inside out
+ gl.glFrontFace(GL.GL_CW);
+ gl.glScaled(0.5*scale, 0.5*scale, 0.5*scale);
+ } else {
+ // We want the teapot in it's backward compatible position and
+ // orientation
+ gl.glPushMatrix();
+ gl.glRotatef(270.0f, 1, 0, 0);
+ gl.glScalef((float)(0.5 * scale),
+ (float)(0.5 * scale),
+ (float)(0.5 * scale));
+ gl.glTranslatef(0.0f, 0.0f, -1.5f);
+ }
+ for (i = 0; i < 10; i++) {
+ for (j = 0; j < 4; j++) {
+ for (k = 0; k < 4; k++) {
+ for (l = 0; l < 3; l++) {
+ p[(j*4+k)*3+l] = teapotCPData[teapotPatchData[i][j * 4 + k]][l];
+ q[(j*4+k)*3+l] =
+ teapotCPData[teapotPatchData[i][j * 4 + (3 - k)]][l];
+ if (l == 1)
+ q[(j*4+k)*3+l] *= -1.0;
+ if (i < 6) {
+ r[(j*4+k)*3+l] =
+ teapotCPData[teapotPatchData[i][j * 4 + (3 - k)]][l];
+ if (l == 0)
+ r[(j*4+k)*3+l] *= -1.0;
+ s[(j*4+k)*3+l] = teapotCPData[teapotPatchData[i][j * 4 + k]][l];
+ if (l == 0)
+ s[(j*4+k)*3+l] *= -1.0;
+ if (l == 1)
+ s[(j*4+k)*3+l] *= -1.0;
+ }
+ }
+ }
+ }
+ gl.glMap2f(GL.GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, teapotTex);
+ gl.glMap2f(GL.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, p);
+ gl.glMapGrid2f(grid, 0.0f, 1.0f, grid, 0.0f, 1.0f);
+ evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+ gl.glMap2f(GL.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, q);
+ evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+ if (i < 6) {
+ gl.glMap2f(GL.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, r);
+ evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+ gl.glMap2f(GL.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, s);
+ evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
+ }
+ }
+ if (backCompatible) {
+ gl.glPopMatrix();
+ }
+ gl.glPopAttrib();
+ }
+
+ private static void evaluateTeapotMesh(GL gl,
+ int grid,
+ int type,
+ int partNum,
+ boolean repairSingularities)
+ {
+ if (repairSingularities && (partNum == 5 || partNum == 3)) {
+ // Instead of using evaluators that give bad results at singularities,
+ // evaluate by hand
+ gl.glPolygonMode(GL.GL_FRONT_AND_BACK, type);
+ for (int nv = 0; nv < grid; nv++) {
+ if (nv == 0) {
+ // Draw a small triangle-fan to fill the hole
+ gl.glDisable(GL.GL_AUTO_NORMAL);
+ gl.glNormal3f(0, 0, partNum == 3 ? 1 : -1);
+ gl.glBegin(GL.GL_TRIANGLE_FAN);
+ {
+ gl.glEvalCoord2f(0, 0);
+ // Note that we draw in clock-wise order to match the evaluator
+ // method
+ for (int nu = 0; nu <= grid; nu++)
+ {
+ gl.glEvalCoord2f(nu / (float)grid, (1f / grid) / (float)grid);
+ }
+ }
+ gl.glEnd();
+ gl.glEnable(GL.GL_AUTO_NORMAL);
+ }
+ // Draw the rest of the piece as an evaluated quad-strip
+ gl.glBegin(GL.GL_QUAD_STRIP);
+ {
+ // Note that we draw in clock-wise order to match the evaluator method
+ for (int nu = grid; nu >= 0; nu--) {
+ gl.glEvalCoord2f(nu / (float)grid, (nv + 1) / (float)grid);
+ gl.glEvalCoord2f(nu / (float)grid, Math.max(nv, 1f / grid)
+ / (float)grid);
+ }
+ }
+ gl.glEnd();
+ }
+ } else {
+ gl.glEvalMesh2(type, 0, grid, 0, grid);
+ }
+ }
+
//----------------------------------------------------------------------
// Font implementation
//