aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/HowToBuild.html4
-rw-r--r--doc/userguide/index.html113
-rw-r--r--make/build.xml26
-rw-r--r--make/cgl-macosx.cfg2
-rw-r--r--make/gl-common.cfg10
-rw-r--r--make/gl-impl-macosx.cfg4
-rw-r--r--make/gl-impl-win32.cfg6
-rw-r--r--make/gl-impl-x11.cfg6
-rw-r--r--make/stub_includes/macosx/window-system.c2
-rw-r--r--src/native/jogl/MacOSXWindowSystemInterface.m6
-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
-rw-r--r--www/webstart/jogl-natives-linux.jarbin291265 -> 293968 bytes
-rw-r--r--www/webstart/jogl-natives-macosx.jarbin141074 -> 142648 bytes
-rw-r--r--www/webstart/jogl-natives-solsparc.jarbin258270 -> 258269 bytes
-rw-r--r--www/webstart/jogl-natives-win32.jarbin56931 -> 58220 bytes
-rw-r--r--www/webstart/jogl.jarbin1105076 -> 1111928 bytes
28 files changed, 535 insertions, 112 deletions
diff --git a/doc/HowToBuild.html b/doc/HowToBuild.html
index 6316d1d7b..be17b7e95 100644
--- a/doc/HowToBuild.html
+++ b/doc/HowToBuild.html
@@ -26,11 +26,11 @@ OpenGL binding from a fresh copy of the source distribution:
<LI> <B>Build the source tree:</B> <br> Open a command shell in the "make" directory of the source tree and type "ant [target]", where [target] is one of <code>linux</code>, <code>macosx</code>, <code>solaris</code>, <code>win32.vc6</code>, <code>win32.vc7</code>, or <code>win32.mingw</code>.
<UL>
<LI>The win32 targets require one of Microsoft Visual C++ 6, 7 (Visual Studio .NET) or the free MinGW (<a href="http://www.mingw.org/">http://www.mingw.org/</a>) compilers to be installed. Choose the appropriate target for the compiler desired.
- <LI>An experimental binding to the high-level <a href="http://developer.nvidia.com/view.asp?PAGE=cg_main">Cg</a> language by NVidia corporation can be generated by specifying <code>-Djogl.cg=1</code> to ant; e.g. <code>ant -Djogl.cg=1 win32.vc6</code>. Currently the Cg binding has been tested on Windows and Linux, though in theory it should build and run on Mac OS X with appropriate modification of the host.properties file.
+ <LI>An experimental binding to the high-level <a href="http://developer.nvidia.com/view.asp?PAGE=cg_main">Cg</a> language by NVidia corporation can be generated by specifying <code>-Djogl.cg=1</code> to ant; e.g. <code>ant -Djogl.cg=1 win32.vc6</code>. The Cg binding has been tested on Windows, Linux, and Mac OS X.
</UL>
<LI> <B>Add Jogl to your CLASSPATH:</B> <br> To be able to use Jogl once built, you must add the build process' resulting jogl.jar (<source tree root>/build/jogl.jar) to your CLASSPATH environment variable.
- <LI> <B>Add Jogl to your PATH:</B> <br> To be able to use Jogl once built, you must also add the build process JNI code library directory (<source tree root>/build/obj) to your PATH.
+ <LI> <B>Add Jogl to your PATH or LD_LIBRARY_PATH:</B> <br> To be able to use Jogl once built, you must also add the build process's JNI code library directory (<source tree root>/build/obj) to your PATH (on Windows) or LD_LIBRARY_PATH (on Unix platforms) environment variable.
<LI> <B>Test if everything's working:</B> <br> To test if everything went well, you should check out the source code for the <B>jogl-demos</B> project (available at <a href = "http://jogl-demos.dev.java.net/">http://jogl-demos.dev.java.net/</a>), build the demos using the supplied instructions, and run the Gears demo ("java demos.gears.Gears").
<LI> <B>Build Javadoc:</B> <br> "ant javadoc" will produce the end-user documentation for Jogl along with some auxiliary utility packages. The developers' documentation, including that for the GlueGen tool, can be generated for your current platform using one of the following commands: "ant javadoc.dev.win32", "ant javadoc.dev.x11", or "ant javadoc.dev.macosx". (The javadoc for the Cg binding can be built by inserting <code>-Djogl.cg=1</code> into the command line as above.)
diff --git a/doc/userguide/index.html b/doc/userguide/index.html
index 63e622f1a..d9468ea6d 100644
--- a/doc/userguide/index.html
+++ b/doc/userguide/index.html
@@ -164,17 +164,28 @@ begins to perform rendering.
</P>
<P>
-The <CODE>init()</CODE> method is called once, upon context
-creation. (Hooks for context destruction, and support for context
-recreation, are not yet implemented.) The <CODE>display()</CODE>
-method is called to perform per-frame rendering. The
-<CODE>reshape()</CODE> method is called when the drawable has been
-resized; the default implementation automatically resizes the OpenGL
-viewport so often it is not necessary to do any work in this method.
-The <CODE>displayChanged()</CODE> method is designed to allow
-applications to support on-the-fly screen mode switching, but support
-for this is not yet implemented so the body of this method should
-remain empty.
+The <CODE>init()</CODE> method is called upon OpenGL context creation.
+Any display lists or textures used during the application's normal
+rendering loop can be safely initialized in <CODE>init()</CODE>.
+Because the underlying AWT window may be destroyed and recreated while
+using the same GLCanvas and GLEventListener, the GLEventListener's
+<CODE>init()</CODE> method may be called more than once during the
+lifetime of the application. It is the responsibility of the
+application to understand its sharing of textures and display lists
+between multiple OpenGL contexts and reinitialize them when the
+<CODE>init()</CODE> callback is entered if necessary.
+
+</P>
+<P>
+
+The <CODE>display()</CODE> method is called to perform per-frame
+rendering. The <CODE>reshape()</CODE> method is called when the
+drawable has been resized; the default implementation automatically
+resizes the OpenGL viewport so often it is not necessary to do any
+work in this method. The <CODE>displayChanged()</CODE> method is
+designed to allow applications to support on-the-fly screen mode
+switching, but support for this is not yet implemented so the body of
+this method should remain empty.
</P>
<P>
@@ -311,44 +322,54 @@ date.
</P>
<P>
-In addition to correctness issues, there are also performance issues
-to consider with multithreaded OpenGL applications. The OpenGL context
-associated with a particular drawable can only be current on one
-thread at a time. If multiple threads may be making the context
-current then this implies that the context must be made current and
-freed during each render; the overhead of these context operations may
-be significant depending on the application. For this reason Jogl has
-a built-in mechanism for optimizing the OpenGL context handling to the
-efficiency of an analogous C application.
+Prior to JOGL 1.1 b10, the JOGL library attempted to give applications
+strict control over which thread or threads performed OpenGL
+rendering. The <CODE>setRenderingThread()</CODE>,
+<CODE>setNoAutoRedrawMode()</CODE> and <CODE>display()</CODE> APIs
+were originally designed to allow the application to create its own
+animation thread and avoid OpenGL context switching on platforms that
+supported it. Unfortunately, serious stability issues caused by
+multithreading bugs in either vendors' OpenGL drivers or in the Java
+platform implementation have arisen on three of JOGL's major supported
+platforms: Windows, Linux and Mac OS X. A detailed description of
+these issues can be found on <a
+href="http://www.javagaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=jogl;action=display;num=1109286717">this
+thread</a> in the <a
+href="http://www.javagaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=jogl">JOGL
+forums</a>. In order to address these bugs, the threading model in
+JOGL 1.1 b10 and later has changed.
</P>
<P>
-<CODE>GLDrawable.setRenderingThread</CODE> informs the Jogl library
-that rendering to a particular drawable will only occur from the
-specified thread. The intent is that the OpenGL context can be made
-current and remain current on that thread until
-setRenderingThread(null) is called. Unfortunately, due to
-quality-of-implementation bugs in the X11 JAWT, this optimization had
-to be made advisory; in other words, it was not possible to guarantee
-that setRenderingThread would yield any faster OpenGL context handling
-on these platforms.
+All GLEventListener callbacks and other internal OpenGL context
+management are now performed on one thread: the AWT event queue
+thread. This is a thread internal to the implementation of the AWT and
+is always present when the AWT is being used. When the
+<CODE>GLDrawable.display()</CODE> method is called from user code, it
+now performs the work synchronously on the AWT event queue thread,
+even if the calling thread is a different thread. The
+<CODE>setRenderingThread()</CODE> optimization is now a no-op. The
+<CODE>setNoAutoRedraw()</CODE> API still works as previously
+advertised, though now that all work is done on the AWT event queue
+thread it no longer needs to be used in most cases. (It was previously
+useful for working around certain kinds of OpenGL driver bugs.)
</P>
<P>
-In some situations, typically when an application is using pbuffers to
-compute intermediate results, it is required that automatic redraws be
-suspended for a particular drawable so that the application can
-completely control when and where the display() method is called. For
-this reason the <CODE>GLDrawable.setNoAutoRedrawMode()</CODE> method
-was added; it is used not only by the Jogl implementation but also by
-utility libraries such as gleem (included in the jogl-demos
-distribution). We consider it unfortunate that it was necessary to
-expose two APIs to express basically the same idea and hope that if
-the JAWT implementation in the 1.5 platform has better locking
-behavior that <CODE>GLDrawable.setNoAutoRedrawMode()</CODE> may be
-able to be removed.
+Most JOGL applications will not see a change in behavior from this
+change in the JOGL implementation. Applications which use thread-local
+storage or complex multithreading and synchronization may see a change
+in their control flow requiring code changes. While it is strongly
+recommended to change such applications to work under the new
+threading model, the old threading model can be used by specifying the
+system property <CODE>-Djogl.1thread=auto</CODE> or
+<CODE>-Djogl.1thread=false</CODE>. The "auto" setting is equivalent to
+the behavior in 1.1 b09 and before, where on ATI cards the
+single-threaded mode would be used. The "false' setting is equivalent
+to disabling the single-threaded mode. "true" is now the default
+setting.
</P>
@@ -409,13 +430,7 @@ The following issues, among others, are outstanding on all platforms:
<UL>
-<LI> The DefaultGLCapabilitiesChooser tends to choose the wrong visual
-on lower-end graphics cards.
-
-<LI> Hardware acceleration for GLJPanel could be implemented using
-pbuffers.
-
-<LI> Stability issues, in particular on older graphics cards.
+<LI> A few remaining stability issues, mostly on older graphics cards.
</UL>
@@ -471,8 +486,6 @@ The following issues remain with the Mac OS X port:
<UL>
-<LI> GLJPanel is not yet implemented on Mac OS X.
-
<LI> Due to the mechanism by which the Cocoa graphics system selects
OpenGL pixel formats, the GLCapabilitiesChooser mechanism can not be
implemented on Mac OS X as on other platforms. In the future, the
diff --git a/make/build.xml b/make/build.xml
index 7ce104390..604c33849 100644
--- a/make/build.xml
+++ b/make/build.xml
@@ -202,6 +202,7 @@
<property name="java.lib.dir.win32" value="${java.home.dir}/lib" />
<property name="java.lib.dir.linux" value="${java.home.dir}/jre/lib/i386" />
<property name="java.lib.dir.linux.amd64" value="${java.home.dir}/jre/lib/amd64" />
+ <property name="java.lib.dir.linux.ia64" value="${java.home.dir}/jre/lib/ia64" />
<condition property="cpu" value="sparc">
<os name="SunOS" arch="sparc" />
</condition>
@@ -321,6 +322,15 @@
<property name="linker.cfg.id" value="linker.cfg.linux.amd64" />
</target>
+ <target name="declare.linux.ia64" depends="declare.x11">
+ <property name="java.includes.dir.platform" value="${java.includes.dir.linux}" />
+ <property name="java.lib.dir.platform" value="${java.lib.dir.linux.ia64}" />
+
+ <property name="compiler.cfg.id" value="compiler.cfg.linux" />
+ <property name="linker.cfg.id" value="linker.cfg.linux" />
+ </target>
+
+
<target name="declare.freebsd" depends="declare.x11">
<property name="java.includes.dir.platform" value="${java.includes.dir.freebsd}" />
<property name="java.lib.dir.platform" value="${java.lib.dir.linux}" />
@@ -877,6 +887,9 @@
<target name="c.compile.jogl.linux.amd64" depends="declare.linux.amd64, c.build.jogl, c.build.cg" >
</target>
+ <target name="c.compile.jogl.linux.ia64" depends="declare.linux.ia64, c.build.jogl, c.build.cg" >
+ </target>
+
<target name="c.compile.jogl.solaris" depends="declare.solaris, c.build.jogl">
</target>
@@ -1036,7 +1049,7 @@
<target name="all">
<fail>
-Use a platform specific target: linux, linux.amd64, macosx, solaris, win32.vc6, win32.vc7, win32.mingw
+Use a platform specific target: linux, linux.amd64, linux.ia64, macosx, solaris, win32.vc6, win32.vc7, win32.mingw
</fail>
</target>
@@ -1095,6 +1108,17 @@ Use a platform specific target: linux, linux.amd64, macosx, solaris, win32.vc6,
<antcall target="c.compile.jogl.linux.amd64" />
</target>
+ <!--
+ - Linux on IA64 (assuming GCC)
+ -->
+ <target name="linux.ia64" depends="setup.java.home.dir.nonmacosx, declare.linux.ia64">
+ <!-- Generate, compile, and build the jar for the Java sources. -->
+ <antcall target="jar" inheritRefs="true" />
+
+ <!-- Compile the native C sources and build the jogl lib. -->
+ <antcall target="c.compile.jogl.linux.ia64" />
+ </target>
+
<!--
- Solaris (assuming Solaris CC)
-->
diff --git a/make/cgl-macosx.cfg b/make/cgl-macosx.cfg
index c7a7f3841..dab1ec206 100644
--- a/make/cgl-macosx.cfg
+++ b/make/cgl-macosx.cfg
@@ -45,6 +45,8 @@ CustomCCode extern void setContextTextureImageToPBuffer(void* nsContext, void* p
CustomCCode extern void* getProcAddress(const char *procName);
+CustomCCode extern void setSwapInterval(void* nsContext, int interval);
+
# Implement the first argument to getProcAddress as String instead
# of byte[]
ArgumentIsString getProcAddress 0
diff --git a/make/gl-common.cfg b/make/gl-common.cfg
index a2f091f43..da4d7ea17 100644
--- a/make/gl-common.cfg
+++ b/make/gl-common.cfg
@@ -343,6 +343,16 @@ CustomJavaCode GL * {@link GLX#glXAllocateMemoryNV} extension.
CustomJavaCode GL */
CustomJavaCode GL public java.nio.ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3);
+CustomJavaCode GL /** Provides a platform-independent way to specify the minimum swap
+CustomJavaCode GL interval for buffer swaps. An argument of 0 disables
+CustomJavaCode GL sync-to-vertical-refresh completely, while an argument of 1
+CustomJavaCode GL causes the application to wait until the next vertical refresh
+CustomJavaCode GL until swapping buffers. The default, which is platform-specific,
+CustomJavaCode GL is usually either 0 or 1. This function is not guaranteed to
+CustomJavaCode GL have an effect, and in particular only affects heavyweight
+CustomJavaCode GL onscreen components. */
+CustomJavaCode GL public void setSwapInterval(int interval);
+
#
# Directives needed when processing wglext.h on Windows and other platforms
#
diff --git a/make/gl-impl-macosx.cfg b/make/gl-impl-macosx.cfg
index 8ce128851..5a09750dd 100644
--- a/make/gl-impl-macosx.cfg
+++ b/make/gl-impl-macosx.cfg
@@ -73,5 +73,9 @@ CustomJavaCode MacOSXGLImpl // FIXME
CustomJavaCode MacOSXGLImpl throw new GLException("Not yet implemented");
CustomJavaCode MacOSXGLImpl }
+CustomJavaCode MacOSXGLImpl public void setSwapInterval(int interval) { // FIXME: not implemented yet
+CustomJavaCode MacOSXGLImpl _context.setSwapInterval(interval);
+CustomJavaCode MacOSXGLImpl }
+
IncludeAs CustomJavaCode MacOSXGLImpl gl-impl-CustomJavaCode.java
IncludeAs CustomCCode gl-impl-CustomCCode.c
diff --git a/make/gl-impl-win32.cfg b/make/gl-impl-win32.cfg
index bf4f93998..252425659 100644
--- a/make/gl-impl-win32.cfg
+++ b/make/gl-impl-win32.cfg
@@ -60,5 +60,11 @@ CustomJavaCode WindowsGLImpl public java.nio.ByteBuffer glAllocateMemoryNV(int
CustomJavaCode WindowsGLImpl return wglAllocateMemoryNV(arg0, arg1, arg2, arg3);
CustomJavaCode WindowsGLImpl }
+CustomJavaCode WindowsGLImpl public void setSwapInterval(int interval) {
+CustomJavaCode WindowsGLImpl if (isExtensionAvailable("WGL_EXT_swap_control")) {
+CustomJavaCode WindowsGLImpl wglSwapIntervalEXT(interval);
+CustomJavaCode WindowsGLImpl }
+CustomJavaCode WindowsGLImpl }
+
IncludeAs CustomJavaCode WindowsGLImpl gl-impl-CustomJavaCode.java
IncludeAs CustomCCode gl-impl-CustomCCode.c
diff --git a/make/gl-impl-x11.cfg b/make/gl-impl-x11.cfg
index 33527d351..b60a28787 100644
--- a/make/gl-impl-x11.cfg
+++ b/make/gl-impl-x11.cfg
@@ -57,5 +57,11 @@ CustomJavaCode X11GLImpl public java.nio.ByteBuffer glAllocateMemoryNV(int arg
CustomJavaCode X11GLImpl return glXAllocateMemoryNV(arg0, arg1, arg2, arg3);
CustomJavaCode X11GLImpl }
+CustomJavaCode X11GLImpl public void setSwapInterval(int interval) {
+CustomJavaCode X11GLImpl if (isExtensionAvailable("GLX_SGI_swap_control")) {
+CustomJavaCode X11GLImpl glXSwapIntervalSGI(interval);
+CustomJavaCode X11GLImpl }
+CustomJavaCode X11GLImpl }
+
IncludeAs CustomJavaCode X11GLImpl gl-impl-CustomJavaCode.java
IncludeAs CustomCCode gl-impl-CustomCCode.c
diff --git a/make/stub_includes/macosx/window-system.c b/make/stub_includes/macosx/window-system.c
index e5ba4307f..b30c252f3 100644
--- a/make/stub_includes/macosx/window-system.c
+++ b/make/stub_includes/macosx/window-system.c
@@ -32,3 +32,5 @@ void setContextPBuffer(void* nsContext, void* pBuffer);
void setContextTextureImageToPBuffer(void* nsContext, void* pBuffer, int colorBuffer);
void* getProcAddress(const char *procName);
+
+void setSwapInterval(void* nsContext, int interval);
diff --git a/src/native/jogl/MacOSXWindowSystemInterface.m b/src/native/jogl/MacOSXWindowSystemInterface.m
index afa0fea69..6a5969fff 100644
--- a/src/native/jogl/MacOSXWindowSystemInterface.m
+++ b/src/native/jogl/MacOSXWindowSystemInterface.m
@@ -235,3 +235,9 @@ void* getProcAddress(const char *procname)
return NULL;
}
+
+void setSwapInterval(void* context, int interval) {
+ NSOpenGLContext *nsContext = (NSOpenGLContext*)context;
+ long swapInterval = interval;
+ [nsContext setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
+}
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
//
diff --git a/www/webstart/jogl-natives-linux.jar b/www/webstart/jogl-natives-linux.jar
index f17e6ebb0..e15bde46c 100644
--- a/www/webstart/jogl-natives-linux.jar
+++ b/www/webstart/jogl-natives-linux.jar
Binary files differ
diff --git a/www/webstart/jogl-natives-macosx.jar b/www/webstart/jogl-natives-macosx.jar
index 9c9ba0904..0576103a0 100644
--- a/www/webstart/jogl-natives-macosx.jar
+++ b/www/webstart/jogl-natives-macosx.jar
Binary files differ
diff --git a/www/webstart/jogl-natives-solsparc.jar b/www/webstart/jogl-natives-solsparc.jar
index cebc6df79..236cb2990 100644
--- a/www/webstart/jogl-natives-solsparc.jar
+++ b/www/webstart/jogl-natives-solsparc.jar
Binary files differ
diff --git a/www/webstart/jogl-natives-win32.jar b/www/webstart/jogl-natives-win32.jar
index ef7549dad..0292c4a35 100644
--- a/www/webstart/jogl-natives-win32.jar
+++ b/www/webstart/jogl-natives-win32.jar
Binary files differ
diff --git a/www/webstart/jogl.jar b/www/webstart/jogl.jar
index daedcc11d..a027016d4 100644
--- a/www/webstart/jogl.jar
+++ b/www/webstart/jogl.jar
Binary files differ