diff options
Diffstat (limited to 'src/net/java')
-rw-r--r-- | src/net/java/games/gluegen/CMethodBindingEmitter.java | 6 | ||||
-rw-r--r-- | src/net/java/games/gluegen/GlueGen.java | 3 | ||||
-rw-r--r-- | src/net/java/games/gluegen/StructLayout.java | 1 | ||||
-rw-r--r-- | src/net/java/games/gluegen/cgram/types/CompoundType.java | 7 | ||||
-rw-r--r-- | src/net/java/games/jogl/GLJPanel.java | 44 | ||||
-rw-r--r-- | src/net/java/games/jogl/Version.java | 2 | ||||
-rw-r--r-- | src/net/java/games/jogl/impl/GLContext.java | 7 | ||||
-rwxr-xr-x | src/net/java/games/jogl/impl/SingleThreadedWorkaround.java | 11 | ||||
-rw-r--r-- | src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java | 7 | ||||
-rw-r--r-- | src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java | 27 | ||||
-rw-r--r-- | src/net/java/games/jogl/impl/tesselator/Sweep.java | 2 | ||||
-rw-r--r-- | src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java | 7 | ||||
-rw-r--r-- | src/net/java/games/jogl/util/GLUT.java | 344 |
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 // |