diff options
author | Kenneth Russel <[email protected]> | 2005-10-24 19:21:28 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2005-10-24 19:21:28 +0000 |
commit | 6873f65775af236ed270fcbd08661f5b53ba3598 (patch) | |
tree | 6fcefdc3a9429d7d3071b1464c11d40fa7bc3ab9 /src | |
parent | 538be101e7bce7788c82e1b254a66deb5d35bb56 (diff) |
Merged JSR-231 branch on to the main JOGL trunk. The main trunk now
contains the evolving JSR-231 Reference Implementation and the JSR-231
branch is permanently closed.
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/jogl-demos/trunk@144 3298f667-5e0e-4b4a-8ed4-a3559d26a5f4
Diffstat (limited to 'src')
70 files changed, 7763 insertions, 6348 deletions
diff --git a/src/demos/cg/runtime_ogl/cgGL_vertex_example.java b/src/demos/cg/runtime_ogl/cgGL_vertex_example.java index f1f41dd..e8ca280 100644 --- a/src/demos/cg/runtime_ogl/cgGL_vertex_example.java +++ b/src/demos/cg/runtime_ogl/cgGL_vertex_example.java @@ -33,8 +33,10 @@ package demos.cg.runtime_ogl; -import net.java.games.cg.*; -import net.java.games.jogl.*; +import com.sun.opengl.cg.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; import java.awt.*; import java.awt.event.*; @@ -54,6 +56,7 @@ public class cgGL_vertex_example implements GLEventListener private final int TextureRes = 512; + private GLU glu = new GLU(); private static CGcontext Context = null; private static CGprogram Program = null; private static CGparameter KdParam = null; @@ -154,7 +157,7 @@ public class cgGL_vertex_example implements GLEventListener CgGL.cgGLDisableProfile(profile); } - public void display(GLDrawable drawable) + public void display(GLAutoDrawable drawable) { GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); @@ -173,12 +176,12 @@ public class cgGL_vertex_example implements GLEventListener v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1; } - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { // nothing } - public void init(GLDrawable drawable) + public void init(GLAutoDrawable drawable) { // Note: we initialize Cg in this init() method instead of main() // because Cg (apparently) requires an active OpenGL context in order to @@ -223,13 +226,12 @@ public class cgGL_vertex_example implements GLEventListener CheckCgError(); } GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); InitializeCube(CubeVertices); /* Enable a single OpenGL light. */ - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, LightDiffuse); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, LightPosition); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, LightDiffuse, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, LightPosition, 0); gl.glEnable(GL.GL_LIGHT0); if (false) { // #if 0 gl.glEnable(GL.GL_LIGHTING); @@ -259,7 +261,7 @@ public class cgGL_vertex_example implements GLEventListener } - public void reshape(GLDrawable drawable, int x, int y, int width, int height) + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { // do nothing } diff --git a/src/demos/cg/runtime_ogl_vertex_fragment/runtime_ogl_vertex_fragment.java b/src/demos/cg/runtime_ogl_vertex_fragment/runtime_ogl_vertex_fragment.java index 0c389e1..51fe8d5 100644 --- a/src/demos/cg/runtime_ogl_vertex_fragment/runtime_ogl_vertex_fragment.java +++ b/src/demos/cg/runtime_ogl_vertex_fragment/runtime_ogl_vertex_fragment.java @@ -33,9 +33,11 @@ package demos.cg.runtime_ogl_vertex_fragment; -import net.java.games.cg.*; -import net.java.games.jogl.*; -import net.java.games.jogl.util.*; +import com.sun.opengl.cg.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; +import com.sun.opengl.utils.*; import java.awt.*; import java.awt.event.*; @@ -55,6 +57,7 @@ public class runtime_ogl_vertex_fragment implements GLEventListener // in as well as handles to the vertex and fragment program used in this // demo. + private GLU glu = new GLU(); CGcontext context; CGprogram vertexProgram, fragmentProgram; @@ -91,7 +94,7 @@ public class runtime_ogl_vertex_fragment implements GLEventListener // and all the rest happens in the display function... } - public void init(GLDrawable drawable) + public void init(GLAutoDrawable drawable) { // Use debug pipeline // drawable.setGL(new DebugGL(drawable.getGL())); @@ -125,11 +128,10 @@ public class runtime_ogl_vertex_fragment implements GLEventListener private static int curTime = 0; // display callback function - public void display(GLDrawable drawable) + public void display(GLAutoDrawable drawable) { GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); // The usual OpenGL stuff to clear the screen and set up viewing. gl.glClearColor(.25f, .25f, .25f, 1.0f); @@ -168,15 +170,15 @@ public class runtime_ogl_vertex_fragment implements GLEventListener // vertex shader could be modified so that these were uniform for // better efficiency, but this gives us flexibility for the future. float Kd[] = { .7f, .2f, .2f }, Ks[] = { .9f, .9f, .9f }; - CgGL.cgGLSetParameter3fv(CgGL.cgGetNamedParameter(vertexProgram, "diffuse"), Kd); - CgGL.cgGLSetParameter3fv(CgGL.cgGetNamedParameter(vertexProgram, "specular"), Ks); + CgGL.cgGLSetParameter3fv(CgGL.cgGetNamedParameter(vertexProgram, "diffuse"), Kd, 0); + CgGL.cgGLSetParameter3fv(CgGL.cgGetNamedParameter(vertexProgram, "specular"), Ks, 0); // Now bind uniform parameters to fragment shader float lightPos[] = { 3, 2, -3 }; - CgGL.cgGLSetParameter3fv(CgGL.cgGetNamedParameter(fragmentProgram, "Plight"), lightPos); + CgGL.cgGLSetParameter3fv(CgGL.cgGetNamedParameter(fragmentProgram, "Plight"), lightPos, 0); float lightColor[] = { 1, 1, 1 }; CgGL.cgGLSetParameter3fv(CgGL.cgGetNamedParameter(fragmentProgram, "lightColor"), - lightColor); + lightColor, 0); CgGL.cgGLSetParameter1f(CgGL.cgGetNamedParameter(fragmentProgram, "shininess"), 40); // And finally, enable the approprate texture for fragment shader; the @@ -273,7 +275,7 @@ public class runtime_ogl_vertex_fragment implements GLEventListener // checkerboard--which is used to modulate the diffuse channel in the // fragment shader. int[] handle = new int[1]; - gl.glGenTextures(1, handle); + gl.glGenTextures(1, handle, 0); // Basic OpenGL texture state setup gl.glBindTexture(GL.GL_TEXTURE_2D, handle[0]); @@ -303,7 +305,7 @@ public class runtime_ogl_vertex_fragment implements GLEventListener } } - gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, RES, RES, 0, GL.GL_RGBA, GL.GL_FLOAT, data); + gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, RES, RES, 0, GL.GL_RGBA, GL.GL_FLOAT, FloatBuffer.wrap(data)); // Tell Cg which texture handle should be associated with the sampler2D // parameter to the fragment shader. @@ -417,12 +419,12 @@ public class runtime_ogl_vertex_fragment implements GLEventListener N.put(offsetN + 2, P.get(offsetP + 2)); } - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { // nothing } - public void reshape(GLDrawable drawable, int x, int y, int width, int height) + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { // do nothing } diff --git a/src/demos/common/Demo.java b/src/demos/common/Demo.java new file mode 100755 index 0000000..00f5956 --- /dev/null +++ b/src/demos/common/Demo.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package demos.common; + +import javax.media.opengl.*; + +public abstract class Demo implements GLEventListener { + protected DemoListener demoListener; + private boolean doShutdown = true; + + public void setDemoListener(DemoListener listener) { + this.demoListener = listener; + } + + // Override this with any other cleanup actions + public void shutdownDemo() { + // Execute only once + boolean shouldDoShutdown = doShutdown; + doShutdown = false; + if (shouldDoShutdown) { + demoListener.shutdownDemo(); + } + } +} diff --git a/src/demos/common/DemoListener.java b/src/demos/common/DemoListener.java new file mode 100755 index 0000000..95b5e9c --- /dev/null +++ b/src/demos/common/DemoListener.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package demos.common; + +/** Defines certain events demos can send. Different harnesses + may respond differently to these events. */ +public interface DemoListener { + /** Indicates that the demo wants to be terminated. */ + public void shutdownDemo(); + + /** Indicates that a repaint should be scheduled later. */ + public void repaint(); +} diff --git a/src/demos/context/DualContext.java b/src/demos/context/DualContext.java new file mode 100755 index 0000000..0f9fea9 --- /dev/null +++ b/src/demos/context/DualContext.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package demos.context; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; + +/** This demo illustrates the use of the GLDrawable and GLContext APIs + to create two OpenGL contexts for the same Canvas. The red and + blue portions of the canvas are drawn with separate OpenGL + contexts. The front and back buffers of the GLDrawable are swapped + using the GLDrawable.swapBuffers() API. */ + +public class DualContext extends Canvas { + private GLDrawable drawable; + private GLContext context1; + private GLContext context2; + private GLU glu; + private GLUT glut; + private int repaintNum; + + public DualContext(GLCapabilities capabilities) { + super(GLDrawableFactory.getFactory().chooseGraphicsConfiguration(capabilities, null, null)); + drawable = GLDrawableFactory.getFactory().getGLDrawable(this, capabilities, null); + context1 = drawable.createContext(null); + context2 = drawable.createContext(null); + glu = new GLU(); + glut = new GLUT(); + } + + public void addNotify() { + super.addNotify(); + drawable.setRealized(true); + } + + public void removeNotify() { + context1.destroy(); + context2.destroy(); + drawable.setRealized(false); + } + + public void paint(Graphics g) { + int width = getWidth(); + int height = getHeight(); + int mid = width / 2; + String str = "" + (++repaintNum); + int res = context1.makeCurrent(); + if (res != GLContext.CONTEXT_NOT_CURRENT) { + clearAndDraw(context1.getGL(), + 1, 0, 0, + 0, 0, mid, height, str); + context1.release(); + } + + res = context2.makeCurrent(); + if (res != GLContext.CONTEXT_NOT_CURRENT) { + clearAndDraw(context2.getGL(), + 0, 0, 1, + mid, 0, width - mid, height, str); + context2.release(); + } + + drawable.swapBuffers(); + } + + private void clearAndDraw(GL gl, + float br, + float bg, + float bb, + int x, + int y, + int width, + int height, + String str) { + gl.glViewport(x, y, width, height); + gl.glScissor(x, y, width, height); + gl.glEnable(GL.GL_SCISSOR_TEST); + gl.glClearColor(br, bg, bb, 1); + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + float length = glut.glutStrokeLengthf(GLUT.STROKE_ROMAN, str); + gl.glMatrixMode(GL.GL_PROJECTION); + gl.glLoadIdentity(); + glu.gluOrtho2D(x, x + width, y, y + height); + gl.glTranslatef(x + (width - length) / 2, y + height / 2, 0); + glut.glutStrokeString(GLUT.STROKE_ROMAN, str); + } + + public static void main(String[] args) { + JFrame frame = new JFrame("Dual OpenGL Context Test"); + final DualContext dc = new DualContext(new GLCapabilities()); + frame.getContentPane().add(dc, BorderLayout.CENTER); + JButton button = new JButton("Repaint"); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + dc.repaint(); + } + }); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().add(button, BorderLayout.SOUTH); + frame.setSize(800, 400); + frame.setVisible(true); + } +} diff --git a/src/demos/data/images/java_logo.png b/src/demos/data/images/java_logo.png Binary files differnew file mode 100755 index 0000000..94350e5 --- /dev/null +++ b/src/demos/data/images/java_logo.png diff --git a/src/demos/data/images/opengl_logo.png b/src/demos/data/images/opengl_logo.png Binary files differnew file mode 100755 index 0000000..b6eacb3 --- /dev/null +++ b/src/demos/data/images/opengl_logo.png diff --git a/src/demos/fullscreen/FullscreenWorkaround.java b/src/demos/fullscreen/FullscreenWorkaround.java new file mode 100755 index 0000000..4327346 --- /dev/null +++ b/src/demos/fullscreen/FullscreenWorkaround.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package demos.fullscreen; + +import java.awt.*; +import javax.swing.*; + +import javax.media.opengl.*; +import com.sun.opengl.utils.*; + +/** Class which implements workaround for full-screen bugs on Windows + when <code>-Dsun.java2d.noddraw=true</code> is specified as well + as a similar bug on Mac OS X. This code currently expects that the + GLAutoDrawable will be placed in a containing Frame. */ + +public class FullscreenWorkaround implements GLEventListener { + private int width; + private int height; + + /** Creates a full-screen workaround with the specified width and + height to set the full-screen window to later. */ + public FullscreenWorkaround(int width, int height) { + this.width = width; + this.height = height; + } + + public void init(GLAutoDrawable drawable) { + // Find parent frame if any + final Frame frame = getParentFrame((Component) drawable); + if (frame != null) { + EventQueue.invokeLater(new Runnable() { + public void run() { + frame.setVisible(false); + frame.setBounds(0, 0, width, height); + frame.setVisible(true); + frame.toFront(); + } + }); + } + } + + public void display(GLAutoDrawable drawable) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + + //---------------------------------------------------------------------- + // Internals only below this point + // + + private static Frame getParentFrame(Component c) { + while (c != null && + (!(c instanceof Frame))) { + c = c.getParent(); + } + return (Frame) c; + } +} diff --git a/src/demos/fullscreen/GearsFullscreen.java b/src/demos/fullscreen/GearsFullscreen.java index d8971fb..c0a1345 100755 --- a/src/demos/fullscreen/GearsFullscreen.java +++ b/src/demos/fullscreen/GearsFullscreen.java @@ -3,7 +3,9 @@ package demos.fullscreen; import java.awt.*; import java.awt.event.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; +import demos.gears.Gears; import demos.util.*; /** @@ -50,9 +52,11 @@ public class GearsFullscreen { if (newMode != null) { frame.setUndecorated(true); } - GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); + final GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); + + canvas.addGLEventListener(new Gears()); + canvas.addGLEventListener(new FullscreenWorkaround(initWidth, initHeight)); - canvas.addGLEventListener(new GearRenderer()); frame.add(canvas); frame.setSize(initWidth, initHeight); animator = new Animator(canvas); @@ -91,308 +95,6 @@ public class GearsFullscreen { animator.start(); } - class GearRenderer implements GLEventListener, MouseListener, MouseMotionListener { - private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f; - private int gear1, gear2, gear3; - private float angle = 0.0f; - - private int prevMouseX, prevMouseY; - private boolean mouseRButtonDown = false; - - public void init(GLDrawable drawable) { - // Use debug pipeline - // drawable.setGL(new DebugGL(drawable.getGL())); - - GL gl = drawable.getGL(); - - // FIXME: workaround for Windows full-screen bug when - // sun.java2d.noddraw=true and similar bug on Mac OS X - if (fullScreen) { - final GLDrawable tmpDrawable = drawable; - EventQueue.invokeLater(new Runnable() { - public void run() { - frame.setBounds(0, 0, initWidth, initHeight); - tmpDrawable.setSize(initWidth, initHeight); - frame.toFront(); - } - }); - } - - System.err.println("INIT GL IS: " + gl.getClass().getName()); - - gl.setSwapInterval(1); - - float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; - float red[] = { 0.8f, 0.1f, 0.0f, 1.0f }; - float green[] = { 0.0f, 0.8f, 0.2f, 1.0f }; - float blue[] = { 0.2f, 0.2f, 1.0f, 1.0f }; - - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos); - gl.glEnable(GL.GL_CULL_FACE); - gl.glEnable(GL.GL_LIGHTING); - gl.glEnable(GL.GL_LIGHT0); - gl.glEnable(GL.GL_DEPTH_TEST); - - /* make the gears */ - gear1 = gl.glGenLists(1); - gl.glNewList(gear1, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red); - gear(gl, 1.0f, 4.0f, 1.0f, 20, 0.7f); - gl.glEndList(); - - gear2 = gl.glGenLists(1); - gl.glNewList(gear2, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, green); - gear(gl, 0.5f, 2.0f, 2.0f, 10, 0.7f); - gl.glEndList(); - - gear3 = gl.glGenLists(1); - gl.glNewList(gear3, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, blue); - gear(gl, 1.3f, 2.0f, 0.5f, 10, 0.7f); - gl.glEndList(); - - gl.glEnable(GL.GL_NORMALIZE); - - drawable.addMouseListener(this); - drawable.addMouseMotionListener(this); - - drawable.addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent e) { - dispatchKey(e.getKeyCode()); - } - }); - } - - public void reshape(GLDrawable drawable, int x, int y, int width, int height) { - GL gl = drawable.getGL(); - - float h = (float)height / (float)width; - - gl.glMatrixMode(GL.GL_PROJECTION); - - System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)); - System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)); - System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)); - System.err.println(); - System.err.println("glLoadTransposeMatrixfARB() supported: " + - gl.isFunctionAvailable("glLoadTransposeMatrixfARB")); - if (!gl.isFunctionAvailable("glLoadTransposeMatrixfARB")) { - // --- not using extensions - gl.glLoadIdentity(); - } else { - // --- using extensions - final float[] identityTranspose = new float[] { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - }; - gl.glLoadTransposeMatrixfARB(identityTranspose); - } - gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f); - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glLoadIdentity(); - gl.glTranslatef(0.0f, 0.0f, -40.0f); - } - - public void display(GLDrawable drawable) { - angle += 2.0f; - - GL gl = drawable.getGL(); - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - - gl.glPushMatrix(); - gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f); - gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f); - gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f); - - gl.glPushMatrix(); - gl.glTranslatef(-3.0f, -2.0f, 0.0f); - gl.glRotatef(angle, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear1); - gl.glPopMatrix(); - - gl.glPushMatrix(); - gl.glTranslatef(3.1f, -2.0f, 0.0f); - gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear2); - gl.glPopMatrix(); - - gl.glPushMatrix(); - gl.glTranslatef(-3.1f, 4.2f, 0.0f); - gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear3); - gl.glPopMatrix(); - - gl.glPopMatrix(); - } - - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - - private void gear(GL gl, - float inner_radius, - float outer_radius, - float width, - int teeth, - float tooth_depth) - { - int i; - float r0, r1, r2; - float angle, da; - float u, v, len; - - r0 = inner_radius; - r1 = outer_radius - tooth_depth / 2.0f; - r2 = outer_radius + tooth_depth / 2.0f; - - da = 2.0f * (float) Math.PI / teeth / 4.0f; - - gl.glShadeModel(GL.GL_FLAT); - - gl.glNormal3f(0.0f, 0.0f, 1.0f); - - /* draw front face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - if(i < teeth) - { - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - } - gl.glEnd(); - - /* draw front sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2.0f * da), r2 * (float)Math.sin(angle + 2.0f * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - gl.glEnd(); - - /* draw back face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); - - /* draw back sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); - - /* draw outward faces of teeth */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - u = r2 * (float)Math.cos(angle + da) - r1 * (float)Math.cos(angle); - v = r2 * (float)Math.sin(angle + da) - r1 * (float)Math.sin(angle); - len = (float)Math.sqrt(u * u + v * v); - u /= len; - v /= len; - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - u = r1 * (float)Math.cos(angle + 3 * da) - r2 * (float)Math.cos(angle + 2 * da); - v = r1 * (float)Math.sin(angle + 3 * da) - r2 * (float)Math.sin(angle + 2 * da); - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - } - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), -width * 0.5f); - gl.glEnd(); - - gl.glShadeModel(GL.GL_SMOOTH); - - /* draw inside radius cylinder */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glNormal3f(-(float)Math.cos(angle), -(float)Math.sin(angle), 0.0f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - } - gl.glEnd(); - } - - // Methods required for the implementation of MouseListener - public void mouseEntered(MouseEvent e) {} - public void mouseExited(MouseEvent e) {} - - public void mousePressed(MouseEvent e) { - prevMouseX = e.getX(); - prevMouseY = e.getY(); - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = true; - } - } - - public void mouseReleased(MouseEvent e) { - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = false; - } - } - - public void mouseClicked(MouseEvent e) {} - - // Methods required for the implementation of MouseMotionListener - public void mouseDragged(MouseEvent e) { - int x = e.getX(); - int y = e.getY(); - Dimension size = e.getComponent().getSize(); - - float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)size.width); - float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)size.height); - - prevMouseX = x; - prevMouseY = y; - - view_rotx += thetaX; - view_roty += thetaY; - } - - public void mouseMoved(MouseEvent e) {} - - public void dispatchKey(int keyCode) { - switch (keyCode) { - case KeyEvent.VK_Q: - case KeyEvent.VK_ESCAPE: - runExit(); - } - } - } - public void runExit() { // Run this on another thread than the AWT event queue to // make sure the call to Animator.stop() completes before diff --git a/src/demos/fullscreen/GearsFullscreen2.java b/src/demos/fullscreen/GearsFullscreen2.java index 5ed02f8..1a5086c 100755 --- a/src/demos/fullscreen/GearsFullscreen2.java +++ b/src/demos/fullscreen/GearsFullscreen2.java @@ -4,7 +4,9 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; +import demos.gears.Gears; import demos.util.*; /** @@ -53,7 +55,8 @@ public class GearsFullscreen2 { } GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); - canvas.addGLEventListener(new GearRenderer()); + canvas.addGLEventListener(new Gears()); + canvas.addGLEventListener(new FullscreenWorkaround(initWidth, initHeight)); frame.getContentPane().setLayout(new BorderLayout()); ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false); @@ -112,309 +115,6 @@ public class GearsFullscreen2 { animator.start(); } - class GearRenderer implements GLEventListener, MouseListener, MouseMotionListener { - private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f; - private int gear1, gear2, gear3; - private float angle = 0.0f; - - private int prevMouseX, prevMouseY; - private boolean mouseRButtonDown = false; - - public void init(GLDrawable drawable) { - // Use debug pipeline - // drawable.setGL(new DebugGL(drawable.getGL())); - - GL gl = drawable.getGL(); - - // FIXME: workaround for Windows full-screen bug when - // sun.java2d.noddraw=true and similar bug on Mac OS X - if (fullScreen) { - final GLDrawable tmpDrawable = drawable; - EventQueue.invokeLater(new Runnable() { - public void run() { - frame.setVisible(false); - frame.setBounds(0, 0, initWidth, initHeight); - frame.setVisible(true); - frame.toFront(); - } - }); - } - - System.err.println("INIT GL IS: " + gl.getClass().getName()); - - gl.setSwapInterval(1); - - float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; - float red[] = { 0.8f, 0.1f, 0.0f, 1.0f }; - float green[] = { 0.0f, 0.8f, 0.2f, 1.0f }; - float blue[] = { 0.2f, 0.2f, 1.0f, 1.0f }; - - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos); - gl.glEnable(GL.GL_CULL_FACE); - gl.glEnable(GL.GL_LIGHTING); - gl.glEnable(GL.GL_LIGHT0); - gl.glEnable(GL.GL_DEPTH_TEST); - - /* make the gears */ - gear1 = gl.glGenLists(1); - gl.glNewList(gear1, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red); - gear(gl, 1.0f, 4.0f, 1.0f, 20, 0.7f); - gl.glEndList(); - - gear2 = gl.glGenLists(1); - gl.glNewList(gear2, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, green); - gear(gl, 0.5f, 2.0f, 2.0f, 10, 0.7f); - gl.glEndList(); - - gear3 = gl.glGenLists(1); - gl.glNewList(gear3, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, blue); - gear(gl, 1.3f, 2.0f, 0.5f, 10, 0.7f); - gl.glEndList(); - - gl.glEnable(GL.GL_NORMALIZE); - - drawable.addMouseListener(this); - drawable.addMouseMotionListener(this); - - drawable.addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent e) { - dispatchKey(e.getKeyCode()); - } - }); - } - - public void reshape(GLDrawable drawable, int x, int y, int width, int height) { - GL gl = drawable.getGL(); - - float h = (float)height / (float)width; - - gl.glMatrixMode(GL.GL_PROJECTION); - - System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)); - System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)); - System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)); - System.err.println(); - System.err.println("glLoadTransposeMatrixfARB() supported: " + - gl.isFunctionAvailable("glLoadTransposeMatrixfARB")); - if (!gl.isFunctionAvailable("glLoadTransposeMatrixfARB")) { - // --- not using extensions - gl.glLoadIdentity(); - } else { - // --- using extensions - final float[] identityTranspose = new float[] { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - }; - gl.glLoadTransposeMatrixfARB(identityTranspose); - } - gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f); - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glLoadIdentity(); - gl.glTranslatef(0.0f, 0.0f, -40.0f); - } - - public void display(GLDrawable drawable) { - angle += 2.0f; - - GL gl = drawable.getGL(); - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - - gl.glPushMatrix(); - gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f); - gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f); - gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f); - - gl.glPushMatrix(); - gl.glTranslatef(-3.0f, -2.0f, 0.0f); - gl.glRotatef(angle, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear1); - gl.glPopMatrix(); - - gl.glPushMatrix(); - gl.glTranslatef(3.1f, -2.0f, 0.0f); - gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear2); - gl.glPopMatrix(); - - gl.glPushMatrix(); - gl.glTranslatef(-3.1f, 4.2f, 0.0f); - gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear3); - gl.glPopMatrix(); - - gl.glPopMatrix(); - } - - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - - private void gear(GL gl, - float inner_radius, - float outer_radius, - float width, - int teeth, - float tooth_depth) - { - int i; - float r0, r1, r2; - float angle, da; - float u, v, len; - - r0 = inner_radius; - r1 = outer_radius - tooth_depth / 2.0f; - r2 = outer_radius + tooth_depth / 2.0f; - - da = 2.0f * (float) Math.PI / teeth / 4.0f; - - gl.glShadeModel(GL.GL_FLAT); - - gl.glNormal3f(0.0f, 0.0f, 1.0f); - - /* draw front face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - if(i < teeth) - { - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - } - gl.glEnd(); - - /* draw front sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2.0f * da), r2 * (float)Math.sin(angle + 2.0f * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - gl.glEnd(); - - /* draw back face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); - - /* draw back sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); - - /* draw outward faces of teeth */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - u = r2 * (float)Math.cos(angle + da) - r1 * (float)Math.cos(angle); - v = r2 * (float)Math.sin(angle + da) - r1 * (float)Math.sin(angle); - len = (float)Math.sqrt(u * u + v * v); - u /= len; - v /= len; - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - u = r1 * (float)Math.cos(angle + 3 * da) - r2 * (float)Math.cos(angle + 2 * da); - v = r1 * (float)Math.sin(angle + 3 * da) - r2 * (float)Math.sin(angle + 2 * da); - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - } - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), -width * 0.5f); - gl.glEnd(); - - gl.glShadeModel(GL.GL_SMOOTH); - - /* draw inside radius cylinder */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glNormal3f(-(float)Math.cos(angle), -(float)Math.sin(angle), 0.0f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - } - gl.glEnd(); - } - - // Methods required for the implementation of MouseListener - public void mouseEntered(MouseEvent e) {} - public void mouseExited(MouseEvent e) {} - - public void mousePressed(MouseEvent e) { - prevMouseX = e.getX(); - prevMouseY = e.getY(); - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = true; - } - } - - public void mouseReleased(MouseEvent e) { - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = false; - } - } - - public void mouseClicked(MouseEvent e) {} - - // Methods required for the implementation of MouseMotionListener - public void mouseDragged(MouseEvent e) { - int x = e.getX(); - int y = e.getY(); - Dimension size = e.getComponent().getSize(); - - float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)size.width); - float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)size.height); - - prevMouseX = x; - prevMouseY = y; - - view_rotx += thetaX; - view_roty += thetaY; - } - - public void mouseMoved(MouseEvent e) {} - - public void dispatchKey(int keyCode) { - switch (keyCode) { - case KeyEvent.VK_Q: - case KeyEvent.VK_ESCAPE: - runExit(); - } - } - } - public void runExit() { // Run this on another thread than the AWT event queue to // make sure the call to Animator.stop() completes before diff --git a/src/demos/fullscreen/JGearsFullscreen.java b/src/demos/fullscreen/JGearsFullscreen.java index 84c79b7..68a0bce 100755 --- a/src/demos/fullscreen/JGearsFullscreen.java +++ b/src/demos/fullscreen/JGearsFullscreen.java @@ -4,7 +4,9 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; +import demos.jgears.JGears; import demos.util.*; /** @@ -51,8 +53,8 @@ public class JGearsFullscreen { if (newMode != null) { frame.setUndecorated(true); } - GLJPanel drawable = GLDrawableFactory.getFactory().createGLJPanel(new GLCapabilities()); - drawable.addGLEventListener(new GearRenderer()); + GLJPanel drawable = new JGears(); + drawable.addGLEventListener(new FullscreenWorkaround(initWidth, initHeight)); frame.getContentPane().setLayout(new BorderLayout()); @@ -110,324 +112,6 @@ public class JGearsFullscreen { animator.start(); } - class GearRenderer implements GLEventListener, MouseListener, MouseMotionListener { - private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f; - private int gear1, gear2, gear3; - private float angle = 0.0f; - - private int prevMouseX, prevMouseY; - private boolean mouseRButtonDown = false; - - public void init(GLDrawable drawable) { - // Use debug pipeline - // drawable.setGL(new DebugGL(drawable.getGL())); - - GL gl = drawable.getGL(); - - // FIXME: workaround for Windows full-screen bug when - // sun.java2d.noddraw=true and similar bug on Mac OS X - if (fullScreen) { - final GLDrawable tmpDrawable = drawable; - Runnable r = new Runnable() { - public void run() { - frame.setVisible(false); - frame.setBounds(0, 0, initWidth, initHeight); - frame.setVisible(true); - frame.toFront(); - frame.requestFocus(); - } - }; - // FIXME: this is a total hack to work around behavior seen on JDK 1.5 - // Should find a better way / place to do this (to ensure the - // fixup runnable is only invoked once things have settled - // down) - EventQueue.invokeLater(r); - EventQueue.invokeLater(r); - } - - System.err.println("INIT GL IS: " + gl.getClass().getName()); - - gl.setSwapInterval(1); - - float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; - float red[] = { 0.8f, 0.1f, 0.0f, 1.0f }; - float green[] = { 0.0f, 0.8f, 0.2f, 1.0f }; - float blue[] = { 0.2f, 0.2f, 1.0f, 1.0f }; - - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos); - gl.glEnable(GL.GL_CULL_FACE); - gl.glEnable(GL.GL_LIGHTING); - gl.glEnable(GL.GL_LIGHT0); - gl.glEnable(GL.GL_DEPTH_TEST); - - /* make the gears */ - gear1 = gl.glGenLists(1); - gl.glNewList(gear1, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red); - gear(gl, 1.0f, 4.0f, 1.0f, 20, 0.7f); - gl.glEndList(); - - gear2 = gl.glGenLists(1); - gl.glNewList(gear2, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, green); - gear(gl, 0.5f, 2.0f, 2.0f, 10, 0.7f); - gl.glEndList(); - - gear3 = gl.glGenLists(1); - gl.glNewList(gear3, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, blue); - gear(gl, 1.3f, 2.0f, 0.5f, 10, 0.7f); - gl.glEndList(); - - gl.glEnable(GL.GL_NORMALIZE); - - drawable.addMouseListener(this); - drawable.addMouseMotionListener(this); - - // FIXME: for some reason, adding a key listener to the GLJPanel - // isn't working in this configuration - InputMap map = ((GLJPanel) drawable).getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); - ActionMap actMap = ((GLJPanel) drawable).getActionMap(); - Action act = new AbstractAction() { - public void actionPerformed(ActionEvent e) { - runExit(); - } - }; - - map.put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), act); - map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), act); - actMap.put(act, act); - } - - public void reshape(GLDrawable drawable, int x, int y, int width, int height) { - GL gl = drawable.getGL(); - - float h = (float)height / (float)width; - - gl.glMatrixMode(GL.GL_PROJECTION); - - System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)); - System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)); - System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)); - System.err.println(); - System.err.println("glLoadTransposeMatrixfARB() supported: " + - gl.isFunctionAvailable("glLoadTransposeMatrixfARB")); - if (!gl.isFunctionAvailable("glLoadTransposeMatrixfARB")) { - // --- not using extensions - gl.glLoadIdentity(); - } else { - // --- using extensions - final float[] identityTranspose = new float[] { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - }; - gl.glLoadTransposeMatrixfARB(identityTranspose); - } - gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f); - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glLoadIdentity(); - gl.glTranslatef(0.0f, 0.0f, -40.0f); - } - - public void display(GLDrawable drawable) { - angle += 2.0f; - - GL gl = drawable.getGL(); - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - - gl.glPushMatrix(); - gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f); - gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f); - gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f); - - gl.glPushMatrix(); - gl.glTranslatef(-3.0f, -2.0f, 0.0f); - gl.glRotatef(angle, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear1); - gl.glPopMatrix(); - - gl.glPushMatrix(); - gl.glTranslatef(3.1f, -2.0f, 0.0f); - gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear2); - gl.glPopMatrix(); - - gl.glPushMatrix(); - gl.glTranslatef(-3.1f, 4.2f, 0.0f); - gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear3); - gl.glPopMatrix(); - - gl.glPopMatrix(); - } - - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - - private void gear(GL gl, - float inner_radius, - float outer_radius, - float width, - int teeth, - float tooth_depth) - { - int i; - float r0, r1, r2; - float angle, da; - float u, v, len; - - r0 = inner_radius; - r1 = outer_radius - tooth_depth / 2.0f; - r2 = outer_radius + tooth_depth / 2.0f; - - da = 2.0f * (float) Math.PI / teeth / 4.0f; - - gl.glShadeModel(GL.GL_FLAT); - - gl.glNormal3f(0.0f, 0.0f, 1.0f); - - /* draw front face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - if(i < teeth) - { - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - } - gl.glEnd(); - - /* draw front sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2.0f * da), r2 * (float)Math.sin(angle + 2.0f * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - gl.glEnd(); - - /* draw back face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); - - /* draw back sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); - - /* draw outward faces of teeth */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - u = r2 * (float)Math.cos(angle + da) - r1 * (float)Math.cos(angle); - v = r2 * (float)Math.sin(angle + da) - r1 * (float)Math.sin(angle); - len = (float)Math.sqrt(u * u + v * v); - u /= len; - v /= len; - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - u = r1 * (float)Math.cos(angle + 3 * da) - r2 * (float)Math.cos(angle + 2 * da); - v = r1 * (float)Math.sin(angle + 3 * da) - r2 * (float)Math.sin(angle + 2 * da); - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - } - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), -width * 0.5f); - gl.glEnd(); - - gl.glShadeModel(GL.GL_SMOOTH); - - /* draw inside radius cylinder */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glNormal3f(-(float)Math.cos(angle), -(float)Math.sin(angle), 0.0f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - } - gl.glEnd(); - } - - // Methods required for the implementation of MouseListener - public void mouseEntered(MouseEvent e) {} - public void mouseExited(MouseEvent e) {} - - public void mousePressed(MouseEvent e) { - prevMouseX = e.getX(); - prevMouseY = e.getY(); - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = true; - } - } - - public void mouseReleased(MouseEvent e) { - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = false; - } - } - - public void mouseClicked(MouseEvent e) {} - - // Methods required for the implementation of MouseMotionListener - public void mouseDragged(MouseEvent e) { - int x = e.getX(); - int y = e.getY(); - Dimension size = e.getComponent().getSize(); - - float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)size.width); - float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)size.height); - - prevMouseX = x; - prevMouseY = y; - - view_rotx += thetaX; - view_roty += thetaY; - } - - public void mouseMoved(MouseEvent e) {} - - public void dispatchKey(int keyCode) { - switch (keyCode) { - case KeyEvent.VK_Q: - case KeyEvent.VK_ESCAPE: - runExit(); - } - } - } - public void runExit() { // Run this on another thread than the AWT event queue to // make sure the call to Animator.stop() completes before diff --git a/src/demos/gears/Gears.java b/src/demos/gears/Gears.java index da8fdba..9382e40 100644 --- a/src/demos/gears/Gears.java +++ b/src/demos/gears/Gears.java @@ -3,7 +3,8 @@ package demos.gears; import java.awt.*; import java.awt.event.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** * Gears.java <BR> @@ -12,12 +13,12 @@ import net.java.games.jogl.*; * This version is equal to Brian Paul's version 1.2 1999/10/21 */ -public class Gears { +public class Gears implements GLEventListener, MouseListener, MouseMotionListener { public static void main(String[] args) { Frame frame = new Frame("Gear Demo"); GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); - canvas.addGLEventListener(new GearRenderer()); + canvas.addGLEventListener(new Gears()); frame.add(canvas); frame.setSize(300, 300); final Animator animator = new Animator(canvas); @@ -38,279 +39,268 @@ public class Gears { animator.start(); } - static class GearRenderer implements GLEventListener, MouseListener, MouseMotionListener { - private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f; - private int gear1, gear2, gear3; - private float angle = 0.0f; + private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f; + private int gear1, gear2, gear3; + private float angle = 0.0f; - private int prevMouseX, prevMouseY; - private boolean mouseRButtonDown = false; + private int prevMouseX, prevMouseY; + private boolean mouseRButtonDown = false; - public void init(GLDrawable drawable) { - // Use debug pipeline - // drawable.setGL(new DebugGL(drawable.getGL())); + public void init(GLAutoDrawable drawable) { + // Use debug pipeline + // drawable.setGL(new DebugGL(drawable.getGL())); - GL gl = drawable.getGL(); + GL gl = drawable.getGL(); - System.err.println("INIT GL IS: " + gl.getClass().getName()); + System.err.println("INIT GL IS: " + gl.getClass().getName()); - gl.setSwapInterval(1); + gl.setSwapInterval(1); - float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; - float red[] = { 0.8f, 0.1f, 0.0f, 1.0f }; - float green[] = { 0.0f, 0.8f, 0.2f, 1.0f }; - float blue[] = { 0.2f, 0.2f, 1.0f, 1.0f }; + float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; + float red[] = { 0.8f, 0.1f, 0.0f, 1.0f }; + float green[] = { 0.0f, 0.8f, 0.2f, 1.0f }; + float blue[] = { 0.2f, 0.2f, 1.0f, 1.0f }; - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos); - gl.glEnable(GL.GL_CULL_FACE); - gl.glEnable(GL.GL_LIGHTING); - gl.glEnable(GL.GL_LIGHT0); - gl.glEnable(GL.GL_DEPTH_TEST); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos, 0); + gl.glEnable(GL.GL_CULL_FACE); + gl.glEnable(GL.GL_LIGHTING); + gl.glEnable(GL.GL_LIGHT0); + gl.glEnable(GL.GL_DEPTH_TEST); - /* make the gears */ - gear1 = gl.glGenLists(1); - gl.glNewList(gear1, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red); - gear(gl, 1.0f, 4.0f, 1.0f, 20, 0.7f); - gl.glEndList(); + /* make the gears */ + gear1 = gl.glGenLists(1); + gl.glNewList(gear1, GL.GL_COMPILE); + gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red, 0); + gear(gl, 1.0f, 4.0f, 1.0f, 20, 0.7f); + gl.glEndList(); - gear2 = gl.glGenLists(1); - gl.glNewList(gear2, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, green); - gear(gl, 0.5f, 2.0f, 2.0f, 10, 0.7f); - gl.glEndList(); + gear2 = gl.glGenLists(1); + gl.glNewList(gear2, GL.GL_COMPILE); + gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, green, 0); + gear(gl, 0.5f, 2.0f, 2.0f, 10, 0.7f); + gl.glEndList(); - gear3 = gl.glGenLists(1); - gl.glNewList(gear3, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, blue); - gear(gl, 1.3f, 2.0f, 0.5f, 10, 0.7f); - gl.glEndList(); + gear3 = gl.glGenLists(1); + gl.glNewList(gear3, GL.GL_COMPILE); + gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, blue, 0); + gear(gl, 1.3f, 2.0f, 0.5f, 10, 0.7f); + gl.glEndList(); - gl.glEnable(GL.GL_NORMALIZE); + gl.glEnable(GL.GL_NORMALIZE); - drawable.addMouseListener(this); - drawable.addMouseMotionListener(this); - } + drawable.addMouseListener(this); + drawable.addMouseMotionListener(this); + } - public void reshape(GLDrawable drawable, int x, int y, int width, int height) { - GL gl = drawable.getGL(); + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + GL gl = drawable.getGL(); - float h = (float)height / (float)width; + float h = (float)height / (float)width; - gl.glMatrixMode(GL.GL_PROJECTION); + gl.glMatrixMode(GL.GL_PROJECTION); - System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)); - System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)); - System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)); - System.err.println(); - System.err.println("glLoadTransposeMatrixfARB() supported: " + - gl.isFunctionAvailable("glLoadTransposeMatrixfARB")); - if (!gl.isFunctionAvailable("glLoadTransposeMatrixfARB")) { - // --- not using extensions - gl.glLoadIdentity(); - } else { - // --- using extensions - final float[] identityTranspose = new float[] { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - }; - gl.glLoadTransposeMatrixfARB(identityTranspose); - } - gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f); - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glLoadIdentity(); - gl.glTranslatef(0.0f, 0.0f, -40.0f); - } + System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)); + System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)); + System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)); + gl.glLoadIdentity(); + gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f); + gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glLoadIdentity(); + gl.glTranslatef(0.0f, 0.0f, -40.0f); + } - public void display(GLDrawable drawable) { - angle += 2.0f; + public void display(GLAutoDrawable drawable) { + angle += 2.0f; - GL gl = drawable.getGL(); + GL gl = drawable.getGL(); + if ((drawable instanceof GLJPanel) && + !((GLJPanel) drawable).isOpaque() && + ((GLJPanel) drawable).shouldPreserveColorBufferIfTranslucent()) { + gl.glClear(GL.GL_DEPTH_BUFFER_BIT); + } else { gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + } - gl.glPushMatrix(); - gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f); - gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f); - gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f); + gl.glPushMatrix(); + gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f); + gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f); + gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f); - gl.glPushMatrix(); - gl.glTranslatef(-3.0f, -2.0f, 0.0f); - gl.glRotatef(angle, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear1); - gl.glPopMatrix(); + gl.glPushMatrix(); + gl.glTranslatef(-3.0f, -2.0f, 0.0f); + gl.glRotatef(angle, 0.0f, 0.0f, 1.0f); + gl.glCallList(gear1); + gl.glPopMatrix(); - gl.glPushMatrix(); - gl.glTranslatef(3.1f, -2.0f, 0.0f); - gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear2); - gl.glPopMatrix(); + gl.glPushMatrix(); + gl.glTranslatef(3.1f, -2.0f, 0.0f); + gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f); + gl.glCallList(gear2); + gl.glPopMatrix(); - gl.glPushMatrix(); - gl.glTranslatef(-3.1f, 4.2f, 0.0f); - gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear3); - gl.glPopMatrix(); + gl.glPushMatrix(); + gl.glTranslatef(-3.1f, 4.2f, 0.0f); + gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f); + gl.glCallList(gear3); + gl.glPopMatrix(); - gl.glPopMatrix(); - } + gl.glPopMatrix(); + } - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - private void gear(GL gl, - float inner_radius, - float outer_radius, - float width, - int teeth, - float tooth_depth) - { - int i; - float r0, r1, r2; - float angle, da; - float u, v, len; + private void gear(GL gl, + float inner_radius, + float outer_radius, + float width, + int teeth, + float tooth_depth) + { + int i; + float r0, r1, r2; + float angle, da; + float u, v, len; - r0 = inner_radius; - r1 = outer_radius - tooth_depth / 2.0f; - r2 = outer_radius + tooth_depth / 2.0f; + r0 = inner_radius; + r1 = outer_radius - tooth_depth / 2.0f; + r2 = outer_radius + tooth_depth / 2.0f; - da = 2.0f * (float) Math.PI / teeth / 4.0f; + da = 2.0f * (float) Math.PI / teeth / 4.0f; - gl.glShadeModel(GL.GL_FLAT); + gl.glShadeModel(GL.GL_FLAT); - gl.glNormal3f(0.0f, 0.0f, 1.0f); + gl.glNormal3f(0.0f, 0.0f, 1.0f); - /* draw front face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - if(i < teeth) - { - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - } - gl.glEnd(); + /* draw front face */ + gl.glBegin(GL.GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) + { + angle = i * 2.0f * (float) Math.PI / teeth; + gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); + gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); + if(i < teeth) + { + gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); + gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); + } + } + gl.glEnd(); - /* draw front sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2.0f * da), r2 * (float)Math.sin(angle + 2.0f * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - gl.glEnd(); + /* draw front sides of teeth */ + gl.glBegin(GL.GL_QUADS); + for (i = 0; i < teeth; i++) + { + angle = i * 2.0f * (float) Math.PI / teeth; + gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); + gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); + gl.glVertex3f(r2 * (float)Math.cos(angle + 2.0f * da), r2 * (float)Math.sin(angle + 2.0f * da), width * 0.5f); + gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); + } + gl.glEnd(); - /* draw back face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); + /* draw back face */ + gl.glBegin(GL.GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) + { + angle = i * 2.0f * (float) Math.PI / teeth; + gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); + gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); + gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); + gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); + } + gl.glEnd(); - /* draw back sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); + /* draw back sides of teeth */ + gl.glBegin(GL.GL_QUADS); + for (i = 0; i < teeth; i++) + { + angle = i * 2.0f * (float) Math.PI / teeth; + gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); + gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); + gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); + gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); + } + gl.glEnd(); - /* draw outward faces of teeth */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - u = r2 * (float)Math.cos(angle + da) - r1 * (float)Math.cos(angle); - v = r2 * (float)Math.sin(angle + da) - r1 * (float)Math.sin(angle); - len = (float)Math.sqrt(u * u + v * v); - u /= len; - v /= len; - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - u = r1 * (float)Math.cos(angle + 3 * da) - r2 * (float)Math.cos(angle + 2 * da); - v = r1 * (float)Math.sin(angle + 3 * da) - r2 * (float)Math.sin(angle + 2 * da); - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - } - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), -width * 0.5f); - gl.glEnd(); + /* draw outward faces of teeth */ + gl.glBegin(GL.GL_QUAD_STRIP); + for (i = 0; i < teeth; i++) + { + angle = i * 2.0f * (float) Math.PI / teeth; + gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); + gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); + u = r2 * (float)Math.cos(angle + da) - r1 * (float)Math.cos(angle); + v = r2 * (float)Math.sin(angle + da) - r1 * (float)Math.sin(angle); + len = (float)Math.sqrt(u * u + v * v); + u /= len; + v /= len; + gl.glNormal3f(v, -u, 0.0f); + gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); + gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); + gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); + gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), width * 0.5f); + gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); + u = r1 * (float)Math.cos(angle + 3 * da) - r2 * (float)Math.cos(angle + 2 * da); + v = r1 * (float)Math.sin(angle + 3 * da) - r2 * (float)Math.sin(angle + 2 * da); + gl.glNormal3f(v, -u, 0.0f); + gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), width * 0.5f); + gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); + gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); + } + gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), width * 0.5f); + gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), -width * 0.5f); + gl.glEnd(); - gl.glShadeModel(GL.GL_SMOOTH); + gl.glShadeModel(GL.GL_SMOOTH); - /* draw inside radius cylinder */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glNormal3f(-(float)Math.cos(angle), -(float)Math.sin(angle), 0.0f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - } - gl.glEnd(); - } + /* draw inside radius cylinder */ + gl.glBegin(GL.GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) + { + angle = i * 2.0f * (float) Math.PI / teeth; + gl.glNormal3f(-(float)Math.cos(angle), -(float)Math.sin(angle), 0.0f); + gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); + gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); + } + gl.glEnd(); + } - // Methods required for the implementation of MouseListener - public void mouseEntered(MouseEvent e) {} - public void mouseExited(MouseEvent e) {} + // Methods required for the implementation of MouseListener + public void mouseEntered(MouseEvent e) {} + public void mouseExited(MouseEvent e) {} - public void mousePressed(MouseEvent e) { - prevMouseX = e.getX(); - prevMouseY = e.getY(); - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = true; - } + public void mousePressed(MouseEvent e) { + prevMouseX = e.getX(); + prevMouseY = e.getY(); + if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { + mouseRButtonDown = true; } + } - public void mouseReleased(MouseEvent e) { - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = false; - } + public void mouseReleased(MouseEvent e) { + if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { + mouseRButtonDown = false; } + } - public void mouseClicked(MouseEvent e) {} + public void mouseClicked(MouseEvent e) {} - // Methods required for the implementation of MouseMotionListener - public void mouseDragged(MouseEvent e) { - int x = e.getX(); - int y = e.getY(); - Dimension size = e.getComponent().getSize(); + // Methods required for the implementation of MouseMotionListener + public void mouseDragged(MouseEvent e) { + int x = e.getX(); + int y = e.getY(); + Dimension size = e.getComponent().getSize(); - float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)size.width); - float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)size.height); + float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)size.width); + float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)size.height); - prevMouseX = x; - prevMouseY = y; + prevMouseX = x; + prevMouseY = y; - view_rotx += thetaX; - view_roty += thetaY; - } - - public void mouseMoved(MouseEvent e) {} + view_rotx += thetaX; + view_roty += thetaY; } + + public void mouseMoved(MouseEvent e) {} } diff --git a/src/demos/hdr/ARBFPPipeline.java b/src/demos/hdr/ARBFPPipeline.java index e13b9f7..4501db3 100755 --- a/src/demos/hdr/ARBFPPipeline.java +++ b/src/demos/hdr/ARBFPPipeline.java @@ -3,7 +3,8 @@ package demos.hdr; import java.io.*; import java.util.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; import demos.util.*; public class ARBFPPipeline implements Pipeline { @@ -26,7 +27,7 @@ public class ARBFPPipeline implements Pipeline { } public void copyToTexture(GL gl, int textureObject, int w, int h) { - gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_NV, textureObject); + gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_NV, textureObject); gl.glCopyTexSubImage2D(GL.GL_TEXTURE_RECTANGLE_NV, 0, 0, 0, 0, 0, w, h); } @@ -46,12 +47,12 @@ public class ARBFPPipeline implements Pipeline { private int loadProgram(GL gl, String fileName, int profile) throws IOException { String programBuffer = FileUtils.loadStreamIntoString(getClass().getClassLoader().getResourceAsStream(fileName)); int[] tmpInt = new int[1]; - gl.glGenProgramsARB(1, tmpInt); + gl.glGenProgramsARB(1, tmpInt, 0); int res = tmpInt[0]; gl.glBindProgramARB(profile, res); gl.glProgramStringARB(profile, GL.GL_PROGRAM_FORMAT_ASCII_ARB, programBuffer.length(), programBuffer); int[] errPos = new int[1]; - gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos); + gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos, 0); if (errPos[0] >= 0) { String kind = "Program"; if (profile == GL.GL_VERTEX_PROGRAM_ARB) { @@ -78,7 +79,7 @@ public class ARBFPPipeline implements Pipeline { int[] isNative = new int[1]; gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB, GL.GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, - isNative); + isNative, 0); if (isNative[0] != 1) { System.out.println("WARNING: fragment program is over native resource limits"); Thread.dumpStack(); @@ -146,8 +147,8 @@ public class ARBFPPipeline implements Pipeline { float[] mvp = new float[16]; // Get matrices - gl.glGetFloatv(GL.GL_PROJECTION_MATRIX, projection); - gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, modelView); + gl.glGetFloatv(GL.GL_PROJECTION_MATRIX, projection, 0); + gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, modelView, 0); // Multiply together for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { diff --git a/src/demos/hdr/CgPipeline.java b/src/demos/hdr/CgPipeline.java index 2f3a9f5..9a2bd0b 100755 --- a/src/demos/hdr/CgPipeline.java +++ b/src/demos/hdr/CgPipeline.java @@ -3,8 +3,9 @@ package demos.hdr; import java.io.*; import java.util.*; -import net.java.games.jogl.*; -import net.java.games.cg.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; +import com.sun.opengl.cg.*; import demos.util.*; public class CgPipeline implements Pipeline { @@ -108,6 +109,6 @@ public class CgPipeline implements Pipeline { } public void setMatrixParameterfc(GL gl, int param, float[] matrix) { - CgGL.cgGLSetMatrixParameterfc((CGparameter) parameters.get(param), matrix); + CgGL.cgGLSetMatrixParameterfc((CGparameter) parameters.get(param), matrix, 0); } } diff --git a/src/demos/hdr/HDR.java b/src/demos/hdr/HDR.java index 2e650fc..5cdf56b 100755 --- a/src/demos/hdr/HDR.java +++ b/src/demos/hdr/HDR.java @@ -7,9 +7,10 @@ import java.nio.*; import java.util.*; import javax.swing.*; -import net.java.games.jogl.*; -import net.java.games.cg.*; -import net.java.games.jogl.util.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; +import demos.common.*; import demos.util.*; import gleem.*; import gleem.linalg.*; @@ -19,12 +20,19 @@ import gleem.linalg.*; Ported to Java by Kenneth Russell */ -public class HDR { +public class HDR extends Demo { + private static String[] defaultArgs = { + "demos/data/images/stpeters_cross.hdr", + "512", + "384", + "2", + "7", + "3", + "demos/data/models/teapot.obj" + }; + private GLAutoDrawable drawable; private boolean useCg; - private GLCanvas canvas; - private Frame frame; - private Animator animator; - private boolean initFailed; + private boolean initComplete; private HDRTexture hdr; private String modelFilename; private ObjReader model; @@ -97,10 +105,42 @@ public class HDR { 0.0f, 0.0f, 0.0f, 1.0f }; public static void main(String[] args) { - new HDR().run(args); + GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); + HDR demo = new HDR(); + canvas.addGLEventListener(demo); + + final Animator animator = new Animator(canvas); + demo.setDemoListener(new DemoListener() { + public void shutdownDemo() { + runExit(animator); + } + public void repaint() {} + }); + demo.setup(args); + + Frame frame = new Frame("High Dynamic Range Rendering Demo"); + frame.setLayout(new BorderLayout()); + canvas.setSize(demo.getPreferredWidth(), demo.getPreferredHeight()); + + frame.add(canvas, BorderLayout.CENTER); + frame.pack(); + frame.show(); + canvas.requestFocus(); + + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + runExit(animator); + } + }); + + animator.start(); } - public void run(String[] args) { + public void setup(String[] args) { + if ((args == null) || (args.length == 0)) { + args = defaultArgs; + } + if (args.length < 6 || args.length > 8) { usage(); } @@ -168,333 +208,354 @@ public class HDR { System.exit(0); } - canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); - canvas.addGLEventListener(new Listener()); - canvas.setNoAutoRedrawMode(true); - - animator = new Animator(canvas); - - frame = new Frame("HDR test"); - frame.setLayout(new BorderLayout()); - canvas.setSize(win_w, win_h); - - frame.add(canvas, BorderLayout.CENTER); - frame.pack(); - frame.setResizable(false); - frame.show(); - canvas.requestFocus(); + } - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - runExit(); - } - }); + public int getPreferredWidth() { + return win_w; + } - animator.start(); + public int getPreferredHeight() { + return win_h; } //---------------------------------------------------------------------- // Internals only below this point // + public void shutdownDemo() { + ManipManager.getManipManager().unregisterWindow(drawable); + drawable.removeGLEventListener(this); + super.shutdownDemo(); + } + //---------------------------------------------------------------------- - // Listeners for main window and pbuffers + // Listener for main window // - class Listener implements GLEventListener { - private float zNear = 0.1f; - private float zFar = 10.0f; - private boolean wire = false; - private boolean toggleWire = false; - - public void init(GLDrawable drawable) { - // printThreadName("init for Listener"); + private float zNear = 0.1f; + private float zFar = 10.0f; + private boolean wire = false; + private boolean toggleWire = false; + private GLU glu = new GLU(); + + public void init(GLAutoDrawable drawable) { + initComplete = false; + // printThreadName("init for Listener"); + + GL gl = drawable.getGL(); + + checkExtension(gl, "GL_VERSION_1_3"); // For multitexture + checkExtension(gl, "GL_ARB_pbuffer"); + checkExtension(gl, "GL_ARB_vertex_program"); + checkExtension(gl, "GL_ARB_fragment_program"); + if (!gl.isExtensionAvailable("GL_NV_texture_rectangle") && + !gl.isExtensionAvailable("GL_EXT_texture_rectangle") && + !gl.isExtensionAvailable("GL_ARB_texture_rectangle")) { + // NOTE: it turns out the constants associated with these extensions are all identical + unavailableExtension("Texture rectangle extension not available (need one of GL_NV_texture_rectangle, GL_EXT_texture_rectangle or GL_ARB_texture_rectangle"); + } - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); - - checkExtension(gl, "GL_ARB_multitexture"); - checkExtension(gl, "GL_ARB_pbuffer"); - checkExtension(gl, "GL_ARB_vertex_program"); - checkExtension(gl, "GL_ARB_fragment_program"); - if (!gl.isExtensionAvailable("GL_NV_texture_rectangle") && - !gl.isExtensionAvailable("GL_EXT_texture_rectangle") && - !gl.isExtensionAvailable("GL_ARB_texture_rectangle")) { - // NOTE: it turns out the constants associated with these extensions are all identical - unavailableExtension("Texture rectangle extension not available (need one of GL_NV_texture_rectangle, GL_EXT_texture_rectangle or GL_ARB_texture_rectangle"); - } + if (!gl.isExtensionAvailable("GL_NV_float_buffer") && + !gl.isExtensionAvailable("GL_ATI_texture_float") && + !gl.isExtensionAvailable("GL_APPLE_float_pixels")) { + unavailableExtension("Floating-point textures not available (need one of GL_NV_float_buffer, GL_ATI_texture_float, or GL_APPLE_float_pixels"); + } - if (!gl.isExtensionAvailable("GL_NV_float_buffer") && - !gl.isExtensionAvailable("GL_ATI_texture_float") && - !gl.isExtensionAvailable("GL_APPLE_float_pixels")) { - unavailableExtension("Floating-point textures not available (need one of GL_NV_float_buffer, GL_ATI_texture_float, or GL_APPLE_float_pixels"); - } + setOrthoProjection(gl, 0, 0, win_w, win_h); + + gamma_tex = createGammaTexture(gl, 1024, 1.0f / 2.2f); + vignette_tex = createVignetteTexture(gl, pbuffer_w, pbuffer_h, 0.25f*pbuffer_w, 0.7f*pbuffer_w); + + int floatBits = 16; + int floatAlphaBits = 0; + // int floatDepthBits = 16; + // Workaround for apparent bug when not using render-to-texture-rectangle + int floatDepthBits = 1; + + GLCapabilities caps = new GLCapabilities(); + caps.setDoubleBuffered(false); + caps.setOffscreenFloatingPointBuffers(true); + caps.setRedBits(floatBits); + caps.setGreenBits(floatBits); + caps.setBlueBits(floatBits); + caps.setAlphaBits(floatAlphaBits); + caps.setDepthBits(floatDepthBits); + int[] tmp = new int[1]; + if (!GLDrawableFactory.getFactory().canCreateGLPbuffer()) { + unavailableExtension("Can not create pbuffer"); + } + if (pbuffer != null) { + pbuffer.destroy(); + pbuffer = null; + } + if (blur_pbuffer != null) { + blur_pbuffer.destroy(); + blur_pbuffer = null; + } + if (blur2_pbuffer != null) { + blur2_pbuffer.destroy(); + blur2_pbuffer = null; + } + if (tonemap_pbuffer != null) { + tonemap_pbuffer.destroy(); + tonemap_pbuffer = null; + } - setOrthoProjection(gl, win_w, win_h); - - gamma_tex = createGammaTexture(gl, 1024, 1.0f / 2.2f); - vignette_tex = createVignetteTexture(gl, pbuffer_w, pbuffer_h, 0.25f*pbuffer_w, 0.7f*pbuffer_w); - - int floatBits = 16; - int floatAlphaBits = 0; - // int floatDepthBits = 16; - // Workaround for apparent bug when not using render-to-texture-rectangle - int floatDepthBits = 1; - - GLCapabilities caps = new GLCapabilities(); - caps.setDoubleBuffered(false); - caps.setOffscreenFloatingPointBuffers(true); - caps.setRedBits(floatBits); - caps.setGreenBits(floatBits); - caps.setBlueBits(floatBits); - caps.setAlphaBits(floatAlphaBits); - caps.setDepthBits(floatDepthBits); - int[] tmp = new int[1]; - pbuffer = drawable.createOffscreenDrawable(caps, pbuffer_w, pbuffer_h); - pbuffer.addGLEventListener(new PbufferListener()); - gl.glGenTextures(1, tmp); - pbuffer_tex = tmp[0]; - blur_pbuffer = drawable.createOffscreenDrawable(caps, blur_w, blur_h); - blur_pbuffer.addGLEventListener(new BlurPbufferListener()); - gl.glGenTextures(1, tmp); - blur_pbuffer_tex = tmp[0]; - blur2_pbuffer = drawable.createOffscreenDrawable(caps, blur_w, blur_h); - blur2_pbuffer.addGLEventListener(new Blur2PbufferListener()); - gl.glGenTextures(1, tmp); - blur2_pbuffer_tex = tmp[0]; - caps.setOffscreenFloatingPointBuffers(false); - caps.setRedBits(8); - caps.setGreenBits(8); - caps.setBlueBits(8); - caps.setDepthBits(24); - tonemap_pbuffer = drawable.createOffscreenDrawable(caps, pbuffer_w, pbuffer_h); - tonemap_pbuffer.addGLEventListener(new TonemapPbufferListener()); - gl.glGenTextures(1, tmp); - tonemap_pbuffer_tex = tmp[0]; + GLContext parentContext = drawable.getContext(); + pbuffer = GLDrawableFactory.getFactory().createGLPbuffer(caps, pbuffer_w, pbuffer_h, parentContext); + pbuffer.addGLEventListener(new PbufferListener()); + gl.glGenTextures(1, tmp, 0); + pbuffer_tex = tmp[0]; + blur_pbuffer = GLDrawableFactory.getFactory().createGLPbuffer(caps, blur_w, blur_h, parentContext); + blur_pbuffer.addGLEventListener(new BlurPbufferListener()); + gl.glGenTextures(1, tmp, 0); + blur_pbuffer_tex = tmp[0]; + blur2_pbuffer = GLDrawableFactory.getFactory().createGLPbuffer(caps, blur_w, blur_h, parentContext); + blur2_pbuffer.addGLEventListener(new Blur2PbufferListener()); + gl.glGenTextures(1, tmp, 0); + blur2_pbuffer_tex = tmp[0]; + caps.setOffscreenFloatingPointBuffers(false); + caps.setRedBits(8); + caps.setGreenBits(8); + caps.setBlueBits(8); + caps.setDepthBits(24); + tonemap_pbuffer = GLDrawableFactory.getFactory().createGLPbuffer(caps, pbuffer_w, pbuffer_h, parentContext); + tonemap_pbuffer.addGLEventListener(new TonemapPbufferListener()); + gl.glGenTextures(1, tmp, 0); + tonemap_pbuffer_tex = tmp[0]; - drawable.addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent e) { - dispatchKey(e.getKeyCode(), e.getKeyChar()); - } - }); - - // Register the window with the ManipManager - ManipManager manager = ManipManager.getManipManager(); - manager.registerWindow(drawable); - - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); - viewer.setNoAltKeyMode(true); - viewer.attach(drawable, new BSphereProvider() { - public BSphere getBoundingSphere() { - return new BSphere(new Vec3f(0, 0, 0), 1.0f); - } - }); - viewer.setZNear(zNear); - viewer.setZFar(zFar); - } + drawable.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + dispatchKey(e.getKeyCode(), e.getKeyChar()); + } + }); - public void display(GLDrawable drawable) { - // printThreadName("display for Listener"); + doViewAll = true; - if (initFailed) { - return; - } + // Register the window with the ManipManager + ManipManager manager = ManipManager.getManipManager(); + manager.registerWindow(drawable); + this.drawable = drawable; - if (!firstRender) { - if (++frameCount == 30) { - timer.stop(); - System.err.println("Frames per second: " + (30.0f / timer.getDurationAsSeconds())); - timer.reset(); - timer.start(); - frameCount = 0; + viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer.setAutoRedrawMode(false); + viewer.setNoAltKeyMode(true); + viewer.attach(drawable, new BSphereProvider() { + public BSphere getBoundingSphere() { + return new BSphere(new Vec3f(0, 0, 0), 1.0f); } - } else { - firstRender = false; - timer.start(); - } + }); + viewer.setZNear(zNear); + viewer.setZFar(zFar); + initComplete = true; + } - time.update(); + public void display(GLAutoDrawable drawable) { + // printThreadName("display for Listener"); - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); + if (!initComplete) { + return; + } - // OK, ready to go - if (b[' ']) { - viewer.rotateAboutFocalPoint(new Rotf(Vec3f.Y_AXIS, (float) (time.deltaT() * animRate))); + if (!firstRender) { + if (++frameCount == 30) { + timer.stop(); + System.err.println("Frames per second: " + (30.0f / timer.getDurationAsSeconds())); + timer.reset(); + timer.start(); + frameCount = 0; } + } else { + firstRender = false; + timer.start(); + } - pbuffer.display(); + time.update(); - // blur pass - if (b['g']) { - // shrink image - blur2Pass = BLUR2_SHRINK_PASS; - blur2_pbuffer.display(); - } + GL gl = drawable.getGL(); - // horizontal blur - blur_pbuffer.display(); + // OK, ready to go + if (b[' ']) { + viewer.rotateAboutFocalPoint(new Rotf(Vec3f.Y_AXIS, (float) (time.deltaT() * animRate))); + } + + pbuffer.display(); + + // FIXME: because of changes in lazy pbuffer instantiation + // behavior the pbuffer might not have been run just now + if (pipeline == null) { + return; + } - // vertical blur - blur2Pass = BLUR2_VERT_BLUR_PASS; + // blur pass + if (b['g']) { + // shrink image + blur2Pass = BLUR2_SHRINK_PASS; blur2_pbuffer.display(); + } - // tone mapping pass - tonemap_pbuffer.display(); + // horizontal blur + blur_pbuffer.display(); - // display in window - gl.glEnable(GL.GL_TEXTURE_RECTANGLE_NV); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); - gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_NV, tonemap_pbuffer_tex); - if (b['n']) { - gl.glTexParameteri( GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); - } else { - gl.glTexParameteri( GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); - } - drawQuadRect4(gl, win_w, win_h, pbuffer_w, pbuffer_h); - gl.glDisable(GL.GL_TEXTURE_RECTANGLE_NV); + // vertical blur + blur2Pass = BLUR2_VERT_BLUR_PASS; + blur2_pbuffer.display(); + + // tone mapping pass + tonemap_pbuffer.display(); - // Try to avoid swamping the CPU on Linux - Thread.yield(); + // display in window + gl.glEnable(GL.GL_TEXTURE_RECTANGLE_NV); + gl.glActiveTexture(GL.GL_TEXTURE0); + gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_NV, tonemap_pbuffer_tex); + if (b['n']) { + gl.glTexParameteri( GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); + } else { + gl.glTexParameteri( GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); } + drawQuadRect4(gl, win_w, win_h, pbuffer_w, pbuffer_h); + gl.glDisable(GL.GL_TEXTURE_RECTANGLE_NV); - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} + // Try to avoid swamping the CPU on Linux + Thread.yield(); + } - // Unused routines - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + setOrthoProjection(drawable.getGL(), x, y, width, height); + win_w = width; + win_h = height; + } - //---------------------------------------------------------------------- - // Internals only below this point - // - private void checkExtension(GL gl, String glExtensionName) { - if (!gl.isExtensionAvailable(glExtensionName)) { - unavailableExtension("Unable to initialize " + glExtensionName + " OpenGL extension"); - } - } + // Unused routines + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - private void unavailableExtension(String message) { - JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); - initFailed = true; - runExit(); - throw new GLException(message); + private void checkExtension(GL gl, String glExtensionName) { + if (!gl.isExtensionAvailable(glExtensionName)) { + unavailableExtension("Unable to initialize " + glExtensionName + " OpenGL extension"); } + } - private void dispatchKey(int keyCode, char k) { - if (k < 256) - b[k] = !b[k]; + private void unavailableExtension(String message) { + JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); + shutdownDemo(); + throw new GLException(message); + } - switch (keyCode) { - case KeyEvent.VK_ESCAPE: - case KeyEvent.VK_Q: - runExit(); - break; + private void dispatchKey(int keyCode, char k) { + if (k < 256) + b[k] = !b[k]; - case KeyEvent.VK_EQUALS: - exposure *= 2; - break; + switch (keyCode) { + case KeyEvent.VK_ESCAPE: + case KeyEvent.VK_Q: + shutdownDemo(); + break; - case KeyEvent.VK_MINUS: - exposure *= 0.5f; - break; + case KeyEvent.VK_EQUALS: + exposure *= 2; + break; - case KeyEvent.VK_PLUS: - exposure += 1.0f; - break; + case KeyEvent.VK_MINUS: + exposure *= 0.5f; + break; - case KeyEvent.VK_UNDERSCORE: - exposure -= 1.0f; - break; + case KeyEvent.VK_PLUS: + exposure += 1.0f; + break; - case KeyEvent.VK_PERIOD: - blurAmount += 0.1f; - break; + case KeyEvent.VK_UNDERSCORE: + exposure -= 1.0f; + break; - case KeyEvent.VK_COMMA: - blurAmount -= 0.1f; - break; + case KeyEvent.VK_PERIOD: + blurAmount += 0.1f; + break; - case KeyEvent.VK_G: - if (b['g']) - blurAmount = 0.5f; - else - blurAmount = 0.0f; - break; + case KeyEvent.VK_COMMA: + blurAmount -= 0.1f; + break; - case KeyEvent.VK_O: - modelno = (modelno + 1) % numModels; - break; + case KeyEvent.VK_G: + if (b['g']) + blurAmount = 0.5f; + else + blurAmount = 0.0f; + break; + + case KeyEvent.VK_O: + modelno = (modelno + 1) % numModels; + break; - case KeyEvent.VK_V: - doViewAll = true; - break; - } + case KeyEvent.VK_V: + doViewAll = true; + break; } + } - // create gamma lookup table texture - private int createGammaTexture(GL gl, int size, float gamma) { - int[] tmp = new int[1]; - gl.glGenTextures(1, tmp); - int texid = tmp[0]; + // create gamma lookup table texture + private int createGammaTexture(GL gl, int size, float gamma) { + int[] tmp = new int[1]; + gl.glGenTextures(1, tmp, 0); + int texid = tmp[0]; - int target = GL.GL_TEXTURE_1D; - gl.glBindTexture(target, texid); - gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); - gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); - gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); + int target = GL.GL_TEXTURE_1D; + gl.glBindTexture(target, texid); + gl.glTexParameteri(target, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); + gl.glTexParameteri(target, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); + gl.glTexParameteri(target, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); - gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); + gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); - float[] img = new float [size]; + float[] img = new float [size]; - for(int i=0; i<size; i++) { - float x = i / (float) size; - img[i] = (float) Math.pow(x, gamma); - } + for(int i=0; i<size; i++) { + float x = i / (float) size; + img[i] = (float) Math.pow(x, gamma); + } - gl.glTexImage1D(target, 0, GL.GL_LUMINANCE, size, 0, GL.GL_LUMINANCE, GL.GL_FLOAT, img); + gl.glTexImage1D(target, 0, GL.GL_LUMINANCE, size, 0, GL.GL_LUMINANCE, GL.GL_FLOAT, FloatBuffer.wrap(img)); - return texid; - } + return texid; + } - // create vignette texture - // based on Debevec's pflare.c - int createVignetteTexture(GL gl, int xsiz, int ysiz, float r0, float r1) { - int[] tmp = new int[1]; - gl.glGenTextures(1, tmp); - int texid = tmp[0]; + // create vignette texture + // based on Debevec's pflare.c + int createVignetteTexture(GL gl, int xsiz, int ysiz, float r0, float r1) { + int[] tmp = new int[1]; + gl.glGenTextures(1, tmp, 0); + int texid = tmp[0]; - gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_NV, texid); - gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); - gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); - gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); - - gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); - - float[] img = new float [xsiz*ysiz]; - - for (int y = 0; y < ysiz; y++) { - for (int x = 0; x < xsiz; x++) { - float radius = (float) Math.sqrt((x-xsiz/2)*(x-xsiz/2) + (y-ysiz/2)*(y-ysiz/2)); - if (radius > r0) { - if (radius < r1) { - float t = 1.0f - (radius-r0)/(r1-r0); - float a = t * 2 - 1; - float reduce = (float) ((0.25 * Math.PI + 0.5 * Math.asin(a) + 0.5 * a * Math.sqrt( 1 - a*a ))/(0.5 * Math.PI)); - img[y*xsiz + x] = reduce; - } else { - img[y*xsiz + x] = 0.0f; - } + gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_NV, texid); + gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); + gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); + gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); + gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_NV, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); + + gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); + + float[] img = new float [xsiz*ysiz]; + + for (int y = 0; y < ysiz; y++) { + for (int x = 0; x < xsiz; x++) { + float radius = (float) Math.sqrt((x-xsiz/2)*(x-xsiz/2) + (y-ysiz/2)*(y-ysiz/2)); + if (radius > r0) { + if (radius < r1) { + float t = 1.0f - (radius-r0)/(r1-r0); + float a = t * 2 - 1; + float reduce = (float) ((0.25 * Math.PI + 0.5 * Math.asin(a) + 0.5 * a * Math.sqrt( 1 - a*a ))/(0.5 * Math.PI)); + img[y*xsiz + x] = reduce; } else { - img[y*xsiz + x] = 1.0f; + img[y*xsiz + x] = 0.0f; } + } else { + img[y*xsiz + x] = 1.0f; } } + } - gl.glTexImage2D(GL.GL_TEXTURE_RECTANGLE_NV, 0, GL.GL_LUMINANCE, xsiz, ysiz, 0, GL.GL_LUMINANCE, GL.GL_FLOAT, img); + gl.glTexImage2D(GL.GL_TEXTURE_RECTANGLE_NV, 0, GL.GL_LUMINANCE, xsiz, ysiz, 0, GL.GL_LUMINANCE, GL.GL_FLOAT, FloatBuffer.wrap(img)); - return texid; - } + return texid; } //---------------------------------------------------------------------- @@ -502,17 +563,16 @@ public class HDR { // class PbufferListener implements GLEventListener { - public void init(GLDrawable drawable) { + public void init(GLAutoDrawable drawable) { // printThreadName("init for PbufferListener"); // drawable.setGL(new DebugGL(drawable.getGL())); GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); gl.glEnable(GL.GL_DEPTH_TEST); // FIXME: what about the ExaminerViewer? - setPerspectiveProjection(gl, glu, pbuffer_w, pbuffer_h); + setPerspectiveProjection(gl, pbuffer_w, pbuffer_h); GLPbuffer pbuffer = (GLPbuffer) drawable; int fpmode = pbuffer.getFloatingPointMode(); @@ -549,28 +609,27 @@ public class HDR { pipeline.initFloatingPointTexture(gl, pbuffer_tex, pbuffer_w, pbuffer_h); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { // printThreadName("display for PbufferListener"); GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); - renderScene(gl, glu); + renderScene(gl); // Copy results back to texture pipeline.copyToTexture(gl, pbuffer_tex, pbuffer_w, pbuffer_h); } // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} //---------------------------------------------------------------------- // Internals only below this point // // render scene to float pbuffer - private void renderScene(GL gl, GLU glu) { + private void renderScene(GL gl) { gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); if (doViewAll) { @@ -583,10 +642,10 @@ public class HDR { gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); if (b['m']) { - gl.glEnable(GL.GL_MULTISAMPLE_ARB); + gl.glEnable(GL.GL_MULTISAMPLE); gl.glHint(GL.GL_MULTISAMPLE_FILTER_HINT_NV, GL.GL_NICEST); } else { - gl.glDisable(GL.GL_MULTISAMPLE_ARB); + gl.glDisable(GL.GL_MULTISAMPLE); } if (!b['e']) { @@ -625,32 +684,32 @@ public class HDR { view.xformPt(eyePos_eye, eyePos_model); pipeline.setVertexProgramParameter3f(gl, eyePos_param, eyePos_model.x(), eyePos_model.y(), eyePos_model.z()); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, hdr_tex); - gl.glEnable(GL.GL_TEXTURE_CUBE_MAP_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); + gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, hdr_tex); + gl.glEnable(GL.GL_TEXTURE_CUBE_MAP); boolean linear = b['l']; if (linear) { - gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); - gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); + gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); + gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); } else { - // glTexParameteri( GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST_MIPMAP_NEAREST); - gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); - gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); + // glTexParameteri( GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST_MIPMAP_NEAREST); + gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); + gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); } if (hilo) { - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, hdr_tex2); - gl.glEnable(GL.GL_TEXTURE_CUBE_MAP_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); + gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, hdr_tex2); + gl.glEnable(GL.GL_TEXTURE_CUBE_MAP); if (linear) { - gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); - gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); + gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); + gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); } else { - // glTexParameteri( GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST_MIPMAP_NEAREST); - gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); - gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); + // glTexParameteri( GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST_MIPMAP_NEAREST); + gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST); + gl.glTexParameteri( GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); } } @@ -658,16 +717,16 @@ public class HDR { switch(modelno) { case 0: - glut.glutSolidTorus(gl, 0.25, 0.5, 40, 40); + glut.glutSolidTorus( 0.25, 0.5, 40, 40); break; case 1: - glut.glutSolidSphere(glu, 0.75f, 40, 40); + glut.glutSolidSphere(0.75f, 40, 40); break; case 2: - glut.glutSolidTetrahedron(gl); + glut.glutSolidTetrahedron(); break; case 3: - glut.glutSolidCube(gl, 1.0f); + glut.glutSolidCube(1.0f); break; case 4: // Something about the teapot's geometry causes bad artifacts @@ -679,7 +738,7 @@ public class HDR { gl.glVertexPointer(3, GL.GL_FLOAT, 0, model.getVertices()); gl.glNormalPointer(GL.GL_FLOAT, 0, model.getVertexNormals()); int[] indices = model.getFaceIndices(); - gl.glDrawElements(GL.GL_TRIANGLES, indices.length, GL.GL_UNSIGNED_INT, indices); + gl.glDrawElements(GL.GL_TRIANGLES, indices.length, GL.GL_UNSIGNED_INT, IntBuffer.wrap(indices)); gl.glDisableClientState(GL.GL_VERTEX_ARRAY); gl.glDisableClientState(GL.GL_NORMAL_ARRAY); break; @@ -693,7 +752,7 @@ public class HDR { } class BlurPbufferListener implements GLEventListener { - public void init(GLDrawable drawable) { + public void init(GLAutoDrawable drawable) { // printThreadName("init for BlurPbufferListener"); // drawable.setGL(new DebugGL(drawable.getGL())); @@ -701,19 +760,19 @@ public class HDR { GL gl = drawable.getGL(); // FIXME: what about the ExaminerViewer? - setOrthoProjection(gl, blur_w, blur_h); + setOrthoProjection(gl, 0, 0, blur_w, blur_h); pipeline.initFloatingPointTexture(gl, blur_pbuffer_tex, blur_w, blur_h); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { // printThreadName("display for BlurPbufferListener"); GL gl = drawable.getGL(); // horizontal blur gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, blurh_fprog); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); pipeline.bindTexture(gl, blur2_pbuffer_tex); glowPass(gl); @@ -721,24 +780,24 @@ public class HDR { } // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } class Blur2PbufferListener implements GLEventListener { - public void init(GLDrawable drawable) { + public void init(GLAutoDrawable drawable) { // printThreadName("init for Blur2PbufferListener"); // drawable.setGL(new DebugGL(drawable.getGL())); GL gl = drawable.getGL(); // FIXME: what about the ExaminerViewer? - setOrthoProjection(gl, blur_w, blur_h); + setOrthoProjection(gl, 0, 0, blur_w, blur_h); pipeline.initFloatingPointTexture(gl, blur2_pbuffer_tex, blur_w, blur_h); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { // printThreadName("display for Blur2PbufferListener"); GL gl = drawable.getGL(); @@ -747,8 +806,8 @@ public class HDR { gl.glClear(GL.GL_COLOR_BUFFER_BIT); pipeline.enableFragmentProgram(gl, shrink_fprog); - setOrthoProjection(gl, blur_w, blur_h); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + setOrthoProjection(gl, 0, 0, blur_w, blur_h); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_NV, pbuffer_tex); drawQuadRect2(gl, blur_w, blur_h, pbuffer_w, pbuffer_h); pipeline.disableFragmentProgram(gl); @@ -757,7 +816,7 @@ public class HDR { // vertical blur gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, blurv_fprog); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); pipeline.bindTexture(gl, blur_pbuffer_tex); glowPass(gl); @@ -769,20 +828,20 @@ public class HDR { } // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } class TonemapPbufferListener implements GLEventListener { - public void init(GLDrawable drawable) { + public void init(GLAutoDrawable drawable) { GL gl = drawable.getGL(); - setOrthoProjection(gl, pbuffer_w, pbuffer_h); + setOrthoProjection(gl, 0, 0, pbuffer_w, pbuffer_h); pipeline.initTexture(gl, tonemap_pbuffer_tex, pbuffer_w, pbuffer_h); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { GL gl = drawable.getGL(); toneMappingPass(gl); @@ -791,15 +850,15 @@ public class HDR { } // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } //---------------------------------------------------------------------- // Rendering routines // - private void setOrthoProjection(GL gl, int w, int h) { + private void setOrthoProjection(GL gl, int x, int y, int w, int h) { gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho(0, w, 0, h, -1.0, 1.0); @@ -807,10 +866,10 @@ public class HDR { gl.glLoadIdentity(); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); - gl.glViewport(0, 0, w, h); + gl.glViewport(x, y, w, h); } - private void setPerspectiveProjection(GL gl, GLU glu, int w, int h) { + private void setPerspectiveProjection(GL gl, int w, int h) { // FIXME: what about ExaminerViewer? gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); @@ -825,7 +884,7 @@ public class HDR { gl.glDisable(GL.GL_DEPTH_TEST); gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB); - setOrthoProjection(gl, blur_w, blur_h); + setOrthoProjection(gl, 0, 0, blur_w, blur_h); drawQuadRect(gl, blur_w, blur_h); gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB); @@ -833,10 +892,10 @@ public class HDR { private void drawQuadRect(GL gl, int w, int h) { gl.glBegin(GL.GL_QUADS); - gl.glTexCoord2f(0, h); gl.glMultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 0, h / blur_scale); gl.glVertex3f(0, h, 0); - gl.glTexCoord2f(w, h); gl.glMultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, w / blur_scale, h / blur_scale); gl.glVertex3f(w, h, 0); - gl.glTexCoord2f(w, 0); gl.glMultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, w / blur_scale, 0); gl.glVertex3f(w, 0, 0); - gl.glTexCoord2f(0, 0); gl.glMultiTexCoord2fARB(GL.GL_TEXTURE1_ARB, 0, 0); gl.glVertex3f(0, 0, 0); + gl.glTexCoord2f(0, h); gl.glMultiTexCoord2f(GL.GL_TEXTURE1, 0, h / blur_scale); gl.glVertex3f(0, h, 0); + gl.glTexCoord2f(w, h); gl.glMultiTexCoord2f(GL.GL_TEXTURE1, w / blur_scale, h / blur_scale); gl.glVertex3f(w, h, 0); + gl.glTexCoord2f(w, 0); gl.glMultiTexCoord2f(GL.GL_TEXTURE1, w / blur_scale, 0); gl.glVertex3f(w, 0, 0); + gl.glTexCoord2f(0, 0); gl.glMultiTexCoord2f(GL.GL_TEXTURE1, 0, 0); gl.glVertex3f(0, 0, 0); gl.glEnd(); } @@ -873,27 +932,27 @@ public class HDR { // draw cubemap background private void drawSkyBox(GL gl) { - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, hdr_tex); - gl.glEnable(GL.GL_TEXTURE_CUBE_MAP_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); + gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, hdr_tex); + gl.glEnable(GL.GL_TEXTURE_CUBE_MAP); if (hilo) { - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, hdr_tex2); - gl.glEnable(GL.GL_TEXTURE_CUBE_MAP_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); + gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, hdr_tex2); + gl.glEnable(GL.GL_TEXTURE_CUBE_MAP); } // initialize object linear texgen - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glPushMatrix(); gl.glLoadIdentity(); float[] s_plane = { 1.0f, 0.0f, 0.0f, 0.0f }; float[] t_plane = { 0.0f, 1.0f, 0.0f, 0.0f }; float[] r_plane = { 0.0f, 0.0f, 1.0f, 0.0f }; - gl.glTexGenfv(GL.GL_S, GL.GL_OBJECT_PLANE, s_plane); - gl.glTexGenfv(GL.GL_T, GL.GL_OBJECT_PLANE, t_plane); - gl.glTexGenfv(GL.GL_R, GL.GL_OBJECT_PLANE, r_plane); + gl.glTexGenfv(GL.GL_S, GL.GL_OBJECT_PLANE, s_plane, 0); + gl.glTexGenfv(GL.GL_T, GL.GL_OBJECT_PLANE, t_plane, 0); + gl.glTexGenfv(GL.GL_R, GL.GL_OBJECT_PLANE, r_plane, 0); gl.glPopMatrix(); gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR); gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR); @@ -911,10 +970,10 @@ public class HDR { gl.glPushMatrix(); gl.glLoadIdentity(); gl.glScalef(10.0f, 10.0f, 10.0f); - glut.glutSolidCube(gl, 1.0f); + glut.glutSolidCube(1.0f); gl.glPopMatrix(); - gl.glDisable(GL.GL_TEXTURE_CUBE_MAP_ARB); + gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); gl.glMatrixMode(GL.GL_TEXTURE); gl.glPopMatrix(); @@ -927,18 +986,18 @@ public class HDR { private void toneMappingPass(GL gl) { gl.glFinish(); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_NV, pbuffer_tex); - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); if (blur2_pbuffer != null) { gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_NV, blur2_pbuffer_tex); } - gl.glActiveTextureARB(GL.GL_TEXTURE2_ARB); + gl.glActiveTexture(GL.GL_TEXTURE2); gl.glBindTexture(GL.GL_TEXTURE_1D, gamma_tex); - gl.glActiveTextureARB(GL.GL_TEXTURE3_ARB); + gl.glActiveTexture(GL.GL_TEXTURE3); pipeline.bindTexture(gl, vignette_tex); pipeline.enableFragmentProgram(gl, tonemap_fprog); @@ -958,7 +1017,14 @@ public class HDR { private String shaderRoot = "demos/hdr/shaders/"; private void initCg(GL gl) { - pipeline = new CgPipeline(); + // NOTE: need to instantiate CgPipeline reflectively to avoid + // compile-time dependence (since Cg support might not be present) + try { + Class cgPipelineClass = Class.forName("demos.hdr.CgPipeline"); + pipeline = (Pipeline) cgPipelineClass.newInstance(); + } catch (Exception e) { + throw new GLException(e); + } pipeline.init(); try { @@ -1032,13 +1098,13 @@ public class HDR { private int loadProgram(GL gl, int target, String code) { int prog_id; int[] tmp = new int[1]; - gl.glGenProgramsARB(1, tmp); + gl.glGenProgramsARB(1, tmp, 0); prog_id = tmp[0]; gl.glBindProgramARB(target, prog_id); int size = code.length(); gl.glProgramStringARB(target, GL.GL_PROGRAM_FORMAT_ASCII_ARB, code.length(), code); int[] errPos = new int[1]; - gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos); + gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos, 0); if (errPos[0] >= 0) { String kind = "Program"; if (target == GL.GL_VERTEX_PROGRAM_ARB) { @@ -1065,7 +1131,7 @@ public class HDR { int[] isNative = new int[1]; gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB, GL.GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, - isNative); + isNative, 0); if (isNative[0] != 1) { System.out.println("WARNING: fragment program is over native resource limits"); Thread.dumpStack(); @@ -1154,19 +1220,19 @@ public class HDR { private void applyTransform(GL gl, Mat4f mat) { float[] data = new float[16]; mat.getColumnMajorData(data); - gl.glMultMatrixf(data); + gl.glMultMatrixf(data, 0); } private void usage() { System.err.println("usage: java demos.hdr.HDR [-cg] image.hdr pbuffer_w pbuffer_h window_scale blur_width blur_decimate [obj file]"); - System.exit(1); + shutdownDemo(); } private void printThreadName(String where) { System.err.println("In " + where + ": current thread = " + Thread.currentThread().getName()); } - private void runExit() { + private static void runExit(final Animator animator) { // Note: calling System.exit() synchronously inside the draw, // reshape or init callbacks can lead to deadlocks on certain // platforms (in particular, X11) because the JAWT's locking diff --git a/src/demos/hdr/HDRTexture.java b/src/demos/hdr/HDRTexture.java index fcaac11..b2fa935 100755 --- a/src/demos/hdr/HDRTexture.java +++ b/src/demos/hdr/HDRTexture.java @@ -1,8 +1,10 @@ package demos.hdr; import java.io.*; +import java.nio.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; public class HDRTexture { private RGBE.Header header; @@ -94,7 +96,7 @@ public class HDRTexture { public int create2DTextureRGBE(GL gl, int targetTextureType) { m_target = targetTextureType; int[] tmp = new int[1]; - gl.glGenTextures(1, tmp); + gl.glGenTextures(1, tmp, 0); int texid = tmp[1]; gl.glBindTexture(m_target, texid); @@ -106,7 +108,7 @@ public class HDRTexture { gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); gl.glTexParameteri(m_target, GL.GL_GENERATE_MIPMAP_SGIS, GL.GL_TRUE); - gl.glTexImage2D(m_target, 0, GL.GL_RGBA, m_width, m_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, m_data); + gl.glTexImage2D(m_target, 0, GL.GL_RGBA, m_width, m_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap(m_data)); return texid; } @@ -114,7 +116,7 @@ public class HDRTexture { public int create2DTextureHILO(GL gl, int targetTextureType, boolean rg) { m_target = targetTextureType; int[] tmp = new int[1]; - gl.glGenTextures(1, tmp); + gl.glGenTextures(1, tmp, 0); int texid = tmp[0]; gl.glBindTexture(m_target, texid); @@ -143,7 +145,7 @@ public class HDRTexture { } } - gl.glTexImage2D(m_target, 0, GL.GL_HILO16_NV, m_width, m_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, img); + gl.glTexImage2D(m_target, 0, GL.GL_HILO16_NV, m_width, m_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, FloatBuffer.wrap(img)); return texid; } @@ -155,9 +157,9 @@ public class HDRTexture { int face_height = m_height / 4; byte[] face = new byte[face_width * face_height * 4]; - m_target = GL.GL_TEXTURE_CUBE_MAP_ARB; + m_target = GL.GL_TEXTURE_CUBE_MAP; int[] tmp = new int[1]; - gl.glGenTextures(1, tmp); + gl.glGenTextures(1, tmp, 0); int texid = tmp[0]; gl.glBindTexture(m_target, texid); @@ -184,7 +186,7 @@ public class HDRTexture { face[ptr++] = m_data[src++]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap(face)); // positive X ptr = 0; @@ -197,7 +199,7 @@ public class HDRTexture { face[ptr++] = m_data[src++]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap(face)); // negative Z ptr = 0; @@ -210,7 +212,7 @@ public class HDRTexture { face[ptr++] = m_data[src++]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap(face)); // negative X ptr = 0; @@ -223,7 +225,7 @@ public class HDRTexture { face[ptr++] = m_data[src++]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap(face)); // negative Y ptr = 0; @@ -236,7 +238,7 @@ public class HDRTexture { face[ptr++] = m_data[src++]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap(face)); // positive Z ptr = 0; @@ -249,7 +251,7 @@ public class HDRTexture { face[ptr++] = m_data[src++]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL.GL_RGBA, face_width, face_height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap(face)); return texid; } @@ -260,9 +262,9 @@ public class HDRTexture { int face_height = m_height / 4; float[] face = new float [face_width * face_height * 2]; - m_target = GL.GL_TEXTURE_CUBE_MAP_ARB; + m_target = GL.GL_TEXTURE_CUBE_MAP; int[] tmp = new int[1]; - gl.glGenTextures(1, tmp); + gl.glGenTextures(1, tmp, 0); int texid = tmp[0]; gl.glBindTexture(m_target, texid); @@ -290,7 +292,7 @@ public class HDRTexture { } } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, FloatBuffer.wrap(face)); // positive X ptr = 0; @@ -306,7 +308,7 @@ public class HDRTexture { } } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, FloatBuffer.wrap(face)); // negative Z ptr = 0; @@ -322,7 +324,7 @@ public class HDRTexture { } } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, FloatBuffer.wrap(face)); // negative X ptr = 0; @@ -338,7 +340,7 @@ public class HDRTexture { } } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, FloatBuffer.wrap(face)); // negative Y ptr = 0; @@ -354,7 +356,7 @@ public class HDRTexture { } } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, FloatBuffer.wrap(face)); // positive Z ptr = 0; @@ -370,7 +372,7 @@ public class HDRTexture { } } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL.GL_HILO16_NV, face_width, face_height, 0, GL.GL_HILO_NV, GL.GL_FLOAT, FloatBuffer.wrap(face)); return texid; } @@ -381,9 +383,9 @@ public class HDRTexture { int face_height = m_height / 4; float[] face = new float [face_width * face_height * 3]; - m_target = GL.GL_TEXTURE_CUBE_MAP_ARB; + m_target = GL.GL_TEXTURE_CUBE_MAP; int[] tmp = new int[1]; - gl.glGenTextures(1, tmp); + gl.glGenTextures(1, tmp, 0); int texid = tmp[0]; gl.glBindTexture(m_target, texid); @@ -407,7 +409,7 @@ public class HDRTexture { face[ptr++] = m_floatdata[src + 2]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, FloatBuffer.wrap(face)); // positive X ptr = 0; @@ -419,7 +421,7 @@ public class HDRTexture { face[ptr++] = m_floatdata[src + 2]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, FloatBuffer.wrap(face)); // negative Z ptr = 0; @@ -431,7 +433,7 @@ public class HDRTexture { face[ptr++] = m_floatdata[src + 2]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, FloatBuffer.wrap(face)); // negative X ptr = 0; @@ -443,7 +445,7 @@ public class HDRTexture { face[ptr++] = m_floatdata[src + 2]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, FloatBuffer.wrap(face)); // negative Y ptr = 0; @@ -455,7 +457,7 @@ public class HDRTexture { face[ptr++] = m_floatdata[src + 2]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, FloatBuffer.wrap(face)); // positive Z ptr = 0; @@ -467,7 +469,7 @@ public class HDRTexture { face[ptr++] = m_floatdata[src + 2]; } } - gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, face); + gl.glTexImage2D(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format, face_width, face_height, 0, GL.GL_RGB, GL.GL_FLOAT, FloatBuffer.wrap(face)); return texid; } diff --git a/src/demos/hdr/Pipeline.java b/src/demos/hdr/Pipeline.java index 822c3fb..f79b28d 100755 --- a/src/demos/hdr/Pipeline.java +++ b/src/demos/hdr/Pipeline.java @@ -3,8 +3,9 @@ package demos.hdr; import java.io.*; import java.util.*; -import net.java.games.jogl.*; -import net.java.games.cg.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; +import com.sun.opengl.cg.*; import demos.util.*; public interface Pipeline { diff --git a/src/demos/hwShadowmapsSimple/HWShadowmapsSimple.java b/src/demos/hwShadowmapsSimple/HWShadowmapsSimple.java index f97e875..0078df1 100644 --- a/src/demos/hwShadowmapsSimple/HWShadowmapsSimple.java +++ b/src/demos/hwShadowmapsSimple/HWShadowmapsSimple.java @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2003 Sun Microsystems, Inc. + * Portions Copyright (C) 2003-2005 Sun Microsystems, Inc. * All rights reserved. */ @@ -42,8 +42,10 @@ import java.util.*; import javax.imageio.*; import javax.swing.*; -import net.java.games.jogl.*; -import net.java.games.jogl.util.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; +import demos.common.*; import demos.util.*; import gleem.*; import gleem.linalg.*; @@ -57,12 +59,49 @@ import gleem.linalg.*; Ported to Java by Kenneth Russell */ -public class HWShadowmapsSimple { - private volatile boolean quit; +public class HWShadowmapsSimple extends Demo { + public static void main(String[] args) { + final GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); + HWShadowmapsSimple demo = new HWShadowmapsSimple(); + canvas.addGLEventListener(demo); + + demo.setDemoListener(new DemoListener() { + public void shutdownDemo() { + runExit(); + } + public void repaint() { + canvas.repaint(); + } + }); + + Frame frame = new Frame("ARB_shadow Shadows"); + frame.setLayout(new BorderLayout()); + canvas.setSize(512, 512); + frame.add(canvas, BorderLayout.CENTER); + frame.pack(); + frame.show(); + canvas.requestFocus(); + + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + runExit(); + } + }); + } + + //---------------------------------------------------------------------- + // Internals only below this point + // + + public void shutdownDemo() { + ManipManager.getManipManager().unregisterWindow(drawable); + drawable.removeGLEventListener(this); + super.shutdownDemo(); + } - private GLCanvas canvas; private GLPbuffer pbuffer; + private GLU glu; private GLUT glut; private float[] light_ambient = { 0, 0, 0, 0 }; @@ -116,6 +155,7 @@ public class HWShadowmapsSimple { private float lightshaper_zFar = 5.0f; // Manipulators + private GLAutoDrawable drawable; private ExaminerViewer viewer; private boolean doViewAll = true; // private float zNear = 0.5f; @@ -130,260 +170,246 @@ public class HWShadowmapsSimple { private Mat4f spotlightTransform = new Mat4f(); private Mat4f spotlightInverseTransform = new Mat4f(); private Mat4f objectTransform = new Mat4f(); + private int viewportX; + private int viewportY; - public static void main(String[] args) { - new HWShadowmapsSimple().run(args); - } + public void init(GLAutoDrawable drawable) { + // Use debug pipeline + // drawable.setGL(new DebugGL(drawable.getGL())); - public void run(String[] args) { - canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); - canvas.addGLEventListener(new Listener()); + GL gl = drawable.getGL(); + glu = new GLU(); + glut = new GLUT(); - Frame frame = new Frame("ARB_shadow Shadows"); - frame.setLayout(new BorderLayout()); - canvas.setSize(512, 512); - frame.add(canvas, BorderLayout.CENTER); - frame.pack(); - frame.show(); - canvas.requestFocus(); + try { + checkExtension(gl, "GL_VERSION_1_3"); // For multitexture + checkExtension(gl, "GL_ARB_depth_texture"); + checkExtension(gl, "GL_ARB_shadow"); + checkExtension(gl, "GL_ARB_pbuffer"); + checkExtension(gl, "GL_ARB_pixel_format"); + } catch (GLException e) { + e.printStackTrace(); + throw(e); + } + + gl.glClearColor(.5f, .5f, .5f, .5f); - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - runExit(); - } - }); - } + decal = genTexture(gl); + gl.glBindTexture(GL.GL_TEXTURE_2D, decal); + BufferedImage img = readPNGImage("demos/data/images/decal_image.png"); + makeRGBTexture(gl, img, GL.GL_TEXTURE_2D, true); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); - //---------------------------------------------------------------------- - // Internals only below this point - // + light_image = genTexture(gl); + gl.glBindTexture(GL.GL_TEXTURE_2D, light_image); + img = readPNGImage("demos/data/images/nvlogo_spot.png"); + makeRGBTexture(gl, img, GL.GL_TEXTURE_2D, true); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); - class Listener implements GLEventListener { + quad = gl.glGenLists(1); + gl.glNewList(quad, GL.GL_COMPILE); + gl.glPushMatrix(); + gl.glRotatef(-90, 1, 0, 0); + gl.glScalef(4,4,4); + gl.glBegin(GL.GL_QUADS); + gl.glNormal3f(0, 0, 1); + gl.glVertex2f(-1, -1); + gl.glVertex2f(-1, 1); + gl.glVertex2f( 1, 1); + gl.glVertex2f( 1, -1); + gl.glEnd(); + gl.glPopMatrix(); + gl.glEndList(); - public void init(GLDrawable drawable) { - // Use debug pipeline - // drawable.setGL(new DebugGL(drawable.getGL())); + wirecube = gl.glGenLists(1); + gl.glNewList(wirecube, GL.GL_COMPILE); + glut.glutWireCube(2); + gl.glEndList(); - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); - glut = new GLUT(); - - try { - checkExtension(gl, "GL_ARB_multitexture"); - checkExtension(gl, "GL_ARB_depth_texture"); - checkExtension(gl, "GL_ARB_shadow"); - checkExtension(gl, "GL_ARB_pbuffer"); - checkExtension(gl, "GL_ARB_pixel_format"); - } catch (GLException e) { - e.printStackTrace(); - throw(e); - } - - gl.glClearColor(.5f, .5f, .5f, .5f); - - decal = genTexture(gl); - gl.glBindTexture(GL.GL_TEXTURE_2D, decal); - BufferedImage img = readPNGImage("demos/data/images/decal_image.png"); - makeRGBTexture(gl, glu, img, GL.GL_TEXTURE_2D, true); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); - - light_image = genTexture(gl); - gl.glBindTexture(GL.GL_TEXTURE_2D, light_image); - img = readPNGImage("demos/data/images/nvlogo_spot.png"); - makeRGBTexture(gl, glu, img, GL.GL_TEXTURE_2D, true); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); - - quad = gl.glGenLists(1); - gl.glNewList(quad, GL.GL_COMPILE); - gl.glPushMatrix(); - gl.glRotatef(-90, 1, 0, 0); - gl.glScalef(4,4,4); - gl.glBegin(GL.GL_QUADS); - gl.glNormal3f(0, 0, 1); - gl.glVertex2f(-1, -1); - gl.glVertex2f(-1, 1); - gl.glVertex2f( 1, 1); - gl.glVertex2f( 1, -1); - gl.glEnd(); - gl.glPopMatrix(); - gl.glEndList(); - - wirecube = gl.glGenLists(1); - gl.glNewList(wirecube, GL.GL_COMPILE); - glut.glutWireCube(gl, 2); - gl.glEndList(); - - geometry = gl.glGenLists(1); - gl.glNewList(geometry, GL.GL_COMPILE); - gl.glPushMatrix(); - glut.glutSolidTeapot(gl, 0.8f); - gl.glPopMatrix(); - gl.glEndList(); - - gl.glEnable(GL.GL_LIGHT0); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, light_ambient); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, light_intensity); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, light_intensity); + geometry = gl.glGenLists(1); + gl.glNewList(geometry, GL.GL_COMPILE); + gl.glPushMatrix(); + glut.glutSolidTeapot(0.8f); + gl.glPopMatrix(); + gl.glEndList(); - gl.glEnable(GL.GL_DEPTH_TEST); + gl.glEnable(GL.GL_LIGHT0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, light_ambient, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, light_intensity, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, light_intensity, 0); - // init pbuffer - GLCapabilities caps = new GLCapabilities(); - caps.setDoubleBuffered(false); - pbuffer = drawable.createOffscreenDrawable(caps, TEX_SIZE, TEX_SIZE); - pbuffer.addGLEventListener(new PbufferListener()); - - // Register the window with the ManipManager - ManipManager manager = ManipManager.getManipManager(); - manager.registerWindow(drawable); - - object = new HandleBoxManip(); - object.setTranslation(new Vec3f(0, 0.7f, 1.8f)); - object.setGeometryScale(new Vec3f(0.7f, 0.7f, 0.7f)); - manager.showManipInWindow(object, drawable); - - spotlight = new HandleBoxManip(); - spotlight.setScale(new Vec3f(0.5f, 0.5f, 0.5f)); - spotlight.setTranslation(new Vec3f(-0.25f, 2.35f, 5.0f)); - spotlight.setRotation(new Rotf(Vec3f.X_AXIS, (float) Math.toRadians(-30.0f))); - manager.showManipInWindow(spotlight, drawable); - - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); - viewer.attach(drawable, new BSphereProvider() { - public BSphere getBoundingSphere() { - return new BSphere(object.getTranslation(), 2.0f); - } - }); - viewer.setOrientation(new Rotf(Vec3f.Y_AXIS, (float) Math.toRadians(45.0f)).times - (new Rotf(Vec3f.X_AXIS, (float) Math.toRadians(-15.0f)))); - viewer.setVertFOV((float) Math.toRadians(lightshaper_fovy / 2.0f)); - viewer.setZNear(zNear); - viewer.setZFar(zFar); - - float bias = 1/((float) Math.pow(2.0,16.0)-1); - - tweaks.add(new Tweak("r coordinate scale", 0.5f, bias)); - tweaks.add(new Tweak("r coordinate bias", 0.5f, bias)); - tweaks.add(new Tweak("polygon offset scale", 2.5f, 0.5f)); - tweaks.add(new Tweak("polygon offset bias", 10.0f, 1.0f)); - - drawable.addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent e) { - dispatchKey(e.getKeyChar()); - canvas.repaint(); - } - }); - } + gl.glEnable(GL.GL_DEPTH_TEST); - public void display(GLDrawable drawable) { - viewer.update(); - - // Grab these values once per render to avoid multithreading - // issues with their values being changed by manipulation from - // the AWT thread during the render - CameraParameters params = viewer.getCameraParameters(); - - cameraPerspective.set(params.getProjectionMatrix()); - cameraInverseTransform.set(params.getModelviewMatrix()); - cameraTransform.set(cameraInverseTransform); - cameraTransform.invertRigid(); - spotlightTransform.set(spotlight.getTransform()); - spotlightInverseTransform.set(spotlightTransform); - spotlightInverseTransform.invertRigid(); - objectTransform.set(object.getTransform()); - - if (displayMode == RENDER_SCENE_FROM_CAMERA_VIEW_SHADOWED || !fullyInitialized) { - if (pbuffer != null) { - pbuffer.display(); + // init pbuffer + GLCapabilities caps = new GLCapabilities(); + caps.setDoubleBuffered(false); + + if (!GLDrawableFactory.getFactory().canCreateGLPbuffer()) { + unavailableExtension("Can not create pbuffer"); + } + if (pbuffer != null) { + pbuffer.destroy(); + pbuffer = null; + } + pbuffer = GLDrawableFactory.getFactory().createGLPbuffer(caps, TEX_SIZE, TEX_SIZE, drawable.getContext()); + pbuffer.addGLEventListener(new PbufferListener()); + + doViewAll = true; + + // Register the window with the ManipManager + ManipManager manager = ManipManager.getManipManager(); + manager.registerWindow(drawable); + this.drawable = drawable; + + object = new HandleBoxManip(); + object.setTranslation(new Vec3f(0, 0.7f, 1.8f)); + object.setGeometryScale(new Vec3f(0.7f, 0.7f, 0.7f)); + manager.showManipInWindow(object, drawable); + + spotlight = new HandleBoxManip(); + spotlight.setScale(new Vec3f(0.5f, 0.5f, 0.5f)); + spotlight.setTranslation(new Vec3f(-0.25f, 2.35f, 5.0f)); + spotlight.setRotation(new Rotf(Vec3f.X_AXIS, (float) Math.toRadians(-30.0f))); + manager.showManipInWindow(spotlight, drawable); + + viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer.attach(drawable, new BSphereProvider() { + public BSphere getBoundingSphere() { + return new BSphere(object.getTranslation(), 2.0f); } - } + }); + viewer.setOrientation(new Rotf(Vec3f.Y_AXIS, (float) Math.toRadians(45.0f)).times + (new Rotf(Vec3f.X_AXIS, (float) Math.toRadians(-15.0f)))); + viewer.setVertFOV((float) Math.toRadians(lightshaper_fovy / 2.0f)); + viewer.setZNear(zNear); + viewer.setZFar(zFar); + + float bias = 1/((float) Math.pow(2.0,16.0)-1); + + tweaks.add(new Tweak("r coordinate scale", 0.5f, bias)); + tweaks.add(new Tweak("r coordinate bias", 0.5f, bias)); + tweaks.add(new Tweak("polygon offset scale", 2.5f, 0.5f)); + tweaks.add(new Tweak("polygon offset bias", 10.0f, 1.0f)); + + drawable.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + dispatchKey(e.getKeyChar()); + demoListener.repaint(); + } + }); + } - if (!fullyInitialized) { - return; + public void display(GLAutoDrawable drawable) { + viewer.update(); + + // Grab these values once per render to avoid multithreading + // issues with their values being changed by manipulation from + // the AWT thread during the render + CameraParameters params = viewer.getCameraParameters(); + + cameraPerspective.set(params.getProjectionMatrix()); + cameraInverseTransform.set(params.getModelviewMatrix()); + cameraTransform.set(cameraInverseTransform); + cameraTransform.invertRigid(); + spotlightTransform.set(spotlight.getTransform()); + spotlightInverseTransform.set(spotlightTransform); + spotlightInverseTransform.invertRigid(); + objectTransform.set(object.getTransform()); + + if (displayMode == RENDER_SCENE_FROM_CAMERA_VIEW_SHADOWED || !fullyInitialized) { + if (pbuffer != null) { + pbuffer.display(); } + } - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); + if (!fullyInitialized) { + // Repaint again later once everything is set up + demoListener.repaint(); + return; + } - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + GL gl = drawable.getGL(); - if (doViewAll) { - viewer.viewAll(gl); - doViewAll = false; - // Immediately zap effects - gl.glMatrixMode(GL.GL_PROJECTION); - gl.glLoadIdentity(); - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glLoadIdentity(); - // Schedule repaint to clean up first bogus frame - canvas.repaint(); - } + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - switch (displayMode) { - case RENDER_SCENE_FROM_CAMERA_VIEW: render_scene_from_camera_view(gl, glu, drawable, params); break; - case RENDER_SCENE_FROM_CAMERA_VIEW_SHADOWED: render_scene_from_camera_view_shadowed(gl, glu, drawable, params); break; - case RENDER_SCENE_FROM_LIGHT_VIEW: render_scene_from_light_view(gl, glu); break; - default: throw new RuntimeException("Illegal display mode " + displayMode); - } + if (doViewAll) { + viewer.viewAll(gl); + doViewAll = false; + // Immediately zap effects + gl.glMatrixMode(GL.GL_PROJECTION); + gl.glLoadIdentity(); + gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glLoadIdentity(); + // Schedule repaint to clean up first bogus frame + demoListener.repaint(); } - // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - - //---------------------------------------------------------------------- - // Internals only below this point - // - - private void checkExtension(GL gl, String extensionName) { - if (!gl.isExtensionAvailable(extensionName)) { - String message = "Unable to initialize " + extensionName + " OpenGL extension"; - JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); - throw new GLException(message); - } + switch (displayMode) { + case RENDER_SCENE_FROM_CAMERA_VIEW: render_scene_from_camera_view(gl, drawable, params); break; + case RENDER_SCENE_FROM_CAMERA_VIEW_SHADOWED: render_scene_from_camera_view_shadowed(gl, drawable, params); break; + case RENDER_SCENE_FROM_LIGHT_VIEW: render_scene_from_light_view(gl, drawable, viewportX, viewportY); break; + default: throw new RuntimeException("Illegal display mode " + displayMode); } + } - private void dispatchKey(char k) { - switch (k) { - case 27: - case 'q': - runExit(); - break; + // Unused routines + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + viewportX = x; + viewportY = y; + } + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - case 'v': - doViewAll = true; - System.err.println("Forcing viewAll()"); - break; + private void checkExtension(GL gl, String extensionName) { + if (!gl.isExtensionAvailable(extensionName)) { + String message = "Unable to initialize " + extensionName + " OpenGL extension"; + unavailableExtension(message); + } + } - case ' ': - displayMode = (displayMode + 1) % NUM_DISPLAY_MODES; - System.err.println("Switching to display mode " + displayMode); - break; + private void unavailableExtension(String message) { + JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); + throw new GLException(message); + } - // FIXME: add more key behaviors from original demo + private void dispatchKey(char k) { + switch (k) { + case 27: + case 'q': + shutdownDemo(); + break; - default: - break; - } + case 'v': + doViewAll = true; + System.err.println("Forcing viewAll()"); + break; + + case ' ': + displayMode = (displayMode + 1) % NUM_DISPLAY_MODES; + System.err.println("Switching to display mode " + displayMode); + break; + + // FIXME: add more key behaviors from original demo + + default: + break; } } class PbufferListener implements GLEventListener { - public void init(GLDrawable drawable) { + public void init(GLAutoDrawable drawable) { // Use debug pipeline // drawable.setGL(new DebugGL(drawable.getGL())); GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); gl.glEnable(GL.GL_DEPTH_TEST); int[] depth_bits = new int[1]; - gl.glGetIntegerv(GL.GL_DEPTH_BITS, depth_bits); + gl.glGetIntegerv(GL.GL_DEPTH_BITS, depth_bits, 0); if (depth_bits[0] == 16) depth_format = GL.GL_DEPTH_COMPONENT16_ARB; else depth_format = GL.GL_DEPTH_COMPONENT24_ARB; @@ -391,15 +417,14 @@ public class HWShadowmapsSimple { light_view_depth = genTexture(gl); gl.glBindTexture(GL.GL_TEXTURE_2D, light_view_depth); gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, depth_format, TEX_SIZE, TEX_SIZE, 0, - GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT, (byte[]) null); + GL.GL_DEPTH_COMPONENT, GL.GL_UNSIGNED_INT, null); set_light_view_texture_parameters(gl); fullyInitialized = true; } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); @@ -407,7 +432,7 @@ public class HWShadowmapsSimple { ((Tweak) tweaks.get(POLYGON_OFFSET_BIAS)).val); gl.glEnable(GL.GL_POLYGON_OFFSET_FILL); - render_scene_from_light_view(gl, glu); + render_scene_from_light_view(gl, drawable, 0, 0); gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); @@ -418,8 +443,8 @@ public class HWShadowmapsSimple { } // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } private void set_light_view_texture_parameters(GL gl) { @@ -434,7 +459,7 @@ public class HWShadowmapsSimple { private int genTexture(GL gl) { int[] tmp = new int[1]; - gl.glGenTextures(1, tmp); + gl.glGenTextures(1, tmp, 0); return tmp[0]; } @@ -451,37 +476,36 @@ public class HWShadowmapsSimple { } } - private void makeRGBTexture(GL gl, GLU glu, BufferedImage img, int target, boolean mipmapped) { - ByteBuffer dest = null; + private void makeRGBTexture(GL gl, BufferedImage img, int target, boolean mipmapped) { switch (img.getType()) { case BufferedImage.TYPE_3BYTE_BGR: case BufferedImage.TYPE_CUSTOM: { byte[] data = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); - dest = ByteBuffer.allocateDirect(data.length); - dest.order(ByteOrder.nativeOrder()); - dest.put(data, 0, data.length); + if (mipmapped) { + glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(), img.getHeight(), GL.GL_RGB, + GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap(data)); + } else { + gl.glTexImage2D(target, 0, GL.GL_RGB, img.getWidth(), img.getHeight(), 0, + GL.GL_RGB, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap(data)); + } break; } case BufferedImage.TYPE_INT_RGB: { int[] data = ((DataBufferInt) img.getRaster().getDataBuffer()).getData(); - dest = ByteBuffer.allocateDirect(data.length * BufferUtils.SIZEOF_INT); - dest.order(ByteOrder.nativeOrder()); - dest.asIntBuffer().put(data, 0, data.length); + if (mipmapped) { + glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(), img.getHeight(), GL.GL_RGB, + GL.GL_UNSIGNED_BYTE, IntBuffer.wrap(data)); + } else { + gl.glTexImage2D(target, 0, GL.GL_RGB, img.getWidth(), img.getHeight(), 0, + GL.GL_RGB, GL.GL_UNSIGNED_BYTE, IntBuffer.wrap(data)); + } break; } default: throw new RuntimeException("Unsupported image type " + img.getType()); } - - if (mipmapped) { - glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(), img.getHeight(), GL.GL_RGB, - GL.GL_UNSIGNED_BYTE, dest); - } else { - gl.glTexImage2D(target, 0, GL.GL_RGB, img.getWidth(), img.getHeight(), 0, - GL.GL_RGB, GL.GL_UNSIGNED_BYTE, dest); - } } private void eye_linear_texgen(GL gl) { @@ -511,7 +535,7 @@ public class HWShadowmapsSimple { float[] row = new float[4]; for(int i = 0; i < 4; i++) { getRow(m, i, row); - gl.glTexGenfv(coord[i], plane_type, row); + gl.glTexGenfv(coord[i], plane_type, row, 0); } } @@ -543,7 +567,7 @@ public class HWShadowmapsSimple { } private void render_quad(GL gl) { - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); obj_linear_texgen(gl); texgen(gl, true); gl.glMatrixMode(GL.GL_TEXTURE); @@ -564,7 +588,7 @@ public class HWShadowmapsSimple { gl.glMatrixMode(GL.GL_MODELVIEW); } - private void render_scene(GL gl, Mat4f view, GLDrawable drawable, CameraParameters params) { + private void render_scene(GL gl, Mat4f view, GLAutoDrawable drawable, CameraParameters params) { gl.glColor3f(1,1,1); gl.glPushMatrix(); Mat4f inverseView = new Mat4f(view); @@ -585,7 +609,7 @@ public class HWShadowmapsSimple { gl.glPopMatrix(); } - private void render_manipulators(GL gl, Mat4f view, GLDrawable drawable, CameraParameters params) { + private void render_manipulators(GL gl, Mat4f view, GLAutoDrawable drawable, CameraParameters params) { gl.glColor3f(1,1,1); gl.glPushMatrix(); Mat4f inverseView = new Mat4f(view); @@ -600,17 +624,17 @@ public class HWShadowmapsSimple { gl.glPopMatrix(); } - private void render_scene_from_camera_view(GL gl, GLU glu, GLDrawable drawable, CameraParameters params) { + private void render_scene_from_camera_view(GL gl, GLAutoDrawable drawable, CameraParameters params) { // place light gl.glPushMatrix(); gl.glLoadIdentity(); applyTransform(gl, cameraInverseTransform); applyTransform(gl, spotlightTransform); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_pos); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_pos, 0); gl.glPopMatrix(); // spot image - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); gl.glPushMatrix(); applyTransform(gl, cameraInverseTransform); @@ -630,34 +654,34 @@ public class HWShadowmapsSimple { gl.glEnable(GL.GL_TEXTURE_2D); gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); - gl.glViewport(0, 0, canvas.getWidth(), canvas.getHeight()); + gl.glViewport(viewportX, viewportY, drawable.getWidth(), drawable.getHeight()); applyTransform(gl, cameraPerspective); gl.glMatrixMode(GL.GL_MODELVIEW); render_scene(gl, cameraTransform, drawable, params); - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); gl.glDisable(GL.GL_TEXTURE_2D); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); render_manipulators(gl, cameraTransform, drawable, params); render_light_frustum(gl); } - private void render_scene_from_camera_view_shadowed(GL gl, GLU glu, GLDrawable drawable, CameraParameters params) { + private void render_scene_from_camera_view_shadowed(GL gl, GLAutoDrawable drawable, CameraParameters params) { // place light gl.glPushMatrix(); gl.glLoadIdentity(); applyTransform(gl, cameraInverseTransform); applyTransform(gl, spotlightTransform); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_pos); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_pos, 0); gl.glPopMatrix(); // spot image - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); gl.glPushMatrix(); applyTransform(gl, cameraInverseTransform); @@ -678,7 +702,7 @@ public class HWShadowmapsSimple { gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE); // depth compare - gl.glActiveTextureARB(GL.GL_TEXTURE2_ARB); + gl.glActiveTexture(GL.GL_TEXTURE2); gl.glPushMatrix(); applyTransform(gl, cameraInverseTransform); @@ -698,44 +722,43 @@ public class HWShadowmapsSimple { gl.glEnable(GL.GL_TEXTURE_2D); gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); - gl.glViewport(0, 0, canvas.getWidth(), canvas.getHeight()); + gl.glViewport(viewportX, viewportY, drawable.getWidth(), drawable.getHeight()); applyTransform(gl, cameraPerspective); gl.glMatrixMode(GL.GL_MODELVIEW); render_scene(gl, cameraTransform, drawable, params); - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); gl.glDisable(GL.GL_TEXTURE_2D); - gl.glActiveTextureARB(GL.GL_TEXTURE2_ARB); + gl.glActiveTexture(GL.GL_TEXTURE2); gl.glDisable(GL.GL_TEXTURE_2D); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); render_manipulators(gl, cameraTransform, drawable, params); render_light_frustum(gl); } - private void largest_square_power_of_two_viewport(GL gl) { - Dimension dim = canvas.getSize(); - float min = Math.min(dim.width, dim.height); + private void largest_square_power_of_two_viewport(GL gl, GLAutoDrawable drawable, int viewportX, int viewportY) { + float min = Math.min(drawable.getWidth(), drawable.getHeight()); float log2min = (float) Math.log(min) / (float) Math.log(2.0); float pow2 = (float) Math.floor(log2min); int size = 1 << (int) pow2; - gl.glViewport(0, 0, size, size); + gl.glViewport(viewportX, viewportY, size, size); } - private void render_scene_from_light_view(GL gl, GLU glu) { + private void render_scene_from_light_view(GL gl, GLAutoDrawable drawable, int viewportX, int viewportY) { // place light gl.glPushMatrix(); gl.glLoadIdentity(); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_pos); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_pos, 0); gl.glPopMatrix(); // spot image - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); gl.glPushMatrix(); eye_linear_texgen(gl); @@ -753,7 +776,7 @@ public class HWShadowmapsSimple { gl.glEnable(GL.GL_TEXTURE_2D); gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glViewport(0, 0, TEX_SIZE, TEX_SIZE); gl.glMatrixMode(GL.GL_PROJECTION); @@ -761,12 +784,12 @@ public class HWShadowmapsSimple { glu.gluPerspective(lightshaper_fovy, 1, lightshaper_zNear, lightshaper_zFar); gl.glMatrixMode(GL.GL_MODELVIEW); if (displayMode == RENDER_SCENE_FROM_LIGHT_VIEW) - largest_square_power_of_two_viewport(gl); + largest_square_power_of_two_viewport(gl, drawable, viewportX, viewportY); render_scene(gl, spotlightTransform, null, null); - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); gl.glDisable(GL.GL_TEXTURE_2D); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); } private static void getRow(Mat4f m, int row, float[] out) { @@ -779,7 +802,7 @@ public class HWShadowmapsSimple { private static void applyTransform(GL gl, Mat4f xform) { float[] data = new float[16]; xform.getColumnMajorData(data); - gl.glMultMatrixf(data); + gl.glMultMatrixf(data, 0); } private static Mat4f perspectiveInverse(float fovy, float aspect, float zNear, float zFar) { @@ -810,7 +833,7 @@ public class HWShadowmapsSimple { return m; } - private void runExit() { + private static void runExit() { // Note: calling System.exit() synchronously inside the draw, // reshape or init callbacks can lead to deadlocks on certain // platforms (in particular, X11) because the JAWT's locking diff --git a/src/demos/infiniteShadowVolumes/InfiniteShadowVolumes.java b/src/demos/infiniteShadowVolumes/InfiniteShadowVolumes.java index f091c11..e35bdf0 100644 --- a/src/demos/infiniteShadowVolumes/InfiniteShadowVolumes.java +++ b/src/demos/infiniteShadowVolumes/InfiniteShadowVolumes.java @@ -42,8 +42,10 @@ import java.util.*; import javax.imageio.*; import javax.imageio.stream.*; -import net.java.games.jogl.*; -import net.java.games.jogl.util.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; +import demos.common.*; import demos.util.*; import gleem.*; import gleem.linalg.*; @@ -65,19 +67,22 @@ import gleem.linalg.*; Ported to Java by Kenneth Russell */ -public class InfiniteShadowVolumes { - private GLCanvas canvas; - private volatile boolean quit; - +public class InfiniteShadowVolumes extends Demo { public static void main(String[] args) { - new InfiniteShadowVolumes().run(args); - } - - public void run(String[] args) { GLCapabilities caps = new GLCapabilities(); caps.setStencilBits(16); - canvas = GLDrawableFactory.getFactory().createGLCanvas(caps); - canvas.addGLEventListener(new Listener()); + final GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(caps); + InfiniteShadowVolumes demo = new InfiniteShadowVolumes(); + canvas.addGLEventListener(demo); + + demo.setDemoListener(new DemoListener() { + public void shutdownDemo() { + runExit(); + } + public void repaint() { + canvas.repaint(); + } + }); Frame frame = new Frame("Infinite Stenciled Shadow Volumes"); frame.setLayout(new BorderLayout()); @@ -94,6 +99,16 @@ public class InfiniteShadowVolumes { }); } + //---------------------------------------------------------------------- + // Internals only below this point + // + + public void shutdownDemo() { + ManipManager.getManipManager().unregisterWindow(drawable); + drawable.removeGLEventListener(this); + super.shutdownDemo(); + } + static class Model { Model() { frame_num = 0; @@ -132,8 +147,10 @@ public class InfiniteShadowVolumes { private static final int CLIP_VIEW = 2; private int curr_view = CAMERA_VIEW; + private GLU glu = new GLU(); private GLUT glut = new GLUT(); + private GLAutoDrawable drawable; private ExaminerViewer viewer; private HandleBoxManip objectManip; private HandleBoxManip lightManip; @@ -159,1136 +176,1127 @@ public class InfiniteShadowVolumes { private boolean hideCurrentModel; private boolean toggleWireframe; - class Listener implements GLEventListener { - public void init(GLDrawable drawable) { - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); + public void init(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); + + gl.glClearStencil(128); + //glEnable(GL.GL_DEPTH_CLAMP_NV); + gl.glEnable(GL.GL_DEPTH_TEST); + gl.glDepthFunc(GL.GL_LESS); + gl.glEnable(GL.GL_NORMALIZE); + gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_FALSE); + float[] ambient = new float[] {0.3f, 0.3f, 0.3f, 1}; + gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient, 0); + faceDisplayList = gl.glGenLists(1); + gl.glNewList(faceDisplayList, GL.GL_COMPILE); + drawMesh(gl, 20, 40); + gl.glEndList(); + + int[] tmp = new int[1]; + gl.glGenTextures(1, tmp, 0); + wallTexObject = tmp[0]; + gl.glBindTexture(GL.GL_TEXTURE_2D, wallTexObject); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_GENERATE_MIPMAP_SGIS, GL.GL_TRUE); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); + gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); + + float[] tex = new float[32*32]; + for(int i=0; i < 32; i++) { + for(int j=0; j < 32; j++) { + if ((i>>4 ^ j>>4) != 0) + tex[i+j*32] = 1; + else + tex[i+j*32] = .9f; + } + } + gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, 32, 32, 0, GL.GL_LUMINANCE, GL.GL_FLOAT, FloatBuffer.wrap(tex)); + + initModel(); + + b['S'] = true; // no silhouette outlines + b['v'] = true; // no volume drawing + b['I'] = true; // use infinite far plane + b['L'] = true; // use local light for shadowing - gl.glClearStencil(128); - //glEnable(GL.GL_DEPTH_CLAMP_NV); - gl.glEnable(GL.GL_DEPTH_TEST); - gl.glDepthFunc(GL.GL_LESS); - gl.glEnable(GL.GL_NORMALIZE); - gl.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE, GL.GL_FALSE); - float[] ambient = new float[] {0.3f, 0.3f, 0.3f, 1}; - gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient); - faceDisplayList = gl.glGenLists(1); - gl.glNewList(faceDisplayList, GL.GL_COMPILE); - drawMesh(gl, 20, 40); - gl.glEndList(); + doViewAll = true; - int[] tmp = new int[1]; - gl.glGenTextures(1, tmp); - wallTexObject = tmp[0]; - gl.glBindTexture(GL.GL_TEXTURE_2D, wallTexObject); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_GENERATE_MIPMAP_SGIS, GL.GL_TRUE); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); - gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); - float[] tex = new float[32*32]; - for(int i=0; i < 32; i++) { - for(int j=0; j < 32; j++) { - if ((i>>4 ^ j>>4) != 0) - tex[i+j*32] = 1; - else - tex[i+j*32] = .9f; + drawable.addKeyListener(new KeyAdapter() { + public void keyTyped(KeyEvent e) { + dispatchKey(e.getKeyChar()); + demoListener.repaint(); } - } - gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, 32, 32, 0, GL.GL_LUMINANCE, GL.GL_FLOAT, tex); - - initModel(); - - b['S'] = true; // no silhouette outlines - b['v'] = true; // no volume drawing - b['I'] = true; // use infinite far plane - b['L'] = true; // use local light for shadowing - - drawable.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { - dispatchKey(e.getKeyChar()); - canvas.repaint(); - } - }); - - // Register the window with the ManipManager - ManipManager manager = ManipManager.getManipManager(); - manager.registerWindow(drawable); - - objectManip = new HandleBoxManip(); - manager.showManipInWindow(objectManip, drawable); - objectManip.setTranslation(new Vec3f(0, 0, -2)); - objectManip.setRotation(new Rotf(new Vec3f(1, 0, 0), (float) Math.toRadians(-90))); - - lightManip = new HandleBoxManip(); - manager.showManipInWindow(lightManip, drawable); - lightManip.setTranslation(new Vec3f(0.5f, 0.5f, -1)); - lightManip.setGeometryScale(new Vec3f(0.1f, 0.1f, 0.1f)); - - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); - viewer.attach(drawable, new BSphereProvider() { - public BSphere getBoundingSphere() { - return new BSphere(objectManip.getTranslation(), 1.0f); - } - }); - viewer.setZNear(1.0f); - viewer.setZFar(100.0f); - viewer.setOrientation(new Rotf(new Vec3f(0, 1, 0), (float) Math.toRadians(15))); + }); - // FIXME - // glutAddMenuEntry("mouse controls view [1]", '1'); - // glutAddMenuEntry("mouse controls model [2]", '2'); - // glutAddMenuEntry("mouse controls light [3]", '3'); - // glutAddMenuEntry("mouse controls room [4]", '4'); - // glutAddMenuEntry("enable depth clamp [!]", '!'); - // glutAddMenuEntry("disable depth clamp [~]", '~'); - // glutAddMenuEntry("start animation [ ]", ' '); - // glutAddMenuEntry("step animation forward [a]", 'a'); - // glutAddMenuEntry("step animation backward [b]", 'b'); - // glutAddMenuEntry("toggle drawing silhouette [S]", 'S'); - // glutAddMenuEntry("toggle drawing shadow [s]", 's'); - // glutAddMenuEntry("toggle drawing visible shadow volume [v]", 'v'); - // glutAddMenuEntry("toggle drawing model geometry[m]", 'm'); + // Register the window with the ManipManager + ManipManager manager = ManipManager.getManipManager(); + manager.registerWindow(drawable); + this.drawable = drawable; + + objectManip = new HandleBoxManip(); + manager.showManipInWindow(objectManip, drawable); + objectManip.setTranslation(new Vec3f(0, 0, -2)); + objectManip.setRotation(new Rotf(new Vec3f(1, 0, 0), (float) Math.toRadians(-90))); + + lightManip = new HandleBoxManip(); + manager.showManipInWindow(lightManip, drawable); + lightManip.setTranslation(new Vec3f(0.5f, 0.5f, -1)); + lightManip.setGeometryScale(new Vec3f(0.1f, 0.1f, 0.1f)); + + viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer.attach(drawable, new BSphereProvider() { + public BSphere getBoundingSphere() { + return new BSphere(objectManip.getTranslation(), 1.0f); + } + }); + viewer.setZNear(1.0f); + viewer.setZFar(100.0f); + viewer.setOrientation(new Rotf(new Vec3f(0, 1, 0), (float) Math.toRadians(15))); + + // FIXME + // glutAddMenuEntry("mouse controls view [1]", '1'); + // glutAddMenuEntry("mouse controls model [2]", '2'); + // glutAddMenuEntry("mouse controls light [3]", '3'); + // glutAddMenuEntry("mouse controls room [4]", '4'); + // glutAddMenuEntry("enable depth clamp [!]", '!'); + // glutAddMenuEntry("disable depth clamp [~]", '~'); + // glutAddMenuEntry("start animation [ ]", ' '); + // glutAddMenuEntry("step animation forward [a]", 'a'); + // glutAddMenuEntry("step animation backward [b]", 'b'); + // glutAddMenuEntry("toggle drawing silhouette [S]", 'S'); + // glutAddMenuEntry("toggle drawing shadow [s]", 's'); + // glutAddMenuEntry("toggle drawing visible shadow volume [v]", 'v'); + // glutAddMenuEntry("toggle drawing model geometry[m]", 'm'); + + // glutAddMenuEntry("increase shadow volume alpha [;]", ';'); + // glutAddMenuEntry("decrease shadow volume alpha [:]", ':'); - // glutAddMenuEntry("increase shadow volume alpha [;]", ';'); - // glutAddMenuEntry("decrease shadow volume alpha [:]", ':'); + // glutAddMenuEntry("next model [,]", ','); + // glutAddMenuEntry("hide current model [.]", '.'); - // glutAddMenuEntry("next model [,]", ','); - // glutAddMenuEntry("hide current model [.]", '.'); + // glutAddMenuEntry("toggle view frustum clip planes [X]", 'X'); - // glutAddMenuEntry("toggle view frustum clip planes [X]", 'X'); + // glutAddMenuEntry("camera view [5]", '5'); + // glutAddMenuEntry("scene view [6]", '6'); + // glutAddMenuEntry("clipspace view [7]", '7'); - // glutAddMenuEntry("camera view [5]", '5'); - // glutAddMenuEntry("scene view [6]", '6'); - // glutAddMenuEntry("clipspace view [7]", '7'); + // glutAddMenuEntry("enable depth clamp [!]", '!'); + // glutAddMenuEntry("disable depth clamp [~]", '~'); - // glutAddMenuEntry("enable depth clamp [!]", '!'); - // glutAddMenuEntry("disable depth clamp [~]", '~'); + // glutAddMenuEntry("increase light size [n]", 'n'); + // glutAddMenuEntry("decrease light size [N]", 'N'); - // glutAddMenuEntry("increase light size [n]", 'n'); - // glutAddMenuEntry("decrease light size [N]", 'N'); + // glutAddMenuEntry("move near plane in [[]", '['); + // glutAddMenuEntry("move near plane out []]", ']'); + // glutAddMenuEntry("move far plane in [{]", '['); + // glutAddMenuEntry("move far plane out [}]", ']'); - // glutAddMenuEntry("move near plane in [[]", '['); - // glutAddMenuEntry("move near plane out []]", ']'); - // glutAddMenuEntry("move far plane in [{]", '['); - // glutAddMenuEntry("move far plane out [}]", ']'); + // glutAddMenuEntry("toggle local/infinite light [L]", 'L'); - // glutAddMenuEntry("toggle local/infinite light [L]", 'L'); + // glutAddMenuEntry("hide room [R]", 'R'); - // glutAddMenuEntry("hide room [R]", 'R'); + // glutAddMenuEntry("view all with camera [c]", 'c'); + + // glutAddMenuEntry("quit [<esc>]", 27); + } - // glutAddMenuEntry("view all with camera [c]", 'c'); + public void display(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); - // glutAddMenuEntry("quit [<esc>]", 27); + gl.glMatrixMode(GL.GL_PROJECTION); + gl.glLoadIdentity(); + + if (doViewAll) { + viewer.viewAll(gl); + doViewAll = false; } - public void display(GLDrawable drawable) { - if (quit) { - return; + objectManipXform = objectManip.getTransform(); + lightManipXform = lightManip.getTransform(); + + if (toggleDepthClampNV) { + if (enableDepthClampNV) { + gl.glEnable(GL.GL_DEPTH_CLAMP_NV); + } else { + gl.glDisable(GL.GL_DEPTH_CLAMP_NV); } + toggleDepthClampNV = false; + } - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); + if (b[' ']) { + animateForward = true; + } - gl.glMatrixMode(GL.GL_PROJECTION); - gl.glLoadIdentity(); + if (animateForward) { + Model mm = m[curr_model]; + mm.frame_num += mm.frame_incr; + if (mm.frame_num >= mm.mod.f.length) + mm.frame_num = 0; + interpolate_frame(); + animateForward = false; + } - if (doViewAll) { - viewer.viewAll(gl); - doViewAll = false; - } + if (animateBackward) { + Model mm = m[curr_model]; + mm.frame_num -= mm.frame_incr; + if (mm.frame_num < 0) + mm.frame_num += mm.mod.f.length; + interpolate_frame(); + animateBackward = false; + } - objectManipXform = objectManip.getTransform(); - lightManipXform = lightManip.getTransform(); + if (hideCurrentModel) { + gl.glNewList(faceDisplayList, GL.GL_COMPILE); + drawMesh(gl, 20, 40); + gl.glEndList(); + hideCurrentModel = false; + } - if (toggleDepthClampNV) { - if (enableDepthClampNV) { - gl.glEnable(GL.GL_DEPTH_CLAMP_NV); - } else { - gl.glDisable(GL.GL_DEPTH_CLAMP_NV); - } - toggleDepthClampNV = false; - } + if (toggleWireframe) { + if(b['w']) + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); + else + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); + } - if (b[' ']) { - animateForward = true; - } + if(b['I']) { + // push far plane to infinity + switch (curr_view) { + case CAMERA_VIEW: + viewer.update(gl); + // Undo perspective effects of ExaminerViewer + gl.glMatrixMode(GL.GL_PROJECTION); + gl.glLoadIdentity(); + applyInfinitePerspective(gl, viewer); + break; - if (animateForward) { - Model mm = m[curr_model]; - mm.frame_num += mm.frame_incr; - if (mm.frame_num >= mm.mod.f.length) - mm.frame_num = 0; - interpolate_frame(); - animateForward = false; - } + case SCENE_VIEW: + applyInfinitePerspective(gl, viewer); + // FIXME: do we need more primitives in the ExaminerViewer class? + // scenecam.apply_inverse_transform(); + break; - if (animateBackward) { - Model mm = m[curr_model]; - mm.frame_num -= mm.frame_incr; - if (mm.frame_num < 0) - mm.frame_num += mm.mod.f.length; - interpolate_frame(); - animateBackward = false; - } + case CLIP_VIEW: + applyInfinitePerspective(gl, viewer); + // FIXME + // clipcam.apply_inverse_transform(); + gl.glScalef(10,10,-10); + applyInfinitePerspective(gl, viewer); + break; - if (hideCurrentModel) { - gl.glNewList(faceDisplayList, GL.GL_COMPILE); - drawMesh(gl, 20, 40); - gl.glEndList(); - hideCurrentModel = false; + default: + break; } + } else { + switch (curr_view) { + case CAMERA_VIEW: + viewer.update(gl); + break; + + case SCENE_VIEW: + applyInfinitePerspective(gl, viewer); + // FIXME + // scenecam.apply_inverse_transform(); + break; - if (toggleWireframe) { - if(b['w']) - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); - else - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); - } + case CLIP_VIEW: + applyInfinitePerspective(gl, viewer); + // FIXME + // clipcam.apply_inverse_transform(); + gl.glScalef(10,10,-10); + // FIXME + // reshaper.apply_projection(); + break; - if(b['I']) { - // push far plane to infinity - switch (curr_view) { - case CAMERA_VIEW: - viewer.update(gl); - // Undo perspective effects of ExaminerViewer - gl.glMatrixMode(GL.GL_PROJECTION); - gl.glLoadIdentity(); - applyInfinitePerspective(gl, viewer); - break; - - case SCENE_VIEW: - applyInfinitePerspective(gl, viewer); - // FIXME: do we need more primitives in the ExaminerViewer class? - // scenecam.apply_inverse_transform(); - break; - - case CLIP_VIEW: - applyInfinitePerspective(gl, viewer); - // FIXME - // clipcam.apply_inverse_transform(); - gl.glScalef(10,10,-10); - applyInfinitePerspective(gl, viewer); - break; - - default: - break; - } - } else { - switch (curr_view) { - case CAMERA_VIEW: - viewer.update(gl); - break; - - case SCENE_VIEW: - applyInfinitePerspective(gl, viewer); - // FIXME - // scenecam.apply_inverse_transform(); - break; - - case CLIP_VIEW: - applyInfinitePerspective(gl, viewer); - // FIXME - // clipcam.apply_inverse_transform(); - gl.glScalef(10,10,-10); - // FIXME - // reshaper.apply_projection(); - break; - - default: - break; - } + default: + break; } + } - gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glMatrixMode(GL.GL_MODELVIEW); - // FIXME - if (b['X']) { - gl.glLoadIdentity(); - if(b['I']) { - // FIXME - applyInfinitePerspectiveInverse(gl, viewer); - } else { - // FIXME - // reshaper.apply_projection_inverse(); - } - double[] pos_x = new double[] {-1, 0, 0, 1}; - double[] neg_x = new double[] { 1, 0, 0, 1}; - double[] pos_y = new double[] { 0,-1, 0, 1}; - double[] neg_y = new double[] { 0, 1, 0, 1}; - double[] pos_z = new double[] { 0, 0,-1, 1}; - double[] neg_z = new double[] { 0, 0, 1, 1}; - gl.glClipPlane(GL.GL_CLIP_PLANE0, pos_x); - gl.glClipPlane(GL.GL_CLIP_PLANE1, neg_x); - gl.glClipPlane(GL.GL_CLIP_PLANE2, pos_y); - gl.glClipPlane(GL.GL_CLIP_PLANE3, neg_y); - gl.glClipPlane(GL.GL_CLIP_PLANE4, pos_z); - gl.glClipPlane(GL.GL_CLIP_PLANE5, neg_z); - gl.glEnable(GL.GL_CLIP_PLANE0); - gl.glEnable(GL.GL_CLIP_PLANE1); - gl.glEnable(GL.GL_CLIP_PLANE2); - gl.glEnable(GL.GL_CLIP_PLANE3); - gl.glEnable(GL.GL_CLIP_PLANE4); - gl.glEnable(GL.GL_CLIP_PLANE5); - gl.glLoadIdentity(); + // FIXME + if (b['X']) { + gl.glLoadIdentity(); + if(b['I']) { + // FIXME + applyInfinitePerspectiveInverse(gl, viewer); + } else { + // FIXME + // reshaper.apply_projection_inverse(); } + double[] pos_x = new double[] {-1, 0, 0, 1}; + double[] neg_x = new double[] { 1, 0, 0, 1}; + double[] pos_y = new double[] { 0,-1, 0, 1}; + double[] neg_y = new double[] { 0, 1, 0, 1}; + double[] pos_z = new double[] { 0, 0,-1, 1}; + double[] neg_z = new double[] { 0, 0, 1, 1}; + gl.glClipPlane(GL.GL_CLIP_PLANE0, pos_x, 0); + gl.glClipPlane(GL.GL_CLIP_PLANE1, neg_x, 0); + gl.glClipPlane(GL.GL_CLIP_PLANE2, pos_y, 0); + gl.glClipPlane(GL.GL_CLIP_PLANE3, neg_y, 0); + gl.glClipPlane(GL.GL_CLIP_PLANE4, pos_z, 0); + gl.glClipPlane(GL.GL_CLIP_PLANE5, neg_z, 0); + gl.glEnable(GL.GL_CLIP_PLANE0); + gl.glEnable(GL.GL_CLIP_PLANE1); + gl.glEnable(GL.GL_CLIP_PLANE2); + gl.glEnable(GL.GL_CLIP_PLANE3); + gl.glEnable(GL.GL_CLIP_PLANE4); + gl.glEnable(GL.GL_CLIP_PLANE5); + gl.glLoadIdentity(); + } - gl.glPushMatrix(); - // FIXME - // camera.apply_inverse_transform(); - // light.apply_transform(); - gl.glMultMatrixf(getData(lightManipXform)); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, getData(light_position)); - gl.glPopMatrix(); - gl.glEnable(GL.GL_LIGHT0); - - // FIXME - gl.glPushMatrix(); - // gl.glLoadIdentity(); - // camera.apply_inverse_transform(); + gl.glPushMatrix(); + // FIXME + // camera.apply_inverse_transform(); + // light.apply_transform(); + gl.glMultMatrixf(getData(lightManipXform), 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, getData(light_position), 0); + gl.glPopMatrix(); + gl.glEnable(GL.GL_LIGHT0); - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT); + // FIXME + gl.glPushMatrix(); + // gl.glLoadIdentity(); + // camera.apply_inverse_transform(); - ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters()); - ManipManager.getManipManager().render(drawable, gl); + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT); - if (!b['R']) { - drawRoom(gl, false); - } + ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters()); + ManipManager.getManipManager().render(drawable, gl); - if (!b['m']) { - for (int i = 0; i < num_models; i++) - if (m[i].draw) - drawModel(gl, i, false); - } + if (!b['R']) { + drawRoom(gl, false); + } - if (b['X']) { - gl.glDisable(GL.GL_CLIP_PLANE0); - gl.glDisable(GL.GL_CLIP_PLANE1); - gl.glDisable(GL.GL_CLIP_PLANE2); - gl.glDisable(GL.GL_CLIP_PLANE3); - gl.glDisable(GL.GL_CLIP_PLANE4); - gl.glDisable(GL.GL_CLIP_PLANE5); - } + if (!b['m']) { + for (int i = 0; i < num_models; i++) + if (m[i].draw) + drawModel(gl, i, false); + } - if (!b['s']) { - for (int i = 0; i < num_models; i++) - if (m[i].draw) - drawShadowVolumeToStencil(gl, i); - } + if (b['X']) { + gl.glDisable(GL.GL_CLIP_PLANE0); + gl.glDisable(GL.GL_CLIP_PLANE1); + gl.glDisable(GL.GL_CLIP_PLANE2); + gl.glDisable(GL.GL_CLIP_PLANE3); + gl.glDisable(GL.GL_CLIP_PLANE4); + gl.glDisable(GL.GL_CLIP_PLANE5); + } - // Be aware that this can cause some multipass artifacts - // due to invariance issues. - if (b['X']) { - gl.glEnable(GL.GL_CLIP_PLANE0); - gl.glEnable(GL.GL_CLIP_PLANE1); - gl.glEnable(GL.GL_CLIP_PLANE2); - gl.glEnable(GL.GL_CLIP_PLANE3); - gl.glEnable(GL.GL_CLIP_PLANE4); - gl.glEnable(GL.GL_CLIP_PLANE5); - } - if (!b['d']) { - if (!b['R']) - drawRoom(gl, true); - if (!b['m']) - for (int i = 0; i < num_models; i++) - if (m[i].draw) - drawModel(gl, i, true); - } + if (!b['s']) { + for (int i = 0; i < num_models; i++) + if (m[i].draw) + drawShadowVolumeToStencil(gl, i); + } - if(!b['S']) { + // Be aware that this can cause some multipass artifacts + // due to invariance issues. + if (b['X']) { + gl.glEnable(GL.GL_CLIP_PLANE0); + gl.glEnable(GL.GL_CLIP_PLANE1); + gl.glEnable(GL.GL_CLIP_PLANE2); + gl.glEnable(GL.GL_CLIP_PLANE3); + gl.glEnable(GL.GL_CLIP_PLANE4); + gl.glEnable(GL.GL_CLIP_PLANE5); + } + if (!b['d']) { + if (!b['R']) + drawRoom(gl, true); + if (!b['m']) for (int i = 0; i < num_models; i++) if (m[i].draw) - drawPossibleSilhouette(gl, i); - } + drawModel(gl, i, true); + } - if (!b['v']) { - for (int i = 0; i < num_models; i++) - if (m[i].draw) - drawShadowVolumeToColor(gl, i); - } + if(!b['S']) { + for (int i = 0; i < num_models; i++) + if (m[i].draw) + drawPossibleSilhouette(gl, i); + } - // Be aware that this can cause some multipass artifacts - // due to invariance issues. - if (b['X']) { - gl.glDisable(GL.GL_CLIP_PLANE0); - gl.glDisable(GL.GL_CLIP_PLANE1); - gl.glDisable(GL.GL_CLIP_PLANE2); - gl.glDisable(GL.GL_CLIP_PLANE3); - gl.glDisable(GL.GL_CLIP_PLANE4); - gl.glDisable(GL.GL_CLIP_PLANE5); - } + if (!b['v']) { + for (int i = 0; i < num_models; i++) + if (m[i].draw) + drawShadowVolumeToColor(gl, i); + } - drawLight(gl, glu); + // Be aware that this can cause some multipass artifacts + // due to invariance issues. + if (b['X']) { + gl.glDisable(GL.GL_CLIP_PLANE0); + gl.glDisable(GL.GL_CLIP_PLANE1); + gl.glDisable(GL.GL_CLIP_PLANE2); + gl.glDisable(GL.GL_CLIP_PLANE3); + gl.glDisable(GL.GL_CLIP_PLANE4); + gl.glDisable(GL.GL_CLIP_PLANE5); + } - gl.glPopMatrix(); + drawLight(gl); - // In an "external" viewing mode, show the camera's view volume - // as a yellow wireframe cube or frustum. - if (curr_view != CAMERA_VIEW) { - gl.glPushMatrix(); - if (b['I']) { - // FIXME - applyInfinitePerspectiveInverse(gl, viewer); - } else { - // FIXME - // reshaper.apply_projection_inverse(); - } - gl.glColor3f(.75f,.75f,0); - gl.glLineWidth(3); - glut.glutWireCube(gl, 2); - gl.glLineWidth(1); - gl.glPopMatrix(); - } + gl.glPopMatrix(); - if (b[' ']) { - // Animating continually. Schedule another repaint soon. - canvas.repaint(); + // In an "external" viewing mode, show the camera's view volume + // as a yellow wireframe cube or frustum. + if (curr_view != CAMERA_VIEW) { + gl.glPushMatrix(); + if (b['I']) { + // FIXME + applyInfinitePerspectiveInverse(gl, viewer); + } else { + // FIXME + // reshaper.apply_projection_inverse(); } + gl.glColor3f(.75f,.75f,0); + gl.glLineWidth(3); + glut.glutWireCube(2); + gl.glLineWidth(1); + gl.glPopMatrix(); } - // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + if (b[' ']) { + // Animating continually. Schedule another repaint soon. + demoListener.repaint(); + } + } - //---------------------------------------------------------------------- - // Internals only below this point - // + // Unused routines + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - private void dispatchKey(char k) { - b[k] = ! b[k]; - if (k==27 || k=='q') { - runExit(); - return; - } + private void dispatchKey(char k) { + b[k] = ! b[k]; + if (k==27 || k=='q') { + shutdownDemo(); + return; + } - if(';' == k) { - volume_alpha *= 1.1f; - } - if(':' == k) { - volume_alpha /= 1.1f; - } + if(';' == k) { + volume_alpha *= 1.1f; + } + if(':' == k) { + volume_alpha /= 1.1f; + } - if('\'' == k) { - room_ambient += .025f; - } - if('"' == k) { - room_ambient -= .025f; - } + if('\'' == k) { + room_ambient += .025f; + } + if('"' == k) { + room_ambient -= .025f; + } - if(',' == k) { - curr_model++; - curr_model %= num_models; - // FIXME - // key('2',0,0); - } - if('.' == k) { - m[curr_model].draw = ! m[curr_model].draw; - } - if('w' == k) { - toggleWireframe = true; - } - if('1' == k) { - // FIXME - /* + if(',' == k) { + curr_model++; + curr_model %= num_models; + // FIXME + // key('2',0,0); + } + if('.' == k) { + m[curr_model].draw = ! m[curr_model].draw; + } + if('w' == k) { + toggleWireframe = true; + } + if('1' == k) { + // FIXME + /* curr_manip = 1; camera.disable(); clipcam.disable(); scenecam.disable(); if(curr_view == 0) - camera.enable(); + camera.enable(); else if(curr_view == 1) - scenecam.enable(); + scenecam.enable(); else - clipcam.enable(); + clipcam.enable(); for(int i=0; i < num_models; i++) - object[i].disable(); + object[i].disable(); light.disable(); room.disable(); - */ - } - if('2' == k) { - // FIXME - /* + */ + } + if('2' == k) { + // FIXME + /* curr_manip = 2; camera.disable(); clipcam.disable(); scenecam.disable(); light.disable(); for(int i=0; i < num_models; i++) - object[i].disable(); + object[i].disable(); object[curr_model].enable(); room.disable(); - */ - } - if('3' == k) { - // FIXME - /* + */ + } + if('3' == k) { + // FIXME + /* curr_manip = 3; camera.disable(); clipcam.disable(); scenecam.disable(); light.enable(); for(int i=0; i < num_models; i++) - object[i].disable(); + object[i].disable(); room.disable(); - */ - } - if('4' == k) { - // FIXME - /* + */ + } + if('4' == k) { + // FIXME + /* curr_manip = 4; camera.disable(); clipcam.disable(); scenecam.disable(); light.disable(); for(int i=0; i < num_models; i++) - object[i].disable(); + object[i].disable(); room.enable(); - */ - } + */ + } - if('5' == k) { - // FIXME - /* + if('5' == k) { + // FIXME + /* curr_view = 0; if(curr_manip == 1) - key('1',0,0); - */ - } + key('1',0,0); + */ + } - if('6' == k) { - // FIXME - /* + if('6' == k) { + // FIXME + /* curr_view = 1; if(curr_manip == 1) - key('1',0,0); - */ - } + key('1',0,0); + */ + } - if('7' == k) { - // FIXME - /* + if('7' == k) { + // FIXME + /* curr_view = 2; if(curr_manip == 1) - key('1',0,0); - */ - } - - if('[' == k) { - // FIXME: correct? - viewer.setZNear(viewer.getZNear() / 2); - // reshaper.zNear /= 2; - } - if(']' == k) { - // FIXME: correct? - viewer.setZNear(viewer.getZNear() * 2); - // reshaper.zNear *= 2; - } + key('1',0,0); + */ + } - if('{' == k) { - // FIXME: correct? - viewer.setZFar(viewer.getZFar() / 2); - // reshaper.zFar /= 2; - } - if('}' == k) { - // FIXME: correct? - viewer.setZFar(viewer.getZFar() * 2); - // reshaper.zFar *= 2; - } + if('[' == k) { + // FIXME: correct? + viewer.setZNear(viewer.getZNear() / 2); + // reshaper.zNear /= 2; + } + if(']' == k) { + // FIXME: correct? + viewer.setZNear(viewer.getZNear() * 2); + // reshaper.zNear *= 2; + } - if('!' == k) { - enableDepthClampNV = true; - toggleDepthClampNV = true; - } - if('~' == k) { - enableDepthClampNV = false; - toggleDepthClampNV = true; - } + if('{' == k) { + // FIXME: correct? + viewer.setZFar(viewer.getZFar() / 2); + // reshaper.zFar /= 2; + } + if('}' == k) { + // FIXME: correct? + viewer.setZFar(viewer.getZFar() * 2); + // reshaper.zFar *= 2; + } - if('a' == k) { - animateForward = true; - } + if('!' == k) { + enableDepthClampNV = true; + toggleDepthClampNV = true; + } + if('~' == k) { + enableDepthClampNV = false; + toggleDepthClampNV = true; + } - if('b' == k) { - animateBackward = true; - } + if('a' == k) { + animateForward = true; + } - if('.' == k) { - hideCurrentModel = true; - } + if('b' == k) { + animateBackward = true; + } - if('n' == k) { - light_object_scale *= 1.1f; - } - if('N' == k) { - light_object_scale /= 1.1f; - } + if('.' == k) { + hideCurrentModel = true; + } - if('L' == k) { - if(b[k]) - light_position.set(0,0,0,1); - else - light_position.set(0.25f, 0.25f, 1, 0); - } + if('n' == k) { + light_object_scale *= 1.1f; + } + if('N' == k) { + light_object_scale /= 1.1f; + } - if ('c' == k) { - doViewAll = true; - } + if('L' == k) { + if(b[k]) + light_position.set(0,0,0,1); + else + light_position.set(0.25f, 0.25f, 1, 0); } - private void initModel() { - int i = 0; - - try { - MD2.Model mod = MD2.loadMD2(getClass().getClassLoader().getResourceAsStream("demos/data/models/knight.md2")); - m[i] = new Model(); - m[i].mod = mod; - m[i].interp_frame = (MD2.Frame) m[i].mod.f[0].clone(); - m[i].ambient.componentMul(m[i].diffuse); - i++; - } catch (IOException e) { - e.printStackTrace(); - } + if ('c' == k) { + doViewAll = true; + } + } - num_models = i; + private void initModel() { + int i = 0; + + try { + MD2.Model mod = MD2.loadMD2(getClass().getClassLoader().getResourceAsStream("demos/data/models/knight.md2")); + m[i] = new Model(); + m[i].mod = mod; + m[i].interp_frame = (MD2.Frame) m[i].mod.f[0].clone(); + m[i].ambient.componentMul(m[i].diffuse); + i++; + } catch (IOException e) { + e.printStackTrace(); } - // interpolate between keyframes - private void interpolate_frame() { - float frac = m[curr_model].frame_num - (float) Math.floor(m[curr_model].frame_num); - int f0_index = (int) Math.floor(m[curr_model].frame_num); - int f1_index = ((int) Math.ceil(m[curr_model].frame_num)) % m[curr_model].mod.f.length; - MD2.Frame f0 = m[curr_model].mod.f[f0_index]; - MD2.Frame f1 = m[curr_model].mod.f[f1_index]; - - for (int i = 0; i < f0.pn.length; i++) { - MD2.PositionNormal pn = m[curr_model].interp_frame.pn[i]; - MD2.PositionNormal pn0 = f0.pn[i]; - MD2.PositionNormal pn1 = f1.pn[i]; - - pn.x = (1-frac) * pn0.x + frac * pn1.x; - pn.y = (1-frac) * pn0.y + frac * pn1.y; - pn.z = (1-frac) * pn0.z + frac * pn1.z; - pn.nx = (1-frac) * pn0.nx + frac * pn1.nx; - pn.ny = (1-frac) * pn0.ny + frac * pn1.ny; - pn.nz = (1-frac) * pn0.nz + frac * pn1.nz; - } + num_models = i; + } + + // interpolate between keyframes + private void interpolate_frame() { + float frac = m[curr_model].frame_num - (float) Math.floor(m[curr_model].frame_num); + int f0_index = (int) Math.floor(m[curr_model].frame_num); + int f1_index = ((int) Math.ceil(m[curr_model].frame_num)) % m[curr_model].mod.f.length; + MD2.Frame f0 = m[curr_model].mod.f[f0_index]; + MD2.Frame f1 = m[curr_model].mod.f[f1_index]; + + for (int i = 0; i < f0.pn.length; i++) { + MD2.PositionNormal pn = m[curr_model].interp_frame.pn[i]; + MD2.PositionNormal pn0 = f0.pn[i]; + MD2.PositionNormal pn1 = f1.pn[i]; + + pn.x = (1-frac) * pn0.x + frac * pn1.x; + pn.y = (1-frac) * pn0.y + frac * pn1.y; + pn.z = (1-frac) * pn0.z + frac * pn1.z; + pn.nx = (1-frac) * pn0.nx + frac * pn1.nx; + pn.ny = (1-frac) * pn0.ny + frac * pn1.ny; + pn.nz = (1-frac) * pn0.nz + frac * pn1.nz; + } - for (int i = 0; i < f0.triplane.length; i++) { - MD2.Plane p = m[curr_model].interp_frame.triplane[i]; + for (int i = 0; i < f0.triplane.length; i++) { + MD2.Plane p = m[curr_model].interp_frame.triplane[i]; - MD2.computePlane(m[curr_model].interp_frame.pn[m[curr_model].mod.tri[i].v[0].pn_index], - m[curr_model].interp_frame.pn[m[curr_model].mod.tri[i].v[1].pn_index], - m[curr_model].interp_frame.pn[m[curr_model].mod.tri[i].v[2].pn_index], - p); - } + MD2.computePlane(m[curr_model].interp_frame.pn[m[curr_model].mod.tri[i].v[0].pn_index], + m[curr_model].interp_frame.pn[m[curr_model].mod.tri[i].v[1].pn_index], + m[curr_model].interp_frame.pn[m[curr_model].mod.tri[i].v[2].pn_index], + p); } + } - // This routine draws the end caps (both local and infinite) for an - // occluder. These caps are required for the zfail approach to work. - private void drawShadowVolumeEndCaps(GL gl, int mindex) { - Vec4f olight = new Vec4f(); + // This routine draws the end caps (both local and infinite) for an + // occluder. These caps are required for the zfail approach to work. + private void drawShadowVolumeEndCaps(GL gl, int mindex) { + Vec4f olight = new Vec4f(); + + Mat4f ml = new Mat4f(objectManipXform); + ml.invertRigid(); + ml = ml.mul(lightManipXform); + ml.xformVec(light_position, olight); + + MD2.PositionNormal[] vpn = m[mindex].interp_frame.pn; + + gl.glPushMatrix(); + gl.glMultMatrixf(getData(objectManipXform), 0); + gl.glBegin(GL.GL_TRIANGLES); + for (int i = 0; i < m[mindex].mod.tri.length; i++) { + if (m[mindex].mod.tri[i].kill) + continue; + MD2.Plane p = m[mindex].interp_frame.triplane[i]; + + boolean facing_light = (( p.a * olight.get(0) + + p.b * olight.get(1) + + p.c * olight.get(2) + + p.d * olight.get(3) ) >= 0 ); + + for (int j = 0; j < 3; j++) { + MD2.PositionNormal pn = vpn[m[mindex].mod.tri[i].v[j].pn_index]; + if (facing_light) // draw locally + gl.glVertex4f(pn.x, pn.y, pn.z, 1); + else // draw at infinity + gl.glVertex4f(pn.x*olight.get(3) - olight.get(0), + pn.y*olight.get(3) - olight.get(1), + pn.z*olight.get(3) - olight.get(2), + 0); + } + } + gl.glEnd(); + gl.glPopMatrix(); + } - Mat4f ml = new Mat4f(objectManipXform); - ml.invertRigid(); - ml = ml.mul(lightManipXform); - ml.xformVec(light_position, olight); + private void drawModel(GL gl, int mindex, boolean do_diffuse) { + MD2.PositionNormal[] vpn = m[mindex].interp_frame.pn; + + float[] zero = new float[] { 0, 0, 0, 0}; + float[] dim = new float[] {.2f,.2f,.2f,.2f}; + float[] diffuse = new float[4]; + float[] specular = new float[4]; + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, getData(m[mindex].ambient), 0); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, getData(m[mindex].diffuse), 0); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, getData(m[mindex].specular), 0); + gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, m[mindex].shininess); + if (!do_diffuse) { + gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, dim, 0); + gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, specular, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, zero, 0); + } else { + gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE); + gl.glEnable(GL.GL_BLEND); + gl.glStencilFunc(GL.GL_EQUAL, 128, ~0); + gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); + gl.glEnable(GL.GL_STENCIL_TEST); + gl.glDepthFunc(GL.GL_EQUAL); + } + gl.glPushMatrix(); + gl.glMultMatrixf(getData(objectManipXform), 0); + gl.glEnable(GL.GL_LIGHTING); - MD2.PositionNormal[] vpn = m[mindex].interp_frame.pn; + gl.glPolygonOffset(0,-2); + gl.glEnable(GL.GL_POLYGON_OFFSET_FILL); - gl.glPushMatrix(); - gl.glMultMatrixf(getData(objectManipXform)); - gl.glBegin(GL.GL_TRIANGLES); + gl.glBegin(GL.GL_TRIANGLES); + { for (int i = 0; i < m[mindex].mod.tri.length; i++) { - if (m[mindex].mod.tri[i].kill) - continue; - MD2.Plane p = m[mindex].interp_frame.triplane[i]; - - boolean facing_light = (( p.a * olight.get(0) + - p.b * olight.get(1) + - p.c * olight.get(2) + - p.d * olight.get(3) ) >= 0 ); - - for (int j = 0; j < 3; j++) { + for(int j=0; j < 3; j++) { MD2.PositionNormal pn = vpn[m[mindex].mod.tri[i].v[j].pn_index]; - if (facing_light) // draw locally - gl.glVertex4f(pn.x, pn.y, pn.z, 1); - else // draw at infinity - gl.glVertex4f(pn.x*olight.get(3) - olight.get(0), - pn.y*olight.get(3) - olight.get(1), - pn.z*olight.get(3) - olight.get(2), - 0); + gl.glNormal3f(pn.nx, pn.ny, pn.nz); + gl.glVertex4f(pn.x, pn.y, pn.z, 1); } } - gl.glEnd(); - gl.glPopMatrix(); } + gl.glEnd(); - private void drawModel(GL gl, int mindex, boolean do_diffuse) { - MD2.PositionNormal[] vpn = m[mindex].interp_frame.pn; - - float[] zero = new float[] { 0, 0, 0, 0}; - float[] dim = new float[] {.2f,.2f,.2f,.2f}; - float[] diffuse = new float[4]; - float[] specular = new float[4]; - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, getData(m[mindex].ambient)); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, getData(m[mindex].diffuse)); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, getData(m[mindex].specular)); - gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, m[mindex].shininess); - if (!do_diffuse) { - gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, dim); - gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, specular); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, zero); - } else { - gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE); - gl.glEnable(GL.GL_BLEND); - gl.glStencilFunc(GL.GL_EQUAL, 128, ~0); - gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); - gl.glEnable(GL.GL_STENCIL_TEST); - gl.glDepthFunc(GL.GL_EQUAL); - } - gl.glPushMatrix(); - gl.glMultMatrixf(getData(objectManipXform)); - gl.glEnable(GL.GL_LIGHTING); - - gl.glPolygonOffset(0,-2); - gl.glEnable(GL.GL_POLYGON_OFFSET_FILL); - - gl.glBegin(GL.GL_TRIANGLES); - { - for (int i = 0; i < m[mindex].mod.tri.length; i++) { - for(int j=0; j < 3; j++) { - MD2.PositionNormal pn = vpn[m[mindex].mod.tri[i].v[j].pn_index]; - gl.glNormal3f(pn.nx, pn.ny, pn.nz); - gl.glVertex4f(pn.x, pn.y, pn.z, 1); - } - } - } - gl.glEnd(); - - gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); + gl.glDisable(GL.GL_POLYGON_OFFSET_FILL); - gl.glDisable(GL.GL_LIGHTING); - gl.glPopMatrix(); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, new float[] { 0.8f, 0.8f, 0.8f, 1}); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, new float[] { 0.3f, 0.3f, 0.3f, 1}); + gl.glDisable(GL.GL_LIGHTING); + gl.glPopMatrix(); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, new float[] { 0.8f, 0.8f, 0.8f, 1}, 0); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, new float[] { 0.3f, 0.3f, 0.3f, 1}, 0); - if (!do_diffuse) { - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, specular); - } else { - gl.glDisable(GL.GL_BLEND); - //glDisable(GL.GL_STENCIL_TEST); - gl.glStencilFunc(GL.GL_ALWAYS, 128, ~0); - gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); + if (!do_diffuse) { + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, specular, 0); + } else { + gl.glDisable(GL.GL_BLEND); + //glDisable(GL.GL_STENCIL_TEST); + gl.glStencilFunc(GL.GL_ALWAYS, 128, ~0); + gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); - gl.glDepthFunc(GL.GL_LESS); - } + gl.glDepthFunc(GL.GL_LESS); } + } - // This is for drawing the walls of the room. - private void drawMesh(GL gl, float size, int tess) { - float hsize = size/2; - float delta = size/(tess-1); + // This is for drawing the walls of the room. + private void drawMesh(GL gl, float size, int tess) { + float hsize = size/2; + float delta = size/(tess-1); - gl.glPushMatrix(); - gl.glTranslatef(-hsize, -hsize, hsize); + gl.glPushMatrix(); + gl.glTranslatef(-hsize, -hsize, hsize); - gl.glNormal3f(0,0,-1); - - float x = 0; - for(int i=0; i < tess-1; i++) { - float y = 0; - gl.glBegin(GL.GL_QUAD_STRIP); - for(int j=0; j < tess; j++) { - gl.glTexCoord2f( x, y); - gl.glVertex2f ( x, y); - gl.glTexCoord2f(x+delta, y); - gl.glVertex2f (x+delta, y); - y += delta; - } - gl.glEnd(); - x += delta; + gl.glNormal3f(0,0,-1); + + float x = 0; + for(int i=0; i < tess-1; i++) { + float y = 0; + gl.glBegin(GL.GL_QUAD_STRIP); + for(int j=0; j < tess; j++) { + gl.glTexCoord2f( x, y); + gl.glVertex2f ( x, y); + gl.glTexCoord2f(x+delta, y); + gl.glVertex2f (x+delta, y); + y += delta; } - gl.glPopMatrix(); + gl.glEnd(); + x += delta; } + gl.glPopMatrix(); + } - private void drawCube(GL gl) { - gl.glBindTexture(GL.GL_TEXTURE_2D, wallTexObject); - gl.glEnable(GL.GL_TEXTURE_2D); - gl.glPushMatrix(); - // FIXME - // room.apply_transform(); - gl.glCallList(faceDisplayList); - gl.glRotatef(90, 1, 0, 0); - gl.glCallList(faceDisplayList); - gl.glRotatef(90, 1, 0, 0); - gl.glCallList(faceDisplayList); - gl.glRotatef(90, 1, 0, 0); - gl.glCallList(faceDisplayList); - gl.glRotatef(90, 1, 0, 0); - gl.glRotatef(90, 0, 1, 0); - gl.glCallList(faceDisplayList); - gl.glRotatef(180, 0, 1, 0); - gl.glCallList(faceDisplayList); - gl.glPopMatrix(); - gl.glDisable(GL.GL_TEXTURE_2D); - } + private void drawCube(GL gl) { + gl.glBindTexture(GL.GL_TEXTURE_2D, wallTexObject); + gl.glEnable(GL.GL_TEXTURE_2D); + gl.glPushMatrix(); + // FIXME + // room.apply_transform(); + gl.glCallList(faceDisplayList); + gl.glRotatef(90, 1, 0, 0); + gl.glCallList(faceDisplayList); + gl.glRotatef(90, 1, 0, 0); + gl.glCallList(faceDisplayList); + gl.glRotatef(90, 1, 0, 0); + gl.glCallList(faceDisplayList); + gl.glRotatef(90, 1, 0, 0); + gl.glRotatef(90, 0, 1, 0); + gl.glCallList(faceDisplayList); + gl.glRotatef(180, 0, 1, 0); + gl.glCallList(faceDisplayList); + gl.glPopMatrix(); + gl.glDisable(GL.GL_TEXTURE_2D); + } - private void drawRoom(GL gl, boolean do_diffuse) { - float[] zero = new float[] {0,0,0,0}; - float[] a = new float[4]; - a[0] = room_ambient; - a[1] = room_ambient; - a[2] = room_ambient; - a[3] = 1; - - float[] d1 = new float[] {.1f,.1f,.1f,.1f}; - float[] d2 = new float[] {.7f,.7f,.7f,.7f}; - float[] s = new float[] {.7f,.7f,.7f,.7f}; - float[] emission = new float[4]; - float[] ambient = new float[4]; - float[] diffuse = new float[4]; - float[] specular = new float[4]; - - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, a); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, new float[] {0.8f, 0.8f, 0.8f, 1}); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, new float[] {0.4f, 0.4f, 0.4f, 1}); - gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, 64.0f); - - if (!do_diffuse) { - gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, d1); - gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, specular); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, zero); - gl.glStencilFunc(GL.GL_ALWAYS, 128, ~0); - } else { - gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_EMISSION, emission); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_EMISSION, zero); - gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, zero); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, d2); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, s); - - gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE); - gl.glEnable(GL.GL_BLEND); - gl.glStencilFunc(GL.GL_EQUAL, 128, ~0); - gl.glDepthFunc(GL.GL_EQUAL); - } - gl.glPushMatrix(); - gl.glTranslatef(0,9,0); - gl.glEnable(GL.GL_LIGHTING); - gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); - gl.glEnable(GL.GL_STENCIL_TEST); + private void drawRoom(GL gl, boolean do_diffuse) { + float[] zero = new float[] {0,0,0,0}; + float[] a = new float[4]; + a[0] = room_ambient; + a[1] = room_ambient; + a[2] = room_ambient; + a[3] = 1; + + float[] d1 = new float[] {.1f,.1f,.1f,.1f}; + float[] d2 = new float[] {.7f,.7f,.7f,.7f}; + float[] s = new float[] {.7f,.7f,.7f,.7f}; + float[] emission = new float[4]; + float[] ambient = new float[4]; + float[] diffuse = new float[4]; + float[] specular = new float[4]; + + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, a, 0); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, new float[] {0.8f, 0.8f, 0.8f, 1}, 0); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, new float[] {0.4f, 0.4f, 0.4f, 1}, 0); + gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, 64.0f); + + if (!do_diffuse) { + gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, d1, 0); + gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, specular, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, zero, 0); + gl.glStencilFunc(GL.GL_ALWAYS, 128, ~0); + } else { + gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_EMISSION, emission, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_EMISSION, zero, 0); + gl.glGetLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, zero, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, d2, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, s, 0); + + gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE); + gl.glEnable(GL.GL_BLEND); + gl.glStencilFunc(GL.GL_EQUAL, 128, ~0); + gl.glDepthFunc(GL.GL_EQUAL); + } + gl.glPushMatrix(); + gl.glTranslatef(0,9,0); + gl.glEnable(GL.GL_LIGHTING); + gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); + gl.glEnable(GL.GL_STENCIL_TEST); - drawCube(gl); + drawCube(gl); - gl.glStencilFunc(GL.GL_ALWAYS, 128, ~0); - gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); + gl.glStencilFunc(GL.GL_ALWAYS, 128, ~0); + gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); - gl.glDisable(GL.GL_LIGHTING); - gl.glPopMatrix(); + gl.glDisable(GL.GL_LIGHTING); + gl.glPopMatrix(); - if (!do_diffuse) { - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, specular); - } else { - gl.glLightfv(GL.GL_LIGHT0, GL.GL_EMISSION, emission); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient); + if (!do_diffuse) { + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, specular, 0); + } else { + gl.glLightfv(GL.GL_LIGHT0, GL.GL_EMISSION, emission, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient, 0); - gl.glDisable(GL.GL_BLEND); - gl.glDepthFunc(GL.GL_LESS); - } + gl.glDisable(GL.GL_BLEND); + gl.glDepthFunc(GL.GL_LESS); } + } - // This routine draws the extruded "possible silhouette" edge. The - // edge is extruded to infinity. - - // The paper describes identifying silhouette edge loops. The approach - // in this demo is to visit each edge, determine if it's a "possible silhouette" - // or not, and if it is, draw the extruded edge. This approach is not - // as efficient, but it has the benefit of being extremely simple. - - // This routine also doubles as the routine for drawing the local and ininite - // silhouette edges (when prim == GL_LINES). - private void drawShadowVolumeEdges(GL gl, - int mindex, - int prim, - boolean local, - boolean infinity) { - Vec4f olight = new Vec4f(); - - Mat4f ml = new Mat4f(objectManipXform); - ml.invertRigid(); - ml = ml.mul(lightManipXform); - ml.xformVec(light_position, olight); - - gl.glPushMatrix(); - gl.glMultMatrixf(getData(objectManipXform)); - - MD2.Frame f = m[mindex].interp_frame; - - gl.glBegin(prim); - for (int i = 0; i < m[mindex].mod.edge.length; i++) { - MD2.WingedEdge we = m[mindex].mod.edge[i]; - if (we.w[0] == -1 || m[mindex].mod.tri[we.w[0]].kill || - we.w[1] == -1 || m[mindex].mod.tri[we.w[1]].kill ) - continue; - - MD2.Plane p0 = f.triplane[we.w[0]]; - float f0 = ( p0.a * olight.get(0) + - p0.b * olight.get(1) + - p0.c * olight.get(2) + - p0.d * olight.get(3) ); + // This routine draws the extruded "possible silhouette" edge. The + // edge is extruded to infinity. + + // The paper describes identifying silhouette edge loops. The approach + // in this demo is to visit each edge, determine if it's a "possible silhouette" + // or not, and if it is, draw the extruded edge. This approach is not + // as efficient, but it has the benefit of being extremely simple. + + // This routine also doubles as the routine for drawing the local and ininite + // silhouette edges (when prim == GL_LINES). + private void drawShadowVolumeEdges(GL gl, + int mindex, + int prim, + boolean local, + boolean infinity) { + Vec4f olight = new Vec4f(); + + Mat4f ml = new Mat4f(objectManipXform); + ml.invertRigid(); + ml = ml.mul(lightManipXform); + ml.xformVec(light_position, olight); + + gl.glPushMatrix(); + gl.glMultMatrixf(getData(objectManipXform), 0); + + MD2.Frame f = m[mindex].interp_frame; + + gl.glBegin(prim); + for (int i = 0; i < m[mindex].mod.edge.length; i++) { + MD2.WingedEdge we = m[mindex].mod.edge[i]; + if (we.w[0] == -1 || m[mindex].mod.tri[we.w[0]].kill || + we.w[1] == -1 || m[mindex].mod.tri[we.w[1]].kill ) + continue; + + MD2.Plane p0 = f.triplane[we.w[0]]; + float f0 = ( p0.a * olight.get(0) + + p0.b * olight.get(1) + + p0.c * olight.get(2) + + p0.d * olight.get(3) ); - float f1 = -f0; - if(we.w[1] != -1) { - MD2.Plane p1 = f.triplane[we.w[1]]; - - f1 = ( p1.a * olight.get(0) + - p1.b * olight.get(1) + - p1.c * olight.get(2) + - p1.d * olight.get(3) ); - } - - int[] edge = new int[2]; - - if(f0 >= 0 && f1 < 0) { - edge[0] = we.e[1]; - edge[1] = we.e[0]; - } else if(f1 >= 0 && f0 < 0) { - edge[0] = we.e[0]; - edge[1] = we.e[1]; - } else { - continue; - } + float f1 = -f0; + if(we.w[1] != -1) { + MD2.Plane p1 = f.triplane[we.w[1]]; + + f1 = ( p1.a * olight.get(0) + + p1.b * olight.get(1) + + p1.c * olight.get(2) + + p1.d * olight.get(3) ); + } + + int[] edge = new int[2]; + + if(f0 >= 0 && f1 < 0) { + edge[0] = we.e[1]; + edge[1] = we.e[0]; + } else if(f1 >= 0 && f0 < 0) { + edge[0] = we.e[0]; + edge[1] = we.e[1]; + } else { + continue; + } - MD2.PositionNormal pn0 = f.pn[edge[0]]; - MD2.PositionNormal pn1 = f.pn[edge[1]]; - - if(prim == GL.GL_QUADS || local) { - // local segment - gl.glVertex4f(pn0.x, pn0.y, pn0.z, 1); - gl.glVertex4f(pn1.x, pn1.y, pn1.z, 1); - } - if(prim == GL.GL_QUADS || infinity) { - // segment projected to infinity - gl.glVertex4f(pn1.x*olight.get(3) - olight.get(0), - pn1.y*olight.get(3) - olight.get(1), - pn1.z*olight.get(3) - olight.get(2), - 0); - gl.glVertex4f(pn0.x*olight.get(3) - olight.get(0), - pn0.y*olight.get(3) - olight.get(1), - pn0.z*olight.get(3) - olight.get(2), - 0); - } - } - gl.glEnd(); - gl.glPopMatrix(); - } + MD2.PositionNormal pn0 = f.pn[edge[0]]; + MD2.PositionNormal pn1 = f.pn[edge[1]]; - private void drawShadowVolumeExtrudedEdges(GL gl, int mindex) { - drawShadowVolumeEdges(gl, mindex, GL.GL_QUADS, true, true); + if(prim == GL.GL_QUADS || local) { + // local segment + gl.glVertex4f(pn0.x, pn0.y, pn0.z, 1); + gl.glVertex4f(pn1.x, pn1.y, pn1.z, 1); + } + if(prim == GL.GL_QUADS || infinity) { + // segment projected to infinity + gl.glVertex4f(pn1.x*olight.get(3) - olight.get(0), + pn1.y*olight.get(3) - olight.get(1), + pn1.z*olight.get(3) - olight.get(2), + 0); + gl.glVertex4f(pn0.x*olight.get(3) - olight.get(0), + pn0.y*olight.get(3) - olight.get(1), + pn0.z*olight.get(3) - olight.get(2), + 0); + } } + gl.glEnd(); + gl.glPopMatrix(); + } - private void drawPossibleSilhouette(GL gl, int mindex) { - gl.glLineWidth(3); - gl.glColor3f(1,1,1); - drawShadowVolumeEdges(gl, mindex, GL.GL_LINES, true, !b['-']); - gl.glLineWidth(1); - } + private void drawShadowVolumeExtrudedEdges(GL gl, int mindex) { + drawShadowVolumeEdges(gl, mindex, GL.GL_QUADS, true, true); + } - // Draw the shadow volume into the stencil buffer. - private void drawShadowVolumeToStencil(GL gl, int mindex) { - gl.glDepthFunc(GL.GL_LESS); - gl.glDepthMask(false); + private void drawPossibleSilhouette(GL gl, int mindex) { + gl.glLineWidth(3); + gl.glColor3f(1,1,1); + drawShadowVolumeEdges(gl, mindex, GL.GL_LINES, true, !b['-']); + gl.glLineWidth(1); + } - gl.glStencilFunc(GL.GL_ALWAYS, 128, ~0); - gl.glEnable(GL.GL_STENCIL_TEST); + // Draw the shadow volume into the stencil buffer. + private void drawShadowVolumeToStencil(GL gl, int mindex) { + gl.glDepthFunc(GL.GL_LESS); + gl.glDepthMask(false); - gl.glEnable(GL.GL_CULL_FACE); - gl.glCullFace(GL.GL_FRONT); - gl.glStencilOp(GL.GL_KEEP, GL.GL_INCR, GL.GL_KEEP); - gl.glColorMask(false, false, false, false); + gl.glStencilFunc(GL.GL_ALWAYS, 128, ~0); + gl.glEnable(GL.GL_STENCIL_TEST); - drawShadowVolumeExtrudedEdges(gl, mindex); - drawShadowVolumeEndCaps(gl, mindex); + gl.glEnable(GL.GL_CULL_FACE); + gl.glCullFace(GL.GL_FRONT); + gl.glStencilOp(GL.GL_KEEP, GL.GL_INCR, GL.GL_KEEP); + gl.glColorMask(false, false, false, false); - gl.glCullFace(GL.GL_BACK); - gl.glStencilOp(GL.GL_KEEP, GL.GL_DECR, GL.GL_KEEP); + drawShadowVolumeExtrudedEdges(gl, mindex); + drawShadowVolumeEndCaps(gl, mindex); - drawShadowVolumeExtrudedEdges(gl, mindex); - drawShadowVolumeEndCaps(gl, mindex); + gl.glCullFace(GL.GL_BACK); + gl.glStencilOp(GL.GL_KEEP, GL.GL_DECR, GL.GL_KEEP); - gl.glColorMask(true, true, true, true); - gl.glDisable(GL.GL_CULL_FACE); + drawShadowVolumeExtrudedEdges(gl, mindex); + drawShadowVolumeEndCaps(gl, mindex); - gl.glStencilFunc(GL.GL_ALWAYS, 128, ~0); - gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); + gl.glColorMask(true, true, true, true); + gl.glDisable(GL.GL_CULL_FACE); - gl.glDepthMask(true); - gl.glDepthFunc(GL.GL_LESS); - } + gl.glStencilFunc(GL.GL_ALWAYS, 128, ~0); + gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); - // Draw the shadow volume into the color buffer. - private void drawShadowVolumeToColor(GL gl, int mindex) { - gl.glDepthFunc(GL.GL_LESS); - gl.glDepthMask(false); + gl.glDepthMask(true); + gl.glDepthFunc(GL.GL_LESS); + } - gl.glEnable(GL.GL_BLEND); - gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); + // Draw the shadow volume into the color buffer. + private void drawShadowVolumeToColor(GL gl, int mindex) { + gl.glDepthFunc(GL.GL_LESS); + gl.glDepthMask(false); - gl.glColor4f(1,1,1,.7f * volume_alpha); - drawShadowVolumeEndCaps(gl, mindex); - gl.glColor4f(1,1,.7f,.15f * volume_alpha); - drawShadowVolumeExtrudedEdges(gl, mindex); + gl.glEnable(GL.GL_BLEND); + gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); - gl.glDepthMask(true); - gl.glDepthFunc(GL.GL_LESS); - gl.glDisable(GL.GL_BLEND); - } + gl.glColor4f(1,1,1,.7f * volume_alpha); + drawShadowVolumeEndCaps(gl, mindex); + gl.glColor4f(1,1,.7f,.15f * volume_alpha); + drawShadowVolumeExtrudedEdges(gl, mindex); - // Draw an icon to show where the local light is - // or in what direction the infinite light is pointing. - private void drawLight(GL gl, GLU glu) { - gl.glColor3f(1,1,0); - gl.glPushMatrix(); - gl.glMultMatrixf(getData(lightManipXform)); - gl.glScalef(light_object_scale, light_object_scale, light_object_scale); - if (b['L']) { - glut.glutSolidSphere(glu, .01f, 20, 10); - } else { - Vec3f ldir = new Vec3f(light_position.get(0), - light_position.get(1), - light_position.get(2)); - Rotf r = new Rotf(new Vec3f(0,0,1), ldir); - Mat4f m = new Mat4f(); - m.makeIdent(); - m.setRotation(r); - m = m.mul(perspectiveInverse(30, 1, 0.001f, 0.04f)); - gl.glRotatef(180, 1, 0, 0); - gl.glTranslatef(0,0,-0.02f); - gl.glMultMatrixf(getData(m)); - glut.glutSolidCube(gl, 2); - } - gl.glPopMatrix(); - } + gl.glDepthMask(true); + gl.glDepthFunc(GL.GL_LESS); + gl.glDisable(GL.GL_BLEND); + } - // The infinite frustum set-up code. - private Mat4f infiniteFrustum(float left, float right, - float bottom, float top, - float zNear) { + // Draw an icon to show where the local light is + // or in what direction the infinite light is pointing. + private void drawLight(GL gl) { + gl.glColor3f(1,1,0); + gl.glPushMatrix(); + gl.glMultMatrixf(getData(lightManipXform), 0); + gl.glScalef(light_object_scale, light_object_scale, light_object_scale); + if (b['L']) { + glut.glutSolidSphere(.01f, 20, 10); + } else { + Vec3f ldir = new Vec3f(light_position.get(0), + light_position.get(1), + light_position.get(2)); + Rotf r = new Rotf(new Vec3f(0,0,1), ldir); Mat4f m = new Mat4f(); m.makeIdent(); + m.setRotation(r); + m = m.mul(perspectiveInverse(30, 1, 0.001f, 0.04f)); + gl.glRotatef(180, 1, 0, 0); + gl.glTranslatef(0,0,-0.02f); + gl.glMultMatrixf(getData(m), 0); + glut.glutSolidCube(2); + } + gl.glPopMatrix(); + } + + // The infinite frustum set-up code. + private Mat4f infiniteFrustum(float left, float right, + float bottom, float top, + float zNear) { + Mat4f m = new Mat4f(); + m.makeIdent(); - m.set(0,0, (2*zNear) / (right - left)); - m.set(0,2, (right + left) / (right - left)); + m.set(0,0, (2*zNear) / (right - left)); + m.set(0,2, (right + left) / (right - left)); - m.set(1,1, (2*zNear) / (top - bottom)); - m.set(1,2, (top + bottom) / (top - bottom)); + m.set(1,1, (2*zNear) / (top - bottom)); + m.set(1,2, (top + bottom) / (top - bottom)); - // nudge infinity in just slightly for lsb slop - float nudge = 1 - 1.0f / (1<<23); + // nudge infinity in just slightly for lsb slop + float nudge = 1 - 1.0f / (1<<23); - m.set(2,2, -1 * nudge); - m.set(2,3, -2*zNear * nudge); + m.set(2,2, -1 * nudge); + m.set(2,3, -2*zNear * nudge); - m.set(3,2, -1); - m.set(3,3, 0); + m.set(3,2, -1); + m.set(3,3, 0); - m.transpose(); + m.transpose(); - return m; - } + return m; + } - private Mat4f infiniteFrustumInverse(float left, float right, - float bottom, float top, - float zNear) { - Mat4f m = new Mat4f(); - m.makeIdent(); + private Mat4f infiniteFrustumInverse(float left, float right, + float bottom, float top, + float zNear) { + Mat4f m = new Mat4f(); + m.makeIdent(); - m.set(0,0, (right - left) / (2 * zNear)); - m.set(0,3, (right + left) / (2 * zNear)); + m.set(0,0, (right - left) / (2 * zNear)); + m.set(0,3, (right + left) / (2 * zNear)); - m.set(1,1, (top - bottom) / (2 * zNear)); - m.set(1,3, (top + bottom) / (2 * zNear)); + m.set(1,1, (top - bottom) / (2 * zNear)); + m.set(1,3, (top + bottom) / (2 * zNear)); - m.set(2,2, 0); - m.set(2,3, -1); + m.set(2,2, 0); + m.set(2,3, -1); - m.set(3,2, -1 / (2 * zNear)); - m.set(3,3, 1 / (2 * zNear)); + m.set(3,2, -1 / (2 * zNear)); + m.set(3,3, 1 / (2 * zNear)); - return m; - } + return m; + } - private Mat4f infinitePerspective(float fovy, float aspect, float zNear) { - float tangent = (float) Math.tan(fovy / 2.0); - float y = tangent * zNear; - float x = aspect * y; - return infiniteFrustum(-x, x, -y, y, zNear); - } + private Mat4f infinitePerspective(float fovy, float aspect, float zNear) { + float tangent = (float) Math.tan(fovy / 2.0); + float y = tangent * zNear; + float x = aspect * y; + return infiniteFrustum(-x, x, -y, y, zNear); + } - private Mat4f infinitePerspectiveInverse(float fovy, float aspect, float zNear) { - float tangent = (float) Math.tan(fovy / 2.0); - float y = tangent * zNear; - float x = aspect * y; - return infiniteFrustumInverse(-x, x, -y, y, zNear); - } + private Mat4f infinitePerspectiveInverse(float fovy, float aspect, float zNear) { + float tangent = (float) Math.tan(fovy / 2.0); + float y = tangent * zNear; + float x = aspect * y; + return infiniteFrustumInverse(-x, x, -y, y, zNear); + } - private void applyInfinitePerspective(GL gl, ExaminerViewer v) { - CameraParameters parms = v.getCameraParameters(); - float aspect = parms.getImagePlaneAspectRatio(); - gl.glMultMatrixf(getData(infinitePerspective(parms.getVertFOV(), aspect, v.getZNear()))); - } + private void applyInfinitePerspective(GL gl, ExaminerViewer v) { + CameraParameters parms = v.getCameraParameters(); + float aspect = parms.getImagePlaneAspectRatio(); + gl.glMultMatrixf(getData(infinitePerspective(parms.getVertFOV(), aspect, v.getZNear())), 0); + } - private void applyInfinitePerspectiveInverse(GL gl, ExaminerViewer v) { - CameraParameters parms = v.getCameraParameters(); - float aspect = parms.getImagePlaneAspectRatio(); - gl.glMultMatrixf(getData(infinitePerspectiveInverse(parms.getVertFOV(), aspect, v.getZNear()))); - } + private void applyInfinitePerspectiveInverse(GL gl, ExaminerViewer v) { + CameraParameters parms = v.getCameraParameters(); + float aspect = parms.getImagePlaneAspectRatio(); + gl.glMultMatrixf(getData(infinitePerspectiveInverse(parms.getVertFOV(), aspect, v.getZNear())), 0); + } - private Mat4f perspectiveInverse(float fovy, float aspect, float zNear, float zFar) { - float tangent = (float) Math.tan(Math.toRadians(fovy / 2.0)); - float y = tangent * zNear; - float x = aspect * y; - return frustumInverse(-x, x, -y, y, zNear, zFar); - } + private Mat4f perspectiveInverse(float fovy, float aspect, float zNear, float zFar) { + float tangent = (float) Math.tan(Math.toRadians(fovy / 2.0)); + float y = tangent * zNear; + float x = aspect * y; + return frustumInverse(-x, x, -y, y, zNear, zFar); + } - private Mat4f frustumInverse(float left, float right, - float bottom, float top, - float zNear, float zFar) { - Mat4f m = new Mat4f(); - m.makeIdent(); + private Mat4f frustumInverse(float left, float right, + float bottom, float top, + float zNear, float zFar) { + Mat4f m = new Mat4f(); + m.makeIdent(); - m.set(0, 0, (right - left) / (2 * zNear)); - m.set(0, 3, (right + left) / (2 * zNear)); + m.set(0, 0, (right - left) / (2 * zNear)); + m.set(0, 3, (right + left) / (2 * zNear)); - m.set(1, 1, (top - bottom) / (2 * zNear)); - m.set(1, 3, (top + bottom) / (2 * zNear)); + m.set(1, 1, (top - bottom) / (2 * zNear)); + m.set(1, 3, (top + bottom) / (2 * zNear)); - m.set(2, 2, 0); - m.set(2, 3, -1); + m.set(2, 2, 0); + m.set(2, 3, -1); - m.set(3, 2, -(zFar - zNear) / (2 * zFar * zNear)); - m.set(3, 3, (zFar + zNear) / (2 * zFar * zNear)); + m.set(3, 2, -(zFar - zNear) / (2 * zFar * zNear)); + m.set(3, 3, (zFar + zNear) / (2 * zFar * zNear)); - return m; - } + return m; + } - private float[] getData(Vec4f v) { - return new float[] { v.x(), v.y(), v.z(), v.w() }; - } + private float[] getData(Vec4f v) { + return new float[] { v.x(), v.y(), v.z(), v.w() }; + } - private float[] getData(Mat4f m) { - float[] res = new float[16]; - m.getColumnMajorData(res); - return res; - } + private float[] getData(Mat4f m) { + float[] res = new float[16]; + m.getColumnMajorData(res); + return res; } - private void runExit() { - quit = true; + private static void runExit() { // Note: calling System.exit() synchronously inside the draw, // reshape or init callbacks can lead to deadlocks on certain // platforms (in particular, X11) because the JAWT's locking diff --git a/src/demos/jgears/JGears.java b/src/demos/jgears/JGears.java index 59e6c79..5cdcadc 100644 --- a/src/demos/jgears/JGears.java +++ b/src/demos/jgears/JGears.java @@ -2,9 +2,16 @@ package demos.jgears; import java.awt.*; import java.awt.event.*; +import java.awt.geom.*; +import java.awt.image.*; +import java.io.*; +import java.text.*; +import javax.imageio.*; import javax.swing.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; +import demos.gears.Gears; /** * JGears.java <BR> @@ -13,16 +20,68 @@ import net.java.games.jogl.*; * This version is equal to Brian Paul's version 1.2 1999/10/21 */ -public class JGears { - public static void main(String[] args) { - JFrame frame = new JFrame("Gear Demo"); - frame.getContentPane().setLayout(new BorderLayout()); - GLCapabilities caps = new GLCapabilities(); +public class JGears extends GLJPanel { + private static GLCapabilities caps; + private long startTime; + private int frameCount; + private float fps; + private static Font fpsFont = new Font("SansSerif", Font.BOLD, 24); + private DecimalFormat format = new DecimalFormat("####.00"); + private BufferedImage javaImage; + private BufferedImage openglImage; + + static { + caps = new GLCapabilities(); caps.setAlphaBits(8); - final GLJPanel drawable = GLDrawableFactory.getFactory().createGLJPanel(caps); - drawable.setOpaque(false); - drawable.addGLEventListener(new GearRenderer()); + } + + public JGears() { + super(caps, null, null); + addGLEventListener(new Gears()); + try { + InputStream in = JGears.class.getClassLoader().getResourceAsStream("demos/data/images/java_logo.png"); + BufferedImage image = ImageIO.read(in); + javaImage = scaleImage(image, 0.25f, 0.25f); + + in = JGears.class.getClassLoader().getResourceAsStream("demos/data/images/opengl_logo.png"); + image = ImageIO.read(in); + openglImage = scaleImage(image, 0.45f, 0.45f); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + if (startTime == 0) { + startTime = System.currentTimeMillis(); + } + + if (++frameCount == 30) { + long endTime = System.currentTimeMillis(); + fps = 30.0f / (float) (endTime - startTime) * 1000; + frameCount = 0; + startTime = System.currentTimeMillis(); + } + + if (fps > 0) { + g.setColor(Color.WHITE); + g.setFont(fpsFont); + g.drawString("FPS: " + format.format(fps), getWidth() - 140, getHeight() - 30); + } + + int sp = 10; + if (javaImage != null) { + g.drawImage(javaImage, sp, getHeight() - javaImage.getHeight() - sp, null); + if (openglImage != null) { + g.drawImage(openglImage, sp + javaImage.getWidth() + sp, getHeight() - openglImage.getHeight() - sp, null); + } + } + } + + // Helper routine for various demos + public static JPanel createGradientPanel() { JPanel gradientPanel = new JPanel() { public void paintComponent(Graphics g) { ((Graphics2D) g).setPaint(new GradientPaint(0, 0, Color.WHITE, @@ -31,6 +90,29 @@ public class JGears { } }; gradientPanel.setLayout(new BorderLayout()); + return gradientPanel; + } + + private BufferedImage scaleImage(BufferedImage img, float xScale, float yScale) { + BufferedImage scaled = new BufferedImage((int) (img.getWidth() * xScale), + (int) (img.getHeight() * yScale), + BufferedImage.TYPE_INT_ARGB); + Graphics2D g = scaled.createGraphics(); + g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); + g.drawRenderedImage(img, AffineTransform.getScaleInstance(xScale, yScale)); + return scaled; + } + + public static void main(String[] args) { + JFrame frame = new JFrame("Gear Demo"); + frame.getContentPane().setLayout(new BorderLayout()); + GLCapabilities caps = new GLCapabilities(); + caps.setAlphaBits(8); + final GLJPanel drawable = new JGears(); + drawable.setOpaque(false); + + JPanel gradientPanel = createGradientPanel(); frame.getContentPane().add(gradientPanel, BorderLayout.CENTER); gradientPanel.add(drawable, BorderLayout.CENTER); @@ -60,278 +142,4 @@ public class JGears { frame.show(); animator.start(); } - - static class GearRenderer implements GLEventListener, MouseListener, MouseMotionListener { - private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f; - private int gear1, gear2, gear3; - private float angle = 0.0f; - - private int prevMouseX, prevMouseY; - private boolean mouseRButtonDown = false; - - - public void init(GLDrawable drawable) { - // Use debug pipeline - // drawable.setGL(new DebugGL(drawable.getGL())); - - GL gl = drawable.getGL(); - System.err.println("INIT GL IS: " + gl.getClass().getName()); - - float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; - float red[] = { 0.8f, 0.1f, 0.0f, 1.0f }; - float green[] = { 0.0f, 0.8f, 0.2f, 1.0f }; - float blue[] = { 0.2f, 0.2f, 1.0f, 1.0f }; - - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos); - gl.glEnable(GL.GL_CULL_FACE); - gl.glEnable(GL.GL_LIGHTING); - gl.glEnable(GL.GL_LIGHT0); - gl.glEnable(GL.GL_DEPTH_TEST); - - /* make the gears */ - gear1 = gl.glGenLists(1); - gl.glNewList(gear1, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red); - gear(gl, 1.0f, 4.0f, 1.0f, 20, 0.7f); - gl.glEndList(); - - gear2 = gl.glGenLists(1); - gl.glNewList(gear2, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, green); - gear(gl, 0.5f, 2.0f, 2.0f, 10, 0.7f); - gl.glEndList(); - - gear3 = gl.glGenLists(1); - gl.glNewList(gear3, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, blue); - gear(gl, 1.3f, 2.0f, 0.5f, 10, 0.7f); - gl.glEndList(); - - gl.glEnable(GL.GL_NORMALIZE); - - drawable.addMouseListener(this); - drawable.addMouseMotionListener(this); - } - - public void reshape(GLDrawable drawable, int x, int y, int width, int height) { - GL gl = drawable.getGL(); - - float h = (float)height / (float)width; - - gl.glMatrixMode(GL.GL_PROJECTION); - - System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)); - System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)); - System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)); - System.err.println(); - System.err.println("glLoadTransposeMatrixfARB() supported: " + - gl.isFunctionAvailable("glLoadTransposeMatrixfARB")); - if (!gl.isFunctionAvailable("glLoadTransposeMatrixfARB")) { - // --- not using extensions - gl.glLoadIdentity(); - } else { - // --- using extensions - final float[] identityTranspose = new float[] { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - }; - gl.glLoadTransposeMatrixfARB(identityTranspose); - } - gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f); - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glLoadIdentity(); - gl.glTranslatef(0.0f, 0.0f, -40.0f); - } - - public void display(GLDrawable drawable) { - angle += 2.0f; - - GL gl = drawable.getGL(); - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - - gl.glPushMatrix(); - gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f); - gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f); - gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f); - - gl.glPushMatrix(); - gl.glTranslatef(-3.0f, -2.0f, 0.0f); - gl.glRotatef(angle, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear1); - gl.glPopMatrix(); - - gl.glPushMatrix(); - gl.glTranslatef(3.1f, -2.0f, 0.0f); - gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear2); - gl.glPopMatrix(); - - gl.glPushMatrix(); - gl.glTranslatef(-3.1f, 4.2f, 0.0f); - gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear3); - gl.glPopMatrix(); - - gl.glPopMatrix(); - } - - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - - private void gear(GL gl, - float inner_radius, - float outer_radius, - float width, - int teeth, - float tooth_depth) - { - int i; - float r0, r1, r2; - float angle, da; - float u, v, len; - - r0 = inner_radius; - r1 = outer_radius - tooth_depth / 2.0f; - r2 = outer_radius + tooth_depth / 2.0f; - - da = 2.0f * (float) Math.PI / teeth / 4.0f; - - gl.glShadeModel(GL.GL_FLAT); - - gl.glNormal3f(0.0f, 0.0f, 1.0f); - - /* draw front face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - if(i < teeth) - { - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - } - gl.glEnd(); - - /* draw front sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2.0f * da), r2 * (float)Math.sin(angle + 2.0f * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - gl.glEnd(); - - /* draw back face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); - - /* draw back sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); - - /* draw outward faces of teeth */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - u = r2 * (float)Math.cos(angle + da) - r1 * (float)Math.cos(angle); - v = r2 * (float)Math.sin(angle + da) - r1 * (float)Math.sin(angle); - len = (float)Math.sqrt(u * u + v * v); - u /= len; - v /= len; - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - u = r1 * (float)Math.cos(angle + 3 * da) - r2 * (float)Math.cos(angle + 2 * da); - v = r1 * (float)Math.sin(angle + 3 * da) - r2 * (float)Math.sin(angle + 2 * da); - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - } - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), -width * 0.5f); - gl.glEnd(); - - gl.glShadeModel(GL.GL_SMOOTH); - - /* draw inside radius cylinder */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glNormal3f(-(float)Math.cos(angle), -(float)Math.sin(angle), 0.0f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - } - gl.glEnd(); - } - - // Methods required for the implementation of MouseListener - public void mouseEntered(MouseEvent e) {} - public void mouseExited(MouseEvent e) {} - - public void mousePressed(MouseEvent e) { - prevMouseX = e.getX(); - prevMouseY = e.getY(); - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = true; - } - } - - public void mouseReleased(MouseEvent e) { - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = false; - } - } - - public void mouseClicked(MouseEvent e) {} - - // Methods required for the implementation of MouseMotionListener - public void mouseDragged(MouseEvent e) { - int x = e.getX(); - int y = e.getY(); - Dimension size = e.getComponent().getSize(); - - float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)size.width); - float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)size.height); - - prevMouseX = x; - prevMouseY = y; - - view_rotx += thetaX; - view_roty += thetaY; - } - - public void mouseMoved(MouseEvent e) {} - } } - diff --git a/src/demos/jrefract/JRefract.java b/src/demos/jrefract/JRefract.java index e842eba..60361e0 100755 --- a/src/demos/jrefract/JRefract.java +++ b/src/demos/jrefract/JRefract.java @@ -35,20 +35,25 @@ package demos.jrefract; import java.awt.*; import java.awt.event.*; -import java.awt.image.*; -import java.io.*; -import java.nio.*; import java.util.*; -import javax.imageio.*; -import javax.imageio.stream.*; import javax.swing.*; import javax.swing.event.*; -import net.java.games.jogl.*; -import net.java.games.jogl.util.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; +import com.sun.opengl.utils.*; +import demos.common.*; +import demos.hdr.HDR; +import demos.hwShadowmapsSimple.HWShadowmapsSimple; +import demos.infiniteShadowVolumes.InfiniteShadowVolumes; +import demos.jgears.JGears; +import demos.proceduralTexturePhysics.ProceduralTexturePhysics; import demos.util.*; -import gleem.*; -import gleem.linalg.*; +import demos.vertexBufferObject.VertexBufferObject; +import demos.vertexProgRefract.VertexProgRefract; +import demos.vertexProgWarp.VertexProgWarp; + +import demos.xtrans.*; /** Wavelength-dependent refraction demo<br> @@ -64,34 +69,129 @@ import gleem.linalg.*; public class JRefract { private boolean useRegisterCombiners; - private ArrayList canvases; - private volatile boolean quit; - private volatile boolean animatorStopped; + private Animator animator; private JDesktopPane desktop; public static void main(String[] args) { new JRefract().run(args); } - private JInternalFrame addWindow(boolean bunny) { - String str = bunny ? - "Refraction Using Vertex Programs" : - "Gears Demo"; + private static final int GEARS = 1; + private static final int HDR = 2; + private static final int HWSHADOWS = 3; + private static final int INFINITE = 4; + private static final int REFRACT = 5; + private static final int VBO = 6; + private static final int WARP = 7; + private static final int WATER = 8; + + private JInternalFrame addWindow(int which) { + // FIXME: workaround for problem in 1.6 where ALL Components, + // including Swing components, are Finalizable, requiring two full + // GC cycles (and running of finalizers) to reclaim + System.gc(); + // Try to get finalizers run + try { + Thread.sleep(1); + } catch (InterruptedException e) { + } + System.gc(); + + String str = ""; + switch (which) { + case GEARS: str = "Gears Demo"; break; + case HDR: str = "High Dynamic Range Rendering Demo"; break; + case HWSHADOWS: str = "ARB_shadow Shadows"; break; + case INFINITE: str = "Infinite Shadow Volumes"; break; + case REFRACT: str = "Refraction Using Vertex Programs"; break; + case VBO: str = "Very Simple vertex_buffer_object demo"; break; + case WATER: str = "Procedural Texture Waves"; break; + } final JInternalFrame inner = new JInternalFrame(str); inner.setResizable(true); inner.setClosable(true); inner.setVisible(true); GLCapabilities caps = new GLCapabilities(); - if (!bunny) { - caps.setAlphaBits(8); + if (which == INFINITE) { + caps.setStencilBits(16); } - final GLJPanel canvas = GLDrawableFactory.getFactory().createGLJPanel(caps); - if (bunny) { - canvas.addGLEventListener(new Listener()); - } else { - canvas.addGLEventListener(new GearRenderer()); + final GLJPanel canvas = + (which == GEARS) ? + new JGears() : + GLDrawableFactory.getFactory().createGLJPanel(caps); + final DemoListener demoListener = new DemoListener() { + public void shutdownDemo() { + removeJPanel(canvas); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + inner.doDefaultCloseAction(); + } + }); + } + + public void repaint() { + canvas.repaint(); + } + }; + + Demo demo = null; + switch (which) { + case GEARS: { + // GLEventListener already added + break; + } + + case HDR: { + demo = new HDR(); + ((HDR) demo).setup(null); + inner.setSize(((HDR) demo).getPreferredWidth(), ((HDR) demo).getPreferredHeight()); + break; + } + + case HWSHADOWS: { + demo = new HWShadowmapsSimple(); + break; + } + + case INFINITE: { + demo = new InfiniteShadowVolumes(); + break; + } + + case REFRACT: { + demo = new VertexProgRefract(); + break; + } + + case VBO: { + demo = new VertexBufferObject(); + break; + } + + case WARP: { + demo = new VertexProgWarp(); + ((VertexProgWarp) demo).setTitleSetter(new VertexProgWarp.TitleSetter() { + public void setTitle(final String title) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + inner.setTitle(title); + } + }); + } + }); + break; + } + + case WATER: { + demo = new ProceduralTexturePhysics(); + break; + } + } + if (which != GEARS) { + demo.setDemoListener(demoListener); + canvas.addGLEventListener(demo); } canvas.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { @@ -101,31 +201,27 @@ public class JRefract { addJPanel(canvas); + final Demo fDemo = demo; + inner.addInternalFrameListener(new InternalFrameAdapter() { public void internalFrameClosed(InternalFrameEvent e) { - removeJPanel(canvas); - System.gc(); + if (fDemo != null) { + fDemo.shutdownDemo(); + } } }); inner.getContentPane().setLayout(new BorderLayout()); - if (bunny) { - inner.getContentPane().add(canvas, BorderLayout.CENTER); - inner.getContentPane().add(new JButton("West"), BorderLayout.WEST); - inner.getContentPane().add(new JButton("East"), BorderLayout.EAST); - inner.getContentPane().add(new JButton("North"), BorderLayout.NORTH); - inner.getContentPane().add(new JButton("South"), BorderLayout.SOUTH); - } else { + /* if (which == REFRACT) { + // Testing scrolling + canvas.setSize(512, 512); + canvas.setPreferredSize(new Dimension(512, 512)); + JScrollPane scroller = new JScrollPane(canvas); + inner.getContentPane().add(scroller); + } else */ if (which == GEARS) { // Provide control over transparency of gears background canvas.setOpaque(false); - JPanel gradientPanel = new JPanel() { - public void paintComponent(Graphics g) { - ((Graphics2D) g).setPaint(new GradientPaint(0, 0, Color.WHITE, - getWidth(), getHeight(), Color.DARK_GRAY)); - g.fillRect(0, 0, getWidth(), getHeight()); - } - }; - gradientPanel.setLayout(new BorderLayout()); + JPanel gradientPanel = JGears.createGradientPanel(); inner.getContentPane().add(gradientPanel, BorderLayout.CENTER); gradientPanel.add(canvas, BorderLayout.CENTER); @@ -136,20 +232,28 @@ public class JRefract { } }); inner.getContentPane().add(checkBox, BorderLayout.SOUTH); + } else { + inner.getContentPane().add(canvas, BorderLayout.CENTER); } - inner.setSize(512, 512); + if (which != HDR) { + inner.setSize(512, 512); + } desktop.add(inner); return inner; } public void run(String[] args) { - - canvases = new ArrayList(); - JFrame frame = new JFrame("JOGL and Swing Interoperability"); - desktop = new JDesktopPane(); + if ((args.length > 0) && args[0].equals("-xt")) { + desktop = new XTDesktopPane(); + // FIXME: this is a hack to get the repaint behavior to work correctly + ((XTDesktopPane) desktop).setAlwaysRedraw(true); + } else { + desktop = new JDesktopPane(); + } + desktop.setSize(1024, 768); frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add(desktop, BorderLayout.CENTER); @@ -166,698 +270,102 @@ public class JRefract { JMenuBar menuBar = new JMenuBar(); JMenu menu = new JMenu("Actions"); - JMenuItem item = new JMenuItem("New bunny"); + JMenuItem item; + + item = new JMenuItem("Gears"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - addWindow(true); + addWindow(GEARS); } }); menu.add(item); - item = new JMenuItem("New gears"); + item = new JMenuItem("High Dynamic Range"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - addWindow(false); + addWindow(HDR); } }); menu.add(item); - item = new JMenuItem("Auto mode"); + item = new JMenuItem("Hardware Shadow Maps"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - startAutoMode(); + addWindow(HWSHADOWS); } }); menu.add(item); - item = new JMenuItem("Exit"); + item = new JMenuItem("Infinite Shadow Volumes"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - runExit(); + addWindow(INFINITE); } }); menu.add(item); - menuBar.add(menu); - frame.setJMenuBar(menuBar); - - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - runExit(); + item = new JMenuItem("Refraction"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + addWindow(REFRACT); } }); - frame.setSize(desktop.getSize()); - frame.setVisible(true); - - new Thread(new ListAnimator()).start(); - } - - class Listener implements GLEventListener { - private boolean firstRender = true; - private int vtxProg; - private int fragProg; - private int cubemap; - private int bunnydl; - private int obj; - - private GLUT glut = new GLUT(); - - private ExaminerViewer viewer; - private boolean doViewAll = true; - - private Time time = new SystemTime(); - private float animRate = (float) Math.toRadians(-6.0f); // Radians / sec - - private float refract = 1.1f; // ratio of indicies of refraction - private float wavelengthDelta = 0.05f; // difference in refraction for each "wavelength" (R,G,B) - private float fresnel = 2.0f; // Fresnel multiplier - - private boolean wire = false; - private boolean toggleWire = false; - - private static final String transformRefract = -"!!ARBvp1.0\n" + -"# Refraction\n" + -"\n" + -"# Parameters\n" + -"PARAM mvp [4] = { state.matrix.mvp }; # modelview projection matrix\n" + -"PARAM mvit[4] = { state.matrix.modelview.invtrans }; # modelview matrix inverse transpose\n" + -"PARAM mv [4] = { state.matrix.modelview }; # modelview matrix\n" + -"PARAM tex [4] = { state.matrix.texture }; # texture matrix\n" + -"PARAM eyePosition = program.env[0]; # eye position\n" + -"PARAM fresnel = program.env[1]; # fresnel multiplier\n" + -"PARAM texScale = program.env[2]; # texture scale\n" + -"PARAM misc = program.env[3]; # misc. constants\n" + -"PARAM refraction = program.env[4]; # refractive index\n" + -"\n" + -"# Per vertex inputs\n" + -"ATTRIB iPos = vertex.position; #position\n" + -"ATTRIB iCol0 = vertex.color; #color\n" + -"ATTRIB iNorm = vertex.normal; #normal\n" + -"\n" + -"# Temporaries\n" + -"TEMP r0;\n" + -"TEMP r1;\n" + -"TEMP r2;\n" + -"TEMP r3;\n" + -"TEMP r8;\n" + -"TEMP r9;\n" + -"TEMP r11;\n" + -"\n" + -"# Outputs\n" + -"OUTPUT oPos = result.position; #position\n" + -"OUTPUT oCol0 = result.color; #primary color\n" + -"OUTPUT oTex0 = result.texcoord[0]; #texture coordinate set 0\n" + -"OUTPUT oTex1 = result.texcoord[1]; #texture coordinate set 1\n" + -"\n" + -"\n" + -"# transform vertex position to eye space\n" + -"DP4 r9.x, mv[0], iPos ;\n" + -"DP4 r9.y, mv[1], iPos ;\n" + -"DP4 r9.z, mv[2], iPos ;\n" + -"DP4 r9.w, mv[3], iPos ;\n" + -"\n" + -"# transform normal to eye space\n" + -"DP3 r11.x, mvit[0], iNorm ;\n" + -"DP3 r11.y, mvit[1], iNorm ;\n" + -"DP3 r11.z, mvit[2], iNorm ;\n" + -"\n" + -"# vertex->eye vector\n" + -"ADD r0, -r9, eyePosition;\n" + -"\n" + -"# normalize\n" + -"DP3 r8.w, r0, r0;\n" + -"RSQ r8.w, r8.w;\n" + -"MUL r8, r0, r8.w; # r8 = eye/incident vector\n" + -"\n" + -"# refraction, Renderman style\n" + -"\n" + -"# float IdotN = I.N;\n" + -"# float k = 1 - eta*eta*(1 - IdotN*IdotN);\n" + -"# return k < 0 ? (0,0,0) : eta*I - (eta*IdotN + sqrt(k))*N;\n" + -"\n" + -"DP3 r0.x, r11, -r8; # r0 = N.I\n" + -"\n" + -"MAD r1.x, -r0.x, r0.x, misc.y; # r1 = -IdotN*IdotN + 1\n" + -"MUL r1.x, r1.x, refraction.y; # r1 = -(r1*eta*eta)+1\n" + -"ADD r1.x, misc.y, -r1.x;\n" + -"\n" + -"RSQ r2.x, r1.x;\n" + -"RCP r2.x, r2.x;\n" + -"MAD r2.x, refraction.x, r0.x, r2.x;\n" + -"MUL r2, r11, r2.x;\n" + -"MAD r2, refraction.x, -r8, r2;\n" + -"\n" + -"# transform refracted ray by cubemap transform\n" + -"DP3 oTex0.x, tex[0], r2;\n" + -"DP3 oTex0.y, tex[1], r2;\n" + -"DP3 oTex0.z, tex[2], r2;\n" + -"\n" + -"# calculate reflection\n" + -"MUL r0, r11, misc.z;\n" + -"DP3 r3.w, r11, r8;\n" + -"MAD r3, r3.w, r0, -r8;\n" + -"\n" + -"# transform reflected ray by cubemap transform\n" + -"DP3 oTex1.x, tex[0], r3;\n" + -"DP3 oTex1.y, tex[1], r3;\n" + -"DP3 oTex1.z, tex[2], r3;\n" + -"\n" + -"# cheesy Fresnel approximation = (1-(I.N))^p\n" + -"DP3 r0.x, r8, r11;\n" + -"ADD r0.x, misc.y, -r0.x;\n" + -"MUL r0.x, r0.x, r0.x;\n" + -"MUL oCol0, r0.x, fresnel;\n" + -"\n" + -"# transform vertex to clip space\n" + -"DP4 oPos.x, mvp[0], iPos ;\n" + -"DP4 oPos.y, mvp[1], iPos ;\n" + -"DP4 oPos.z, mvp[2], iPos ;\n" + -"DP4 oPos.w, mvp[3], iPos ;\n" + -"\n" + -"END\n"; - - public void init(GLDrawable drawable) { - // Use debug pipeline - // drawable.setGL(new DebugGL(drawable.getGL())); - - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); - float cc = 1.0f; - gl.glClearColor(cc, cc, cc, 1); - gl.glColor3f(1,1,1); - gl.glEnable(GL.GL_DEPTH_TEST); + menu.add(item); - try { - initExtension(gl, "GL_ARB_vertex_program"); - initExtension(gl, "GL_ARB_multitexture"); - if (!gl.isExtensionAvailable("GL_ARB_fragment_program")) { - if (gl.isExtensionAvailable("GL_NV_register_combiners")) { - useRegisterCombiners = true; - } else { - final String message = "This demo requires either the GL_ARB_fragment_program\n" + - "or GL_NV_register_combiners extension"; - new Thread(new Runnable() { - public void run() { - JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); - runExit(); - } - }).start(); - throw new RuntimeException(message); - } + item = new JMenuItem("Vertex Buffer Object"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + addWindow(VBO); } - } catch (RuntimeException e) { - quit = true; - throw(e); - } - - b[' '] = true; // animate by default - - int[] vtxProgTmp = new int[1]; - gl.glGenProgramsARB(1, vtxProgTmp); - vtxProg = vtxProgTmp[0]; - gl.glBindProgramARB (GL.GL_VERTEX_PROGRAM_ARB, vtxProg); - gl.glProgramStringARB(GL.GL_VERTEX_PROGRAM_ARB, GL.GL_PROGRAM_FORMAT_ASCII_ARB, transformRefract.length(), transformRefract); - - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 0, 0.0f, 0.0f, 0.0f, 1.0f); // eye position - - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 1, fresnel, fresnel, fresnel, 1.0f); // fresnel multiplier - - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 2, 1.0f, -1.0f, 1.0f, 0.0f); // texture scale - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 3, 0.0f, 1.0f, 2.0f, 3.0f); // misc constants - - int[] cubemapTmp = new int[1]; - gl.glGenTextures(1, cubemapTmp); - cubemap = cubemapTmp[0]; - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, cubemap); - - gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); - gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); - - try { - loadPNGCubemap(gl, glu, "demos/data/cubemaps/uffizi", true); - } catch (IOException e) { - runExit(); - throw new RuntimeException(e); - } - - gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); - - gl.glDisable(GL.GL_CULL_FACE); - - if (useRegisterCombiners) { - initCombiners(gl); - } else { - initFragmentProgram(gl); - } - - try { - bunnydl = Bunny.gen3DObjectList(gl); - } catch (IOException e) { - throw new RuntimeException(e); - } - - drawable.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { - dispatchKey(e.getKeyChar()); - } - }); - - doViewAll = true; - - // Do this only once per drawable, not once each time the OpenGL - // context is created - if (firstRender) { - firstRender = false; - - drawable.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { - dispatchKey(e.getKeyChar()); - } - }); - - // Register the window with the ManipManager - ManipManager manager = ManipManager.getManipManager(); - manager.registerWindow(drawable); - - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); - viewer.setNoAltKeyMode(true); - viewer.attach(drawable, new BSphereProvider() { - public BSphere getBoundingSphere() { - return new BSphere(new Vec3f(0, 0, 0), 1.0f); - } - }); - viewer.setVertFOV((float) (15.0f * Math.PI / 32.0f)); - viewer.setZNear(0.1f); - viewer.setZFar(10.0f); - } - } - - public void display(GLDrawable drawable) { - if (quit) { - return; - } - - time.update(); - - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); - gl.glClear(GL.GL_COLOR_BUFFER_BIT|GL.GL_DEPTH_BUFFER_BIT); - - if (doViewAll) { - System.err.println("viewer.viewAll()"); - viewer.viewAll(gl); - doViewAll = false; - } - - if (getFlag(' ')) { - viewer.rotateAboutFocalPoint(new Rotf(Vec3f.Y_AXIS, (float) (time.deltaT() * animRate))); - } + }); + menu.add(item); - if (toggleWire) { - toggleWire = false; - wire = !wire; - if (wire) { - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); - } else { - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); + item = new JMenuItem("Warp"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + addWindow(WARP); } - } - - // draw background - gl.glDisable(GL.GL_DEPTH_TEST); - drawSkyBox(gl, glu); - gl.glEnable(GL.GL_DEPTH_TEST); - - gl.glPushMatrix(); - - viewer.update(gl); - ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters()); - ManipManager.getManipManager().render(drawable, gl); - - gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, vtxProg); - - gl.glEnable(GL.GL_VERTEX_PROGRAM_ARB); - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 62, fresnel, fresnel, fresnel, 1.0f); - - // set texture transforms - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, cubemap); - gl.glEnable(GL.GL_TEXTURE_CUBE_MAP_ARB); - gl.glMatrixMode(GL.GL_TEXTURE); - gl.glLoadIdentity(); - gl.glScalef(1.0f, -1.0f, 1.0f); - viewer.updateInverseRotation(gl); - - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, cubemap); - gl.glEnable(GL.GL_TEXTURE_CUBE_MAP_ARB); - gl.glMatrixMode(GL.GL_TEXTURE); - gl.glLoadIdentity(); - gl.glScalef(1.0f, -1.0f, 1.0f); - viewer.updateInverseRotation(gl); - - if (useRegisterCombiners) { - gl.glEnable(GL.GL_REGISTER_COMBINERS_NV); - } else { - gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); - gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB); - } - - gl.glColor3f(1.0f, 1.0f, 1.0f); - - if (getFlag('s')) { - // single pass - setRefraction(gl, refract); - drawObj(gl, glu, obj); - - } else { - // red pass - gl.glColorMask(true, false, false, false); - setRefraction(gl, refract); - drawObj(gl, glu, obj); - - gl.glDepthMask(false); - gl.glDepthFunc(GL.GL_EQUAL); - - // green pass - gl.glColorMask(false, true, false, false); - setRefraction(gl, refract + wavelengthDelta); - drawObj(gl, glu, obj); - - // blue pass - gl.glColorMask(false, false, true, false); - setRefraction(gl, refract + (wavelengthDelta * 2)); - drawObj(gl, glu, obj); - - gl.glDepthMask(true); - gl.glDepthFunc(GL.GL_LESS); - gl.glColorMask(true, true, true, false); - } - - if (useRegisterCombiners) { - gl.glDisable(GL.GL_REGISTER_COMBINERS_NV); - } else { - gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB); - } - gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB); - - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glPopMatrix(); - } - - // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - - //---------------------------------------------------------------------- - // Internals only below this point - // - private boolean[] b = new boolean[256]; - private void dispatchKey(char k) { - setFlag(k, !getFlag(k)); - // Quit on escape or 'q' - if ((k == (char) 27) || (k == 'q')) { - runExit(); - return; - } - - switch (k) { - case '1': - obj = 0; - break; - - case '2': - obj = 1; - break; - - case '3': - obj = 2; - break; - - case '4': - obj = 3; - break; - - case 'v': - doViewAll = true; - break; - - case 'w': - toggleWire = true; - break; - - default: - break; - } - } - - private void setFlag(char key, boolean val) { - b[((int) key) & 0xFF] = val; - } - - private boolean getFlag(char key) { - return b[((int) key) & 0xFF]; - } - - // FIXME: note we found that we had to swap the negy and posy portions of the cubemap. - // Not sure why this is the case. Vertical flip in the image read? Possible, but doesn't - // appear to be the case (have tried this and produced wrong results at the time). - String[] suffixes = { "posx", "negx", "negy", "posy", "posz", "negz" }; - int[] targets = { GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, - GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, - GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB }; - private void loadPNGCubemap(GL gl, GLU glu, String baseName, boolean mipmapped) throws IOException { - for (int i = 0; i < suffixes.length; i++) { - String resourceName = baseName + "_" + suffixes[i] + ".png"; - // Note: use of BufferedInputStream works around 4764639/4892246 - BufferedInputStream bis = new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(resourceName)); - BufferedImage img = ImageIO.read(bis); - bis.close(); - if (img == null) { - throw new RuntimeException("Error reading PNG image " + resourceName); - } - makeRGBTexture(gl, glu, img, targets[i], mipmapped); - } - } + }); + menu.add(item); - private void makeRGBTexture(GL gl, GLU glu, BufferedImage img, int target, boolean mipmapped) { - switch (img.getType()) { - case BufferedImage.TYPE_3BYTE_BGR: - case BufferedImage.TYPE_CUSTOM: { - byte[] data = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); - if (mipmapped) { - glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(), img.getHeight(), GL.GL_RGB, - GL.GL_UNSIGNED_BYTE, data); - } else { - gl.glTexImage2D(target, 0, GL.GL_RGB, img.getWidth(), img.getHeight(), 0, - GL.GL_RGB, GL.GL_UNSIGNED_BYTE, data); - } - break; + item = new JMenuItem("Water"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + addWindow(WATER); } + }); + menu.add(item); - case BufferedImage.TYPE_INT_RGB: { - int[] data = ((DataBufferInt) img.getRaster().getDataBuffer()).getData(); - if (mipmapped) { - glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(), img.getHeight(), GL.GL_RGB, - GL.GL_UNSIGNED_BYTE, data); - } else { - gl.glTexImage2D(target, 0, GL.GL_RGB, img.getWidth(), img.getHeight(), 0, - GL.GL_RGB, GL.GL_UNSIGNED_BYTE, data); - } - break; + item = new JMenuItem("Loop Gears Demo"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + startAutoMode(); } + }); + menu.add(item); - default: - throw new RuntimeException("Unsupported image type " + img.getType()); - } - } - - private void initExtension(GL gl, String glExtensionName) { - if (!gl.isExtensionAvailable(glExtensionName)) { - final String message = "OpenGL extension \"" + glExtensionName + "\" not available"; - new Thread(new Runnable() { - public void run() { - JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); - runExit(); - } - }).start(); - throw new RuntimeException(message); - } - } - - // initalize texture combiners to compute: - // refraction*(1-fresnel) + reflection*fresnel - private void initCombiners(GL gl) { - gl.glCombinerParameteriNV(GL.GL_NUM_GENERAL_COMBINERS_NV, 1); - - // combiner 0 - // a*b+c*d - gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_A_NV, GL.GL_TEXTURE0_ARB, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_B_NV, GL.GL_PRIMARY_COLOR_NV, GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); - gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_C_NV, GL.GL_TEXTURE1_ARB, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_D_NV, GL.GL_PRIMARY_COLOR_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - - // output: - // (stage, portion, abOutput, cdOutput, sumOutput, scale, bias, abDotProduct, cdDotProduct, muxSum) - gl.glCombinerOutputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, GL.GL_SPARE0_NV, GL.GL_NONE, GL.GL_NONE, false, false, false); - - // final combiner - // output: Frgb = A*B + (1-A)*C + D - // (variable, input, mapping, componentUsage); - gl.glFinalCombinerInputNV(GL.GL_VARIABLE_A_NV, GL.GL_SPARE0_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - gl.glFinalCombinerInputNV(GL.GL_VARIABLE_B_NV, GL.GL_ZERO, GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); - gl.glFinalCombinerInputNV(GL.GL_VARIABLE_C_NV, GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - gl.glFinalCombinerInputNV(GL.GL_VARIABLE_D_NV, GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - } - - private void initFragmentProgram(GL gl) { - int[] fragProgTmp = new int[1]; - gl.glGenProgramsARB(1, fragProgTmp); - fragProg = fragProgTmp[0]; - String combineFragProg = -"!!ARBfp1.0\n" + -"# compute refraction*(1-fresnel) + reflection*fresnel\n" + -"TEMP texSamp0, texSamp1;\n" + -"TEMP invFresnel;\n" + -"PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n" + -"TEX texSamp0, fragment.texcoord[0], texture[0], CUBE;\n" + -"TEX texSamp1, fragment.texcoord[1], texture[1], CUBE;\n" + -"SUB invFresnel, one, fragment.color;\n" + -"MUL texSamp0, texSamp0, invFresnel;\n" + -"MUL texSamp1, texSamp1, fragment.color;\n" + -"ADD texSamp0, texSamp0, texSamp1;\n" + -"MOV result.color, texSamp0;\n" + -"END"; - - gl.glBindProgramARB (GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); - gl.glProgramStringARB(GL.GL_FRAGMENT_PROGRAM_ARB, GL.GL_PROGRAM_FORMAT_ASCII_ARB, - combineFragProg.length(), combineFragProg); - int[] errPos = new int[1]; - gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos); - if (errPos[0] >= 0) { - System.out.println("Fragment program failed to load:"); - String errMsg = gl.glGetString(GL.GL_PROGRAM_ERROR_STRING_ARB); - if (errMsg == null) { - System.out.println("[No error message available]"); - } else { - System.out.println("Error message: \"" + errMsg + "\""); - } - System.out.println("Error occurred at position " + errPos[0] + " in program:"); - int endPos = errPos[0]; - while (endPos < combineFragProg.length() && combineFragProg.charAt(endPos) != '\n') { - ++endPos; + item = new JMenuItem("Quit"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + runExit(); } - System.out.println(combineFragProg.substring(errPos[0], endPos)); - } - } - - private void drawSkyBox(GL gl, GLU glu) { - // Compensates for ExaminerViewer's modification of modelview matrix - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glLoadIdentity(); - - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); - gl.glDisable(GL.GL_TEXTURE_CUBE_MAP_ARB); - - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, cubemap); - gl.glEnable(GL.GL_TEXTURE_CUBE_MAP_ARB); - - // This is a workaround for a driver bug on Mac OS X where the - // normals are not being sent down to the hardware in - // GL_NORMAL_MAP_EXT texgen mode. Temporarily enabling lighting - // causes the normals to be sent down. Thanks to Ken Dyke. - gl.glEnable(GL.GL_LIGHTING); - - gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP_EXT); - gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP_EXT); - gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP_EXT); - - gl.glEnable(GL.GL_TEXTURE_GEN_S); - gl.glEnable(GL.GL_TEXTURE_GEN_T); - gl.glEnable(GL.GL_TEXTURE_GEN_R); - - gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); - - gl.glMatrixMode(GL.GL_TEXTURE); - gl.glPushMatrix(); - gl.glLoadIdentity(); - gl.glScalef(1.0f, -1.0f, 1.0f); - viewer.updateInverseRotation(gl); - - glut.glutSolidSphere(glu, 5.0, 40, 20); - - gl.glDisable(GL.GL_LIGHTING); - - gl.glPopMatrix(); - gl.glMatrixMode(GL.GL_MODELVIEW); - - gl.glDisable(GL.GL_TEXTURE_GEN_S); - gl.glDisable(GL.GL_TEXTURE_GEN_T); - gl.glDisable(GL.GL_TEXTURE_GEN_R); - } - - private void drawObj(GL gl, GLU glu, int obj) { - switch(obj) { - case 0: - gl.glCallList(bunnydl); - break; - - case 1: - glut.glutSolidSphere(glu, 0.5, 64, 64); - break; - - case 2: - glut.glutSolidTorus(gl, 0.25, 0.5, 64, 64); - break; - - case 3: - drawPlane(gl, 1.0f, 1.0f, 50, 50); - break; - } - } - - private void setRefraction(GL gl, float index) { - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 4, index, index*index, 0.0f, 0.0f); - } - - // draw square subdivided into quad strips - private void drawPlane(GL gl, float w, float h, int rows, int cols) { - int x, y; - float vx, vy, s, t; - float ts, tt, tw, th; - - ts = 1.0f / cols; - tt = 1.0f / rows; - - tw = w / cols; - th = h / rows; - - gl.glNormal3f(0.0f, 0.0f, 1.0f); + }); + item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_MASK)); + menu.add(item); - for(y=0; y<rows; y++) { - gl.glBegin(GL.GL_QUAD_STRIP); - for(x=0; x<=cols; x++) { - vx = tw * x -(w/2.0f); - vy = th * y -(h/2.0f); - s = ts * x; - t = tt * y; + menuBar.add(menu); + frame.setJMenuBar(menuBar); - gl.glTexCoord2f(s, t); - gl.glColor3f(s, t, 0.0f); - gl.glVertex3f(vx, vy, 0.0f); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + runExit(); + } + }); + frame.setSize(desktop.getSize()); + frame.setVisible(true); - gl.glColor3f(s, t + tt, 0.0f); - gl.glTexCoord2f(s, t + tt); - gl.glVertex3f(vx, vy + th, 0.0f); - } - gl.glEnd(); - } - } + animator = new FPSAnimator(60); + animator.start(); } private void runExit() { @@ -868,324 +376,18 @@ public class JRefract { // the exit routine in another thread. new Thread(new Runnable() { public void run() { - quit = true; - while (!animatorStopped) { - try { - Thread.sleep(1); - } catch (InterruptedException e) { - } - } + animator.stop(); System.exit(0); } }).start(); } private synchronized void addJPanel(GLJPanel panel) { - ArrayList newCanvases = (ArrayList) canvases.clone(); - newCanvases.add(panel); - canvases = newCanvases; + animator.add(panel); } private synchronized void removeJPanel(GLJPanel panel) { - ArrayList newCanvases = (ArrayList) canvases.clone(); - newCanvases.remove(panel); - canvases = newCanvases; - } - - class ListAnimator implements Runnable { - public void run() { - while (!quit) { - if (canvases.isEmpty()) { - try { - Thread.sleep(10); - } catch (InterruptedException e) { - } - } else { - for (Iterator iter = canvases.iterator(); iter.hasNext(); ) { - GLJPanel panel = (GLJPanel) iter.next(); - panel.display(); - } - try { - Thread.sleep(1); - } catch (InterruptedException e) { - } - } - } - animatorStopped = true; - } - } - - static class GearRenderer implements GLEventListener, MouseListener, MouseMotionListener { - private float view_rotx = 20.0f, view_roty = 30.0f, view_rotz = 0.0f; - private int gear1, gear2, gear3; - private float angle = 0.0f; - - private int prevMouseX, prevMouseY; - private boolean mouseRButtonDown = false; - - - public void init(GLDrawable drawable) { - // Use debug pipeline - // drawable.setGL(new DebugGL(drawable.getGL())); - - GL gl = drawable.getGL(); - System.err.println("INIT GL IS: " + gl.getClass().getName()); - - float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; - float red[] = { 0.8f, 0.1f, 0.0f, 1.0f }; - float green[] = { 0.0f, 0.8f, 0.2f, 1.0f }; - float blue[] = { 0.2f, 0.2f, 1.0f, 1.0f }; - - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos); - gl.glEnable(GL.GL_CULL_FACE); - gl.glEnable(GL.GL_LIGHTING); - gl.glEnable(GL.GL_LIGHT0); - gl.glEnable(GL.GL_DEPTH_TEST); - - /* make the gears */ - gear1 = gl.glGenLists(1); - gl.glNewList(gear1, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red); - gear(gl, 1.0f, 4.0f, 1.0f, 20, 0.7f); - gl.glEndList(); - - gear2 = gl.glGenLists(1); - gl.glNewList(gear2, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, green); - gear(gl, 0.5f, 2.0f, 2.0f, 10, 0.7f); - gl.glEndList(); - - gear3 = gl.glGenLists(1); - gl.glNewList(gear3, GL.GL_COMPILE); - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, blue); - gear(gl, 1.3f, 2.0f, 0.5f, 10, 0.7f); - gl.glEndList(); - - gl.glEnable(GL.GL_NORMALIZE); - - drawable.addMouseListener(this); - drawable.addMouseMotionListener(this); - } - - public void reshape(GLDrawable drawable, int x, int y, int width, int height) { - GL gl = drawable.getGL(); - - float h = (float)height / (float)width; - - gl.glMatrixMode(GL.GL_PROJECTION); - - System.err.println("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR)); - System.err.println("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER)); - System.err.println("GL_VERSION: " + gl.glGetString(GL.GL_VERSION)); - System.err.println(); - System.err.println("glLoadTransposeMatrixfARB() supported: " + - gl.isFunctionAvailable("glLoadTransposeMatrixfARB")); - if (!gl.isFunctionAvailable("glLoadTransposeMatrixfARB")) { - // --- not using extensions - gl.glLoadIdentity(); - } else { - // --- using extensions - final float[] identityTranspose = new float[] { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - }; - gl.glLoadTransposeMatrixfARB(identityTranspose); - } - gl.glFrustum(-1.0f, 1.0f, -h, h, 5.0f, 60.0f); - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glLoadIdentity(); - gl.glTranslatef(0.0f, 0.0f, -40.0f); - } - - public void display(GLDrawable drawable) { - angle += 2.0f; - - GL gl = drawable.getGL(); - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - - gl.glPushMatrix(); - gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f); - gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f); - gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f); - - gl.glPushMatrix(); - gl.glTranslatef(-3.0f, -2.0f, 0.0f); - gl.glRotatef(angle, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear1); - gl.glPopMatrix(); - - gl.glPushMatrix(); - gl.glTranslatef(3.1f, -2.0f, 0.0f); - gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear2); - gl.glPopMatrix(); - - gl.glPushMatrix(); - gl.glTranslatef(-3.1f, 4.2f, 0.0f); - gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f); - gl.glCallList(gear3); - gl.glPopMatrix(); - - gl.glPopMatrix(); - } - - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - - private void gear(GL gl, - float inner_radius, - float outer_radius, - float width, - int teeth, - float tooth_depth) - { - int i; - float r0, r1, r2; - float angle, da; - float u, v, len; - - r0 = inner_radius; - r1 = outer_radius - tooth_depth / 2.0f; - r2 = outer_radius + tooth_depth / 2.0f; - - da = 2.0f * (float) Math.PI / teeth / 4.0f; - - gl.glShadeModel(GL.GL_FLAT); - - gl.glNormal3f(0.0f, 0.0f, 1.0f); - - /* draw front face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - if(i < teeth) - { - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - } - gl.glEnd(); - - /* draw front sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2.0f * da), r2 * (float)Math.sin(angle + 2.0f * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); - } - gl.glEnd(); - - /* draw back face */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); - - /* draw back sides of teeth */ - gl.glBegin(GL.GL_QUADS); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - } - gl.glEnd(); - - /* draw outward faces of teeth */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i < teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); - u = r2 * (float)Math.cos(angle + da) - r1 * (float)Math.cos(angle); - v = r2 * (float)Math.sin(angle + da) - r1 * (float)Math.sin(angle); - len = (float)Math.sqrt(u * u + v * v); - u /= len; - v /= len; - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), width * 0.5f); - gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); - u = r1 * (float)Math.cos(angle + 3 * da) - r2 * (float)Math.cos(angle + 2 * da); - v = r1 * (float)Math.sin(angle + 3 * da) - r2 * (float)Math.sin(angle + 2 * da); - gl.glNormal3f(v, -u, 0.0f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); - gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); - } - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), width * 0.5f); - gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), -width * 0.5f); - gl.glEnd(); - - gl.glShadeModel(GL.GL_SMOOTH); - - /* draw inside radius cylinder */ - gl.glBegin(GL.GL_QUAD_STRIP); - for (i = 0; i <= teeth; i++) - { - angle = i * 2.0f * (float) Math.PI / teeth; - gl.glNormal3f(-(float)Math.cos(angle), -(float)Math.sin(angle), 0.0f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); - gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); - } - gl.glEnd(); - } - - // Methods required for the implementation of MouseListener - public void mouseEntered(MouseEvent e) {} - public void mouseExited(MouseEvent e) {} - - public void mousePressed(MouseEvent e) { - prevMouseX = e.getX(); - prevMouseY = e.getY(); - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = true; - } - } - - public void mouseReleased(MouseEvent e) { - if ((e.getModifiers() & e.BUTTON3_MASK) != 0) { - mouseRButtonDown = false; - } - } - - public void mouseClicked(MouseEvent e) {} - - // Methods required for the implementation of MouseMotionListener - public void mouseDragged(MouseEvent e) { - int x = e.getX(); - int y = e.getY(); - Dimension size = e.getComponent().getSize(); - - float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)size.width); - float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)size.height); - - prevMouseX = x; - prevMouseY = y; - - view_rotx += thetaX; - view_roty += thetaY; - } - - public void mouseMoved(MouseEvent e) {} + animator.remove(panel); } private JInternalFrame curFrame; @@ -1196,7 +398,7 @@ public class JRefract { try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { - curFrame = addWindow(false); + curFrame = addWindow(GEARS); } }); } catch (Exception e) { diff --git a/src/demos/multisample/Multisample.java b/src/demos/multisample/Multisample.java index f479b0e..ff7d7ca 100755 --- a/src/demos/multisample/Multisample.java +++ b/src/demos/multisample/Multisample.java @@ -41,7 +41,8 @@ package demos.multisample; import java.awt.*; import java.awt.event.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; public class Multisample { private GLCanvas canvas; @@ -83,7 +84,7 @@ public class Multisample { caps.setSampleBuffers(true); caps.setNumSamples(4); - canvas = GLDrawableFactory.getFactory().createGLCanvas(caps, chooser); + canvas = GLDrawableFactory.getFactory().createGLCanvas(caps, chooser, null, null); canvas.addGLEventListener(new Listener()); Frame frame = new Frame("Full-scene antialiasing"); @@ -123,9 +124,8 @@ public class Multisample { } class Listener implements GLEventListener { - public void init(GLDrawable drawable) { + public void init(GLAutoDrawable drawable) { GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); gl.glClearColor(0, 0, 0, 0); // gl.glEnable(GL.GL_DEPTH_TEST); @@ -138,9 +138,8 @@ public class Multisample { gl.glOrtho(-1, 1, -1, 1, -1, 1); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); @@ -161,8 +160,8 @@ public class Multisample { } // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } private void runExit() { diff --git a/src/demos/printext/PrintExt.java b/src/demos/printext/PrintExt.java index 3edb3a0..4d21ee9 100755 --- a/src/demos/printext/PrintExt.java +++ b/src/demos/printext/PrintExt.java @@ -6,7 +6,8 @@ package demos.printext; import java.awt.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; public class PrintExt { public static void main(String[] args) { @@ -20,7 +21,7 @@ public class PrintExt { } static class Listener implements GLEventListener { - public void init(GLDrawable drawable) { + public void init(GLAutoDrawable drawable) { GL gl = drawable.getGL(); System.out.println("GL vendor: " + gl.glGetString(GL.GL_VENDOR)); System.out.println("GL version: " + gl.glGetString(GL.GL_VERSION)); @@ -44,13 +45,13 @@ public class PrintExt { runExit(); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { } - public void reshape(GLDrawable drawable, int x, int y, int w, int h) { + public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { } - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { } } diff --git a/src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java b/src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java index d2a04af..7599778 100644 --- a/src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java +++ b/src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java @@ -37,7 +37,9 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; +import demos.common.*; import demos.util.*; import gleem.*; import gleem.linalg.*; @@ -56,35 +58,19 @@ import gleem.linalg.*; * */ -public class ProceduralTexturePhysics { - private volatile boolean drawing; - private volatile int mousePosX; - private volatile int mousePosY; - - private Dimension dim = new Dimension(); - private GLCanvas canvas; - private Water water; - private Animator animator; - private volatile ExaminerViewer viewer; - private boolean[] b = new boolean[256]; - private boolean doViewAll = true; - private float zNear = 0.1f; - private float zFar = 10.0f; - - private DurationTimer timer = new DurationTimer(); - private boolean firstRender = true; - private int frameCount; - +public class ProceduralTexturePhysics extends Demo { public static void main(String[] args) { - new ProceduralTexturePhysics().run(args); - } - - public void run(String[] args) { - canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); - canvas.addGLEventListener(new Listener()); - canvas.setNoAutoRedrawMode(true); - - animator = new Animator(canvas); + GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); + ProceduralTexturePhysics demo = new ProceduralTexturePhysics(); + canvas.addGLEventListener(demo); + + final Animator animator = new Animator(canvas); + demo.setDemoListener(new DemoListener() { + public void shutdownDemo() { + runExit(animator); + } + public void repaint() {} + }); Frame frame = new Frame("Procedural Texture Waves"); frame.setLayout(new BorderLayout()); @@ -96,16 +82,10 @@ public class ProceduralTexturePhysics { frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { - runExit(); + runExit(animator); } }); - water = new Water(); - water.initialize("demos/data/images/nvfixed.tga", - "demos/data/images/nvspin.tga", - "demos/data/images/droplet.tga", - "demos/data/cubemaps/CloudyHills_{0}.tga", - canvas); animator.start(); } @@ -113,49 +93,76 @@ public class ProceduralTexturePhysics { // Internals only below this point // - private void setFlag(char key, boolean val) { - b[((int) key) & 0xFF] = val; + public void shutdownDemo() { + ManipManager.getManipManager().unregisterWindow(drawable); + drawable.removeGLEventListener(this); + super.shutdownDemo(); } - private boolean getFlag(char key) { - return b[((int) key) & 0xFF]; - } + private volatile boolean drawing; + private volatile int mousePosX; + private volatile int mousePosY; - class Listener implements GLEventListener { - private float blurIncrement = 0.01f; - private float bumpIncrement = 0.01f; - private float frequencyIncrement = 0.1f; - - public void init(GLDrawable drawable) { - GL gl = drawable.getGL(); - gl.setSwapInterval(1); - - try { - checkExtension(gl, "GL_ARB_multitexture"); - checkExtension(gl, "GL_ARB_vertex_program"); - checkExtension(gl, "GL_ARB_fragment_program"); - checkExtension(gl, "GL_ARB_pbuffer"); - checkExtension(gl, "GL_ARB_pixel_format"); - } catch (GLException e) { - e.printStackTrace(); - throw(e); - } + private GLAutoDrawable drawable; + private Water water = new Water(); + private volatile ExaminerViewer viewer; + private boolean[] b = new boolean[256]; + private boolean doViewAll = true; + private float zNear = 0.1f; + private float zFar = 10.0f; + + private DurationTimer timer = new DurationTimer(); + private boolean firstRender = true; + private int frameCount; + + private float blurIncrement = 0.01f; + private float bumpIncrement = 0.01f; + private float frequencyIncrement = 0.1f; + + public void init(GLAutoDrawable drawable) { + water.destroy(); + water.initialize("demos/data/images/nvfixed.tga", + "demos/data/images/nvspin.tga", + "demos/data/images/droplet.tga", + "demos/data/cubemaps/CloudyHills_{0}.tga", + drawable); + + GL gl = drawable.getGL(); + gl.setSwapInterval(1); + + try { + checkExtension(gl, "GL_VERSION_1_3"); // For multitexture + checkExtension(gl, "GL_ARB_vertex_program"); + checkExtension(gl, "GL_ARB_fragment_program"); + checkExtension(gl, "GL_ARB_pbuffer"); + checkExtension(gl, "GL_ARB_pixel_format"); + } catch (GLException e) { + e.printStackTrace(); + throw(e); + } - gl.glClearColor(0, 0.2f, 0.5f, 0); - gl.glDisable(GL.GL_LIGHTING); - gl.glDisable(GL.GL_DEPTH_TEST); - gl.glDisable(GL.GL_CULL_FACE); + gl.glClearColor(0, 0.2f, 0.5f, 0); + gl.glDisable(GL.GL_LIGHTING); + gl.glDisable(GL.GL_DEPTH_TEST); + gl.glDisable(GL.GL_CULL_FACE); + + doViewAll = true; + + if (firstRender) { + firstRender = false; // Register the window with the ManipManager ManipManager manager = ManipManager.getManipManager(); manager.registerWindow(drawable); + this.drawable = drawable; viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer.setAutoRedrawMode(false); viewer.attach(drawable, new BSphereProvider() { - public BSphere getBoundingSphere() { - return new BSphere(new Vec3f(0, 0, 0), 1.2f); - } - }); + public BSphere getBoundingSphere() { + return new BSphere(new Vec3f(0, 0, 0), 1.2f); + } + }); viewer.setVertFOV((float) (15.0f * Math.PI / 32.0f)); viewer.setZNear(zNear); viewer.setZFar(zFar); @@ -187,175 +194,176 @@ public class ProceduralTexturePhysics { mousePosY = e.getY(); } }); - } - public void display(GLDrawable drawable) { - if (!firstRender) { - if (++frameCount == 30) { - timer.stop(); - System.err.println("Frames per second: " + (30.0f / timer.getDurationAsSeconds())); - timer.reset(); - timer.start(); - frameCount = 0; - } - } else { - firstRender = false; - timer.start(); - } + timer.start(); + } + } - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); + public void display(GLAutoDrawable drawable) { + if (++frameCount == 30) { + timer.stop(); + System.err.println("Frames per second: " + (30.0f / timer.getDurationAsSeconds())); + timer.reset(); + timer.start(); + frameCount = 0; + } - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + GL gl = drawable.getGL(); - if (doViewAll) { - viewer.viewAll(gl); - doViewAll = false; - } + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - viewer.update(gl); - ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters()); - ManipManager.getManipManager().render(drawable, gl); + if (doViewAll) { + viewer.viewAll(gl); + doViewAll = false; + } - if (drawing) { - canvas.getSize(dim); - water.addDroplet(new Water.Droplet( 2 * (mousePosX / (float) dim.width - 0.5f), - -2 * (mousePosY / (float) dim.height - 0.5f), - 0.08f)); - } - water.tick(); + viewer.update(gl); + ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters()); + ManipManager.getManipManager().render(drawable, gl); - CameraParameters params = viewer.getCameraParameters(); - water.draw(gl, params.getOrientation().inverse()); + if (drawing) { + int w = drawable.getWidth(); + int h = drawable.getHeight(); + water.addDroplet(new Water.Droplet( 2 * (mousePosX / (float) w - 0.5f), + -2 * (mousePosY / (float) h - 0.5f), + 0.08f)); } + water.tick(); - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} + CameraParameters params = viewer.getCameraParameters(); + water.draw(gl, params.getOrientation().inverse()); + } - // Unused routines - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} - //---------------------------------------------------------------------- - // Internals only below this point - // + // Unused routines + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - private void checkExtension(GL gl, String extensionName) { - if (!gl.isExtensionAvailable(extensionName)) { - String message = "Unable to initialize " + extensionName + " OpenGL extension"; - JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); - runExit(); - } + private void setFlag(char key, boolean val) { + b[((int) key) & 0xFF] = val; + } + + private boolean getFlag(char key) { + return b[((int) key) & 0xFF]; + } + + private void checkExtension(GL gl, String extensionName) { + if (!gl.isExtensionAvailable(extensionName)) { + String message = "Unable to initialize " + extensionName + " OpenGL extension"; + JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); + shutdownDemo(); } + } - private void dispatchKey(char k) { - setFlag(k, !getFlag(k)); - - switch (k) { - case 27: - case 'q': - runExit(); - break; - case 'w': - water.enableWireframe(getFlag('w')); - break; - case 'd': - // FIXME - /* - - if (getKey('d')) { - glutMouseFunc(glh::glut_mouse_function); - glutMotionFunc(glh::glut_motion_function); - } - else - { - glutMouseFunc(Mouse); - glutMotionFunc(Motion); - } - */ - break; - case ' ': - water.enableAnimation(getFlag(' ')); - break; - case 'b': - water.enableBorderWrapping(getFlag('b')); - break; - case 'n': - water.singleStep(); - break; - case 's': - water.enableSlowAnimation(getFlag('s')); - break; - case '1': - water.setRenderMode(Water.CA_FULLSCREEN_REFLECT); - break; - case '2': - water.setRenderMode(Water.CA_FULLSCREEN_HEIGHT); - break; - case '3': - water.setRenderMode(Water.CA_FULLSCREEN_FORCE); - break; - case '4': - water.setRenderMode(Water.CA_FULLSCREEN_NORMALMAP); - break; - case '5': - water.setRenderMode(Water.CA_TILED_THREE_WINDOWS); - break; - case 'r': - water.reset(); - break; - case 'i': - // FIXME: make sure this is what this does - doViewAll = true; - // gluPerspective(90, 1, .01, 10); - break; - case 'c': { - float dist = water.getBlurDistance(); - if (dist > blurIncrement) - water.setBlurDistance(dist - blurIncrement); - break; - } - case 'v': { - float dist = water.getBlurDistance(); - if (dist < 1) - water.setBlurDistance(dist + blurIncrement); - break; - } - case '-': { - float scale = water.getBumpScale(); - if (scale > -1) - water.setBumpScale(scale - bumpIncrement); - break; - } - case '=': { - float scale = water.getBumpScale(); - if (scale < 1) - water.setBumpScale(scale + bumpIncrement); - break; - } - case 'l': - water.enableBoundaryApplication(getFlag('l')); - break; - case 'o': - water.enableSpinningLogo(getFlag('o')); - break; - case '.': { - float frequency = water.getBumpScale(); - if (frequency < 1) - water.setDropFrequency(frequency + frequencyIncrement); - break; - } - case ',': { - float frequency = water.getBumpScale(); - if (frequency > 0) - water.setDropFrequency(frequency - frequencyIncrement); - break; - } - default: - break; + private void dispatchKey(char k) { + setFlag(k, !getFlag(k)); + + switch (k) { + case 27: + case 'q': + shutdownDemo(); + break; + case 'w': + water.enableWireframe(getFlag('w')); + break; + case 'd': + // FIXME + /* + + if (getKey('d')) { + glutMouseFunc(glh::glut_mouse_function); + glutMotionFunc(glh::glut_motion_function); } + else + { + glutMouseFunc(Mouse); + glutMotionFunc(Motion); + } + */ + break; + case ' ': + water.enableAnimation(getFlag(' ')); + break; + case 'b': + water.enableBorderWrapping(getFlag('b')); + break; + case 'n': + water.singleStep(); + break; + case 's': + water.enableSlowAnimation(getFlag('s')); + break; + case '1': + water.setRenderMode(Water.CA_FULLSCREEN_REFLECT); + break; + case '2': + water.setRenderMode(Water.CA_FULLSCREEN_HEIGHT); + break; + case '3': + water.setRenderMode(Water.CA_FULLSCREEN_FORCE); + break; + case '4': + water.setRenderMode(Water.CA_FULLSCREEN_NORMALMAP); + break; + case '5': + water.setRenderMode(Water.CA_TILED_THREE_WINDOWS); + break; + case 'r': + water.reset(); + break; + case 'i': + // FIXME: make sure this is what this does + doViewAll = true; + // gluPerspective(90, 1, .01, 10); + break; + case 'c': { + float dist = water.getBlurDistance(); + if (dist > blurIncrement) + water.setBlurDistance(dist - blurIncrement); + break; + } + case 'v': { + float dist = water.getBlurDistance(); + if (dist < 1) + water.setBlurDistance(dist + blurIncrement); + break; + } + case '-': { + float scale = water.getBumpScale(); + if (scale > -1) + water.setBumpScale(scale - bumpIncrement); + break; } - } + case '=': { + float scale = water.getBumpScale(); + if (scale < 1) + water.setBumpScale(scale + bumpIncrement); + break; + } + case 'l': + water.enableBoundaryApplication(getFlag('l')); + break; + case 'o': + water.enableSpinningLogo(getFlag('o')); + break; + case '.': { + float frequency = water.getBumpScale(); + if (frequency < 1) + water.setDropFrequency(frequency + frequencyIncrement); + break; + } + case ',': { + float frequency = water.getBumpScale(); + if (frequency > 0) + water.setDropFrequency(frequency - frequencyIncrement); + break; + } + default: + break; + } + } - private void runExit() { + private static void runExit(final Animator animator) { // Note: calling System.exit() synchronously inside the draw, // reshape or init callbacks can lead to deadlocks on certain // platforms (in particular, X11) because the JAWT's locking diff --git a/src/demos/proceduralTexturePhysics/Water.java b/src/demos/proceduralTexturePhysics/Water.java index 0522c70..701a10f 100644 --- a/src/demos/proceduralTexturePhysics/Water.java +++ b/src/demos/proceduralTexturePhysics/Water.java @@ -36,11 +36,14 @@ package demos.proceduralTexturePhysics; import java.awt.Image; import java.awt.image.*; import java.io.*; +import java.nio.*; import java.text.*; import java.util.*; import gleem.linalg.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; import demos.util.*; /** @@ -60,6 +63,8 @@ public class Water { // used to render the water geometry (with the parent drawable's GL // object). + private GLU glu = new GLU(); + // Rendering modes public static final int CA_FULLSCREEN_REFLECT = 0; public static final int CA_FULLSCREEN_FORCE = 1; @@ -75,7 +80,7 @@ public class Water { private String tmpDropletFilename; private String tmpCubeMapFilenamePattern; - private GLDrawable pbuffer; + private GLPbuffer pbuffer; private Rotf cameraOrientation = new Rotf(); // Static texture names @@ -186,7 +191,7 @@ public class Water { String spinFilename, String dropletFilename, String cubeMapFilenamePattern, - GLDrawable parentWindow) { + GLAutoDrawable parentWindow) { loadInitialTexture(initialMapFilename); tmpSpinFilename = spinFilename; tmpDropletFilename = dropletFilename; @@ -194,17 +199,26 @@ public class Water { // create the pbuffer. Will use this as an offscreen rendering buffer. // it allows rendering a texture larger than our window. - if (!parentWindow.canCreateOffscreenDrawable()) { - throw new GLException("Parent window doesn't support creation of pbuffers"); - } GLCapabilities caps = new GLCapabilities(); caps.setDoubleBuffered(false); - pbuffer = parentWindow.createOffscreenDrawable(caps, - initialMapDimensions[0], - initialMapDimensions[1]); + if (!GLDrawableFactory.getFactory().canCreateGLPbuffer()) { + throw new GLException("Pbuffers not supported with this graphics card"); + } + pbuffer = GLDrawableFactory.getFactory().createGLPbuffer(caps, + initialMapDimensions[0], + initialMapDimensions[1], + parentWindow.getContext()); pbuffer.addGLEventListener(new Listener()); } + public void destroy() { + if (pbuffer != null) { + pbuffer.destroy(); + pbuffer = null; + } + reset = true; + } + public void tick() { pbuffer.display(); } @@ -223,7 +237,7 @@ public class Water { } else { gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glEnable(GL.GL_TEXTURE_2D); } @@ -242,38 +256,38 @@ public class Water { gl.glCallList(displayListIDs[CA_FRAGMENT_PROGRAM_REFLECT]); // Draw quad over full display - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, dynamicTextureIDs[CA_TEXTURE_NORMAL_MAP]); gl.glDisable(GL.GL_TEXTURE_2D); - gl.glActiveTextureARB(GL.GL_TEXTURE3_ARB); - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, staticTextureIDs[CA_TEXTURE_CUBEMAP]); + gl.glActiveTexture(GL.GL_TEXTURE3); + gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, staticTextureIDs[CA_TEXTURE_CUBEMAP]); gl.glEnable(GL.GL_TEXTURE_2D); gl.glColor4f(1, 1, 1, 1); gl.glBegin(GL.GL_QUADS); - gl.glMultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 0,0); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE1_ARB, matRot.get(0,0), matRot.get(0,1), matRot.get(0,2), 1); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE2_ARB, matRot.get(1,0), matRot.get(1,1), matRot.get(1,2), 1); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE3_ARB, matRot.get(2,0), matRot.get(2,1), matRot.get(2,2), 1); + gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 0,0); + gl.glMultiTexCoord4f(GL.GL_TEXTURE1, matRot.get(0,0), matRot.get(0,1), matRot.get(0,2), 1); + gl.glMultiTexCoord4f(GL.GL_TEXTURE2, matRot.get(1,0), matRot.get(1,1), matRot.get(1,2), 1); + gl.glMultiTexCoord4f(GL.GL_TEXTURE3, matRot.get(2,0), matRot.get(2,1), matRot.get(2,2), 1); gl.glVertex2f(-1,-1); - gl.glMultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 1,0); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE1_ARB, matRot.get(0,0), matRot.get(0,1), matRot.get(0,2), -1); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE2_ARB, matRot.get(1,0), matRot.get(1,1), matRot.get(1,2), 1); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE3_ARB, matRot.get(2,0), matRot.get(2,1), matRot.get(2,2), 1); + gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 1,0); + gl.glMultiTexCoord4f(GL.GL_TEXTURE1, matRot.get(0,0), matRot.get(0,1), matRot.get(0,2), -1); + gl.glMultiTexCoord4f(GL.GL_TEXTURE2, matRot.get(1,0), matRot.get(1,1), matRot.get(1,2), 1); + gl.glMultiTexCoord4f(GL.GL_TEXTURE3, matRot.get(2,0), matRot.get(2,1), matRot.get(2,2), 1); gl.glVertex2f( 1,-1); - gl.glMultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 1,1); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE1_ARB, matRot.get(0,0), matRot.get(0,1), matRot.get(0,2), -1); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE2_ARB, matRot.get(1,0), matRot.get(1,1), matRot.get(1,2), -1); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE3_ARB, matRot.get(2,0), matRot.get(2,1), matRot.get(2,2), 1); + gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 1,1); + gl.glMultiTexCoord4f(GL.GL_TEXTURE1, matRot.get(0,0), matRot.get(0,1), matRot.get(0,2), -1); + gl.glMultiTexCoord4f(GL.GL_TEXTURE2, matRot.get(1,0), matRot.get(1,1), matRot.get(1,2), -1); + gl.glMultiTexCoord4f(GL.GL_TEXTURE3, matRot.get(2,0), matRot.get(2,1), matRot.get(2,2), 1); gl.glVertex2f( 1, 1); - gl.glMultiTexCoord2fARB(GL.GL_TEXTURE0_ARB, 0,1); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE1_ARB, matRot.get(0,0), matRot.get(0,1), matRot.get(0,2), 1); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE2_ARB, matRot.get(1,0), matRot.get(1,1), matRot.get(1,2), -1); - gl.glMultiTexCoord4fARB(GL.GL_TEXTURE3_ARB, matRot.get(2,0), matRot.get(2,1), matRot.get(2,2), 1); + gl.glMultiTexCoord2f(GL.GL_TEXTURE0, 0,1); + gl.glMultiTexCoord4f(GL.GL_TEXTURE1, matRot.get(0,0), matRot.get(0,1), matRot.get(0,2), 1); + gl.glMultiTexCoord4f(GL.GL_TEXTURE2, matRot.get(1,0), matRot.get(1,1), matRot.get(1,2), -1); + gl.glMultiTexCoord4f(GL.GL_TEXTURE3, matRot.get(2,0), matRot.get(2,1), matRot.get(2,2), 1); gl.glVertex2f(-1, 1); gl.glEnd(); @@ -285,7 +299,7 @@ public class Water { case CA_FULLSCREEN_NORMALMAP: { // Draw quad over full display - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, dynamicTextureIDs[CA_TEXTURE_NORMAL_MAP]); gl.glCallList(displayListIDs[CA_DRAW_SCREEN_QUAD]); @@ -294,7 +308,7 @@ public class Water { case CA_FULLSCREEN_HEIGHT: { // Draw quad over full display - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, texHeightOutput); gl.glCallList(displayListIDs[CA_DRAW_SCREEN_QUAD]); @@ -303,7 +317,7 @@ public class Water { case CA_FULLSCREEN_FORCE: { // Draw quad over full display - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, dynamicTextureIDs[CA_TEXTURE_FORCE_TARGET]); gl.glCallList(displayListIDs[CA_DRAW_SCREEN_QUAD]); @@ -313,7 +327,7 @@ public class Water { case CA_TILED_THREE_WINDOWS: { // Draw quad over full display // lower left - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, dynamicTextureIDs[CA_TEXTURE_FORCE_TARGET]); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glPushMatrix(); @@ -408,14 +422,13 @@ public class Water { // class Listener implements GLEventListener { - public void init(GLDrawable drawable) { + public void init(GLAutoDrawable drawable) { GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); - initOpenGL(gl, glu); + initOpenGL(gl); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { GL gl = drawable.getGL(); if (mustUpdateBlurOffsets) { updateBlurVertOffset(gl); @@ -448,10 +461,10 @@ public class Water { } } - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} // Unused routines - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } private TGAImage loadImage(String resourceName) { @@ -474,7 +487,7 @@ public class Water { initialMapDimensions[1] = initialMap.getHeight(); } - private void initOpenGL(GL gl, GLU glu) { + private void initOpenGL(GL gl) { loadTextures(gl, tmpSpinFilename, tmpDropletFilename, tmpCubeMapFilenamePattern); tmpSpinFilename = null; tmpDropletFilename = null; @@ -501,7 +514,7 @@ public class Water { /////////////////////////////////////////////////////////////////////////// int[] tmpInt = new int[1]; - gl.glGenProgramsARB(1, tmpInt); + gl.glGenProgramsARB(1, tmpInt, 0); vertexProgramID = tmpInt[0]; gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, vertexProgramID); @@ -581,7 +594,7 @@ public class Water { // set up constants (not currently used in the vertex program, though) float[] rCVConsts = new float[] { 0, 0.5f, 1.0f, 2.0f }; - gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_CONSTS_1, rCVConsts); + gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_CONSTS_1, rCVConsts, 0); loadProgram(gl, GL.GL_VERTEX_PROGRAM_ARB, programBuffer); @@ -668,7 +681,7 @@ public class Water { gl.glClear(GL.GL_COLOR_BUFFER_BIT); // Now we need to copy the resulting pixels into the intermediate force field texture - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, texVelocityInput); // use CopyTexSubImage for speed (even though we copy all of it) since we pre-allocated the texture @@ -713,7 +726,7 @@ public class Water { // set current source texture for stage 0 texture for (int i = 0; i < 4; i++) { - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB + i); + gl.glActiveTexture(GL.GL_TEXTURE0 + i); gl.glBindTexture(GL.GL_TEXTURE_2D, texHeightInput); gl.glEnable(GL.GL_TEXTURE_2D); } @@ -738,7 +751,7 @@ public class Water { gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB); // Now we need to copy the resulting pixels into the intermediate force field texture - gl.glActiveTextureARB(GL.GL_TEXTURE2_ARB); + gl.glActiveTexture(GL.GL_TEXTURE2); gl.glBindTexture(GL.GL_TEXTURE_2D, dynamicTextureIDs[CA_TEXTURE_FORCE_INTERMEDIATE]); // use CopyTexSubImage for speed (even though we copy all of it) since we pre-allocated the texture @@ -767,7 +780,7 @@ public class Water { gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, wrapMode); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapMode); - gl.glActiveTextureARB(GL.GL_TEXTURE3_ARB); + gl.glActiveTexture(GL.GL_TEXTURE3); gl.glDisable(GL.GL_TEXTURE_2D); // vertex program already bound. @@ -780,7 +793,7 @@ public class Water { gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB); // Now we need to copy the resulting pixels into the intermediate force field texture - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); gl.glBindTexture(GL.GL_TEXTURE_2D, dynamicTextureIDs[CA_TEXTURE_FORCE_TARGET]); // use CopyTexSubImage for speed (even though we copy all of it) since we pre-allocated the texture @@ -797,13 +810,13 @@ public class Water { // bind the vertex program to be used for this step and the next one. - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, texVelocityInput); - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); gl.glBindTexture(GL.GL_TEXTURE_2D, dynamicTextureIDs[CA_TEXTURE_FORCE_TARGET]); - gl.glActiveTextureARB(GL.GL_TEXTURE2_ARB); + gl.glActiveTexture(GL.GL_TEXTURE2); gl.glDisable(GL.GL_TEXTURE_2D); - gl.glActiveTextureARB(GL.GL_TEXTURE3_ARB); + gl.glActiveTexture(GL.GL_TEXTURE3); gl.glDisable(GL.GL_TEXTURE_2D); // Draw the quad to add in force. @@ -832,7 +845,7 @@ public class Water { } // Now we need to copy the resulting pixels into the velocity texture - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); gl.glBindTexture(GL.GL_TEXTURE_2D, texVelocityOutput); // use CopyTexSubImage for speed (even though we copy all of it) since we pre-allocated the texture @@ -843,9 +856,9 @@ public class Water { gl.glCallList(displayListIDs[CA_FRAGMENT_PROGRAM_APPLY_VELOCITY]); gl.glEnable(GL.GL_VERTEX_PROGRAM_ARB); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, texHeightInput); - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); // velocity output already bound + gl.glActiveTexture(GL.GL_TEXTURE1); // velocity output already bound gl.glEnable(GL.GL_TEXTURE_2D); // use offsets of zero @@ -857,7 +870,7 @@ public class Water { gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB); // Now we need to copy the resulting pixels into the input height texture - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, texHeightInput); // use CopyTexSubImage for speed (even though we copy all of it) since we pre-allocated the texture @@ -869,7 +882,7 @@ public class Water { // offsets with bilinear on for (int i = 1; i < 4; i++) { - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB + i); + gl.glActiveTexture(GL.GL_TEXTURE0 + i); gl.glBindTexture(GL.GL_TEXTURE_2D, texHeightInput); gl.glEnable(GL.GL_TEXTURE_2D); } @@ -889,7 +902,7 @@ public class Water { } // Now we need to copy the resulting pixels into the velocity texture - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, texHeightOutput); // use CopyTexSubImage for speed (even though we copy all of it) since we pre-allocated the texture @@ -920,7 +933,7 @@ public class Water { private void createNormalMap(GL gl) { // use the height output on all four texture stages for (int i = 0; i < 4; i++) { - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB + i); + gl.glActiveTexture(GL.GL_TEXTURE0 + i); gl.glBindTexture(GL.GL_TEXTURE_2D, texHeightOutput); gl.glEnable(GL.GL_TEXTURE_2D); } @@ -929,12 +942,12 @@ public class Water { // Red mask first float[] pixMasks = new float[] { normalSTScale, 0.0f, 0.0f, 0.0f }; - gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 0, pixMasks); + gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 0, pixMasks, 0); // Now green mask & scale: pixMasks[0] = 0.0f; pixMasks[1] = normalSTScale; - gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 1, pixMasks); + gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 1, pixMasks, 0); gl.glCallList(displayListIDs[CA_FRAGMENT_PROGRAM_CREATE_NORMAL_MAP]); @@ -947,7 +960,7 @@ public class Water { gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB); // Now we need to copy the resulting pixels into the normal map - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, dynamicTextureIDs[CA_TEXTURE_NORMAL_MAP]); // use CopyTexSubImage for speed (even though we copy all of it) since we pre-allocated the texture @@ -957,7 +970,7 @@ public class Water { private void drawInteriorBoundaryObjects(GL gl) { gl.glDisable(GL.GL_REGISTER_COMBINERS_NV); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, staticTextureIDs[CA_TEXTURE_INITIAL_MAP]); gl.glEnable(GL.GL_TEXTURE_2D); @@ -965,7 +978,7 @@ public class Water { // disable other texture units. for (int i = 1; i < 4; i++) { - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB + i); + gl.glActiveTexture(GL.GL_TEXTURE0 + i); gl.glDisable(GL.GL_TEXTURE_2D); } @@ -975,7 +988,7 @@ public class Water { gl.glCallList(displayListIDs[CA_DRAW_SCREEN_QUAD]); if (spinLogo) { - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, staticTextureIDs[CA_TEXTURE_SPIN]); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glPushMatrix(); @@ -1002,7 +1015,7 @@ public class Water { 0, image.getGLFormat(), GL.GL_UNSIGNED_BYTE, - image.getData()); + ByteBuffer.wrap(image.getData())); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); @@ -1010,27 +1023,27 @@ public class Water { } private void loadCubeMap(GL gl, int id, String filenamePattern, boolean mipmap) { - int[] faces = new int[] { GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, - GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, - GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB }; + int[] faces = new int[] { GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; String[] faceNames = new String[] { "posx", "negx", "posy", "negy", "posz", "negz" }; // create and bind a cubemap texture object - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, id); + gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, id); // enable automipmap generation if needed. - gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_GENERATE_MIPMAP_SGIS, (mipmap ? 1 : 0)); + gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_GENERATE_MIPMAP_SGIS, (mipmap ? 1 : 0)); if (mipmap) - gl.glTexParameterf(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); + gl.glTexParameterf(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); else - gl.glTexParameterf(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); - gl.glTexParameterf(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); - gl.glTexParameterf(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); - gl.glTexParameterf(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); + gl.glTexParameterf(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); + gl.glTexParameterf(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); + gl.glTexParameterf(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); + gl.glTexParameterf(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); // load 6 faces. MessageFormat fmt = new MessageFormat(filenamePattern); @@ -1045,7 +1058,7 @@ public class Water { 0, image.getGLFormat(), GL.GL_UNSIGNED_BYTE, - image.getData()); + ByteBuffer.wrap(image.getData())); } } @@ -1060,8 +1073,8 @@ public class Water { TGAImage spin = loadImage(spinFilename); TGAImage droplet = loadImage(dropletFilename); - gl.glGenTextures(CA_NUM_STATIC_TEXTURES, staticTextureIDs); - gl.glGenTextures(CA_NUM_DYNAMIC_TEXTURES, dynamicTextureIDs); // also create intermediate texture object + gl.glGenTextures(CA_NUM_STATIC_TEXTURES, staticTextureIDs, 0); + gl.glGenTextures(CA_NUM_DYNAMIC_TEXTURES, dynamicTextureIDs, 0); // also create intermediate texture object // upload the initial map texture createTextureObject(gl, staticTextureIDs[CA_TEXTURE_INITIAL_MAP], initialMap, true); @@ -1147,10 +1160,10 @@ public class Water { float type2Offset[] = { type2OffsetX[i], type2OffsetY[i], 0.0f, 0.0f }; float type4Offset[] = { type4OffsetX[i], type4OffsetY[i], 0.0f, 0.0f }; - gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_UV_T0_NO_OFFSET + 5 * i, noOffset); - gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_UV_T0_TYPE1 + 5 * i, type1Offset); - gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_UV_T0_TYPE2 + 5 * i, type2Offset); - gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_UV_T0_TYPE4 + 5 * i, type4Offset); + gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_UV_T0_NO_OFFSET + 5 * i, noOffset, 0); + gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_UV_T0_TYPE1 + 5 * i, type1Offset, 0); + gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_UV_T0_TYPE2 + 5 * i, type2Offset, 0); + gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_UV_T0_TYPE4 + 5 * i, type4Offset, 0); } } @@ -1170,7 +1183,7 @@ public class Water { for (int i = 0; i < 4; ++i) { offsets[0] = blurDist * ( type3OffsetX[i]); offsets[1] = blurDist * ( type3OffsetY[i]); - gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_UV_T0_TYPE3 + 5 * i, offsets); + gl.glProgramEnvParameter4fvARB(GL.GL_VERTEX_PROGRAM_ARB, CV_UV_T0_TYPE3 + 5 * i, offsets, 0); } } @@ -1178,11 +1191,11 @@ public class Water { gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB); gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); + gl.glActiveTexture(GL.GL_TEXTURE0); gl.glBindTexture(GL.GL_TEXTURE_2D, staticTextureIDs[CA_TEXTURE_DROPLET]); gl.glEnable(GL.GL_TEXTURE_2D); - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); gl.glDisable(GL.GL_TEXTURE_2D); gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE); @@ -1254,7 +1267,7 @@ public class Water { float[] const0 = new float[] { 0.5f, 0.5f, 0.5f, 1.0f }; int[] tmpInt = new int[1]; - gl.glGenProgramsARB(1, tmpInt); + gl.glGenProgramsARB(1, tmpInt, 0); int fragProg = tmpInt[0]; gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); @@ -1281,7 +1294,7 @@ public class Water { loadProgram(gl, GL.GL_FRAGMENT_PROGRAM_ARB, program); gl.glNewList(displayListID, GL.GL_COMPILE); - gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 0, const0); + gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 0, const0, 0); gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB); gl.glEndList(); @@ -1381,7 +1394,7 @@ public class Water { float[] const0 = new float[] { 0.5f, 0.5f, 0.5f, 1.0f }; int[] tmpInt = new int[1]; - gl.glGenProgramsARB(1, tmpInt); + gl.glGenProgramsARB(1, tmpInt, 0); int fragProg = tmpInt[0]; gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); @@ -1425,7 +1438,7 @@ public class Water { loadProgram(gl, GL.GL_FRAGMENT_PROGRAM_ARB, program); gl.glNewList(displayListID, GL.GL_COMPILE); - gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 0, const0); + gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 0, const0, 0); gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB); gl.glEndList(); @@ -1468,7 +1481,7 @@ public class Water { // } int[] tmpInt = new int[1]; - gl.glGenProgramsARB(1, tmpInt); + gl.glGenProgramsARB(1, tmpInt, 0); int fragProg = tmpInt[0]; gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); @@ -1540,7 +1553,7 @@ public class Water { float[] const1 = new float[] { 0.5f, 0.5f, 0.5f, 1.0f }; int[] tmpInt = new int[1]; - gl.glGenProgramsARB(1, tmpInt); + gl.glGenProgramsARB(1, tmpInt, 0); int fragProg = tmpInt[0]; gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); @@ -1566,8 +1579,8 @@ public class Water { loadProgram(gl, GL.GL_FRAGMENT_PROGRAM_ARB, program); gl.glNewList(displayListID, GL.GL_COMPILE); - gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 0, const0); - gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 1, const1); + gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 0, const0, 0); + gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 1, const1, 0); gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB); gl.glEndList(); @@ -1619,7 +1632,7 @@ public class Water { float[] const0 = new float[] { 0.5f, 0.5f, 0.5f, 1.0f }; int[] tmpInt = new int[1]; - gl.glGenProgramsARB(1, tmpInt); + gl.glGenProgramsARB(1, tmpInt, 0); int fragProg = tmpInt[0]; gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); @@ -1644,7 +1657,7 @@ public class Water { loadProgram(gl, GL.GL_FRAGMENT_PROGRAM_ARB, program); gl.glNewList(displayListID, GL.GL_COMPILE); - gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 0, const0); + gl.glProgramEnvParameter4fvARB(GL.GL_FRAGMENT_PROGRAM_ARB, 0, const0, 0); gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB); gl.glEndList(); @@ -1736,7 +1749,7 @@ public class Water { float[] const0 = new float[] { 0.5f, 0.5f, 0.5f, 1.0f }; int[] tmpInt = new int[1]; - gl.glGenProgramsARB(1, tmpInt); + gl.glGenProgramsARB(1, tmpInt, 0); int fragProg = tmpInt[0]; gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); @@ -1811,7 +1824,7 @@ public class Water { // of a visual difference so they are skipped as well. int[] tmpInt = new int[1]; - gl.glGenProgramsARB(1, tmpInt); + gl.glGenProgramsARB(1, tmpInt, 0); int fragProg = tmpInt[0]; gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); @@ -1848,7 +1861,7 @@ public class Water { String programBuffer) { gl.glProgramStringARB(target, GL.GL_PROGRAM_FORMAT_ASCII_ARB, programBuffer.length(), programBuffer); int[] errPos = new int[1]; - gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos); + gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos, 0); if (errPos[0] >= 0) { String kind = "Program"; if (target == GL.GL_VERTEX_PROGRAM_ARB) { @@ -1875,7 +1888,7 @@ public class Water { int[] isNative = new int[1]; gl.glGetProgramivARB(GL.GL_FRAGMENT_PROGRAM_ARB, GL.GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB, - isNative); + isNative, 0); if (isNative[0] != 1) { System.out.println("WARNING: fragment program is over native resource limits"); Thread.dumpStack(); diff --git a/src/demos/tess/Tess.java b/src/demos/tess/Tess.java index ccbd7a6..d4c9729 100644 --- a/src/demos/tess/Tess.java +++ b/src/demos/tess/Tess.java @@ -58,7 +58,9 @@ package demos.tess; * @author Ported by Nathan Parker Burg, July 2003 */ -import net.java.games.jogl.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; import java.awt.*; import java.awt.event.WindowAdapter; @@ -97,14 +99,13 @@ public class Tess { public static class TessRenderer implements GLEventListener { private GL gl; - private GLU glu; + private GLU glu = new GLU(); private int startList; - public void init(GLDrawable drawable) { + public void init(GLAutoDrawable drawable) { drawable.setGL(new DebugGL(drawable.getGL())); gl = drawable.getGL(); - glu = drawable.getGLU(); double[][] rect = new double[][]{{50.0, 50.0, 0.0}, {200.0, 50.0, 0.0}, @@ -122,7 +123,7 @@ public class Tess { gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); startList = gl.glGenLists(2); - GLUtesselator tobj = glu.gluNewTess(); + GLUtessellator tobj = glu.gluNewTess(); TessCallback tessCallback = new TessCallback(gl, glu); @@ -135,15 +136,15 @@ public class Tess { gl.glShadeModel(GL.GL_FLAT); glu.gluTessBeginPolygon(tobj, null); glu.gluTessBeginContour(tobj); - glu.gluTessVertex(tobj, rect[0], rect[0]); - glu.gluTessVertex(tobj, rect[1], rect[1]); - glu.gluTessVertex(tobj, rect[2], rect[2]); - glu.gluTessVertex(tobj, rect[3], rect[3]); + glu.gluTessVertex(tobj, rect[0], 0, rect[0]); + glu.gluTessVertex(tobj, rect[1], 0, rect[1]); + glu.gluTessVertex(tobj, rect[2], 0, rect[2]); + glu.gluTessVertex(tobj, rect[3], 0, rect[3]); glu.gluTessEndContour(tobj); glu.gluTessBeginContour(tobj); - glu.gluTessVertex(tobj, tri[0], tri[0]); - glu.gluTessVertex(tobj, tri[1], tri[1]); - glu.gluTessVertex(tobj, tri[2], tri[2]); + glu.gluTessVertex(tobj, tri[0], 0, tri[0]); + glu.gluTessVertex(tobj, tri[1], 0, tri[1]); + glu.gluTessVertex(tobj, tri[2], 0, tri[2]); glu.gluTessEndContour(tobj); glu.gluTessEndPolygon(tobj); gl.glEndList(); @@ -159,11 +160,11 @@ public class Tess { glu.gluTessProperty(tobj, GLU.GLU_TESS_WINDING_RULE, GLU.GLU_TESS_WINDING_POSITIVE); glu.gluTessBeginPolygon(tobj, null); glu.gluTessBeginContour(tobj); - glu.gluTessVertex(tobj, star[0], star[0]); - glu.gluTessVertex(tobj, star[1], star[1]); - glu.gluTessVertex(tobj, star[2], star[2]); - glu.gluTessVertex(tobj, star[3], star[3]); - glu.gluTessVertex(tobj, star[4], star[4]); + glu.gluTessVertex(tobj, star[0], 0, star[0]); + glu.gluTessVertex(tobj, star[1], 0, star[1]); + glu.gluTessVertex(tobj, star[2], 0, star[2]); + glu.gluTessVertex(tobj, star[3], 0, star[3]); + glu.gluTessVertex(tobj, star[4], 0, star[4]); glu.gluTessEndContour(tobj); glu.gluTessEndPolygon(tobj); gl.glEndList(); @@ -171,7 +172,7 @@ public class Tess { }//end init - public void reshape(GLDrawable drawable, int x, int y, int width, int height) { + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho( 0, 450, 0, 250, -1, 1 ); @@ -179,10 +180,10 @@ public class Tess { gl.glLoadIdentity(); } - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { gl.glClear(GL.GL_COLOR_BUFFER_BIT); gl.glColor3d(1.0, 1.0, 1.0); gl.glCallList(startList); @@ -193,7 +194,7 @@ public class Tess { }//end TessRenderer - public static class TessCallback extends net.java.games.jogl.GLUtesselatorCallbackAdapter { + public static class TessCallback extends javax.media.opengl.glu.GLUtessellatorCallbackAdapter { GL gl; GLU glu; @@ -213,13 +214,9 @@ public class Tess { if (data instanceof double[]) { double[] d = (double[]) data; if (d.length == 6) { - double[] d2 = {d[0], d[1], d[2]}; - gl.glVertex3dv(d2); - d2 = new double[]{d[3], d[4], d[5]}; - gl.glColor3dv(d2); - } else if (d.length == 3) { - gl.glVertex3dv(d); + gl.glColor3dv(d, 3); } + gl.glVertex3dv(d, 0); } } diff --git a/src/demos/testContextDestruction/TestContextDestruction.java b/src/demos/testContextDestruction/TestContextDestruction.java index bfc0801..86652bb 100755 --- a/src/demos/testContextDestruction/TestContextDestruction.java +++ b/src/demos/testContextDestruction/TestContextDestruction.java @@ -44,7 +44,8 @@ import java.awt.event.*; import java.util.*; import javax.swing.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** A simple demonstration exercising context creation and destruction as a GLCanvas is added to and removed from its parent container. */ @@ -176,14 +177,14 @@ public class TestContextDestruction { } class Listener implements GLEventListener { - public void init(GLDrawable drawable) { + public void init(GLAutoDrawable drawable) { System.out.println("Listener.init()"); drawable.setGL(new DebugGL(drawable.getGL())); GL gl = drawable.getGL(); float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos, 0); gl.glEnable(GL.GL_CULL_FACE); gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_LIGHT0); @@ -193,11 +194,10 @@ public class TestContextDestruction { gl.glEnable(GL.GL_NORMALIZE); - Dimension d = drawable.getSize(); - reshape(drawable, 0, 0, d.width, d.height); + reshape(drawable, 0, 0, drawable.getWidth(), drawable.getHeight()); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { angle += 2.0f; GL gl = drawable.getGL(); @@ -210,7 +210,7 @@ public class TestContextDestruction { gl.glPopMatrix(); } - public void reshape(GLDrawable drawable, int x, int y, int width, int height) { + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { System.out.println("Listener.reshape()"); GL gl = drawable.getGL(); @@ -224,7 +224,7 @@ public class TestContextDestruction { gl.glTranslatef(0.0f, 0.0f, -40.0f); } - public void destroy(GLDrawable drawable) { + public void destroy(GLAutoDrawable drawable) { System.out.println("Listener.destroy()"); GL gl = drawable.getGL(); gl.glDeleteLists(gearDisplayList, 1); @@ -232,14 +232,14 @@ public class TestContextDestruction { } // Unused routines - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } private synchronized void initializeDisplayList(GL gl) { gearDisplayList = gl.glGenLists(1); gl.glNewList(gearDisplayList, GL.GL_COMPILE); float red[] = { 0.8f, 0.1f, 0.0f, 1.0f }; - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red); + gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red, 0); gear(gl, 1.0f, 4.0f, 1.0f, 20, 0.7f); gl.glEndList(); } diff --git a/src/demos/testContextSharing/TestContextSharing.java b/src/demos/testContextSharing/TestContextSharing.java index 569fa50..c6d7552 100644 --- a/src/demos/testContextSharing/TestContextSharing.java +++ b/src/demos/testContextSharing/TestContextSharing.java @@ -42,7 +42,8 @@ package demos.testContextSharing; import java.awt.*; import java.util.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** A simple demonstration of sharing of display lists between drawables. */ @@ -62,7 +63,7 @@ public class TestContextSharing { frame1.setLayout(new BorderLayout()); frame1.add(canvas1, BorderLayout.CENTER); - GLCanvas canvas2 = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities(), canvas1); + GLCanvas canvas2 = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities(), null, canvas1.getContext(), null); canvas2.addGLEventListener(new Listener()); canvas2.setSize(256, 256); Frame frame2 = new Frame("Canvas 2"); @@ -96,13 +97,13 @@ public class TestContextSharing { } class Listener implements GLEventListener { - public void init(GLDrawable drawable) { + public void init(GLAutoDrawable drawable) { drawable.setGL(new DebugGL(drawable.getGL())); GL gl = drawable.getGL(); float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos, 0); gl.glEnable(GL.GL_CULL_FACE); gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_LIGHT0); @@ -113,7 +114,7 @@ public class TestContextSharing { gl.glEnable(GL.GL_NORMALIZE); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); @@ -122,7 +123,7 @@ public class TestContextSharing { gl.glCallList(gearDisplayList); } - public void reshape(GLDrawable drawable, int x, int y, int width, int height) { + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { GL gl = drawable.getGL(); float h = (float)height / (float)width; @@ -136,7 +137,7 @@ public class TestContextSharing { } // Unused routines - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } private synchronized void initializeDisplayList(GL gl) { @@ -147,7 +148,7 @@ public class TestContextSharing { gearDisplayList = gl.glGenLists(1); gl.glNewList(gearDisplayList, GL.GL_COMPILE); float red[] = { 0.8f, 0.1f, 0.0f, 1.0f }; - gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red); + gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT_AND_DIFFUSE, red, 0); gear(gl, 1.0f, 4.0f, 1.0f, 20, 0.7f); gl.glEndList(); } diff --git a/src/demos/util/Bunny.java b/src/demos/util/Bunny.java index fece8da..50033b2 100644 --- a/src/demos/util/Bunny.java +++ b/src/demos/util/Bunny.java @@ -41,7 +41,8 @@ package demos.util; import java.io.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** Renders a bunny. diff --git a/src/demos/util/ObjReader.java b/src/demos/util/ObjReader.java index f8a6cec..1204ed5 100644 --- a/src/demos/util/ObjReader.java +++ b/src/demos/util/ObjReader.java @@ -43,7 +43,7 @@ import java.io.*; import java.nio.*; import java.util.*; -import net.java.games.jogl.util.*; +import com.sun.opengl.utils.*; /** Simple parser for Wavefront .OBJ files. Does not support all file options -- currently requires vertices and normals (only) to be @@ -312,8 +312,10 @@ public class ObjReader { newIndices.trim(); vertices = BufferUtils.newFloatBuffer(newVertices.size()); vertices.put(newVertices.getData()); + vertices.rewind(); normals = BufferUtils.newFloatBuffer(newVertexNormals.size()); normals.put(newVertexNormals.getData()); + normals.rewind(); faceIndices = newIndices; tmpVertices = null; tmpVertexNormals = null; diff --git a/src/demos/util/SGIImage.java b/src/demos/util/SGIImage.java index bf0dda9..7d4468e 100644 --- a/src/demos/util/SGIImage.java +++ b/src/demos/util/SGIImage.java @@ -5,7 +5,8 @@ package demos.util; import java.io.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; // Test harness import java.awt.image.*; @@ -131,7 +132,7 @@ public class SGIImage { return header.ysize; } - /** Returns the OpenGL format for this texture; e.g. GL.GL_BGR_EXT or GL.GL_BGRA_EXT. */ + /** Returns the OpenGL format for this texture; e.g. GL.GL_BGR or GL.GL_BGRA. */ public int getFormat() { return format; } @@ -201,7 +202,7 @@ public class SGIImage { rowSize = null; tmpData = null; tmpRead = null; - format = GL.GL_BGRA_EXT; + format = GL.GL_BGRA; } private void getRow(byte[] buf, int y, int z) { diff --git a/src/demos/util/TGAImage.java b/src/demos/util/TGAImage.java index 24403eb..a99f4f3 100644 --- a/src/demos/util/TGAImage.java +++ b/src/demos/util/TGAImage.java @@ -40,7 +40,8 @@ package demos.util; import java.io.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** * Targa image reader adapted from sources of the <a href = @@ -271,10 +272,10 @@ public class TGAImage { data = new byte[rawWidth * header.height()]; if (header.pixelDepth() == 24) { - format = GL.GL_BGR_EXT; + format = GL.GL_BGR; } else { assert header.pixelDepth() == 32; - format = GL.GL_BGRA_EXT; + format = GL.GL_BGRA; } for (i = 0; i < header.height(); ++i) { @@ -295,7 +296,7 @@ public class TGAImage { /** Returns the height of the image. */ public int getHeight() { return header.height(); } - /** Returns the OpenGL format for this texture; e.g. GL.GL_BGR_EXT or GL.GL_BGRA_EXT. */ + /** Returns the OpenGL format for this texture; e.g. GL.GL_BGR or GL.GL_BGRA. */ public int getGLFormat() { return format; } /** Returns the raw data for this texture in the correct diff --git a/src/demos/util/Triceratops.java b/src/demos/util/Triceratops.java index e013f79..6256a0c 100644 --- a/src/demos/util/Triceratops.java +++ b/src/demos/util/Triceratops.java @@ -41,7 +41,8 @@ package demos.util; import java.io.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** Renders a triceratops. <P> diff --git a/src/demos/vertexArrayRange/VertexArrayRange.java b/src/demos/vertexArrayRange/VertexArrayRange.java index 5252f0e..60d2ba8 100644 --- a/src/demos/vertexArrayRange/VertexArrayRange.java +++ b/src/demos/vertexArrayRange/VertexArrayRange.java @@ -39,7 +39,12 @@ import java.nio.*; import java.util.*; import javax.swing.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; +import com.sun.opengl.utils.*; +import demos.common.*; +import demos.util.*; /** <P> A port of NVidia's [tm] Vertex Array Range demonstration to OpenGL[tm] for Java[tm] and the Java programming language. The @@ -72,7 +77,71 @@ import net.java.games.jogl.*; C++ speed with the HotSpot Client and Server compilers, respectively. </P> */ -public class VertexArrayRange { +public class VertexArrayRange extends Demo { + public static void main(String[] args) { + boolean startSlow = false; + + if (args.length > 1) { + usage(); + } + + if (args.length == 1) { + if (args[0].equals("-slow")) { + startSlow = true; + } else { + usage(); + } + } + + GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); + VertexArrayRange demo = new VertexArrayRange(); + if (startSlow) { + demo.setFlag('v', false); // VAR off + } + canvas.addGLEventListener(demo); + + final Animator animator = new Animator(canvas); + animator.setRunAsFastAsPossible(true); + demo.setDemoListener(new DemoListener() { + public void shutdownDemo() { + runExit(animator); + } + public void repaint() {} + }); + + Frame frame = new Frame("Very Simple NV_vertex_array_range demo"); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + runExit(animator); + } + }); + frame.setLayout(new BorderLayout()); + canvas.setSize(800, 800); + frame.add(canvas, BorderLayout.CENTER); + frame.pack(); + frame.show(); + canvas.requestFocus(); + + animator.start(); + } + + private static void usage() { + System.out.println("usage: java VertexArrayRange [-slow]"); + System.out.println("-slow flag starts up using data in the Java heap"); + System.exit(0); + } + + public VertexArrayRange() { + setFlag(' ', true); // animation on + setFlag('i', true); // infinite viewer and light + setFlag('v', true); // VAR on + } + + //---------------------------------------------------------------------- + // Internals only below this point + // + + private GLU glu = new GLU(); private boolean[] b = new boolean[256]; private static final int SIZEOF_FLOAT = 4; private static final int STRIP_SIZE = 48; @@ -85,7 +154,7 @@ public class VertexArrayRange { private FloatBuffer bigArrayVar; private FloatBuffer bigArraySystem; private FloatBuffer bigArray; - private int[][] elements; + private IntBuffer[] elements; private float[] xyArray; static class VarBuffer { @@ -122,7 +191,6 @@ public class VertexArrayRange { private volatile boolean toggleLighting = false; private volatile boolean toggleLightingModel = false; private volatile boolean recomputeElements = false; - private volatile boolean quit = false; // Frames-per-second computation private boolean firstProfiledFrame; @@ -130,9 +198,6 @@ public class VertexArrayRange { private int numDrawElementsCalls; private long startTimeMillis; - private GLCanvas canvas = null; - private Animator animator; - static class PeriodicIterator { public PeriodicIterator(int arraySize, float period, @@ -176,10 +241,6 @@ public class VertexArrayRange { index = initOffset; } - //---------------------------------------------------------------------- - // Internals only below this point - // - private int arraySizeMask; // fraction bits == 16 private int increment; @@ -187,72 +248,6 @@ public class VertexArrayRange { private int index; } - public static void usage(String className) { - System.out.println("usage: java " + className + " [-slow]"); - System.out.println("-slow flag starts up using data in the Java heap"); - System.exit(0); - } - - public static void main(String[] args) { - new VertexArrayRange().run(args); - } - - public void run(String[] args) { - boolean startSlow = false; - - if (args.length > 1) { - usage(getClass().getName()); - } - - if (args.length == 1) { - if (args[0].equals("-slow")) { - startSlow = true; - } else { - usage(getClass().getName()); - } - } - - if (!startSlow) { - setFlag('v', true); // VAR on - } - setFlag(' ', true); // animation on - setFlag('i', true); // infinite viewer and light - - canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); - VARListener listener = new VARListener(); - canvas.addGLEventListener(listener); - - animator = new Animator(canvas); - - Frame frame = new Frame("Very Simple NV_vertex_array_range demo"); - frame.setLayout(new BorderLayout()); - canvas.setSize(800, 800); - frame.add(canvas, BorderLayout.CENTER); - frame.pack(); - frame.show(); - canvas.requestFocus(); - - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - // Run this on another thread than the AWT event queue to - // make sure the call to Animator.stop() completes before - // exiting - new Thread(new Runnable() { - public void run() { - animator.stop(); - System.exit(0); - } - }).start(); - } - }); - - animator.start(); - } - - //---------------------------------------------------------------------- - // Internals only below this point - // - private void setFlag(char key, boolean val) { b[((int) key) & 0xFF] = val; } @@ -261,403 +256,393 @@ public class VertexArrayRange { return b[((int) key) & 0xFF]; } - private void ensurePresent(String function) { - if (!canvas.getGL().isFunctionAvailable(function)) { + private void ensurePresent(GL gl, String function) { + if (!gl.isFunctionAvailable(function)) { final String message = "OpenGL routine \"" + function + "\" not available"; new Thread(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); - runExit(); + shutdownDemo(); } }).start(); throw new RuntimeException(message); } } - class VARListener implements GLEventListener { - boolean exiting = false; + public void init(GLAutoDrawable drawable) { + // drawable.setGL(new TraceGL(drawable.getGL(), System.err)); + // drawable.setGL(new DebugGL(drawable.getGL())); - public void init(GLDrawable drawable) { - // drawable.setGL(new TraceGL(drawable.getGL(), System.err)); - // drawable.setGL(new DebugGL(drawable.getGL())); + GL gl = drawable.getGL(); - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); + // Try and disable synch-to-retrace for fastest framerate + gl.setSwapInterval(0); - // Try and disable synch-to-retrace for fastest framerate - gl.setSwapInterval(0); - - try { - ensurePresent("glVertexArrayRangeNV"); - ensurePresent("glGenFencesNV"); - ensurePresent("glSetFenceNV"); - ensurePresent("glTestFenceNV"); - ensurePresent("glFinishFenceNV"); - ensurePresent("glAllocateMemoryNV"); - } catch (RuntimeException e) { - quit = true; - throw (e); - } + try { + ensurePresent(gl, "glVertexArrayRangeNV"); + ensurePresent(gl, "glGenFencesNV"); + ensurePresent(gl, "glSetFenceNV"); + ensurePresent(gl, "glTestFenceNV"); + ensurePresent(gl, "glFinishFenceNV"); + ensurePresent(gl, "glAllocateMemoryNV"); + } catch (RuntimeException e) { + shutdownDemo(); + throw (e); + } - gl.glEnable(GL.GL_DEPTH_TEST); - - gl.glClearColor(0, 0, 0, 0); - - gl.glEnable(GL.GL_LIGHT0); - gl.glEnable(GL.GL_LIGHTING); - gl.glEnable(GL.GL_NORMALIZE); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, new float[] {.1f, .1f, 0, 1}); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, new float[] {.6f, .6f, .1f, 1}); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, new float[] { 1, 1, .75f, 1}); - gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, 128.f); - - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, .5f, 0}); - gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 0); - - // NOTE: it looks like GLUT (or something else) sets up the - // projection matrix in the C version of this demo. - gl.glMatrixMode(GL.GL_PROJECTION); - gl.glLoadIdentity(); - glu.gluPerspective(60, 1.0, 0.1, 100); - gl.glMatrixMode(GL.GL_MODELVIEW); - - allocateBigArray(gl, true); - allocateBuffersAndFences(gl); - - sinArray = new float[SIN_ARRAY_SIZE]; - cosArray = new float[SIN_ARRAY_SIZE]; - - for (int i = 0; i < SIN_ARRAY_SIZE; i++) { - double step = i * 2 * Math.PI / SIN_ARRAY_SIZE; - sinArray[i] = (float) Math.sin(step); - cosArray[i] = (float) Math.cos(step); - } + gl.glEnable(GL.GL_DEPTH_TEST); + + gl.glClearColor(0, 0, 0, 0); + + gl.glEnable(GL.GL_LIGHT0); + gl.glEnable(GL.GL_LIGHTING); + gl.glEnable(GL.GL_NORMALIZE); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, new float[] {.1f, .1f, 0, 1}, 0); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, new float[] {.6f, .6f, .1f, 1}, 0); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, new float[] { 1, 1, .75f, 1}, 0); + gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, 128.f); + + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, .5f, 0}, 0); + gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 0); + + // NOTE: it looks like GLUT (or something else) sets up the + // projection matrix in the C version of this demo. + gl.glMatrixMode(GL.GL_PROJECTION); + gl.glLoadIdentity(); + glu.gluPerspective(60, 1.0, 0.1, 100); + gl.glMatrixMode(GL.GL_MODELVIEW); + + allocateBigArray(gl, true); + allocateBuffersAndFences(gl); + + sinArray = new float[SIN_ARRAY_SIZE]; + cosArray = new float[SIN_ARRAY_SIZE]; + + for (int i = 0; i < SIN_ARRAY_SIZE; i++) { + double step = i * 2 * Math.PI / SIN_ARRAY_SIZE; + sinArray[i] = (float) Math.sin(step); + cosArray[i] = (float) Math.cos(step); + } - if (getFlag('v')) { - gl.glEnableClientState(GL.GL_VERTEX_ARRAY_RANGE_NV); - gl.glVertexArrayRangeNV(bufferSize, bigArrayVar); - bigArray = bigArrayVar; - } else { - bigArray = bigArraySystem; - } - setupBuffers(); - gl.glEnableClientState(GL.GL_VERTEX_ARRAY); - gl.glEnableClientState(GL.GL_NORMAL_ARRAY); + if (getFlag('v')) { + gl.glEnableClientState(GL.GL_VERTEX_ARRAY_RANGE_NV); + gl.glVertexArrayRangeNV(bufferSize, bigArrayVar); + bigArray = bigArrayVar; + } else { + bigArray = bigArraySystem; + } + setupBuffers(); + gl.glEnableClientState(GL.GL_VERTEX_ARRAY); + gl.glEnableClientState(GL.GL_NORMAL_ARRAY); - computeElements(); + computeElements(); - drawable.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { - dispatchKey(e.getKeyChar()); - } - }); - } + drawable.addKeyListener(new KeyAdapter() { + public void keyTyped(KeyEvent e) { + dispatchKey(e.getKeyChar()); + } + }); + } - private void allocateBuffersAndFences(GL gl) { - buffers = new VarBuffer[numBuffers]; - int[] fences = new int[1]; - for (int i = 0; i < numBuffers; i++) { - buffers[i] = new VarBuffer(); - gl.glGenFencesNV(1, fences); - buffers[i].fence = fences[0]; - } + private void allocateBuffersAndFences(GL gl) { + buffers = new VarBuffer[numBuffers]; + int[] fences = new int[1]; + for (int i = 0; i < numBuffers; i++) { + buffers[i] = new VarBuffer(); + gl.glGenFencesNV(1, fences, 0); + buffers[i].fence = fences[0]; } + } - private void setupBuffers() { - int sliceSize = bufferLength / numBuffers; - for (int i = 0; i < numBuffers; i++) { - int startIndex = i * sliceSize; - buffers[i].vertices = sliceBuffer(bigArray, startIndex, sliceSize); - buffers[i].normals = sliceBuffer(buffers[i].vertices, 3, - buffers[i].vertices.limit() - 3); - } + private void setupBuffers() { + int sliceSize = bufferLength / numBuffers; + for (int i = 0; i < numBuffers; i++) { + int startIndex = i * sliceSize; + buffers[i].vertices = sliceBuffer(bigArray, startIndex, sliceSize); + buffers[i].normals = sliceBuffer(buffers[i].vertices, 3, + buffers[i].vertices.limit() - 3); } + } - private void dispatchKey(char k) { - setFlag(k, !getFlag(k)); - // Quit on escape or 'q' - if ((k == (char) 27) || (k == 'q')) { - runExit(); - } - - if (k == 'r') { - if (getFlag(k)) { - profiledFrameCount = 0; - numDrawElementsCalls = 0; - firstProfiledFrame = true; - } - } + private void dispatchKey(char k) { + setFlag(k, !getFlag(k)); + // Quit on escape or 'q' + if ((k == (char) 27) || (k == 'q')) { + shutdownDemo(); + return; + } - if (k == 'w') { - if (getFlag(k)) { - primitive = GL.GL_LINE_STRIP; - } else { - primitive = GL.GL_QUAD_STRIP; - } + if (k == 'r') { + if (getFlag(k)) { + profiledFrameCount = 0; + numDrawElementsCalls = 0; + firstProfiledFrame = true; } + } - if (k == 'p') { - if (getFlag(k)) { - primitive = GL.GL_POINTS; - } else { - primitive = GL.GL_QUAD_STRIP; - } + if (k == 'w') { + if (getFlag(k)) { + primitive = GL.GL_LINE_STRIP; + } else { + primitive = GL.GL_QUAD_STRIP; } + } - if (k == 'v') { - toggleVAR = true; + if (k == 'p') { + if (getFlag(k)) { + primitive = GL.GL_POINTS; + } else { + primitive = GL.GL_QUAD_STRIP; } + } - if (k == 'd') { - toggleLighting = true; - } + if (k == 'v') { + toggleVAR = true; + } - if (k == 'i') { - toggleLightingModel = true; - } + if (k == 'd') { + toggleLighting = true; + } - if('h'==k) - hicoef += .005; - if('H'==k) - hicoef -= .005; - if('l'==k) - locoef += .005; - if('L'==k) - locoef -= .005; - if('1'==k) - lofreq += .1f; - if('2'==k) - lofreq -= .1f; - if('3'==k) - hifreq += .1f; - if('4'==k) - hifreq -= .1f; - if('5'==k) - phaseRate += .01f; - if('6'==k) - phaseRate -= .01f; - if('7'==k) - phase2Rate += .01f; - if('8'==k) - phase2Rate -= .01f; - - if('t'==k) { - if(tileSize < 864) { - tileSize += STRIP_SIZE; - recomputeElements = true; - System.err.println("tileSize = " + tileSize); - } - } + if (k == 'i') { + toggleLightingModel = true; + } - if('T'==k) { - if(tileSize > STRIP_SIZE) { - tileSize -= STRIP_SIZE; - recomputeElements = true; - System.err.println("tileSize = " + tileSize); - } + if('h'==k) + hicoef += .005; + if('H'==k) + hicoef -= .005; + if('l'==k) + locoef += .005; + if('L'==k) + locoef -= .005; + if('1'==k) + lofreq += .1f; + if('2'==k) + lofreq -= .1f; + if('3'==k) + hifreq += .1f; + if('4'==k) + hifreq -= .1f; + if('5'==k) + phaseRate += .01f; + if('6'==k) + phaseRate -= .01f; + if('7'==k) + phase2Rate += .01f; + if('8'==k) + phase2Rate -= .01f; + + if('t'==k) { + if(tileSize < 864) { + tileSize += STRIP_SIZE; + recomputeElements = true; + System.err.println("tileSize = " + tileSize); } } - public void display(GLDrawable drawable) { - // Don't try to do OpenGL operations if we're tearing things down - if (quit) { - return; + if('T'==k) { + if(tileSize > STRIP_SIZE) { + tileSize -= STRIP_SIZE; + recomputeElements = true; + System.err.println("tileSize = " + tileSize); } + } + } - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); - - // Check to see whether to animate - if (getFlag(' ')) { - phase += phaseRate; - phase2 += phase2Rate; + public void display(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); - if (phase > (float) (20 * Math.PI)) { - phase = 0; - } + // Check to see whether to animate + if (getFlag(' ')) { + phase += phaseRate; + phase2 += phase2Rate; - if (phase2 < (float) (-20 * Math.PI)) { - phase2 = 0; - } + if (phase > (float) (20 * Math.PI)) { + phase = 0; } - PeriodicIterator loX = - new PeriodicIterator(SIN_ARRAY_SIZE, (float) (2 * Math.PI), phase, (float) ((1.f/tileSize)*lofreq*Math.PI)); - PeriodicIterator loY = new PeriodicIterator(loX); - PeriodicIterator hiX = - new PeriodicIterator(SIN_ARRAY_SIZE, (float) (2 * Math.PI), phase2, (float) ((1.f/tileSize)*hifreq*Math.PI)); - PeriodicIterator hiY = new PeriodicIterator(hiX); - - if (toggleVAR) { - if (getFlag('v')) { - gl.glEnableClientState(GL.GL_VERTEX_ARRAY_RANGE_NV); - gl.glVertexArrayRangeNV(bufferSize, bigArrayVar); - bigArray = bigArrayVar; - } else { - gl.glDisableClientState(GL.GL_VERTEX_ARRAY_RANGE_NV); - bigArray = bigArraySystem; - } - toggleVAR = false; - setupBuffers(); + if (phase2 < (float) (-20 * Math.PI)) { + phase2 = 0; } + } - if (toggleLighting) { - if (getFlag('d')) { - gl.glDisable(GL.GL_LIGHTING); - } else { - gl.glEnable(GL.GL_LIGHTING); - } - toggleLighting = false; + PeriodicIterator loX = + new PeriodicIterator(SIN_ARRAY_SIZE, (float) (2 * Math.PI), phase, (float) ((1.f/tileSize)*lofreq*Math.PI)); + PeriodicIterator loY = new PeriodicIterator(loX); + PeriodicIterator hiX = + new PeriodicIterator(SIN_ARRAY_SIZE, (float) (2 * Math.PI), phase2, (float) ((1.f/tileSize)*hifreq*Math.PI)); + PeriodicIterator hiY = new PeriodicIterator(hiX); + + if (toggleVAR) { + if (getFlag('v')) { + gl.glEnableClientState(GL.GL_VERTEX_ARRAY_RANGE_NV); + gl.glVertexArrayRangeNV(bufferSize, bigArrayVar); + bigArray = bigArrayVar; + } else { + gl.glDisableClientState(GL.GL_VERTEX_ARRAY_RANGE_NV); + bigArray = bigArraySystem; } + toggleVAR = false; + setupBuffers(); + } - if (toggleLightingModel) { - if(getFlag('i')) { - // infinite light - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, .5f, 0 }); - gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 0); - } else { - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, -.5f,1 }); - gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 1); - } - toggleLightingModel = false; + if (toggleLighting) { + if (getFlag('d')) { + gl.glDisable(GL.GL_LIGHTING); + } else { + gl.glEnable(GL.GL_LIGHTING); } + toggleLighting = false; + } - if (recomputeElements) { - computeElements(); - recomputeElements = false; + if (toggleLightingModel) { + if(getFlag('i')) { + // infinite light + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, .5f, 0 }, 0); + gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 0); + } else { + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, -.5f, 1 }, 0); + gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 1); } + toggleLightingModel = false; + } - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + if (recomputeElements) { + computeElements(); + recomputeElements = false; + } - gl.glPushMatrix(); + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - final float[] modelViewMatrix = new float[] { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, -1, 1 - }; - gl.glLoadMatrixf(modelViewMatrix); + gl.glPushMatrix(); - // FIXME: add mouse interaction - // camera.apply_inverse_transform(); - // object.apply_transform(); + final float[] modelViewMatrix = new float[] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, -1, 1 + }; + gl.glLoadMatrixf(modelViewMatrix, 0); - int cur = 0; - int numSlabs = tileSize / STRIP_SIZE; + // FIXME: add mouse interaction + // camera.apply_inverse_transform(); + // object.apply_transform(); - for(int slab = numSlabs; --slab>=0; ) { - cur = slab % numBuffers; - if (slab >= numBuffers) { - if (!gl.glTestFenceNV(buffers[cur].fence)) { - gl.glFinishFenceNV(buffers[cur].fence); - } + int cur = 0; + int numSlabs = tileSize / STRIP_SIZE; + + for(int slab = numSlabs; --slab>=0; ) { + cur = slab % numBuffers; + if (slab >= numBuffers) { + if (!gl.glTestFenceNV(buffers[cur].fence)) { + gl.glFinishFenceNV(buffers[cur].fence); } + } - FloatBuffer v = buffers[cur].vertices; - int vertexIndex = 0; + FloatBuffer v = buffers[cur].vertices; + int vertexIndex = 0; - gl.glVertexPointer(3, GL.GL_FLOAT, 6 * SIZEOF_FLOAT, v); - gl.glNormalPointer(GL.GL_FLOAT, 6 * SIZEOF_FLOAT, buffers[cur].normals); + gl.glVertexPointer(3, GL.GL_FLOAT, 6 * SIZEOF_FLOAT, v); + gl.glNormalPointer(GL.GL_FLOAT, 6 * SIZEOF_FLOAT, buffers[cur].normals); - for(int jj=STRIP_SIZE; --jj>=0; ) { - ysinlo[jj] = sinArray[loY.getIndex()]; - ycoslo[jj] = cosArray[loY.getIndex()]; loY.incr(); - ysinhi[jj] = sinArray[hiY.getIndex()]; - ycoshi[jj] = cosArray[hiY.getIndex()]; hiY.incr(); - } - loY.decr(); - hiY.decr(); - - for(int i = tileSize; --i>=0; ) { - float x = xyArray[i]; - int loXIndex = loX.getIndex(); - int hiXIndex = hiX.getIndex(); - - int jOffset = (STRIP_SIZE-1)*slab; - float nx = locoef * -cosArray[loXIndex] + hicoef * -cosArray[hiXIndex]; - - // Help the HotSpot Client Compiler by hoisting loop - // invariant variables into locals. Note that this may be - // good practice for innermost loops anyway since under - // the new memory model operations like accidental - // synchronization may force any compiler to reload these - // fields from memory, destroying their ability to - // optimize. - float locoef_tmp = locoef; - float hicoef_tmp = hicoef; - float[] ysinlo_tmp = ysinlo; - float[] ysinhi_tmp = ysinhi; - float[] ycoslo_tmp = ycoslo; - float[] ycoshi_tmp = ycoshi; - float[] sinArray_tmp = sinArray; - float[] xyArray_tmp = xyArray; - - for(int j = STRIP_SIZE; --j>=0; ) { - float y; - - y = xyArray_tmp[j + jOffset]; - - float ny; - - v.put(vertexIndex, x); - v.put(vertexIndex + 1, y); - v.put(vertexIndex + 2, (locoef_tmp * (sinArray_tmp[loXIndex] + ysinlo_tmp[j]) + - hicoef_tmp * (sinArray_tmp[hiXIndex] + ysinhi_tmp[j]))); - v.put(vertexIndex + 3, nx); - ny = locoef_tmp * -ycoslo_tmp[j] + hicoef_tmp * -ycoshi_tmp[j]; - v.put(vertexIndex + 4, ny); - v.put(vertexIndex + 5, .15f); //.15f * (1.f - sqrt(nx * nx + ny * ny)); - vertexIndex += 6; - } - loX.incr(); - hiX.incr(); + for(int jj=STRIP_SIZE; --jj>=0; ) { + ysinlo[jj] = sinArray[loY.getIndex()]; + ycoslo[jj] = cosArray[loY.getIndex()]; loY.incr(); + ysinhi[jj] = sinArray[hiY.getIndex()]; + ycoshi[jj] = cosArray[hiY.getIndex()]; hiY.incr(); + } + loY.decr(); + hiY.decr(); + + for(int i = tileSize; --i>=0; ) { + float x = xyArray[i]; + int loXIndex = loX.getIndex(); + int hiXIndex = hiX.getIndex(); + + int jOffset = (STRIP_SIZE-1)*slab; + float nx = locoef * -cosArray[loXIndex] + hicoef * -cosArray[hiXIndex]; + + // Help the HotSpot Client Compiler by hoisting loop + // invariant variables into locals. Note that this may be + // good practice for innermost loops anyway since under + // the new memory model operations like accidental + // synchronization may force any compiler to reload these + // fields from memory, destroying their ability to + // optimize. + float locoef_tmp = locoef; + float hicoef_tmp = hicoef; + float[] ysinlo_tmp = ysinlo; + float[] ysinhi_tmp = ysinhi; + float[] ycoslo_tmp = ycoslo; + float[] ycoshi_tmp = ycoshi; + float[] sinArray_tmp = sinArray; + float[] xyArray_tmp = xyArray; + + for(int j = STRIP_SIZE; --j>=0; ) { + float y; + + y = xyArray_tmp[j + jOffset]; + + float ny; + + v.put(vertexIndex, x); + v.put(vertexIndex + 1, y); + v.put(vertexIndex + 2, (locoef_tmp * (sinArray_tmp[loXIndex] + ysinlo_tmp[j]) + + hicoef_tmp * (sinArray_tmp[hiXIndex] + ysinhi_tmp[j]))); + v.put(vertexIndex + 3, nx); + ny = locoef_tmp * -ycoslo_tmp[j] + hicoef_tmp * -ycoshi_tmp[j]; + v.put(vertexIndex + 4, ny); + v.put(vertexIndex + 5, .15f); //.15f * (1.f - sqrt(nx * nx + ny * ny)); + vertexIndex += 6; } - loX.reset(); - hiX.reset(); - - for (int i = 0; i < elements.length; i++) { - ++numDrawElementsCalls; - gl.glDrawElements(primitive, elements[i].length, GL.GL_UNSIGNED_INT, elements[i]); - if(getFlag('f')) { - gl.glFlush(); - } + loX.incr(); + hiX.incr(); + } + loX.reset(); + hiX.reset(); + + for (int i = 0; i < elements.length; i++) { + ++numDrawElementsCalls; + gl.glDrawElements(primitive, elements[i].capacity(), GL.GL_UNSIGNED_INT, elements[i]); + if(getFlag('f')) { + gl.glFlush(); } - - gl.glSetFenceNV(buffers[cur].fence, GL.GL_ALL_COMPLETED_NV); } - gl.glPopMatrix(); - - gl.glFinishFenceNV(buffers[cur].fence); - - if (getFlag('r')) { - if (!firstProfiledFrame) { - if (++profiledFrameCount == 30) { - long endTimeMillis = System.currentTimeMillis(); - double secs = (endTimeMillis - startTimeMillis) / 1000.0; - double fps = 30.0 / secs; - double ppf = tileSize * tileSize * 2; - double mpps = ppf * fps / 1000000.0; - System.err.println("fps: " + fps + " polys/frame: " + ppf + " million polys/sec: " + mpps + - " DrawElements calls/frame: " + (numDrawElementsCalls / 30)); - profiledFrameCount = 0; - numDrawElementsCalls = 0; - startTimeMillis = System.currentTimeMillis(); - } - } else { - startTimeMillis = System.currentTimeMillis(); - firstProfiledFrame = false; + gl.glSetFenceNV(buffers[cur].fence, GL.GL_ALL_COMPLETED_NV); + } + gl.glPopMatrix(); + + gl.glFinishFenceNV(buffers[cur].fence); + + if (getFlag('r')) { + if (!firstProfiledFrame) { + if (++profiledFrameCount == 30) { + long endTimeMillis = System.currentTimeMillis(); + double secs = (endTimeMillis - startTimeMillis) / 1000.0; + double fps = 30.0 / secs; + double ppf = tileSize * tileSize * 2; + double mpps = ppf * fps / 1000000.0; + System.err.println("fps: " + fps + " polys/frame: " + ppf + " million polys/sec: " + mpps + + " DrawElements calls/frame: " + (numDrawElementsCalls / 30)); + profiledFrameCount = 0; + numDrawElementsCalls = 0; + startTimeMillis = System.currentTimeMillis(); } + } else { + startTimeMillis = System.currentTimeMillis(); + firstProfiledFrame = false; + } } + } - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} - // Unused routines - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - } // end class VARListener + // Unused routines + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} private void allocateBigArray(GL gl, boolean tryAgain) { float priority = .5f; @@ -711,24 +696,22 @@ public class VertexArrayRange { xyArray[i] = i / (tileSize - 1.0f) - 0.5f; } - elements = new int[tileSize - 1][]; + elements = new IntBuffer[tileSize - 1]; for (int i = 0; i < tileSize - 1; i++) { - elements[i] = new int[2 * STRIP_SIZE]; + elements[i] = IntBuffer.allocate(2 * STRIP_SIZE); for (int j = 0; j < 2 * STRIP_SIZE; j += 2) { - elements[i][j] = i * STRIP_SIZE + (j / 2); - elements[i][j+1] = (i + 1) * STRIP_SIZE + (j / 2); + elements[i].put(j, i * STRIP_SIZE + (j / 2)); + elements[i].put(j+1, (i + 1) * STRIP_SIZE + (j / 2)); } } } - private void runExit() { - quit = true; + private static void runExit(final Animator animator) { // Note: calling System.exit() synchronously inside the draw, // reshape or init callbacks can lead to deadlocks on certain // platforms (in particular, X11) because the JAWT's locking // routines cause a global AWT lock to be grabbed. Run the - // exit routine in another thread and cause this one to - // terminate by throwing an exception out of it. + // exit routine in another thread. new Thread(new Runnable() { public void run() { animator.stop(); diff --git a/src/demos/vertexBufferObject/VertexBufferObject.java b/src/demos/vertexBufferObject/VertexBufferObject.java index 02bae92..ef485bd 100644 --- a/src/demos/vertexBufferObject/VertexBufferObject.java +++ b/src/demos/vertexBufferObject/VertexBufferObject.java @@ -39,8 +39,12 @@ import java.nio.*; import java.util.*; import javax.swing.*; -import net.java.games.jogl.*; -import net.java.games.jogl.util.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; +import com.sun.opengl.utils.*; +import demos.common.*; +import demos.util.*; /** <P> A port of NVidia's [tm] Vertex Array Range demonstration to OpenGL[tm] for Java[tm], the Java programming language, and the @@ -65,7 +69,69 @@ import net.java.games.jogl.util.*; same data in system memory allows. </P> */ -public class VertexBufferObject { +public class VertexBufferObject extends Demo { + public static void main(String[] args) { + boolean vboEnabled = true; + + if (args.length > 1) { + usage(); + } + + if (args.length == 1) { + if (args[0].equals("-slow")) { + vboEnabled = false; + } else { + usage(); + } + } + + GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); + VertexBufferObject demo = new VertexBufferObject(); + demo.vboEnabled = vboEnabled; + canvas.addGLEventListener(demo); + + final Animator animator = new Animator(canvas); + animator.setRunAsFastAsPossible(true); + demo.setDemoListener(new DemoListener() { + public void shutdownDemo() { + runExit(animator); + } + public void repaint() {} + }); + + Frame frame = new Frame("Very Simple vertex_buffer_object demo"); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + runExit(animator); + } + }); + frame.setLayout(new BorderLayout()); + canvas.setSize(800, 800); + frame.add(canvas, BorderLayout.CENTER); + frame.pack(); + frame.show(); + canvas.requestFocus(); + + animator.start(); + } + + private static void usage() { + System.out.println("usage: java VertexBufferObject [-slow]"); + System.out.println("-slow flag starts up using data in the Java heap"); + System.exit(0); + } + + public VertexBufferObject() { + setFlag(' ', true); // animation on + setFlag('i', true); // infinite viewer and light + } + + //---------------------------------------------------------------------- + // Internals only below this point + // + + private GLU glu = new GLU(); + private boolean initComplete; private boolean[] b = new boolean[256]; private static final int SIZEOF_FLOAT = 4; // private static final int STRIP_SIZE = 48; @@ -83,7 +149,7 @@ public class VertexBufferObject { private FloatBuffer bigArrayVBO; private FloatBuffer bigArraySystem; private FloatBuffer bigArray; - private int[][] elements; + private IntBuffer[] elements; private int elementBufferObject; private float[] xyArray; @@ -130,9 +196,6 @@ public class VertexBufferObject { private int numDrawElementsCalls; private long startTimeMillis; - private GLCanvas canvas = null; - private Animator animator; - static class PeriodicIterator { public PeriodicIterator(int arraySize, float period, @@ -187,67 +250,6 @@ public class VertexBufferObject { private int index; } - public static void usage(String className) { - System.out.println("usage: java " + className + " [-slow]"); - System.out.println("-slow flag starts up using data in the Java heap"); - System.exit(0); - } - - public static void main(String[] args) { - new VertexBufferObject().run(args); - } - - public void run(String[] args) { - if (args.length > 1) { - usage(getClass().getName()); - } - - if (args.length == 1) { - if (args[0].equals("-slow")) { - vboEnabled = false; - } else { - usage(getClass().getName()); - } - } - - setFlag(' ', true); // animation on - setFlag('i', true); // infinite viewer and light - - canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); - VBOListener listener = new VBOListener(); - canvas.addGLEventListener(listener); - - animator = new Animator(canvas); - - Frame frame = new Frame("Very Simple NV_vertex_array_range demo"); - frame.setLayout(new BorderLayout()); - canvas.setSize(800, 800); - frame.add(canvas, BorderLayout.CENTER); - frame.pack(); - frame.show(); - canvas.requestFocus(); - - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - // Run this on another thread than the AWT event queue to - // make sure the call to Animator.stop() completes before - // exiting - new Thread(new Runnable() { - public void run() { - animator.stop(); - System.exit(0); - } - }).start(); - } - }); - - animator.start(); - } - - //---------------------------------------------------------------------- - // Internals only below this point - // - private void setFlag(char key, boolean val) { b[((int) key) & 0xFF] = val; } @@ -262,432 +264,422 @@ public class VertexBufferObject { new Thread(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); - runExit(); + shutdownDemo(); } }).start(); throw new RuntimeException(message); } } - class VBOListener implements GLEventListener { - boolean exiting = false; - public void init(GLDrawable drawable) { - // drawable.setGL(new TraceGL(drawable.getGL(), System.err)); - // drawable.setGL(new DebugGL(drawable.getGL())); + public void init(GLAutoDrawable drawable) { + initComplete = false; + // drawable.setGL(new TraceGL(drawable.getGL(), System.err)); + // drawable.setGL(new DebugGL(drawable.getGL())); - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); + GL gl = drawable.getGL(); - // Try and disable synch-to-retrace for fastest framerate - if (gl.isFunctionAvailable("wglSwapIntervalEXT")) { - System.err.println("wglSwapIntervalEXT available; disabling sync-to-refresh for best framerate"); - gl.wglSwapIntervalEXT(0); - } - else { - System.err.println("wglSwapIntervalEXT not available; cannot disable sync-to-refresh"); - } + // Try and disable synch-to-retrace for fastest framerate + gl.setSwapInterval(0); - try { - initExtension(gl, "GL_ARB_vertex_buffer_object"); - } catch (RuntimeException e) { - quit = true; - throw (e); - } + try { + initExtension(gl, "GL_ARB_vertex_buffer_object"); + } catch (RuntimeException e) { + throw (e); + } - gl.glEnable(GL.GL_DEPTH_TEST); - - gl.glClearColor(0, 0, 0, 0); - - gl.glEnable(GL.GL_LIGHT0); - gl.glEnable(GL.GL_LIGHTING); - gl.glEnable(GL.GL_NORMALIZE); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, new float[] {.1f, .1f, 0, 1}); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, new float[] {.6f, .6f, .1f, 1}); - gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, new float[] { 1, 1, .75f, 1}); - gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, 128.f); - - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, .5f, 0}); - gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 0); - - // NOTE: it looks like GLUT (or something else) sets up the - // projection matrix in the C version of this demo. - gl.glMatrixMode(GL.GL_PROJECTION); - gl.glLoadIdentity(); - glu.gluPerspective(60, 1.0, 0.1, 100); - gl.glMatrixMode(GL.GL_MODELVIEW); - - allocateBigArray(gl); - allocateBuffers(gl); - - sinArray = new float[SIN_ARRAY_SIZE]; - cosArray = new float[SIN_ARRAY_SIZE]; - - for (int i = 0; i < SIN_ARRAY_SIZE; i++) { - double step = i * 2 * Math.PI / SIN_ARRAY_SIZE; - sinArray[i] = (float) Math.sin(step); - cosArray[i] = (float) Math.cos(step); - } + gl.glEnable(GL.GL_DEPTH_TEST); + + gl.glClearColor(0, 0, 0, 0); + + gl.glEnable(GL.GL_LIGHT0); + gl.glEnable(GL.GL_LIGHTING); + gl.glEnable(GL.GL_NORMALIZE); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT, new float[] {.1f, .1f, 0, 1}, 0); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE, new float[] {.6f, .6f, .1f, 1}, 0); + gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_SPECULAR, new float[] { 1, 1, .75f, 1}, 0); + gl.glMaterialf(GL.GL_FRONT_AND_BACK, GL.GL_SHININESS, 128.f); + + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, .5f, 0}, 0); + gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 0); + + // NOTE: it looks like GLUT (or something else) sets up the + // projection matrix in the C version of this demo. + gl.glMatrixMode(GL.GL_PROJECTION); + gl.glLoadIdentity(); + glu.gluPerspective(60, 1.0, 0.1, 100); + gl.glMatrixMode(GL.GL_MODELVIEW); + + allocateBigArray(gl); + allocateBuffers(gl); + + sinArray = new float[SIN_ARRAY_SIZE]; + cosArray = new float[SIN_ARRAY_SIZE]; + + for (int i = 0; i < SIN_ARRAY_SIZE; i++) { + double step = i * 2 * Math.PI / SIN_ARRAY_SIZE; + sinArray[i] = (float) Math.sin(step); + cosArray[i] = (float) Math.cos(step); + } - if (vboEnabled) { - bigArray = bigArrayVBO; - } else { - bigArray = bigArraySystem; - } - setupBuffers(); - gl.glEnableClientState(GL.GL_VERTEX_ARRAY); - gl.glEnableClientState(GL.GL_NORMAL_ARRAY); + if (vboEnabled) { + bigArray = bigArrayVBO; + } else { + bigArray = bigArraySystem; + } + setupBuffers(); + gl.glEnableClientState(GL.GL_VERTEX_ARRAY); + gl.glEnableClientState(GL.GL_NORMAL_ARRAY); - computeElements(gl); + computeElements(gl); - drawable.addKeyListener(new KeyAdapter() { - public void keyTyped(KeyEvent e) { - dispatchKey(e.getKeyChar()); - } - }); - } + drawable.addKeyListener(new KeyAdapter() { + public void keyTyped(KeyEvent e) { + dispatchKey(e.getKeyChar()); + } + }); + initComplete = true; + } - private void allocateBuffers(GL gl) { - buffers = new VBOBuffer[numBuffers]; - for (int i = 0; i < numBuffers; i++) { - buffers[i] = new VBOBuffer(); - } + private void allocateBuffers(GL gl) { + buffers = new VBOBuffer[numBuffers]; + for (int i = 0; i < numBuffers; i++) { + buffers[i] = new VBOBuffer(); } + } - private void setupBuffers() { - int sliceSize = bufferLength / numBuffers; - for (int i = 0; i < numBuffers; i++) { - int startIndex = i * sliceSize; - buffers[i].vertices = sliceBuffer(bigArray, startIndex, sliceSize); - buffers[i].normals = sliceBuffer(buffers[i].vertices, 3, - buffers[i].vertices.limit() - 3); - buffers[i].vertexOffset = startIndex * BufferUtils.SIZEOF_FLOAT; - buffers[i].normalOffset = (startIndex + 3) * BufferUtils.SIZEOF_FLOAT; - } + private void setupBuffers() { + int sliceSize = bufferLength / numBuffers; + for (int i = 0; i < numBuffers; i++) { + int startIndex = i * sliceSize; + buffers[i].vertices = sliceBuffer(bigArray, startIndex, sliceSize); + buffers[i].normals = sliceBuffer(buffers[i].vertices, 3, + buffers[i].vertices.limit() - 3); + buffers[i].vertexOffset = startIndex * BufferUtils.SIZEOF_FLOAT; + buffers[i].normalOffset = (startIndex + 3) * BufferUtils.SIZEOF_FLOAT; } + } - private void dispatchKey(char k) { - setFlag(k, !getFlag(k)); - // Quit on escape or 'q' - if ((k == (char) 27) || (k == 'q')) { - runExit(); - } - - if (k == 'r') { - if (getFlag(k)) { - profiledFrameCount = 0; - numDrawElementsCalls = 0; - firstProfiledFrame = true; - } - } + private void dispatchKey(char k) { + setFlag(k, !getFlag(k)); + // Quit on escape or 'q' + if ((k == (char) 27) || (k == 'q')) { + shutdownDemo(); + return; + } - if (k == 'w') { - if (getFlag(k)) { - primitive = GL.GL_LINE_STRIP; - } else { - primitive = GL.GL_QUAD_STRIP; - } + if (k == 'r') { + if (getFlag(k)) { + profiledFrameCount = 0; + numDrawElementsCalls = 0; + firstProfiledFrame = true; } + } - if (k == 'p') { - if (getFlag(k)) { - primitive = GL.GL_POINTS; - } else { - primitive = GL.GL_QUAD_STRIP; - } + if (k == 'w') { + if (getFlag(k)) { + primitive = GL.GL_LINE_STRIP; + } else { + primitive = GL.GL_QUAD_STRIP; } + } - if (k == 'v') { - toggleVBO = true; + if (k == 'p') { + if (getFlag(k)) { + primitive = GL.GL_POINTS; + } else { + primitive = GL.GL_QUAD_STRIP; } + } - if (k == 'd') { - toggleLighting = true; - } + if (k == 'v') { + toggleVBO = true; + } - if (k == 'i') { - toggleLightingModel = true; - } + if (k == 'd') { + toggleLighting = true; + } - if('h'==k) - hicoef += .005; - if('H'==k) - hicoef -= .005; - if('l'==k) - locoef += .005; - if('L'==k) - locoef -= .005; - if('1'==k) - lofreq += .1f; - if('2'==k) - lofreq -= .1f; - if('3'==k) - hifreq += .1f; - if('4'==k) - hifreq -= .1f; - if('5'==k) - phaseRate += .01f; - if('6'==k) - phaseRate -= .01f; - if('7'==k) - phase2Rate += .01f; - if('8'==k) - phase2Rate -= .01f; - - if('t'==k) { - if(tileSize < 864) { - tileSize += STRIP_SIZE; - recomputeElements = true; - System.err.println("tileSize = " + tileSize); - } - } + if (k == 'i') { + toggleLightingModel = true; + } - if('T'==k) { - if(tileSize > STRIP_SIZE) { - tileSize -= STRIP_SIZE; - recomputeElements = true; - System.err.println("tileSize = " + tileSize); - } + if('h'==k) + hicoef += .005; + if('H'==k) + hicoef -= .005; + if('l'==k) + locoef += .005; + if('L'==k) + locoef -= .005; + if('1'==k) + lofreq += .1f; + if('2'==k) + lofreq -= .1f; + if('3'==k) + hifreq += .1f; + if('4'==k) + hifreq -= .1f; + if('5'==k) + phaseRate += .01f; + if('6'==k) + phaseRate -= .01f; + if('7'==k) + phase2Rate += .01f; + if('8'==k) + phase2Rate -= .01f; + + if('t'==k) { + if(tileSize < 864) { + tileSize += STRIP_SIZE; + recomputeElements = true; + System.err.println("tileSize = " + tileSize); } } - public void display(GLDrawable drawable) { - // Don't try to do OpenGL operations if we're tearing things down - if (quit) { - return; + if('T'==k) { + if(tileSize > STRIP_SIZE) { + tileSize -= STRIP_SIZE; + recomputeElements = true; + System.err.println("tileSize = " + tileSize); } + } + } - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); + public void display(GLAutoDrawable drawable) { + if (!initComplete) { + return; + } - // Check to see whether to animate - if (getFlag(' ')) { - phase += phaseRate; - phase2 += phase2Rate; + GL gl = drawable.getGL(); - if (phase > (float) (20 * Math.PI)) { - phase = 0; - } + // Check to see whether to animate + if (getFlag(' ')) { + phase += phaseRate; + phase2 += phase2Rate; - if (phase2 < (float) (-20 * Math.PI)) { - phase2 = 0; - } + if (phase > (float) (20 * Math.PI)) { + phase = 0; } - PeriodicIterator loX = - new PeriodicIterator(SIN_ARRAY_SIZE, (float) (2 * Math.PI), phase, (float) ((1.f/tileSize)*lofreq*Math.PI)); - PeriodicIterator loY = new PeriodicIterator(loX); - PeriodicIterator hiX = - new PeriodicIterator(SIN_ARRAY_SIZE, (float) (2 * Math.PI), phase2, (float) ((1.f/tileSize)*hifreq*Math.PI)); - PeriodicIterator hiY = new PeriodicIterator(hiX); - - if (toggleVBO) { - vboEnabled = !vboEnabled; - if (!vboEnabled) { - bigArray = bigArraySystem; - setupBuffers(); - } - toggleVBO = false; + if (phase2 < (float) (-20 * Math.PI)) { + phase2 = 0; } + } - if (toggleLighting) { - if (getFlag('d')) { - gl.glDisable(GL.GL_LIGHTING); - } else { - gl.glEnable(GL.GL_LIGHTING); - } - toggleLighting = false; - } + PeriodicIterator loX = + new PeriodicIterator(SIN_ARRAY_SIZE, (float) (2 * Math.PI), phase, (float) ((1.f/tileSize)*lofreq*Math.PI)); + PeriodicIterator loY = new PeriodicIterator(loX); + PeriodicIterator hiX = + new PeriodicIterator(SIN_ARRAY_SIZE, (float) (2 * Math.PI), phase2, (float) ((1.f/tileSize)*hifreq*Math.PI)); + PeriodicIterator hiY = new PeriodicIterator(hiX); - if (toggleLightingModel) { - if(getFlag('i')) { - // infinite light - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, .5f, 0 }); - gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 0); - } else { - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, -.5f,1 }); - gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 1); - } - toggleLightingModel = false; + if (toggleVBO) { + vboEnabled = !vboEnabled; + if (!vboEnabled) { + bigArray = bigArraySystem; + setupBuffers(); } + toggleVBO = false; + } - if (recomputeElements) { - computeElements(gl); - recomputeElements = false; + if (toggleLighting) { + if (getFlag('d')) { + gl.glDisable(GL.GL_LIGHTING); + } else { + gl.glEnable(GL.GL_LIGHTING); } + toggleLighting = false; + } - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + if (toggleLightingModel) { + if(getFlag('i')) { + // infinite light + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, .5f, 0 }, 0); + gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 0); + } else { + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[] { .5f, 0, -.5f,1 }, 0); + gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 1); + } + toggleLightingModel = false; + } - gl.glPushMatrix(); + if (recomputeElements) { + computeElements(gl); + recomputeElements = false; + } - final float[] modelViewMatrix = new float[] { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, -1, 1 - }; - gl.glLoadMatrixf(modelViewMatrix); + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - // FIXME: add mouse interaction - // camera.apply_inverse_transform(); - // object.apply_transform(); + gl.glPushMatrix(); - int cur = 0; - int numSlabs = tileSize / STRIP_SIZE; + final float[] modelViewMatrix = new float[] { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, -1, 1 + }; + gl.glLoadMatrixf(modelViewMatrix, 0); - if (vboEnabled) { - gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, bigBufferObject); - } else { - gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0); - } + // FIXME: add mouse interaction + // camera.apply_inverse_transform(); + // object.apply_transform(); - for(int slab = numSlabs; --slab>=0; ) { - cur = slab % numBuffers; + int cur = 0; + int numSlabs = tileSize / STRIP_SIZE; - if (vboEnabled) { - ByteBuffer tmp = gl.glMapBufferARB(GL.GL_ARRAY_BUFFER_ARB, GL.GL_WRITE_ONLY_ARB); - if (tmp == null) { - throw new RuntimeException("Unable to map vertex buffer object"); - } - if (tmp != bigArrayVBOBytes) { - bigArrayVBOBytes = tmp; - bigArrayVBO = setupBuffer(tmp); - } - if (bigArray != bigArrayVBO) { - bigArray = bigArrayVBO; - setupBuffers(); - } - } + if (vboEnabled) { + gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, bigBufferObject); + } else { + gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0); + } - FloatBuffer v = buffers[cur].vertices; - int vertexIndex = 0; + for(int slab = numSlabs; --slab>=0; ) { + cur = slab % numBuffers; - if (vboEnabled) { - gl.glVertexPointer(3, GL.GL_FLOAT, 6 * SIZEOF_FLOAT, BufferUtils.bufferOffset(buffers[cur].vertexOffset)); - gl.glNormalPointer( GL.GL_FLOAT, 6 * SIZEOF_FLOAT, BufferUtils.bufferOffset(buffers[cur].normalOffset)); - } else { - gl.glVertexPointer(3, GL.GL_FLOAT, 6 * SIZEOF_FLOAT, v); - gl.glNormalPointer( GL.GL_FLOAT, 6 * SIZEOF_FLOAT, buffers[cur].normals); + if (vboEnabled) { + ByteBuffer tmp = gl.glMapBufferARB(GL.GL_ARRAY_BUFFER_ARB, GL.GL_WRITE_ONLY_ARB); + if (tmp == null) { + throw new RuntimeException("Unable to map vertex buffer object"); } - - for(int jj=STRIP_SIZE; --jj>=0; ) { - ysinlo[jj] = sinArray[loY.getIndex()]; - ycoslo[jj] = cosArray[loY.getIndex()]; loY.incr(); - ysinhi[jj] = sinArray[hiY.getIndex()]; - ycoshi[jj] = cosArray[hiY.getIndex()]; hiY.incr(); + if (tmp != bigArrayVBOBytes) { + bigArrayVBOBytes = tmp; + bigArrayVBO = setupBuffer(tmp); } - loY.decr(); - hiY.decr(); - - for(int i = tileSize; --i>=0; ) { - float x = xyArray[i]; - int loXIndex = loX.getIndex(); - int hiXIndex = hiX.getIndex(); - - int jOffset = (STRIP_SIZE-1)*slab; - float nx = locoef * -cosArray[loXIndex] + hicoef * -cosArray[hiXIndex]; - - // Help the HotSpot Client Compiler by hoisting loop - // invariant variables into locals. Note that this may be - // good practice for innermost loops anyway since under - // the new memory model operations like accidental - // synchronization may force any compiler to reload these - // fields from memory, destroying their ability to - // optimize. - float locoef_tmp = locoef; - float hicoef_tmp = hicoef; - float[] ysinlo_tmp = ysinlo; - float[] ysinhi_tmp = ysinhi; - float[] ycoslo_tmp = ycoslo; - float[] ycoshi_tmp = ycoshi; - float[] sinArray_tmp = sinArray; - float[] xyArray_tmp = xyArray; - - for(int j = STRIP_SIZE; --j>=0; ) { - float y; - - y = xyArray_tmp[j + jOffset]; - - float ny; - - v.put(vertexIndex, x); - v.put(vertexIndex + 1, y); - v.put(vertexIndex + 2, (locoef_tmp * (sinArray_tmp[loXIndex] + ysinlo_tmp[j]) + - hicoef_tmp * (sinArray_tmp[hiXIndex] + ysinhi_tmp[j]))); - v.put(vertexIndex + 3, nx); - ny = locoef_tmp * -ycoslo_tmp[j] + hicoef_tmp * -ycoshi_tmp[j]; - v.put(vertexIndex + 4, ny); - v.put(vertexIndex + 5, .15f); //.15f * (1.f - sqrt(nx * nx + ny * ny)); - vertexIndex += 6; - } - loX.incr(); - hiX.incr(); + if (bigArray != bigArrayVBO) { + bigArray = bigArrayVBO; + setupBuffers(); } - loX.reset(); - hiX.reset(); + } + + FloatBuffer v = buffers[cur].vertices; + int vertexIndex = 0; - if (vboEnabled) { - gl.glUnmapBufferARB(GL.GL_ARRAY_BUFFER_ARB); + if (vboEnabled) { + gl.glVertexPointer(3, GL.GL_FLOAT, 6 * SIZEOF_FLOAT, buffers[cur].vertexOffset); + gl.glNormalPointer( GL.GL_FLOAT, 6 * SIZEOF_FLOAT, buffers[cur].normalOffset); + } else { + gl.glVertexPointer(3, GL.GL_FLOAT, 6 * SIZEOF_FLOAT, v); + gl.glNormalPointer( GL.GL_FLOAT, 6 * SIZEOF_FLOAT, buffers[cur].normals); + } + + for(int jj=STRIP_SIZE; --jj>=0; ) { + ysinlo[jj] = sinArray[loY.getIndex()]; + ycoslo[jj] = cosArray[loY.getIndex()]; loY.incr(); + ysinhi[jj] = sinArray[hiY.getIndex()]; + ycoshi[jj] = cosArray[hiY.getIndex()]; hiY.incr(); + } + loY.decr(); + hiY.decr(); + + for(int i = tileSize; --i>=0; ) { + float x = xyArray[i]; + int loXIndex = loX.getIndex(); + int hiXIndex = hiX.getIndex(); + + int jOffset = (STRIP_SIZE-1)*slab; + float nx = locoef * -cosArray[loXIndex] + hicoef * -cosArray[hiXIndex]; + + // Help the HotSpot Client Compiler by hoisting loop + // invariant variables into locals. Note that this may be + // good practice for innermost loops anyway since under + // the new memory model operations like accidental + // synchronization may force any compiler to reload these + // fields from memory, destroying their ability to + // optimize. + float locoef_tmp = locoef; + float hicoef_tmp = hicoef; + float[] ysinlo_tmp = ysinlo; + float[] ysinhi_tmp = ysinhi; + float[] ycoslo_tmp = ycoslo; + float[] ycoshi_tmp = ycoshi; + float[] sinArray_tmp = sinArray; + float[] xyArray_tmp = xyArray; + + for(int j = STRIP_SIZE; --j>=0; ) { + float y; + + y = xyArray_tmp[j + jOffset]; + + float ny; + + v.put(vertexIndex, x); + v.put(vertexIndex + 1, y); + v.put(vertexIndex + 2, (locoef_tmp * (sinArray_tmp[loXIndex] + ysinlo_tmp[j]) + + hicoef_tmp * (sinArray_tmp[hiXIndex] + ysinhi_tmp[j]))); + v.put(vertexIndex + 3, nx); + ny = locoef_tmp * -ycoslo_tmp[j] + hicoef_tmp * -ycoshi_tmp[j]; + v.put(vertexIndex + 4, ny); + v.put(vertexIndex + 5, .15f); //.15f * (1.f - sqrt(nx * nx + ny * ny)); + vertexIndex += 6; } + loX.incr(); + hiX.incr(); + } + loX.reset(); + hiX.reset(); - if (getFlag('m')) { - // Elements merged into buffer object (doesn't seem to improve performance) - - int len = tileSize - 1; - gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, elementBufferObject); - for (int i = 0; i < len; i++) { - ++numDrawElementsCalls; - gl.glDrawElements(primitive, 2 * STRIP_SIZE, GL.GL_UNSIGNED_INT, - BufferUtils.bufferOffset(i * 2 * STRIP_SIZE * BufferUtils.SIZEOF_INT)); - if(getFlag('f')) { - gl.glFlush(); - } + if (vboEnabled) { + gl.glUnmapBufferARB(GL.GL_ARRAY_BUFFER_ARB); + } + + if (getFlag('m')) { + // Elements merged into buffer object (doesn't seem to improve performance) + + int len = tileSize - 1; + gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, elementBufferObject); + for (int i = 0; i < len; i++) { + ++numDrawElementsCalls; + gl.glDrawElements(primitive, 2 * STRIP_SIZE, GL.GL_UNSIGNED_INT, + i * 2 * STRIP_SIZE * BufferUtils.SIZEOF_INT); + if(getFlag('f')) { + gl.glFlush(); } - gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - } else { - for (int i = 0; i < elements.length; i++) { - ++numDrawElementsCalls; - gl.glDrawElements(primitive, elements[i].length, GL.GL_UNSIGNED_INT, elements[i]); - if(getFlag('f')) { - gl.glFlush(); - } + } + gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + } else { + for (int i = 0; i < elements.length; i++) { + ++numDrawElementsCalls; + gl.glDrawElements(primitive, elements[i].remaining(), GL.GL_UNSIGNED_INT, elements[i]); + if(getFlag('f')) { + gl.glFlush(); } } } + } - gl.glPopMatrix(); - - if (getFlag('r')) { - if (!firstProfiledFrame) { - if (++profiledFrameCount == 30) { - long endTimeMillis = System.currentTimeMillis(); - double secs = (endTimeMillis - startTimeMillis) / 1000.0; - double fps = 30.0 / secs; - double ppf = tileSize * tileSize * 2; - double mpps = ppf * fps / 1000000.0; - System.err.println("fps: " + fps + " polys/frame: " + ppf + " million polys/sec: " + mpps + - " DrawElements calls/frame: " + (numDrawElementsCalls / 30)); - profiledFrameCount = 0; - numDrawElementsCalls = 0; - startTimeMillis = System.currentTimeMillis(); - } - } else { + gl.glPopMatrix(); + + if (getFlag('r')) { + if (!firstProfiledFrame) { + if (++profiledFrameCount == 30) { + long endTimeMillis = System.currentTimeMillis(); + double secs = (endTimeMillis - startTimeMillis) / 1000.0; + double fps = 30.0 / secs; + double ppf = tileSize * tileSize * 2; + double mpps = ppf * fps / 1000000.0; + System.err.println("fps: " + fps + " polys/frame: " + ppf + " million polys/sec: " + mpps + + " DrawElements calls/frame: " + (numDrawElementsCalls / 30)); + profiledFrameCount = 0; + numDrawElementsCalls = 0; startTimeMillis = System.currentTimeMillis(); - firstProfiledFrame = false; } + } else { + startTimeMillis = System.currentTimeMillis(); + firstProfiledFrame = false; } } + } - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} - // Unused routines - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - } // end class VBOListener + // Unused routines + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} private void allocateBigArray(GL gl) { bigArraySystem = setupBuffer(ByteBuffer.allocateDirect(bufferSize)); int[] tmp = new int[1]; - gl.glGenBuffersARB(1, tmp); + gl.glGenBuffersARB(1, tmp, 0); bigBufferObject = tmp[0]; gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, bigBufferObject); // Initialize data store of buffer object @@ -722,43 +714,41 @@ public class VertexBufferObject { xyArray[i] = i / (tileSize - 1.0f) - 0.5f; } - elements = new int[tileSize - 1][]; + elements = new IntBuffer[tileSize - 1]; for (int i = 0; i < tileSize - 1; i++) { - elements[i] = new int[2 * STRIP_SIZE]; + elements[i] = IntBuffer.allocate(2 * STRIP_SIZE); for (int j = 0; j < 2 * STRIP_SIZE; j += 2) { - elements[i][j] = i * STRIP_SIZE + (j / 2); - elements[i][j+1] = (i + 1) * STRIP_SIZE + (j / 2); + elements[i].put(j, i * STRIP_SIZE + (j / 2)); + elements[i].put(j+1, (i + 1) * STRIP_SIZE + (j / 2)); } } // Create element array buffer - int[] linearElements = new int[(tileSize - 1) * (2 * STRIP_SIZE)]; + IntBuffer linearElements = IntBuffer.allocate((tileSize - 1) * (2 * STRIP_SIZE)); int idx = 0; for (int i = 0; i < tileSize - 1; i++) { for (int j = 0; j < 2 * STRIP_SIZE; j += 2) { - linearElements[idx++] = i * STRIP_SIZE + (j / 2); - linearElements[idx++] = (i + 1) * STRIP_SIZE + (j / 2); + linearElements.put(idx++, i * STRIP_SIZE + (j / 2)); + linearElements.put(idx++, (i + 1) * STRIP_SIZE + (j / 2)); } } int[] tmp = new int[1]; - gl.glGenBuffersARB(1, tmp); + gl.glGenBuffersARB(1, tmp, 0); elementBufferObject = tmp[0]; gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, elementBufferObject); gl.glBufferDataARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, - linearElements.length * BufferUtils.SIZEOF_INT, + linearElements.remaining() * BufferUtils.SIZEOF_INT, linearElements, GL.GL_STATIC_DRAW_ARB); gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } - private void runExit() { - quit = true; + private static void runExit(final Animator animator) { // Note: calling System.exit() synchronously inside the draw, // reshape or init callbacks can lead to deadlocks on certain // platforms (in particular, X11) because the JAWT's locking // routines cause a global AWT lock to be grabbed. Run the - // exit routine in another thread and cause this one to - // terminate by throwing an exception out of it. + // exit routine in another thread. new Thread(new Runnable() { public void run() { animator.stop(); diff --git a/src/demos/vertexProgRefract/VertexProgRefract.java b/src/demos/vertexProgRefract/VertexProgRefract.java index e9c6905..63b4a59 100644 --- a/src/demos/vertexProgRefract/VertexProgRefract.java +++ b/src/demos/vertexProgRefract/VertexProgRefract.java @@ -43,8 +43,11 @@ import javax.imageio.*; import javax.imageio.stream.*; import javax.swing.*; -import net.java.games.jogl.*; -import net.java.games.jogl.util.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; +import com.sun.opengl.utils.*; +import demos.common.*; import demos.util.*; import gleem.*; import gleem.linalg.*; @@ -61,21 +64,19 @@ import gleem.linalg.*; Ported to Java and ARB_fragment_program by Kenneth Russell */ -public class VertexProgRefract { - private boolean useRegisterCombiners; - private GLCanvas canvas; - private Animator animator; - private volatile boolean quit; - +public class VertexProgRefract extends Demo { public static void main(String[] args) { - new VertexProgRefract().run(args); - } - - public void run(String[] args) { - canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); - canvas.addGLEventListener(new Listener()); - - animator = new Animator(canvas); + GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); + VertexProgRefract demo = new VertexProgRefract(); + canvas.addGLEventListener(demo); + + final Animator animator = new Animator(canvas); + demo.setDemoListener(new DemoListener() { + public void shutdownDemo() { + runExit(animator); + } + public void repaint() {} + }); Frame frame = new Frame("Refraction Using Vertex Programs"); frame.setLayout(new BorderLayout()); @@ -87,44 +88,40 @@ public class VertexProgRefract { frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { - // Run this on another thread than the AWT event queue to - // make sure the call to Animator.stop() completes before - // exiting - new Thread(new Runnable() { - public void run() { - animator.stop(); - System.exit(0); - } - }).start(); + runExit(animator); } }); animator.start(); } - class Listener implements GLEventListener { - private int vtxProg; - private int fragProg; - private int cubemap; - private int bunnydl; - private int obj; + private boolean useRegisterCombiners; + private boolean initComplete; + private boolean firstRender = true; + private int vtxProg; + private int fragProg; + private int cubemap; + private int bunnydl; + private int obj; - private GLUT glut = new GLUT(); + private GLU glu = new GLU(); + private GLUT glut = new GLUT(); - private ExaminerViewer viewer; - private boolean doViewAll = true; + private GLAutoDrawable drawable; + private ExaminerViewer viewer; + private boolean doViewAll = true; - private Time time = new SystemTime(); - private float animRate = (float) Math.toRadians(-6.0f); // Radians / sec + private Time time = new SystemTime(); + private float animRate = (float) Math.toRadians(-6.0f); // Radians / sec - private float refract = 1.1f; // ratio of indicies of refraction - private float wavelengthDelta = 0.05f; // difference in refraction for each "wavelength" (R,G,B) - private float fresnel = 2.0f; // Fresnel multiplier + private float refract = 1.1f; // ratio of indicies of refraction + private float wavelengthDelta = 0.05f; // difference in refraction for each "wavelength" (R,G,B) + private float fresnel = 2.0f; // Fresnel multiplier - private boolean wire = false; - private boolean toggleWire = false; + private boolean wire = false; + private boolean toggleWire = false; - private static final String transformRefract = + private static final String transformRefract = "!!ARBvp1.0\n" + "# Refraction\n" + "\n" + @@ -226,82 +223,89 @@ public class VertexProgRefract { "\n" + "END\n"; - public void init(GLDrawable drawable) { - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); - float cc = 1.0f; - gl.glClearColor(cc, cc, cc, 1); - gl.glColor3f(1,1,1); - gl.glEnable(GL.GL_DEPTH_TEST); - - try { - initExtension(gl, "GL_ARB_vertex_program"); - initExtension(gl, "GL_ARB_multitexture"); - if (!gl.isExtensionAvailable("GL_ARB_fragment_program")) { - if (gl.isExtensionAvailable("GL_NV_register_combiners")) { - useRegisterCombiners = true; - } else { - final String message = "This demo requires either the GL_ARB_fragment_program\n" + - "or GL_NV_register_combiners extension"; - new Thread(new Runnable() { - public void run() { - JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); - runExit(); - } - }).start(); - throw new RuntimeException(message); - } + public void init(GLAutoDrawable drawable) { + initComplete = false; + GL gl = drawable.getGL(); + float cc = 1.0f; + gl.glClearColor(cc, cc, cc, 1); + gl.glColor3f(1,1,1); + gl.glEnable(GL.GL_DEPTH_TEST); + + try { + initExtension(gl, "GL_ARB_vertex_program"); + initExtension(gl, "GL_VERSION_1_3"); // For multitexturing support + if (!gl.isExtensionAvailable("GL_ARB_fragment_program")) { + if (gl.isExtensionAvailable("GL_NV_register_combiners")) { + useRegisterCombiners = true; + } else { + final String message = "This demo requires either the GL_ARB_fragment_program\n" + + "or GL_NV_register_combiners extension"; + new Thread(new Runnable() { + public void run() { + JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); + shutdownDemo(); + } + }).start(); + throw new RuntimeException(message); } - } catch (RuntimeException e) { - quit = true; - throw(e); } + } catch (RuntimeException e) { + shutdownDemo(); + throw(e); + } - b[' '] = true; // animate by default + b[' '] = true; // animate by default - int[] vtxProgTmp = new int[1]; - gl.glGenProgramsARB(1, vtxProgTmp); - vtxProg = vtxProgTmp[0]; - gl.glBindProgramARB (GL.GL_VERTEX_PROGRAM_ARB, vtxProg); - gl.glProgramStringARB(GL.GL_VERTEX_PROGRAM_ARB, GL.GL_PROGRAM_FORMAT_ASCII_ARB, transformRefract.length(), transformRefract); + int[] vtxProgTmp = new int[1]; + gl.glGenProgramsARB(1, vtxProgTmp, 0); + vtxProg = vtxProgTmp[0]; + gl.glBindProgramARB (GL.GL_VERTEX_PROGRAM_ARB, vtxProg); + gl.glProgramStringARB(GL.GL_VERTEX_PROGRAM_ARB, GL.GL_PROGRAM_FORMAT_ASCII_ARB, transformRefract.length(), transformRefract); - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 0, 0.0f, 0.0f, 0.0f, 1.0f); // eye position + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 0, 0.0f, 0.0f, 0.0f, 1.0f); // eye position - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 1, fresnel, fresnel, fresnel, 1.0f); // fresnel multiplier + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 1, fresnel, fresnel, fresnel, 1.0f); // fresnel multiplier - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 2, 1.0f, -1.0f, 1.0f, 0.0f); // texture scale - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 3, 0.0f, 1.0f, 2.0f, 3.0f); // misc constants + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 2, 1.0f, -1.0f, 1.0f, 0.0f); // texture scale + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 3, 0.0f, 1.0f, 2.0f, 3.0f); // misc constants - int[] cubemapTmp = new int[1]; - gl.glGenTextures(1, cubemapTmp); - cubemap = cubemapTmp[0]; - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, cubemap); + int[] cubemapTmp = new int[1]; + gl.glGenTextures(1, cubemapTmp, 0); + cubemap = cubemapTmp[0]; + gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, cubemap); - gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); - gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP_ARB, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); + gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); + gl.glTexParameteri(GL.GL_TEXTURE_CUBE_MAP, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR); - try { - loadPNGCubemap(gl, glu, "demos/data/cubemaps/uffizi", true); - } catch (IOException e) { - runExit(); - throw new RuntimeException(e); - } + try { + loadPNGCubemap(gl, "demos/data/cubemaps/uffizi", true); + } catch (IOException e) { + shutdownDemo(); + throw new RuntimeException(e); + } - gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); + gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); - gl.glDisable(GL.GL_CULL_FACE); + gl.glDisable(GL.GL_CULL_FACE); - if (useRegisterCombiners) { - initCombiners(gl); - } else { - initFragmentProgram(gl); - } + if (useRegisterCombiners) { + initCombiners(gl); + } else { + initFragmentProgram(gl); + } - try { - bunnydl = Bunny.gen3DObjectList(gl); - } catch (IOException e) { - throw new RuntimeException(e); - } + try { + bunnydl = Bunny.gen3DObjectList(gl); + } catch (IOException e) { + throw new RuntimeException(e); + } + + doViewAll = true; + + // Do this only once per drawable, not once each time the OpenGL + // context is created + if (firstRender) { + firstRender = false; drawable.addKeyListener(new KeyAdapter() { public void keyTyped(KeyEvent e) { @@ -312,282 +316,293 @@ public class VertexProgRefract { // Register the window with the ManipManager ManipManager manager = ManipManager.getManipManager(); manager.registerWindow(drawable); + this.drawable = drawable; viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); viewer.setNoAltKeyMode(true); + viewer.setAutoRedrawMode(false); viewer.attach(drawable, new BSphereProvider() { - public BSphere getBoundingSphere() { - return new BSphere(new Vec3f(0, 0, 0), 1.0f); - } - }); + public BSphere getBoundingSphere() { + return new BSphere(new Vec3f(0, 0, 0), 1.0f); + } + }); viewer.setVertFOV((float) (15.0f * Math.PI / 32.0f)); viewer.setZNear(0.1f); viewer.setZFar(10.0f); } - public void display(GLDrawable drawable) { - if (quit) { - return; - } + initComplete = true; + } - time.update(); + public void display(GLAutoDrawable drawable) { + if (!initComplete) { + return; + } - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); - gl.glClear(GL.GL_COLOR_BUFFER_BIT|GL.GL_DEPTH_BUFFER_BIT); + time.update(); - if (doViewAll) { - viewer.viewAll(gl); - doViewAll = false; - } + GL gl = drawable.getGL(); + gl.glClear(GL.GL_COLOR_BUFFER_BIT|GL.GL_DEPTH_BUFFER_BIT); - if (getFlag(' ')) { - viewer.rotateAboutFocalPoint(new Rotf(Vec3f.Y_AXIS, (float) (time.deltaT() * animRate))); - } + if (doViewAll) { + viewer.viewAll(gl); + doViewAll = false; + } - if (toggleWire) { - toggleWire = false; - wire = !wire; - if (wire) { - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); - } else { - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); - } - } + if (getFlag(' ')) { + viewer.rotateAboutFocalPoint(new Rotf(Vec3f.Y_AXIS, (float) (time.deltaT() * animRate))); + } - // draw background - gl.glDisable(GL.GL_DEPTH_TEST); - drawSkyBox(gl, glu); - gl.glEnable(GL.GL_DEPTH_TEST); - - gl.glPushMatrix(); - - viewer.update(gl); - ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters()); - ManipManager.getManipManager().render(drawable, gl); - - gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, vtxProg); - - gl.glEnable(GL.GL_VERTEX_PROGRAM_ARB); - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 62, fresnel, fresnel, fresnel, 1.0f); - - // set texture transforms - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, cubemap); - gl.glEnable(GL.GL_TEXTURE_CUBE_MAP_ARB); - gl.glMatrixMode(GL.GL_TEXTURE); - gl.glLoadIdentity(); - gl.glScalef(1.0f, -1.0f, 1.0f); - viewer.updateInverseRotation(gl); - - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, cubemap); - gl.glEnable(GL.GL_TEXTURE_CUBE_MAP_ARB); - gl.glMatrixMode(GL.GL_TEXTURE); - gl.glLoadIdentity(); - gl.glScalef(1.0f, -1.0f, 1.0f); - viewer.updateInverseRotation(gl); - - if (useRegisterCombiners) { - gl.glEnable(GL.GL_REGISTER_COMBINERS_NV); + if (toggleWire) { + toggleWire = false; + wire = !wire; + if (wire) { + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); } else { - gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); - gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB); + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); } + } - gl.glColor3f(1.0f, 1.0f, 1.0f); + // draw background + gl.glDisable(GL.GL_DEPTH_TEST); + drawSkyBox(gl); + gl.glEnable(GL.GL_DEPTH_TEST); + + gl.glPushMatrix(); + + viewer.update(gl); + ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters()); + ManipManager.getManipManager().render(drawable, gl); + + gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, vtxProg); + + gl.glEnable(GL.GL_VERTEX_PROGRAM_ARB); + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 62, fresnel, fresnel, fresnel, 1.0f); + + // set texture transforms + gl.glActiveTexture(GL.GL_TEXTURE0); + gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, cubemap); + gl.glEnable(GL.GL_TEXTURE_CUBE_MAP); + gl.glMatrixMode(GL.GL_TEXTURE); + gl.glLoadIdentity(); + gl.glScalef(1.0f, -1.0f, 1.0f); + viewer.updateInverseRotation(gl); + + gl.glActiveTexture(GL.GL_TEXTURE1); + gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, cubemap); + gl.glEnable(GL.GL_TEXTURE_CUBE_MAP); + gl.glMatrixMode(GL.GL_TEXTURE); + gl.glLoadIdentity(); + gl.glScalef(1.0f, -1.0f, 1.0f); + viewer.updateInverseRotation(gl); + + if (useRegisterCombiners) { + gl.glEnable(GL.GL_REGISTER_COMBINERS_NV); + } else { + gl.glBindProgramARB(GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); + gl.glEnable(GL.GL_FRAGMENT_PROGRAM_ARB); + } - if (getFlag('s')) { - // single pass - setRefraction(gl, refract); - drawObj(gl, glu, obj); + gl.glColor3f(1.0f, 1.0f, 1.0f); - } else { - // red pass - gl.glColorMask(true, false, false, false); - setRefraction(gl, refract); - drawObj(gl, glu, obj); - - gl.glDepthMask(false); - gl.glDepthFunc(GL.GL_EQUAL); - - // green pass - gl.glColorMask(false, true, false, false); - setRefraction(gl, refract + wavelengthDelta); - drawObj(gl, glu, obj); - - // blue pass - gl.glColorMask(false, false, true, false); - setRefraction(gl, refract + (wavelengthDelta * 2)); - drawObj(gl, glu, obj); - - gl.glDepthMask(true); - gl.glDepthFunc(GL.GL_LESS); - gl.glColorMask(true, true, true, false); - } + if (getFlag('s')) { + // single pass + setRefraction(gl, refract); + drawObj(gl, obj); - if (useRegisterCombiners) { - gl.glDisable(GL.GL_REGISTER_COMBINERS_NV); - } else { - gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB); - } - gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB); + } else { + // red pass + gl.glColorMask(true, false, false, false); + setRefraction(gl, refract); + drawObj(gl, obj); + + gl.glDepthMask(false); + gl.glDepthFunc(GL.GL_EQUAL); + + // green pass + gl.glColorMask(false, true, false, false); + setRefraction(gl, refract + wavelengthDelta); + drawObj(gl, obj); + + // blue pass + gl.glColorMask(false, false, true, false); + setRefraction(gl, refract + (wavelengthDelta * 2)); + drawObj(gl, obj); + + gl.glDepthMask(true); + gl.glDepthFunc(GL.GL_LESS); + gl.glColorMask(true, true, true, false); + } - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glPopMatrix(); + if (useRegisterCombiners) { + gl.glDisable(GL.GL_REGISTER_COMBINERS_NV); + } else { + gl.glDisable(GL.GL_FRAGMENT_PROGRAM_ARB); } + gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB); - // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} - - //---------------------------------------------------------------------- - // Internals only below this point - // - private boolean[] b = new boolean[256]; - private void dispatchKey(char k) { - setFlag(k, !getFlag(k)); - // Quit on escape or 'q' - if ((k == (char) 27) || (k == 'q')) { - runExit(); - return; - } + gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glPopMatrix(); + } - switch (k) { - case '1': - obj = 0; - break; + // Unused routines + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + + //---------------------------------------------------------------------- + // Internals only below this point + // + public void shutdownDemo() { + ManipManager.getManipManager().unregisterWindow(drawable); + drawable.removeGLEventListener(this); + super.shutdownDemo(); + } - case '2': - obj = 1; - break; + private boolean[] b = new boolean[256]; + private void dispatchKey(char k) { + setFlag(k, !getFlag(k)); - case '3': - obj = 2; - break; + // Quit on escape or 'q' + if ((k == (char) 27) || (k == 'q')) { + shutdownDemo(); + return; + } - case '4': - obj = 3; - break; + switch (k) { + case '1': + obj = 0; + break; - case 'v': - doViewAll = true; - break; + case '2': + obj = 1; + break; - case 'w': - toggleWire = true; - break; + case '3': + obj = 2; + break; - default: - break; - } - } + case '4': + obj = 3; + break; - private void setFlag(char key, boolean val) { - b[((int) key) & 0xFF] = val; - } + case 'v': + doViewAll = true; + break; - private boolean getFlag(char key) { - return b[((int) key) & 0xFF]; - } + case 'w': + toggleWire = true; + break; - // FIXME: note we found that we had to swap the negy and posy portions of the cubemap. - // Not sure why this is the case. Vertical flip in the image read? Possible, but doesn't - // appear to be the case (have tried this and produced wrong results at the time). - String[] suffixes = { "posx", "negx", "negy", "posy", "posz", "negz" }; - int[] targets = { GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, - GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, - GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, - GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB }; - private void loadPNGCubemap(GL gl, GLU glu, String baseName, boolean mipmapped) throws IOException { - for (int i = 0; i < suffixes.length; i++) { - String resourceName = baseName + "_" + suffixes[i] + ".png"; - // Note: use of BufferedInputStream works around 4764639/4892246 - BufferedImage img = ImageIO.read(new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(resourceName))); - if (img == null) { - throw new RuntimeException("Error reading PNG image " + resourceName); - } - makeRGBTexture(gl, glu, img, targets[i], mipmapped); - } + default: + break; } + } - private void makeRGBTexture(GL gl, GLU glu, BufferedImage img, int target, boolean mipmapped) { - switch (img.getType()) { - case BufferedImage.TYPE_3BYTE_BGR: - case BufferedImage.TYPE_CUSTOM: { - byte[] data = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); - if (mipmapped) { - glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(), img.getHeight(), GL.GL_RGB, - GL.GL_UNSIGNED_BYTE, data); - } else { - gl.glTexImage2D(target, 0, GL.GL_RGB, img.getWidth(), img.getHeight(), 0, - GL.GL_RGB, GL.GL_UNSIGNED_BYTE, data); - } - break; - } + private void setFlag(char key, boolean val) { + b[((int) key) & 0xFF] = val; + } - case BufferedImage.TYPE_INT_RGB: { - int[] data = ((DataBufferInt) img.getRaster().getDataBuffer()).getData(); - if (mipmapped) { - glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(), img.getHeight(), GL.GL_RGB, - GL.GL_UNSIGNED_BYTE, data); - } else { - gl.glTexImage2D(target, 0, GL.GL_RGB, img.getWidth(), img.getHeight(), 0, - GL.GL_RGB, GL.GL_UNSIGNED_BYTE, data); - } - break; - } + private boolean getFlag(char key) { + return b[((int) key) & 0xFF]; + } + + // FIXME: note we found that we had to swap the negy and posy portions of the cubemap. + // Not sure why this is the case. Vertical flip in the image read? Possible, but doesn't + // appear to be the case (have tried this and produced wrong results at the time). + String[] suffixes = { "posx", "negx", "negy", "posy", "posz", "negz" }; + int[] targets = { GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z }; + private void loadPNGCubemap(GL gl, String baseName, boolean mipmapped) throws IOException { + for (int i = 0; i < suffixes.length; i++) { + String resourceName = baseName + "_" + suffixes[i] + ".png"; + // Note: use of BufferedInputStream works around 4764639/4892246 + BufferedImage img = ImageIO.read(new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(resourceName))); + if (img == null) { + throw new RuntimeException("Error reading PNG image " + resourceName); + } + makeRGBTexture(gl, img, targets[i], mipmapped); + } + } - default: - throw new RuntimeException("Unsupported image type " + img.getType()); + private void makeRGBTexture(GL gl, BufferedImage img, int target, boolean mipmapped) { + switch (img.getType()) { + case BufferedImage.TYPE_3BYTE_BGR: + case BufferedImage.TYPE_CUSTOM: { + byte[] data = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); + if (mipmapped) { + glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(), img.getHeight(), GL.GL_RGB, + GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap(data)); + } else { + gl.glTexImage2D(target, 0, GL.GL_RGB, img.getWidth(), img.getHeight(), 0, + GL.GL_RGB, GL.GL_UNSIGNED_BYTE, ByteBuffer.wrap(data)); } + break; } - private void initExtension(GL gl, String glExtensionName) { - if (!gl.isExtensionAvailable(glExtensionName)) { - final String message = "OpenGL extension \"" + glExtensionName + "\" not available"; - new Thread(new Runnable() { - public void run() { - JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); - runExit(); - } - }).start(); - throw new RuntimeException(message); + case BufferedImage.TYPE_INT_RGB: { + int[] data = ((DataBufferInt) img.getRaster().getDataBuffer()).getData(); + if (mipmapped) { + glu.gluBuild2DMipmaps(target, GL.GL_RGB8, img.getWidth(), img.getHeight(), GL.GL_RGB, + GL.GL_UNSIGNED_BYTE, IntBuffer.wrap(data)); + } else { + gl.glTexImage2D(target, 0, GL.GL_RGB, img.getWidth(), img.getHeight(), 0, + GL.GL_RGB, GL.GL_UNSIGNED_BYTE, IntBuffer.wrap(data)); } + break; } - // initalize texture combiners to compute: - // refraction*(1-fresnel) + reflection*fresnel - private void initCombiners(GL gl) { - gl.glCombinerParameteriNV(GL.GL_NUM_GENERAL_COMBINERS_NV, 1); + default: + throw new RuntimeException("Unsupported image type " + img.getType()); + } + } + + private void initExtension(GL gl, String glExtensionName) { + if (!gl.isExtensionAvailable(glExtensionName)) { + final String message = "OpenGL extension \"" + glExtensionName + "\" not available"; + new Thread(new Runnable() { + public void run() { + JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); + shutdownDemo(); + } + }).start(); + throw new RuntimeException(message); + } + } + + // initalize texture combiners to compute: + // refraction*(1-fresnel) + reflection*fresnel + private void initCombiners(GL gl) { + gl.glCombinerParameteriNV(GL.GL_NUM_GENERAL_COMBINERS_NV, 1); - // combiner 0 - // a*b+c*d - gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_A_NV, GL.GL_TEXTURE0_ARB, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_B_NV, GL.GL_PRIMARY_COLOR_NV, GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); - gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_C_NV, GL.GL_TEXTURE1_ARB, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_D_NV, GL.GL_PRIMARY_COLOR_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - - // output: - // (stage, portion, abOutput, cdOutput, sumOutput, scale, bias, abDotProduct, cdDotProduct, muxSum) - gl.glCombinerOutputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, GL.GL_SPARE0_NV, GL.GL_NONE, GL.GL_NONE, false, false, false); + // combiner 0 + // a*b+c*d + gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_A_NV, GL.GL_TEXTURE0, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); + gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_B_NV, GL.GL_PRIMARY_COLOR_NV, GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); + gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_C_NV, GL.GL_TEXTURE1, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); + gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_D_NV, GL.GL_PRIMARY_COLOR_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); + + // output: + // (stage, portion, abOutput, cdOutput, sumOutput, scale, bias, abDotProduct, cdDotProduct, muxSum) + gl.glCombinerOutputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, GL.GL_SPARE0_NV, GL.GL_NONE, GL.GL_NONE, false, false, false); - // final combiner - // output: Frgb = A*B + (1-A)*C + D - // (variable, input, mapping, componentUsage); - gl.glFinalCombinerInputNV(GL.GL_VARIABLE_A_NV, GL.GL_SPARE0_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - gl.glFinalCombinerInputNV(GL.GL_VARIABLE_B_NV, GL.GL_ZERO, GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); - gl.glFinalCombinerInputNV(GL.GL_VARIABLE_C_NV, GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - gl.glFinalCombinerInputNV(GL.GL_VARIABLE_D_NV, GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); - } + // final combiner + // output: Frgb = A*B + (1-A)*C + D + // (variable, input, mapping, componentUsage); + gl.glFinalCombinerInputNV(GL.GL_VARIABLE_A_NV, GL.GL_SPARE0_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); + gl.glFinalCombinerInputNV(GL.GL_VARIABLE_B_NV, GL.GL_ZERO, GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB); + gl.glFinalCombinerInputNV(GL.GL_VARIABLE_C_NV, GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); + gl.glFinalCombinerInputNV(GL.GL_VARIABLE_D_NV, GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB); + } - private void initFragmentProgram(GL gl) { - int[] fragProgTmp = new int[1]; - gl.glGenProgramsARB(1, fragProgTmp); - fragProg = fragProgTmp[0]; - String combineFragProg = + private void initFragmentProgram(GL gl) { + int[] fragProgTmp = new int[1]; + gl.glGenProgramsARB(1, fragProgTmp, 0); + fragProg = fragProgTmp[0]; + String combineFragProg = "!!ARBfp1.0\n" + "# compute refraction*(1-fresnel) + reflection*fresnel\n" + "TEMP texSamp0, texSamp1;\n" + @@ -602,135 +617,133 @@ public class VertexProgRefract { "MOV result.color, texSamp0;\n" + "END"; - gl.glBindProgramARB (GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); - gl.glProgramStringARB(GL.GL_FRAGMENT_PROGRAM_ARB, GL.GL_PROGRAM_FORMAT_ASCII_ARB, - combineFragProg.length(), combineFragProg); - int[] errPos = new int[1]; - gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos); - if (errPos[0] >= 0) { - System.out.println("Fragment program failed to load:"); - String errMsg = gl.glGetString(GL.GL_PROGRAM_ERROR_STRING_ARB); - if (errMsg == null) { - System.out.println("[No error message available]"); - } else { - System.out.println("Error message: \"" + errMsg + "\""); - } - System.out.println("Error occurred at position " + errPos[0] + " in program:"); - int endPos = errPos[0]; - while (endPos < combineFragProg.length() && combineFragProg.charAt(endPos) != '\n') { - ++endPos; - } - System.out.println(combineFragProg.substring(errPos[0], endPos)); + gl.glBindProgramARB (GL.GL_FRAGMENT_PROGRAM_ARB, fragProg); + gl.glProgramStringARB(GL.GL_FRAGMENT_PROGRAM_ARB, GL.GL_PROGRAM_FORMAT_ASCII_ARB, + combineFragProg.length(), combineFragProg); + int[] errPos = new int[1]; + gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errPos, 0); + if (errPos[0] >= 0) { + System.out.println("Fragment program failed to load:"); + String errMsg = gl.glGetString(GL.GL_PROGRAM_ERROR_STRING_ARB); + if (errMsg == null) { + System.out.println("[No error message available]"); + } else { + System.out.println("Error message: \"" + errMsg + "\""); + } + System.out.println("Error occurred at position " + errPos[0] + " in program:"); + int endPos = errPos[0]; + while (endPos < combineFragProg.length() && combineFragProg.charAt(endPos) != '\n') { + ++endPos; } + System.out.println(combineFragProg.substring(errPos[0], endPos)); } + } - private void drawSkyBox(GL gl, GLU glu) { - // Compensates for ExaminerViewer's modification of modelview matrix - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glLoadIdentity(); + private void drawSkyBox(GL gl) { + // Compensates for ExaminerViewer's modification of modelview matrix + gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glLoadIdentity(); - gl.glActiveTextureARB(GL.GL_TEXTURE1_ARB); - gl.glDisable(GL.GL_TEXTURE_CUBE_MAP_ARB); + gl.glActiveTexture(GL.GL_TEXTURE1); + gl.glDisable(GL.GL_TEXTURE_CUBE_MAP); - gl.glActiveTextureARB(GL.GL_TEXTURE0_ARB); - gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_ARB, cubemap); - gl.glEnable(GL.GL_TEXTURE_CUBE_MAP_ARB); - - // This is a workaround for a driver bug on Mac OS X where the - // normals are not being sent down to the hardware in - // GL_NORMAL_MAP_EXT texgen mode. Temporarily enabling lighting - // causes the normals to be sent down. Thanks to Ken Dyke. - gl.glEnable(GL.GL_LIGHTING); - - gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP_EXT); - gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP_EXT); - gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP_EXT); - - gl.glEnable(GL.GL_TEXTURE_GEN_S); - gl.glEnable(GL.GL_TEXTURE_GEN_T); - gl.glEnable(GL.GL_TEXTURE_GEN_R); - - gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); - - gl.glMatrixMode(GL.GL_TEXTURE); - gl.glPushMatrix(); - gl.glLoadIdentity(); - gl.glScalef(1.0f, -1.0f, 1.0f); - viewer.updateInverseRotation(gl); + gl.glActiveTexture(GL.GL_TEXTURE0); + gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP, cubemap); + gl.glEnable(GL.GL_TEXTURE_CUBE_MAP); + + // This is a workaround for a driver bug on Mac OS X where the + // normals are not being sent down to the hardware in + // GL_NORMAL_MAP texgen mode. Temporarily enabling lighting + // causes the normals to be sent down. Thanks to Ken Dyke. + gl.glEnable(GL.GL_LIGHTING); + + gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP); + gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP); + gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_NORMAL_MAP); + + gl.glEnable(GL.GL_TEXTURE_GEN_S); + gl.glEnable(GL.GL_TEXTURE_GEN_T); + gl.glEnable(GL.GL_TEXTURE_GEN_R); + + gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE); + + gl.glMatrixMode(GL.GL_TEXTURE); + gl.glPushMatrix(); + gl.glLoadIdentity(); + gl.glScalef(1.0f, -1.0f, 1.0f); + viewer.updateInverseRotation(gl); - glut.glutSolidSphere(glu, 5.0, 40, 20); + glut.glutSolidSphere(5.0, 40, 20); - gl.glDisable(GL.GL_LIGHTING); + gl.glDisable(GL.GL_LIGHTING); - gl.glPopMatrix(); - gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glPopMatrix(); + gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glDisable(GL.GL_TEXTURE_GEN_S); - gl.glDisable(GL.GL_TEXTURE_GEN_T); - gl.glDisable(GL.GL_TEXTURE_GEN_R); - } + gl.glDisable(GL.GL_TEXTURE_GEN_S); + gl.glDisable(GL.GL_TEXTURE_GEN_T); + gl.glDisable(GL.GL_TEXTURE_GEN_R); + } - private void drawObj(GL gl, GLU glu, int obj) { - switch(obj) { - case 0: - gl.glCallList(bunnydl); - break; + private void drawObj(GL gl, int obj) { + switch(obj) { + case 0: + gl.glCallList(bunnydl); + break; - case 1: - glut.glutSolidSphere(glu, 0.5, 64, 64); - break; + case 1: + glut.glutSolidSphere(0.5, 64, 64); + break; - case 2: - glut.glutSolidTorus(gl, 0.25, 0.5, 64, 64); - break; + case 2: + glut.glutSolidTorus(0.25, 0.5, 64, 64); + break; - case 3: - drawPlane(gl, 1.0f, 1.0f, 50, 50); - break; - } + case 3: + drawPlane(gl, 1.0f, 1.0f, 50, 50); + break; } + } - private void setRefraction(GL gl, float index) { - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 4, index, index*index, 0.0f, 0.0f); - } + private void setRefraction(GL gl, float index) { + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 4, index, index*index, 0.0f, 0.0f); + } + + // draw square subdivided into quad strips + private void drawPlane(GL gl, float w, float h, int rows, int cols) { + int x, y; + float vx, vy, s, t; + float ts, tt, tw, th; + + ts = 1.0f / cols; + tt = 1.0f / rows; + + tw = w / cols; + th = h / rows; + + gl.glNormal3f(0.0f, 0.0f, 1.0f); + + for(y=0; y<rows; y++) { + gl.glBegin(GL.GL_QUAD_STRIP); + for(x=0; x<=cols; x++) { + vx = tw * x -(w/2.0f); + vy = th * y -(h/2.0f); + s = ts * x; + t = tt * y; + + gl.glTexCoord2f(s, t); + gl.glColor3f(s, t, 0.0f); + gl.glVertex3f(vx, vy, 0.0f); - // draw square subdivided into quad strips - private void drawPlane(GL gl, float w, float h, int rows, int cols) { - int x, y; - float vx, vy, s, t; - float ts, tt, tw, th; - - ts = 1.0f / cols; - tt = 1.0f / rows; - - tw = w / cols; - th = h / rows; - - gl.glNormal3f(0.0f, 0.0f, 1.0f); - - for(y=0; y<rows; y++) { - gl.glBegin(GL.GL_QUAD_STRIP); - for(x=0; x<=cols; x++) { - vx = tw * x -(w/2.0f); - vy = th * y -(h/2.0f); - s = ts * x; - t = tt * y; - - gl.glTexCoord2f(s, t); - gl.glColor3f(s, t, 0.0f); - gl.glVertex3f(vx, vy, 0.0f); - - gl.glColor3f(s, t + tt, 0.0f); - gl.glTexCoord2f(s, t + tt); - gl.glVertex3f(vx, vy + th, 0.0f); - } - gl.glEnd(); + gl.glColor3f(s, t + tt, 0.0f); + gl.glTexCoord2f(s, t + tt); + gl.glVertex3f(vx, vy + th, 0.0f); } + gl.glEnd(); } } - private void runExit() { - quit = true; + private static void runExit(final Animator animator) { // Note: calling System.exit() synchronously inside the draw, // reshape or init callbacks can lead to deadlocks on certain // platforms (in particular, X11) because the JAWT's locking diff --git a/src/demos/vertexProgWarp/VertexProgWarp.java b/src/demos/vertexProgWarp/VertexProgWarp.java index 3361755..cd39a01 100644 --- a/src/demos/vertexProgWarp/VertexProgWarp.java +++ b/src/demos/vertexProgWarp/VertexProgWarp.java @@ -40,7 +40,10 @@ import java.nio.*; import java.util.*; import javax.swing.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; +import demos.common.*; import demos.util.*; import gleem.*; import gleem.linalg.*; @@ -54,12 +57,12 @@ import gleem.linalg.*; Ported to Java by Kenneth Russell */ -public class VertexProgWarp { - private GLCanvas canvas; +public class VertexProgWarp extends Demo { private Frame frame; private Animator animator; private volatile boolean quit; + private GLAutoDrawable drawable; private DurationTimer timer = new DurationTimer(); private boolean firstRender = true; private int frameCount; @@ -69,12 +72,24 @@ public class VertexProgWarp { } public void run(String[] args) { - canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); - canvas.addGLEventListener(new Listener()); - - animator = new Animator(canvas); + GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); + VertexProgWarp demo = new VertexProgWarp(); + canvas.addGLEventListener(demo); + + final Animator animator = new Animator(canvas); + demo.setDemoListener(new DemoListener() { + public void shutdownDemo() { + runExit(animator); + } + public void repaint() {} + }); - frame = new Frame(); + final Frame frame = new Frame(); + demo.setTitleSetter(new VertexProgWarp.TitleSetter() { + public void setTitle(String title) { + frame.setTitle(title); + } + }); frame.setLayout(new BorderLayout()); canvas.setSize(512, 512); frame.add(canvas, BorderLayout.CENTER); @@ -84,513 +99,529 @@ public class VertexProgWarp { frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { - // Run this on another thread than the AWT event queue to - // make sure the call to Animator.stop() completes before - // exiting - new Thread(new Runnable() { - public void run() { - animator.stop(); - System.exit(0); - } - }).start(); + runExit(animator); } }); animator.start(); } - class Listener implements GLEventListener { - // period of 4-term Taylor approximation to sin isn't quite 2*M_PI - private static final float SIN_PERIOD = 3.079f; - private static final int NUM_OBJS = 5; - private static final int NUM_PROGS = 7; - private int[] programs = new int[NUM_PROGS]; - private float zNear = 0.1f; - private float zFar = 10.0f; - private int program = 2; - private int obj = 2; - private boolean[] b = new boolean[256]; - private boolean wire = false; - private boolean toggleWire = false; - private boolean animating = true; - private boolean doViewAll = true; - - private Time time = new SystemTime(); - private float anim = 0.0f; - private float animScale = 7.0f; - private float amp = 0.05f; - private float freq = 8.0f; - private float d = 4.0f; - - private ExaminerViewer viewer; - - public void init(GLDrawable drawable) { - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); - - float cc = 0.0f; - gl.glClearColor(cc, cc, cc, 1); - - gl.glColor3f(1,1,1); - gl.glEnable(GL.GL_DEPTH_TEST); - gl.glDisable(GL.GL_CULL_FACE); + public static abstract class TitleSetter { + public abstract void setTitle(String title); + } - try { - initExtension(gl, "GL_ARB_vertex_program"); - } catch (RuntimeException e) { - quit = true; - throw(e); - } + public void setTitleSetter(TitleSetter setter) { + titleSetter = setter; + } - for(int i=0; i<NUM_OBJS; i++) { - gl.glNewList(i+1, GL.GL_COMPILE); - drawObject(gl, glu, i); - gl.glEndList(); - } - - for(int i=0; i<NUM_PROGS; i++) { - int[] vtxProgTmp = new int[1]; - gl.glGenProgramsARB(1, vtxProgTmp); - programs[i] = vtxProgTmp[0]; - gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, programs[i]); - gl.glProgramStringARB(GL.GL_VERTEX_PROGRAM_ARB, GL.GL_PROGRAM_FORMAT_ASCII_ARB, programTexts[i].length(), programTexts[i]); - } + private TitleSetter titleSetter; + private boolean initComplete; + + // period of 4-term Taylor approximation to sin isn't quite 2*M_PI + private static final float SIN_PERIOD = 3.079f; + private static final int NUM_OBJS = 5; + private static final int NUM_PROGS = 7; + private int[] programs = new int[NUM_PROGS]; + private float zNear = 0.1f; + private float zFar = 10.0f; + private int program = 2; + private int obj = 2; + private boolean[] b = new boolean[256]; + private boolean wire = false; + private boolean toggleWire = false; + private boolean animating = true; + private boolean doViewAll = true; + + private Time time = new SystemTime(); + private float anim = 0.0f; + private float animScale = 7.0f; + private float amp = 0.05f; + private float freq = 8.0f; + private float d = 4.0f; + + private GLU glu = new GLU(); + private ExaminerViewer viewer; + + public void init(GLAutoDrawable drawable) { + initComplete = false; + GL gl = drawable.getGL(); + + float cc = 0.0f; + gl.glClearColor(cc, cc, cc, 1); + + gl.glColor3f(1,1,1); + gl.glEnable(GL.GL_DEPTH_TEST); + gl.glDisable(GL.GL_CULL_FACE); + + try { + initExtension(gl, "GL_ARB_vertex_program"); + } catch (RuntimeException e) { + shutdownDemo(); + throw(e); + } + + for(int i=0; i<NUM_OBJS; i++) { + gl.glNewList(i+1, GL.GL_COMPILE); + drawObject(gl, i); + gl.glEndList(); + } + + for(int i=0; i<NUM_PROGS; i++) { + int[] vtxProgTmp = new int[1]; + gl.glGenProgramsARB(1, vtxProgTmp, 0); + programs[i] = vtxProgTmp[0]; + gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, programs[i]); + gl.glProgramStringARB(GL.GL_VERTEX_PROGRAM_ARB, GL.GL_PROGRAM_FORMAT_ASCII_ARB, programTexts[i].length(), programTexts[i]); + } - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 0, 0.0f, 0.0f, 1.0f, 0.0f); // light position/direction - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 1, 0.0f, 1.0f, 0.0f, 0.0f); // diffuse color - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 2, 1.0f, 1.0f, 1.0f, 0.0f); // specular color + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 0, 0.0f, 0.0f, 1.0f, 0.0f); // light position/direction + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 1, 0.0f, 1.0f, 0.0f, 0.0f); // diffuse color + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 2, 1.0f, 1.0f, 1.0f, 0.0f); // specular color - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 3, 0.0f, 1.0f, 2.0f, 3.0f); // smoothstep constants + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 3, 0.0f, 1.0f, 2.0f, 3.0f); // smoothstep constants - // sin Taylor series constants - 1, 1/3!, 1/5!, 1/7! - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 4, 1.0f, 1.0f / (3*2), 1.0f / (5*4*3*2), 1.0f / (7*6*5*4*3*2)); + // sin Taylor series constants - 1, 1/3!, 1/5!, 1/7! + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 4, 1.0f, 1.0f / (3*2), 1.0f / (5*4*3*2), 1.0f / (7*6*5*4*3*2)); - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 5, 1.0f / (2.0f * SIN_PERIOD), 2.0f * SIN_PERIOD, SIN_PERIOD, SIN_PERIOD/2.0f); + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 5, 1.0f / (2.0f * SIN_PERIOD), 2.0f * SIN_PERIOD, SIN_PERIOD, SIN_PERIOD/2.0f); - // sin wave frequency, amplitude - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 6, 1.0f, 0.2f, 0.0f, 0.0f); + // sin wave frequency, amplitude + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 6, 1.0f, 0.2f, 0.0f, 0.0f); - // phase animation - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 7, 0.0f, 0.0f, 0.0f, 0.0f); + // phase animation + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 7, 0.0f, 0.0f, 0.0f, 0.0f); - // fisheye sphere radius - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 8, 1.0f, 0.0f, 0.0f, 0.0f); + // fisheye sphere radius + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 8, 1.0f, 0.0f, 0.0f, 0.0f); - setWindowTitle(); + setWindowTitle(); - b['p'] = true; + doViewAll = true; + + b['p'] = true; - drawable.addKeyListener(new KeyAdapter() { - public void keyPressed(KeyEvent e) { - dispatchKey(e.getKeyCode(), e.getKeyChar()); - } - }); - - // Register the window with the ManipManager - ManipManager manager = ManipManager.getManipManager(); - manager.registerWindow(drawable); - - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); - viewer.setNoAltKeyMode(true); - viewer.attach(drawable, new BSphereProvider() { - public BSphere getBoundingSphere() { - return new BSphere(new Vec3f(0, 0, 0), 1.0f); - } - }); - viewer.setVertFOV((float) Math.toRadians(60)); - viewer.setZNear(zNear); - viewer.setZFar(zFar); - } + drawable.addKeyListener(new KeyAdapter() { + public void keyPressed(KeyEvent e) { + dispatchKey(e.getKeyCode(), e.getKeyChar()); + } + }); - public void display(GLDrawable drawable) { - if (!firstRender) { - if (++frameCount == 30) { - timer.stop(); - System.err.println("Frames per second: " + (30.0f / timer.getDurationAsSeconds())); - timer.reset(); - timer.start(); - frameCount = 0; + // Register the window with the ManipManager + ManipManager manager = ManipManager.getManipManager(); + manager.registerWindow(drawable); + this.drawable = drawable; + + viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer.setNoAltKeyMode(true); + viewer.setAutoRedrawMode(false); + viewer.attach(drawable, new BSphereProvider() { + public BSphere getBoundingSphere() { + return new BSphere(new Vec3f(0, 0, 0), 1.0f); } - } else { - firstRender = false; + }); + viewer.setVertFOV((float) Math.toRadians(60)); + viewer.setZNear(zNear); + viewer.setZFar(zFar); + initComplete = true; + } + + public void display(GLAutoDrawable drawable) { + if (!initComplete) { + return; + } + + if (!firstRender) { + if (++frameCount == 30) { + timer.stop(); + System.err.println("Frames per second: " + (30.0f / timer.getDurationAsSeconds())); + timer.reset(); timer.start(); + frameCount = 0; } + } else { + firstRender = false; + timer.start(); + } - time.update(); + time.update(); - GL gl = drawable.getGL(); - GLU glu = drawable.getGLU(); + GL gl = drawable.getGL(); - gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - if (toggleWire) { - wire = !wire; - if (wire) - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); - else - gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); - toggleWire = false; - } + if (toggleWire) { + wire = !wire; + if (wire) + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE); + else + gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL); + toggleWire = false; + } - gl.glPushMatrix(); + gl.glPushMatrix(); - if (doViewAll) { - viewer.viewAll(gl); - doViewAll = false; - } + if (doViewAll) { + viewer.viewAll(gl); + doViewAll = false; + } - if (animating) { - anim -= (float) (animScale * time.deltaT()); - } + if (animating) { + anim -= (float) (animScale * time.deltaT()); + } - viewer.update(gl); - ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters()); - ManipManager.getManipManager().render(drawable, gl); + viewer.update(gl); + ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters()); + ManipManager.getManipManager().render(drawable, gl); - gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, programs[program]); - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 7, anim, 0.0f, 0.0f, 0.0f); + gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, programs[program]); + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 7, anim, 0.0f, 0.0f, 0.0f); - if (program==6) - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 6, (float) Math.sin(anim)*amp*50.0f, 0.0f, 0.0f, 0.0f); - else - gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 6, freq, amp, d, d+1); + if (program==6) + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 6, (float) Math.sin(anim)*amp*50.0f, 0.0f, 0.0f, 0.0f); + else + gl.glProgramEnvParameter4fARB(GL.GL_VERTEX_PROGRAM_ARB, 6, freq, amp, d, d+1); - if (b['p']) - gl.glEnable(GL.GL_VERTEX_PROGRAM_ARB); + if (b['p']) + gl.glEnable(GL.GL_VERTEX_PROGRAM_ARB); - gl.glDisable(GL.GL_TEXTURE_2D); - gl.glCallList(obj+1); + gl.glDisable(GL.GL_TEXTURE_2D); + gl.glCallList(obj+1); - gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB); + gl.glDisable(GL.GL_VERTEX_PROGRAM_ARB); - gl.glPopMatrix(); - } + gl.glPopMatrix(); + } - // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + // Unused routines + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + + //---------------------------------------------------------------------- + // Internals only below this point + // + public void shutdownDemo() { + ManipManager.getManipManager().unregisterWindow(drawable); + drawable.removeGLEventListener(this); + super.shutdownDemo(); + } - //---------------------------------------------------------------------- - // Internals only below this point - // - private void initExtension(GL gl, String glExtensionName) { - if (!gl.isExtensionAvailable(glExtensionName)) { - final String message = "OpenGL extension \"" + glExtensionName + "\" not available"; - new Thread(new Runnable() { - public void run() { - JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); - runExit(); - } - }).start(); - throw new RuntimeException(message); - } + private void initExtension(GL gl, String glExtensionName) { + if (!gl.isExtensionAvailable(glExtensionName)) { + final String message = "OpenGL extension \"" + glExtensionName + "\" not available"; + new Thread(new Runnable() { + public void run() { + JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); + shutdownDemo(); + } + }).start(); + throw new RuntimeException(message); } + } - private void dispatchKey(int keyCode, char k) { - if (k < 256) - b[k] = !b[k]; - - switch (keyCode) { - case KeyEvent.VK_HOME: - case KeyEvent.VK_R: - anim = 0.0f; - amp = 0.05f; - freq = 8.0f; - d = 4.0f; - doViewAll = true; - break; - - case KeyEvent.VK_LEFT: - case KeyEvent.VK_KP_LEFT: - program--; - if (program < 0) - program = NUM_PROGS-1; - setWindowTitle(); - break; - - case KeyEvent.VK_RIGHT: - case KeyEvent.VK_KP_RIGHT: - program = (program + 1) % NUM_PROGS; - setWindowTitle(); - break; - - case KeyEvent.VK_F1: - case KeyEvent.VK_H: - String endl = System.getProperty("line.separator"); - endl = endl + endl; - String msg = ("F1/h - Help" + endl + - "Home - Reset" + endl + - "Left Button & Mouse - Rotate viewpoint" + endl + - "1..5 - Switch object (Sphere, Torus, Triceratop, Cube, Cylinder)" + endl + - "- / + - Change amplitude" + endl + - "[ / ] - Change frequency" + endl + - ", / . - Change square fisheye size" + endl + - "Left - Next vertex program" + endl + - "Right - Previous vertex program" + endl + - "W - Toggle wireframe" + endl + - "Space - Toggle animation" + endl + - "Esc/q - Exit program" + endl); - JOptionPane.showMessageDialog(null, msg, "Help", JOptionPane.INFORMATION_MESSAGE); - break; - - case KeyEvent.VK_ESCAPE: - case KeyEvent.VK_Q: - runExit(); - return; - - case KeyEvent.VK_W: - toggleWire = true; - break; - - case KeyEvent.VK_EQUALS: - case KeyEvent.VK_PLUS: - amp += 0.01; - break; - - case KeyEvent.VK_MINUS: - amp -= 0.01; - break; - - case KeyEvent.VK_CLOSE_BRACKET: - freq += 0.5; - break; - - case KeyEvent.VK_OPEN_BRACKET: - freq -= 0.5; - break; - - case KeyEvent.VK_PERIOD: - d += 0.1; - break; - - case KeyEvent.VK_COMMA: - d -= 0.1; - break; - - case KeyEvent.VK_SPACE: - // Could also start/stop Animator here - animating = !animating; - break; - - case KeyEvent.VK_1: - obj = 0; - break; - - case KeyEvent.VK_2: - obj = 1; - break; - - case KeyEvent.VK_3: - obj = 2; - break; - - case KeyEvent.VK_4: - obj = 3; - break; - - case KeyEvent.VK_5: - obj = 4; - break; - } - } + private void dispatchKey(int keyCode, char k) { + if (k < 256) + b[k] = !b[k]; + + switch (keyCode) { + case KeyEvent.VK_HOME: + case KeyEvent.VK_R: + anim = 0.0f; + amp = 0.05f; + freq = 8.0f; + d = 4.0f; + doViewAll = true; + break; + + case KeyEvent.VK_LEFT: + case KeyEvent.VK_KP_LEFT: + program--; + if (program < 0) + program = NUM_PROGS-1; + setWindowTitle(); + break; - private void setWindowTitle() { - frame.setTitle("SpaceWarp - " + programNames[program]); + case KeyEvent.VK_RIGHT: + case KeyEvent.VK_KP_RIGHT: + program = (program + 1) % NUM_PROGS; + setWindowTitle(); + break; + + case KeyEvent.VK_F1: + case KeyEvent.VK_H: + String endl = System.getProperty("line.separator"); + endl = endl + endl; + String msg = ("F1/h - Help" + endl + + "Home - Reset" + endl + + "Left Button & Mouse - Rotate viewpoint" + endl + + "1..5 - Switch object (Sphere, Torus, Triceratop, Cube, Cylinder)" + endl + + "- / + - Change amplitude" + endl + + "[ / ] - Change frequency" + endl + + ", / . - Change square fisheye size" + endl + + "Left - Next vertex program" + endl + + "Right - Previous vertex program" + endl + + "W - Toggle wireframe" + endl + + "Space - Toggle animation" + endl + + "Esc/q - Exit program" + endl); + JOptionPane.showMessageDialog(null, msg, "Help", JOptionPane.INFORMATION_MESSAGE); + break; + + case KeyEvent.VK_ESCAPE: + case KeyEvent.VK_Q: + shutdownDemo(); + return; + + case KeyEvent.VK_W: + toggleWire = true; + break; + + case KeyEvent.VK_EQUALS: + case KeyEvent.VK_PLUS: + amp += 0.01; + break; + + case KeyEvent.VK_MINUS: + amp -= 0.01; + break; + + case KeyEvent.VK_CLOSE_BRACKET: + freq += 0.5; + break; + + case KeyEvent.VK_OPEN_BRACKET: + freq -= 0.5; + break; + + case KeyEvent.VK_PERIOD: + d += 0.1; + break; + + case KeyEvent.VK_COMMA: + d -= 0.1; + break; + + case KeyEvent.VK_SPACE: + // Could also start/stop Animator here + animating = !animating; + break; + + case KeyEvent.VK_1: + obj = 0; + break; + + case KeyEvent.VK_2: + obj = 1; + break; + + case KeyEvent.VK_3: + obj = 2; + break; + + case KeyEvent.VK_4: + obj = 3; + break; + + case KeyEvent.VK_5: + obj = 4; + break; } + } - private void drawObject(GL gl, GLU glu, int which) { - switch(which) { - case 0: - drawSphere(gl, 0.5f, 100, 100); - break; - - case 1: - drawTorus(gl, 0.25f, 0.5f, 100, 100); - break; - - case 2: - try { - Triceratops.drawObject(gl); - } catch (IOException e) { - runExit(); - throw new RuntimeException(e); - } - break; + private void setWindowTitle() { + titleSetter.setTitle("SpaceWarp - " + programNames[program]); + } + + private void drawObject(GL gl, int which) { + switch(which) { + case 0: + drawSphere(gl, 0.5f, 100, 100); + break; - case 3: - drawCube(gl); - break; + case 1: + drawTorus(gl, 0.25f, 0.5f, 100, 100); + break; - case 4: - drawCylinder(gl, glu); - break; + case 2: + try { + Triceratops.drawObject(gl); + } catch (IOException e) { + shutdownDemo(); + throw new RuntimeException(e); } + break; + + case 3: + drawCube(gl); + break; + + case 4: + drawCylinder(gl); + break; } + } - private void drawSphere(GL gl, float radius, int slices, int stacks) { - int J = stacks; - int I = slices; - for(int j = 0; j < J; j++) { - float v = j/(float) J; - float phi = (float) (v * 2 * Math.PI); - float v2 = (j+1)/(float) J; - float phi2 = (float) (v2 * 2 * Math.PI); - - gl.glBegin(GL.GL_QUAD_STRIP); - for(int i = 0; i < I; i++) { - float u = i/(I-1.0f); - float theta = (float) (u * Math.PI); - float x,y,z,nx,ny,nz; - - nx = (float) (Math.cos(theta)*Math.cos(phi)); - ny = (float) (Math.sin(theta)*Math.cos(phi)); - nz = (float) (Math.sin(phi)); - x = radius * nx; - y = radius * ny; - z = radius * nz; - - gl.glColor3f ( u, v, 0.0f); - gl.glNormal3f(nx, ny, nz); - gl.glVertex3f( x, y, z); - - nx = (float) (Math.cos(theta)*Math.cos(phi2)); - ny = (float) (Math.sin(theta)*Math.cos(phi2)); - nz = (float) (Math.sin(phi2)); - x = radius * nx; - y = radius * ny; - z = radius * nz; - - gl.glColor3f ( u, v+(1.0f/(J-1.0f)), 0.0f); - gl.glNormal3f(nx, ny, nz); - gl.glVertex3f( x, y, z); - } - gl.glEnd(); + private void drawSphere(GL gl, float radius, int slices, int stacks) { + int J = stacks; + int I = slices; + for(int j = 0; j < J; j++) { + float v = j/(float) J; + float phi = (float) (v * 2 * Math.PI); + float v2 = (j+1)/(float) J; + float phi2 = (float) (v2 * 2 * Math.PI); + + gl.glBegin(GL.GL_QUAD_STRIP); + for(int i = 0; i < I; i++) { + float u = i/(I-1.0f); + float theta = (float) (u * Math.PI); + float x,y,z,nx,ny,nz; + + nx = (float) (Math.cos(theta)*Math.cos(phi)); + ny = (float) (Math.sin(theta)*Math.cos(phi)); + nz = (float) (Math.sin(phi)); + x = radius * nx; + y = radius * ny; + z = radius * nz; + + gl.glColor3f ( u, v, 0.0f); + gl.glNormal3f(nx, ny, nz); + gl.glVertex3f( x, y, z); + + nx = (float) (Math.cos(theta)*Math.cos(phi2)); + ny = (float) (Math.sin(theta)*Math.cos(phi2)); + nz = (float) (Math.sin(phi2)); + x = radius * nx; + y = radius * ny; + z = radius * nz; + + gl.glColor3f ( u, v+(1.0f/(J-1.0f)), 0.0f); + gl.glNormal3f(nx, ny, nz); + gl.glVertex3f( x, y, z); } + gl.glEnd(); } + } - private void drawTorus(GL gl, float meridian_radius, float core_radius, - int meridian_slices, int core_slices) { - int J = meridian_slices; - int I = core_slices; - for(int j = 0; j < J-1; j++) { - float v = j/(J-1.0f); - float rho = (float) (v * 2.0f * Math.PI); - float v2 = (j+1)/(J-1.0f); - float rho2 = (float) (v2 * 2.0f * Math.PI); - gl.glBegin(GL.GL_QUAD_STRIP); - for(int i = 0; i < I; i++) { - float u = i/(I-1.0f); - float theta = (float) (u * 2.0f * Math.PI); - float x,y,z,nx,ny,nz; - - x = (float) (core_radius*Math.cos(theta) + meridian_radius*Math.cos(theta)*Math.cos(rho)); - y = (float) (core_radius*Math.sin(theta) + meridian_radius*Math.sin(theta)*Math.cos(rho)); - z = (float) (meridian_radius*Math.sin(rho)); - nx = (float) (Math.cos(theta)*Math.cos(rho)); - ny = (float) (Math.sin(theta)*Math.cos(rho)); - nz = (float) (Math.sin(rho)); - - gl.glColor3f ( u, v, 0.0f); - gl.glNormal3f(nx, ny, nz); - gl.glVertex3f( x, y, z); - - x = (float) (core_radius*Math.cos(theta) + meridian_radius*Math.cos(theta)*Math.cos(rho2)); - y = (float) (core_radius*Math.sin(theta) + meridian_radius*Math.sin(theta)*Math.cos(rho2)); - z = (float) (meridian_radius*Math.sin(rho2)); - nx = (float) (Math.cos(theta)*Math.cos(rho2)); - ny = (float) (Math.sin(theta)*Math.cos(rho2)); - nz = (float) (Math.sin(rho2)); - - gl.glColor3f ( u, v, 0.0f); - gl.glNormal3f(nx, ny, nz); - gl.glVertex3f( x, y, z); - } - gl.glEnd(); + private void drawTorus(GL gl, float meridian_radius, float core_radius, + int meridian_slices, int core_slices) { + int J = meridian_slices; + int I = core_slices; + for(int j = 0; j < J-1; j++) { + float v = j/(J-1.0f); + float rho = (float) (v * 2.0f * Math.PI); + float v2 = (j+1)/(J-1.0f); + float rho2 = (float) (v2 * 2.0f * Math.PI); + gl.glBegin(GL.GL_QUAD_STRIP); + for(int i = 0; i < I; i++) { + float u = i/(I-1.0f); + float theta = (float) (u * 2.0f * Math.PI); + float x,y,z,nx,ny,nz; + + x = (float) (core_radius*Math.cos(theta) + meridian_radius*Math.cos(theta)*Math.cos(rho)); + y = (float) (core_radius*Math.sin(theta) + meridian_radius*Math.sin(theta)*Math.cos(rho)); + z = (float) (meridian_radius*Math.sin(rho)); + nx = (float) (Math.cos(theta)*Math.cos(rho)); + ny = (float) (Math.sin(theta)*Math.cos(rho)); + nz = (float) (Math.sin(rho)); + + gl.glColor3f ( u, v, 0.0f); + gl.glNormal3f(nx, ny, nz); + gl.glVertex3f( x, y, z); + + x = (float) (core_radius*Math.cos(theta) + meridian_radius*Math.cos(theta)*Math.cos(rho2)); + y = (float) (core_radius*Math.sin(theta) + meridian_radius*Math.sin(theta)*Math.cos(rho2)); + z = (float) (meridian_radius*Math.sin(rho2)); + nx = (float) (Math.cos(theta)*Math.cos(rho2)); + ny = (float) (Math.sin(theta)*Math.cos(rho2)); + nz = (float) (Math.sin(rho2)); + + gl.glColor3f ( u, v, 0.0f); + gl.glNormal3f(nx, ny, nz); + gl.glVertex3f( x, y, z); } + gl.glEnd(); } + } - private void drawCube(GL gl) { - int cr = 40; - float scaleFactor = 0.5f; - - // back - gl.glColor3f(1.0f, 0.0f, 0.0f); - gl.glNormal3f(0.0f, 0.0f, -1.0f); - drawGrid(gl, cr, cr, scaleFactor, -1.0f, -1.0f, -1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 2.0f, 0.0f); - - // front - gl.glColor3f(1.0f, 0.0f, 0.0f); - gl.glNormal3f(0.0f, 0.0f, 1.0f); - drawGrid(gl, cr, cr, scaleFactor, -1.0f, -1.0f, 1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 2.0f, 0.0f); - - // left - gl.glColor3f(0.0f, 1.0f, 0.0f); - gl.glNormal3f(-1.0f, 0.0f, 0.0f); - drawGrid(gl, cr, cr, scaleFactor, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 2.0f, 0.0f); - - // right - gl.glColor3f(0.0f, 0.0f, 1.0f); - gl.glNormal3f(1.0f, 0.0f, 0.0f); - drawGrid(gl, cr, cr, scaleFactor, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 2.0f, 0.0f); - - // bottom - gl.glColor3f(1.0f, 1.0f, 0.0f); - gl.glNormal3f(0.0f,-1.0f, 0.0f); - drawGrid(gl, cr, cr, scaleFactor, -1.0f, -1.0f, -1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f); - - // top - gl.glColor3f(0.0f, 1.0f, 1.0f); - gl.glNormal3f(0.0f, 1.0f, 0.0f); - drawGrid(gl, cr, cr, scaleFactor, -1.0f, 1.0f, -1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f); - } + private void drawCube(GL gl) { + int cr = 40; + float scaleFactor = 0.5f; + + // back + gl.glColor3f(1.0f, 0.0f, 0.0f); + gl.glNormal3f(0.0f, 0.0f, -1.0f); + drawGrid(gl, cr, cr, scaleFactor, -1.0f, -1.0f, -1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 2.0f, 0.0f); + + // front + gl.glColor3f(1.0f, 0.0f, 0.0f); + gl.glNormal3f(0.0f, 0.0f, 1.0f); + drawGrid(gl, cr, cr, scaleFactor, -1.0f, -1.0f, 1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 2.0f, 0.0f); + + // left + gl.glColor3f(0.0f, 1.0f, 0.0f); + gl.glNormal3f(-1.0f, 0.0f, 0.0f); + drawGrid(gl, cr, cr, scaleFactor, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 2.0f, 0.0f); + + // right + gl.glColor3f(0.0f, 0.0f, 1.0f); + gl.glNormal3f(1.0f, 0.0f, 0.0f); + drawGrid(gl, cr, cr, scaleFactor, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 2.0f, 0.0f, 2.0f, 0.0f); + + // bottom + gl.glColor3f(1.0f, 1.0f, 0.0f); + gl.glNormal3f(0.0f,-1.0f, 0.0f); + drawGrid(gl, cr, cr, scaleFactor, -1.0f, -1.0f, -1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f); + + // top + gl.glColor3f(0.0f, 1.0f, 1.0f); + gl.glNormal3f(0.0f, 1.0f, 0.0f); + drawGrid(gl, cr, cr, scaleFactor, -1.0f, 1.0f, -1.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f); + } - private void drawGrid(GL gl, int rows, int cols, - float scaleFactor, - float sx, float sy, float sz, - float ux, float uy, float uz, - float vx, float vy, float vz) { - int x, y; - - for(y=0; y<rows; y++) { - gl.glBegin(GL.GL_QUAD_STRIP); - for(x=0; x<=cols; x++) { - float u = x / (float) cols; - float v = y / (float) rows; - float v2 = v + (1.0f / (float) rows); - - gl.glTexCoord2f(u, v); - gl.glVertex3f(scaleFactor * (sx + (u*ux) + (v*vx)), - scaleFactor * (sy + (u*uy) + (v*vy)), - scaleFactor * (sz + (u*uz) + (v*vz))); - - gl.glTexCoord2f(u, v2); - gl.glVertex3f(scaleFactor * (sx + (u*ux) + (v2*vx)), - scaleFactor * (sy + (u*uy) + (v2*vy)), - scaleFactor * (sz + (u*uz) + (v2*vz))); - } - gl.glEnd(); + private void drawGrid(GL gl, int rows, int cols, + float scaleFactor, + float sx, float sy, float sz, + float ux, float uy, float uz, + float vx, float vy, float vz) { + int x, y; + + for(y=0; y<rows; y++) { + gl.glBegin(GL.GL_QUAD_STRIP); + for(x=0; x<=cols; x++) { + float u = x / (float) cols; + float v = y / (float) rows; + float v2 = v + (1.0f / (float) rows); + + gl.glTexCoord2f(u, v); + gl.glVertex3f(scaleFactor * (sx + (u*ux) + (v*vx)), + scaleFactor * (sy + (u*uy) + (v*vy)), + scaleFactor * (sz + (u*uz) + (v*vz))); + + gl.glTexCoord2f(u, v2); + gl.glVertex3f(scaleFactor * (sx + (u*ux) + (v2*vx)), + scaleFactor * (sy + (u*uy) + (v2*vy)), + scaleFactor * (sz + (u*uz) + (v2*vz))); } + gl.glEnd(); } + } - private void drawCylinder(GL gl, GLU glu) { - GLUquadric quad; + private void drawCylinder(GL gl) { + GLUquadric quad; - quad = glu.gluNewQuadric(); - glu.gluQuadricDrawStyle (quad, GLU.GLU_FILL); - glu.gluQuadricOrientation(quad, GLU.GLU_OUTSIDE); - glu.gluQuadricNormals (quad, GLU.GLU_SMOOTH); - glu.gluQuadricTexture (quad, true); + quad = glu.gluNewQuadric(); + glu.gluQuadricDrawStyle (quad, GLU.GLU_FILL); + glu.gluQuadricOrientation(quad, GLU.GLU_OUTSIDE); + glu.gluQuadricNormals (quad, GLU.GLU_SMOOTH); + glu.gluQuadricTexture (quad, true); - gl.glMatrixMode(GL.GL_MODELVIEW); - gl.glPushMatrix(); - gl.glTranslatef(-1.0f, 0.0f, 0.0f); - gl.glRotatef (90.0f, 0.0f, 1.0f, 0.0f); + gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glPushMatrix(); + gl.glTranslatef(-1.0f, 0.0f, 0.0f); + gl.glRotatef (90.0f, 0.0f, 1.0f, 0.0f); - glu.gluCylinder(quad, 0.25f, 0.25f, 2.0f, 60, 30); - gl.glPopMatrix(); + glu.gluCylinder(quad, 0.25f, 0.25f, 2.0f, 60, 30); + gl.glPopMatrix(); - glu.gluDeleteQuadric(quad); - } + glu.gluDeleteQuadric(quad); } private static final String[] programNames = new String[] { @@ -1009,8 +1040,7 @@ public class VertexProgWarp { "END\n" }; - private void runExit() { - quit = true; + private static void runExit(final Animator animator) { // Note: calling System.exit() synchronously inside the draw, // reshape or init callbacks can lead to deadlocks on certain // platforms (in particular, X11) because the JAWT's locking diff --git a/src/demos/xtrans/InterpolatedFloat.java b/src/demos/xtrans/InterpolatedFloat.java new file mode 100755 index 0000000..398e3b4 --- /dev/null +++ b/src/demos/xtrans/InterpolatedFloat.java @@ -0,0 +1,29 @@ +package demos.xtrans; + +import gleem.linalg.*; + +/** A floating-point value which interpolates between specified start + and end values. */ + +public class InterpolatedFloat { + private float start; + private float end; + + /** Returns the starting value for the interpolation. */ + public float getStart() { return start; } + + /** Sets the starting value for the interpolation. */ + public void setStart(float val) { start = val; } + + /** Returns the ending value for the interpolation. */ + public float getEnd() { return end; } + + /** Sets the ending value for the interpolation. */ + public void setEnd(float val) { end = val; } + + /** Gets the current interpolated value at the specified fraction of + interpolation (0.0 - 1.0). */ + public float getCurrent(float fraction) { + return (start * (1.0f - fraction)) + (end * fraction); + } +} diff --git a/src/demos/xtrans/InterpolatedQuad2f.java b/src/demos/xtrans/InterpolatedQuad2f.java new file mode 100755 index 0000000..b7262d7 --- /dev/null +++ b/src/demos/xtrans/InterpolatedQuad2f.java @@ -0,0 +1,45 @@ +package demos.xtrans; + +import gleem.linalg.*; + +/** A quadrilateral of two-dimensional floating-point values which + interpolates between specified start and end values. */ + +public class InterpolatedQuad2f { + private Quad2f start; + private Quad2f end; + + /** Constructs a new InterpolatedQuad2f. By default both the start + and end quadrilaterals have all of their points set to the + origin. */ + public InterpolatedQuad2f() { + start = new Quad2f(); + end = new Quad2f(); + } + + /** Returns the starting value for the interpolation. */ + public Quad2f getStart() { + return start; + } + + /** Sets the starting value for the interpolation. */ + public void setStart(Quad2f quad) { + start.set(quad); + } + + /** Returns the ending value for the interpolation. */ + public Quad2f getEnd() { + return end; + } + + /** Sets the ending value for the interpolation. */ + public void setEnd(Quad2f quad) { + end.set(quad); + } + + /** Gets the current interpolated value at the specified fraction of + interpolation (0.0 - 1.0). */ + public Quad2f getCurrent(float fraction) { + return start.times(1.0f - fraction).plus(end.times(fraction)); + } +} diff --git a/src/demos/xtrans/InterpolatedQuad3f.java b/src/demos/xtrans/InterpolatedQuad3f.java new file mode 100755 index 0000000..895a458 --- /dev/null +++ b/src/demos/xtrans/InterpolatedQuad3f.java @@ -0,0 +1,45 @@ +package demos.xtrans; + +import gleem.linalg.*; + +/** A quadrilateral of three-dimensional floating-point values which + interpolates between specified start and end values. */ + +public class InterpolatedQuad3f { + private Quad3f start; + private Quad3f end; + + /** Constructs a new InterpolatedQuad3f. By default both the start + and end quadrilaterals have all of their points set to the + origin. */ + public InterpolatedQuad3f() { + start = new Quad3f(); + end = new Quad3f(); + } + + /** Returns the starting value for the interpolation. */ + public Quad3f getStart() { + return start; + } + + /** Sets the starting value for the interpolation. */ + public void setStart(Quad3f quad) { + start.set(quad); + } + + /** Returns the ending value for the interpolation. */ + public Quad3f getEnd() { + return end; + } + + /** Sets the ending value for the interpolation. */ + public void setEnd(Quad3f quad) { + end.set(quad); + } + + /** Gets the current interpolated value at the specified fraction of + interpolation (0.0 - 1.0). */ + public Quad3f getCurrent(float fraction) { + return start.times(1.0f - fraction).plus(end.times(fraction)); + } +} diff --git a/src/demos/xtrans/InterpolatedVec3f.java b/src/demos/xtrans/InterpolatedVec3f.java new file mode 100755 index 0000000..28c3051 --- /dev/null +++ b/src/demos/xtrans/InterpolatedVec3f.java @@ -0,0 +1,37 @@ +package demos.xtrans; + +import gleem.linalg.*; + +/** A vector of three-dimensional floating-point values which + interpolates between specified start and end values. */ + +public class InterpolatedVec3f { + private Vec3f start; + private Vec3f end; + + /** Constructs a new InterpolatedQuad2f. By default both the start + and end quadrilaterals have all of their points set to the + origin. */ + public InterpolatedVec3f() { + start = new Vec3f(); + end = new Vec3f(); + } + + /** Returns the starting value for the interpolation. */ + public Vec3f getStart() { return start; } + + /** Sets the starting value for the interpolation. */ + public void setStart(Vec3f vec) { start.set(vec); } + + /** Returns the ending value for the interpolation. */ + public Vec3f getEnd() { return end; } + + /** Sets the ending value for the interpolation. */ + public void setEnd(Vec3f vec) { end.set(vec); } + + /** Gets the current interpolated value at the specified fraction of + interpolation (0.0 - 1.0). */ + public Vec3f getCurrent(float fraction) { + return start.times(1.0f - fraction).plus(end.times(fraction)); + } +} diff --git a/src/demos/xtrans/Main.java b/src/demos/xtrans/Main.java new file mode 100755 index 0000000..07ee010 --- /dev/null +++ b/src/demos/xtrans/Main.java @@ -0,0 +1,229 @@ +package demos.xtrans; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.table.*; +import javax.swing.tree.*; + +/** Demonstration showing off XTDesktopPane. */ + +public class Main { + private XTDesktopPane desktop; + private XTBasicTransitionManager transManager; + + private static final int TABLE = 1; + private static final int TREE = 2; + + private Point loc = new Point(); + + private boolean scrollingEnabled = true; + private boolean rotationEnabled = true; + private boolean fadesEnabled = true; + private Random random; + + private void chooseNextTransition() { + // Only choose one if the user's constraints force us to + if (scrollingEnabled && rotationEnabled && fadesEnabled) { + return; + } + if (random == null) { + random = new Random(); + } + boolean fade = random.nextBoolean(); + if (!fadesEnabled) { + fade = false; + } + + XTBasicTransitionManager.Style style = XTBasicTransitionManager.STYLE_NO_MOTION; + if (scrollingEnabled) { + style = XTBasicTransitionManager.STYLE_SCROLL; + } else if (rotationEnabled) { + style = XTBasicTransitionManager.STYLE_ROTATE; + } + XTBasicTransitionManager.Direction direction = null; + switch (random.nextInt(4)) { + case 0: direction = XTBasicTransitionManager.DIR_LEFT; break; + case 1: direction = XTBasicTransitionManager.DIR_RIGHT; break; + case 2: direction = XTBasicTransitionManager.DIR_UP; break; + default: direction = XTBasicTransitionManager.DIR_DOWN; break; + } + transManager.setNextTransition(style, direction, fade); + } + + private void addWindow(int which) { + JInternalFrame frame = new JInternalFrame(); + frame.setResizable(true); + frame.setClosable(true); + frame.setVisible(true); + + switch (which) { + case TABLE: + { + frame.setTitle("Table Example"); + Object[][] data = produceTableData(3, 20); + DefaultTableModel model = new DefaultTableModel(data, new String[] { "A", "B", "C" }); + JTable table = new JTable(model); + JScrollPane scrollPane = new JScrollPane(table); + frame.getContentPane().add(scrollPane); + break; + } + + case TREE: + { + frame.setTitle("Tree Example"); + DefaultMutableTreeNode root = new DefaultMutableTreeNode(); + populateTree(root, 2); + JTree tree = new JTree(root); + tree.setRootVisible(false); + frame.getContentPane().add(tree); + break; + } + + default: + throw new IllegalArgumentException(); + } + + frame.setLocation(loc); + loc = new Point((loc.x + 20) % desktop.getWidth(), (loc.y + 20) % desktop.getHeight()); + frame.addInternalFrameListener(new InternalFrameAdapter() { + public void internalFrameClosing(InternalFrameEvent e) { + chooseNextTransition(); + } + }); + frame.pack(); + int sz = Math.min(desktop.getWidth() / 3, desktop.getHeight()); + frame.setSize(sz, sz); + chooseNextTransition(); + desktop.add(frame); + desktop.moveToFront(frame); + } + + private Object[][] produceTableData(int cols, int rows) { + Object[][] res = new Object[rows][]; + + Random r = new Random(); + + for (int i = 0; i < rows; i++) { + Object[] row = new Object[cols]; + for (int j = 0; j < cols; j++) { + row[j] = new Integer(r.nextInt(1000)); + } + res[i] = row; + } + + return res; + } + + private void populateTree(DefaultMutableTreeNode node, int depth) { + node.add(new DefaultMutableTreeNode("A")); + node.add(new DefaultMutableTreeNode("B")); + node.add(new DefaultMutableTreeNode("C")); + + if (depth > 0) { + for (Enumeration e = node.children(); e.hasMoreElements(); ) { + populateTree((DefaultMutableTreeNode) e.nextElement(), depth - 1); + } + } + } + + private void run(String[] args) { + JFrame frame = new JFrame("Desktop Demo"); + + JMenu menu = new JMenu("Actions"); + JMenuBar menuBar = new JMenuBar(); + JMenuItem item; + + item = new JMenuItem("Add Table"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + addWindow(TABLE); + } + }); + menu.add(item); + + item = new JMenuItem("Add Tree"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + addWindow(TREE); + } + }); + menu.add(item); + + item = new JMenuItem("Close all"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Component[] cs = desktop.getComponents(); + for (int i = 0; i < cs.length; i++) { + chooseNextTransition(); + desktop.remove(cs[i]); + } + } + }); + menu.add(item); + + item = new JMenuItem("Quit"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.exit(0); + } + }); + item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_MASK)); + menu.add(item); + + menuBar.add(menu); + + menu = new JMenu("Options"); + JCheckBoxMenuItem ckitem = new JCheckBoxMenuItem("Enable Scrolling"); + ckitem.setState(true); + ckitem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + scrollingEnabled = ((JCheckBoxMenuItem) e.getSource()).getState(); + } + }); + menu.add(ckitem); + + ckitem = new JCheckBoxMenuItem("Enable Rotation"); + ckitem.setState(true); + ckitem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + rotationEnabled = ((JCheckBoxMenuItem) e.getSource()).getState(); + } + }); + menu.add(ckitem); + + ckitem = new JCheckBoxMenuItem("Enable Fades"); + ckitem.setState(true); + ckitem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + fadesEnabled = ((JCheckBoxMenuItem) e.getSource()).getState(); + } + }); + menu.add(ckitem); + + menuBar.add(menu); + + frame.setJMenuBar(menuBar); + + desktop = new XTDesktopPane(); + transManager = (XTBasicTransitionManager) desktop.getTransitionManager(); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().add(desktop); + + DisplayMode cur = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode(); + int width = (int) (cur.getWidth() * 0.75f); + int height = (int) (width * 3.0f / 4.0f); + if (height >= 95.0f * cur.getHeight()) { + height = (int) (cur.getHeight() * 0.75f); + width = (int) (height * 4.0f / 3.0f); + } + frame.setSize(width, height); + frame.setVisible(true); + } + + public static void main(String[] args) { + new Main().run(args); + } +} diff --git a/src/demos/xtrans/OffscreenComponentWrapper.java b/src/demos/xtrans/OffscreenComponentWrapper.java new file mode 100755 index 0000000..760343d --- /dev/null +++ b/src/demos/xtrans/OffscreenComponentWrapper.java @@ -0,0 +1,122 @@ +package demos.xtrans; + +import java.awt.*; +import javax.swing.*; + +// Internal JOGL API references +import com.sun.opengl.impl.Debug; +// FIXME: debugging only +import com.sun.opengl.impl.Java2D; + +/** Provides an interposition point where we can install a new + Graphics object in the rendering pipeline. Because lightweight + components always delegate up to their parents to fetch Graphics + objects, we can use this point to swap in the off-screen + VolatileImage we're using for rendering. Applications should not + need to construct instances of this class directly, though they + may encounter them when traversing the component hierarchy created + by the OffscreenDesktopPane, since they are automatically inserted + during add operations. */ + +public class OffscreenComponentWrapper extends JComponent { + private static final boolean DEBUG = Debug.debug("OffscreenComponentWrapper"); + + /** Instantiates an OffscreenComponentWrapper. This should not be + called directly by applications. */ + public OffscreenComponentWrapper(Component arg) { + if (arg == null) { + throw new RuntimeException("Null argument"); + } + add(arg); + setOpaque(false); + } + + protected void addImpl(Component c, Object constraints, int index) { + if (getComponentCount() != 0) { + throw new RuntimeException("May only add one child"); + } + super.addImpl(c, constraints, index); + } + + /** Returns the sole child component of this one. */ + public Component getChild() { + if (getComponentCount() == 0) { + throw new RuntimeException("No child found"); + } + return getComponent(0); + } + + public void remove(int i) { + super.remove(i); + throw new RuntimeException("Should not call this"); + } + + public void remove(Component c) { + super.remove(c); + throw new RuntimeException("Should not call this"); + } + + /** Overrides the superclass's getGraphics() in order to provide a + correctly-translated Graphics object on the + OffscreenDesktopPane's back buffer. */ + public Graphics getGraphics() { + Component parent = getParent(); + if ((parent != null) && (parent instanceof OffscreenDesktopPane)) { + OffscreenDesktopPane desktop = (OffscreenDesktopPane) parent; + OffscreenDesktopManager manager = (OffscreenDesktopManager) desktop.getDesktopManager(); + // Find out where the component we're rendering lives on the back buffer + Graphics g = manager.getOffscreenGraphics(); + Rectangle bounds = manager.getBoundsOnBackBuffer(getChild()); + if (bounds == null) { + if (DEBUG) { + System.err.println("No bounds for child"); + } + + // Not yet laid out on back buffer; however, avoid painting to + // screen + return g; + } + if (DEBUG) { + System.err.println("Graphics.translate(" + bounds.x + "," + bounds.y + ")"); + System.err.println(" Surface identifier = " + Java2D.getOGLSurfaceIdentifier(g)); + } + + g.translate(bounds.x, bounds.y); + // Also take into account the translation of the child + Component c = getChild(); + g.translate(-c.getX(), -c.getY()); + // Make sure any changes the user made to the double-buffering + // of child components don't mess up the rendering results + OffscreenDesktopManager.switchDoubleBuffering(this, false); + // A child component will be performing drawing and therefore + // get the OpenGL copy of the back buffer out of sync; will need + // to repair it + // NOTE: in theory we should only need to set the copy back + // state on the OffscreenDesktopManager. However it seems that + // there are certain operations (like scrolling in a + // JScrollPane) that have unanticipated consequences, such as + // drawing into the Swing back buffer (which is heavily + // undesirable, because it can cause on-screen visual artifacts + // in our rendering paradigm) as well as potentially + // inadvertently copying regions of the back buffer from one + // place to another. Since we don't know the side effects of + // such operations we currently need to treat the entire back + // buffer as being dirty. + manager.setNeedsRedraw(); + // NOTE: this is a bit of a hack but we need to indicate to the + // parent desktop that it is dirty as well since one of its + // children (being painted by alternate means) needs to be + // redrawn + desktop.repaint(); + return g; + } else { + return super.getGraphics(); + } + } + + public void paintComponent(Graphics g) { + } + + protected void paintChildren(Graphics g) { + } +} diff --git a/src/demos/xtrans/OffscreenDesktopManager.java b/src/demos/xtrans/OffscreenDesktopManager.java new file mode 100755 index 0000000..656618f --- /dev/null +++ b/src/demos/xtrans/OffscreenDesktopManager.java @@ -0,0 +1,784 @@ +package demos.xtrans; + +import java.awt.*; +import java.awt.geom.*; +import java.awt.image.*; +import java.beans.*; +import java.nio.*; +import java.util.*; +import javax.swing.*; + +// Internal JOGL API references +import com.sun.opengl.impl.Debug; +// FIXME: debugging only +import com.sun.opengl.impl.Java2D; + +// FIXME: we need a way to lock a portion of the off-screen back +// buffer to be persistent for a while during component removals. It +// turns out that the removal process of JInternalFrames "mostly" +// works OK with temporarily preserving a region of the back buffer +// but in the case of redraws of the target component occurring after +// it has been removed (such as in the case of a GLJPanel being +// animated) we need to preserve that region. + +/** A DesktopManager implementation supporting off-screen rendering + and management of components' images for later compositing. */ + +public class OffscreenDesktopManager implements DesktopManager { + protected final static String HAS_BEEN_ICONIFIED_PROPERTY = "wasIconOnce"; + + protected VolatileImage offscreenBackBuffer; + + // Verious dirty states. + // + // STATE_CLEAN indicates that the OpenGL texture is in sync with the + // VolatileImage back buffer and that no (relatively expensive) copy + // back operations need be performed. + // + // STATE_COPY_BACK indicates that the VolatileImage back buffer must + // be copied back e.g. into an OpenGL texture, but that the back + // buffer's contents are clean. + // + // STATE_REDRAW indicates that all components need to be repainted + // on the back buffer. STATE_REDRAW implies STATE_COPY_BACK. + // + // STATE_RELAYOUT is the most expensive state, in which all + // components are re-laid out on the back buffer and repainted + // completely. This implies STATE_REDRAW, which in turn implies + // STATE_COPY_BACK. + public static final int STATE_CLEAN = 0; + public static final int STATE_COPY_BACK = 1; + public static final int STATE_REDRAW = 2; + public static final int STATE_RELAYOUT = 3; + + // We start off assuming that we need to lay out everything + protected int dirtyState = STATE_RELAYOUT; + + protected Map/*<Component, Rectangle>*/ componentPositionsOnBackBuffer = new WeakHashMap(); + + // For debugging + private static final boolean DEBUG = Debug.debug("OffscreenDesktopManager"); + private static final boolean VERBOSE = Debug.verbose(); + private JFrame debuggingFrame; + private JPanel debuggingPanel; + + public OffscreenDesktopManager() { + if (DEBUG) { + debuggingFrame = new JFrame("Debugging frame"); + debuggingPanel = new JPanel() { + public void paintComponent(Graphics g) { + if (offscreenBackBuffer != null) { + g.drawImage(offscreenBackBuffer, 0, 0, null); + } + } + }; + debuggingPanel.setDoubleBuffered(false); + debuggingFrame.getContentPane().add(debuggingPanel); + debuggingFrame.pack(); + debuggingFrame.setLocation(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDisplayMode().getWidth() / 2, 0); + debuggingFrame.setSize(256, 256); + debuggingFrame.setVisible(true); + } + } + + /** Sets the state bit in the desktop manager indicating that the + offscreen texture has changed and may need to be copied back + e.g. to an OpenGL texture. */ + public void setNeedsCopyBack() { + dirtyState = Math.max(dirtyState, STATE_COPY_BACK); + } + + /** Sets the state bit in the desktop manager indicating that the + child components need to be redrawn to the off-screen buffer. */ + public void setNeedsRedraw() { + dirtyState = Math.max(dirtyState, STATE_REDRAW); + } + + /** Sets the state bit in the desktop manager indicating that the + components need to be re-laid out on the off-screen back buffer. + This implies that all of these components need to be repainted + and also implies that the off-screen back buffer may need to be + copied back (needsCopyBack()). */ + public void setNeedsReLayout() { + dirtyState = Math.max(dirtyState, STATE_RELAYOUT); + } + + /** Returns the state bit in the desktop manager indicating that the + offscreen texture has changed and may need to be copied back + e.g. to an OpenGL texture. */ + public boolean needsCopyBack() { + return (dirtyState >= STATE_COPY_BACK); + } + + /** Returns the state bit in the desktop manager indicating that the + child components need to be redrawn to the off-screen buffer. */ + public boolean needsRedraw() { + return (dirtyState >= STATE_REDRAW); + } + + /** Returns the state bit in the desktop manager indicating that the + components need to be re-laid out on the off-screen back buffer. + This implies that all of these components need to be repainted + and also implies that the off-screen back buffer may need to be + copied back (needsCopyBack()). */ + public boolean needsReLayout() { + return (dirtyState >= STATE_RELAYOUT); + } + + /** Returns the default graphics configuration of the default screen + device for the local graphics environment. */ + protected GraphicsConfiguration getDefaultConfiguration() { + return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); + } + + /** Fetches the Graphics object corresponding to the off-screen back + buffer. */ + public Graphics getOffscreenGraphics() { + return offscreenBackBuffer.getGraphics(); + } + + /** Fetches the Image being used as the back buffer. */ + public Image getOffscreenBackBuffer() { + return offscreenBackBuffer; + } + + /** Returns the width of the off-screen back buffer at this point in + time, or -1 if it has not been created yet. */ + public int getOffscreenBackBufferWidth() { + return offscreenBackBuffer.getWidth(); + } + + /** Returns the height of the off-screen back buffer at this point + in time, or -1 if it has not been created yet. */ + public int getOffscreenBackBufferHeight() { + return offscreenBackBuffer.getHeight(); + } + + /** Fetches the Rectangle corresponding to the bounds of the given + child component on the off-screen back buffer. This portion of + the back buffer can be drawn manually by the end user to display + the given component. */ + public Rectangle getBoundsOnBackBuffer(Component c) { + return (Rectangle) componentPositionsOnBackBuffer.get(c); + } + + /** Updates the layouts of the components on the off-screen back + buffer without repainting the back buffer. This should always be + called after adding, removing or resizing child components. It + is called automatically by {@link #updateOffscreenBuffer + updateOffscreenBuffer}. */ + public void layoutOffscreenBuffer(OffscreenDesktopPane parent) { + if (needsReLayout()) { + // Must do the following: + // 1. Lay out the desktop pane's children on the off-screen back + // buffer, keeping track of where they went + // 2. Draw the children to the off-screen buffer + // (Not done here: 3. Use JOGL to copy the off-screen buffer to a + // texture for later consumption by the XTDesktopPane) + + ////////////////////////////////////////////////////////////////// + // // + // FIXME: must use a more efficient packing algorithm than this // + // // + ////////////////////////////////////////////////////////////////// + + // NOTE: this is the rectangle packing problem, which is NP-hard. + // We could go to arbitrary lengths in order to improve the + // efficiency of this packing. Ideally we would like to minimize + // wasted space and (probably) shoot for a somewhat-square layout. + // Because currently we're just trying to get things working, + // we're going to do the simplest layout possible: just line + // things up left-to-right. + int maxHeight = -1; + int widthSum = 0; + + // Two-pass algorithm, one getting maximum height and summing + // widths, and one laying things out + for (int i = 0; i < parent.getComponentCount(); i++) { + Component c = ((OffscreenComponentWrapper) parent.getComponent(i)).getChild(); + int w = c.getWidth(); + int h = c.getHeight(); + maxHeight = Math.max(maxHeight, h); + widthSum += w; + } + int curX = 0; + for (int i = 0; i < parent.getComponentCount(); i++) { + Component c = ((OffscreenComponentWrapper) parent.getComponent(i)).getChild(); + int w = c.getWidth(); + int h = c.getHeight(); + Rectangle r = new Rectangle(curX, 0, w, h); + componentPositionsOnBackBuffer.put(c, r); + curX += w; + } + + // Re-create off-screen buffer if necessary + int offscreenWidth = nextPowerOf2(widthSum); + int offscreenHeight = nextPowerOf2(maxHeight); + if ((offscreenBackBuffer == null) || + (offscreenWidth != offscreenBackBuffer.getWidth()) || + (offscreenHeight != offscreenBackBuffer.getHeight())) { + if (offscreenBackBuffer != null) { + offscreenBackBuffer.flush(); + } + offscreenBackBuffer = + getDefaultConfiguration().createCompatibleVolatileImage(offscreenWidth, + offscreenHeight); + } + + if (DEBUG) { + debuggingPanel.setPreferredSize(new Dimension(offscreenWidth, offscreenHeight)); + debuggingFrame.setSize(offscreenWidth + 10, offscreenHeight + 30); + } + + dirtyState = STATE_REDRAW; + } + } + + /** Updates the image on the off-screen back buffer. This should + always be called before attempting to draw the child components' + contents on the screen. If the child components' states are + clean, this method does nothing. Note that this changes the + state bits back to clean, so subclasses should capture the + current state before calling the superclass implementation. */ + public void updateOffscreenBuffer(OffscreenDesktopPane parent) { + if (!needsCopyBack()) { + // Cleanest possible state + return; + } + + layoutOffscreenBuffer(parent); + + boolean validated = false; + boolean done = false; + while (!done) { + if (needsRedraw()) { + boolean redrawn = false; + + do { + // Validate it + int res = offscreenBackBuffer.validate(getDefaultConfiguration()); + if (!((res == VolatileImage.IMAGE_OK) || + (res == VolatileImage.IMAGE_RESTORED))) { + // FIXME: fail more gracefully + throw new RuntimeException("Unable to validate VolatileImage"); + } + validated = true; + + // Lay out and render components + final Graphics g = offscreenBackBuffer.getGraphics(); + int curX = 0; + for (int i = 0; i < parent.getComponentCount(); i++) { + Component c = ((OffscreenComponentWrapper) parent.getComponent(i)).getChild(); + + if (c.isVisible()) { + // Ensure this component and all children have double + // buffering disabled to prevent incorrect rendering results. + // Should try to make this more efficient, but doesn't look + // like there's any way to listen for setDoubleBuffered + // changes; could however listen for hierarchy change events, + // which are more likely to break things, but these are + // expensive to deliver as well + switchDoubleBuffering(c, false); + + // NOTE: should probably be smarter about this and only + // paint components which really need it (consult + // RepaintManager?). However, experimentation has shown + // that at this point the RepaintManager is already in + // the process of painting the child components and its + // notion of the dirty regions has already been cleared. + + Rectangle r = (Rectangle) componentPositionsOnBackBuffer.get(c); + if (r == null) { + // May be bug or race condition; for now just skip this one + continue; + } + Graphics g2 = g.create(); + if (DEBUG && VERBOSE) { + System.err.println("Translating Graphics to (" + r.x + "," + r.y + ")"); + System.err.println(" Surface identifier = " + Java2D.getOGLSurfaceIdentifier(g2)); + } + g2.translate(r.x, r.y); + c.paint(g2); + g2.dispose(); + } + } + g.dispose(); + if (!offscreenBackBuffer.contentsLost()) { + redrawn = true; + done = true; + } + } while (!redrawn); + } + + // If we didn't need to re-layout and draw the components, we + // might still need to copy back their results to an OpenGL + // texture. Subclasses should override this method to do + // additional work afterward. + + if (!validated) { + int res = offscreenBackBuffer.validate(getDefaultConfiguration()); + if (!((res == VolatileImage.IMAGE_OK) || + (res == VolatileImage.IMAGE_RESTORED))) { + // FIXME: fail more gracefully + throw new RuntimeException("Unable to validate VolatileImage"); + } + if (res == VolatileImage.IMAGE_RESTORED) { + // The contents were blown away since the time of the last + // render, so force a re-render + setNeedsRedraw(); + } else { + done = true; + } + } + } + + dirtyState = STATE_CLEAN; + + // Subclasses would do the copy back here + + if (DEBUG) { + debuggingPanel.repaint(); + } + } + + public void openFrame(JInternalFrame f) { + if(getDesktopPaneParent(f.getDesktopIcon()) != null) { + getDesktopPaneParent(f.getDesktopIcon()).add(f); + removeIconFor(f); + } + + setNeedsReLayout(); + } + + public void closeFrame(JInternalFrame f) { + boolean findNext = f.isSelected(); + JDesktopPane c = getDesktopPaneParent(f); + if (findNext) + try { f.setSelected(false); } catch (PropertyVetoException e2) { } + if(c != null) { + c.remove(f.getParent()); + repaintPortionOfDesktop(c, f); + } + removeIconFor(f); + if(f.getNormalBounds() != null) + f.setNormalBounds(null); + if(wasIcon(f)) + setWasIcon(f, null); + if (findNext) activateNextFrame(c); + + setNeedsReLayout(); + } + + public void maximizeFrame(JInternalFrame f) { + if (f.isIcon()) { + try { + // In turn calls deiconifyFrame in the desktop manager. + // That method will handle the maximization of the frame. + f.setIcon(false); + } catch (PropertyVetoException e2) { + } + } else { + f.setNormalBounds(f.getBounds()); + Rectangle desktopBounds = getDesktopPaneParent(f).getBounds(); + setBoundsForFrame(f, 0, 0, + desktopBounds.width, desktopBounds.height); + } + + // Set the maximized frame as selected. + try { + f.setSelected(true); + } catch (PropertyVetoException e2) { + } + + setNeedsReLayout(); + } + + public void minimizeFrame(JInternalFrame f) { + // If the frame was an icon restore it back to an icon. + if (f.isIcon()) { + iconifyFrame(f); + return; + } + + if ((f.getNormalBounds()) != null) { + Rectangle r = f.getNormalBounds(); + f.setNormalBounds(null); + try { f.setSelected(true); } catch (PropertyVetoException e2) { } + setBoundsForFrame(f, r.x, r.y, r.width, r.height); + } + + setNeedsReLayout(); + } + + public void iconifyFrame(JInternalFrame f) { + JInternalFrame.JDesktopIcon desktopIcon; + Container c = getDesktopPaneParent(f); + JDesktopPane d = f.getDesktopPane(); + boolean findNext = f.isSelected(); + + desktopIcon = f.getDesktopIcon(); + if(!wasIcon(f)) { + Rectangle r = getBoundsForIconOf(f); + desktopIcon.setBounds(r.x, r.y, r.width, r.height); + setWasIcon(f, Boolean.TRUE); + } + + if (c == null) { + return; + } + + if (c instanceof JLayeredPane) { + JLayeredPane lp = (JLayeredPane)c; + int layer = lp.getLayer(f); + lp.putLayer(desktopIcon, layer); + } + + // If we are maximized we already have the normal bounds recorded + // don't try to re-record them, otherwise we incorrectly set the + // normal bounds to maximized state. + if (!f.isMaximum()) { + f.setNormalBounds(f.getBounds()); + } + c.remove(f); + c.add(desktopIcon); + try { + f.setSelected(false); + } catch (PropertyVetoException e2) { + } + + // Get topmost of the remaining frames + if (findNext) { + activateNextFrame(c); + } + + setNeedsReLayout(); + } + + protected void activateNextFrame(Container c) { + int i; + JInternalFrame nextFrame = null; + if (c == null) return; + for (i = 0; i < c.getComponentCount(); i++) { + if (c.getComponent(i) instanceof JInternalFrame) { + nextFrame = (JInternalFrame) c.getComponent(i); + break; + } + } + if (nextFrame != null) { + try { nextFrame.setSelected(true); } + catch (PropertyVetoException e2) { } + moveToFront(nextFrame); + } + else { + c.requestFocus(); + } + + // This operation will change the graphic contents of the + // offscreen buffer but not the positions of any of the windows + setNeedsCopyBack(); + } + + public void deiconifyFrame(JInternalFrame f) { + JInternalFrame.JDesktopIcon desktopIcon = f.getDesktopIcon(); + Container c = getDesktopPaneParent(desktopIcon); + if (c != null) { + c.add(f); + // If the frame is to be restored to a maximized state make + // sure it still fills the whole desktop. + if (f.isMaximum()) { + Rectangle desktopBounds = c.getBounds(); + if (f.getWidth() != desktopBounds.width || + f.getHeight() != desktopBounds.height) { + setBoundsForFrame(f, 0, 0, + desktopBounds.width, desktopBounds.height); + } + } + removeIconFor(f); + if (f.isSelected()) { + moveToFront(f); + } else { + try { + f.setSelected(true); + } catch (PropertyVetoException e2) { + } + } + } + + setNeedsReLayout(); + } + + public void activateFrame(JInternalFrame f) { + Container p = getDesktopPaneParent(f); + Component[] c; + JDesktopPane d = f.getDesktopPane(); + JInternalFrame currentlyActiveFrame = + (d == null) ? null : d.getSelectedFrame(); + // fix for bug: 4162443 + if(p == null) { + // If the frame is not in parent, its icon maybe, check it + p = getDesktopPaneParent(f.getDesktopIcon()); + if(p == null) + return; + } + // we only need to keep track of the currentActive InternalFrame, if any + if (currentlyActiveFrame == null){ + if (d != null) { d.setSelectedFrame(f);} + } else if (currentlyActiveFrame != f) { + // if not the same frame as the current active + // we deactivate the current + if (currentlyActiveFrame.isSelected()) { + try { + currentlyActiveFrame.setSelected(false); + } + catch(PropertyVetoException e2) {} + } + if (d != null) { d.setSelectedFrame(f);} + } + moveToFront(f); + + // This operation will change the graphic contents of the + // offscreen buffer but not the positions of any of the windows + // setNeedsCopyBack(); + setNeedsRedraw(); + + repaintPortionOfDesktop(f); + } + + public void deactivateFrame(JInternalFrame f) { + JDesktopPane d = f.getDesktopPane(); + JInternalFrame currentlyActiveFrame = + (d == null) ? null : d.getSelectedFrame(); + if (currentlyActiveFrame == f) + d.setSelectedFrame(null); + + // This operation will change the graphic contents of the + // offscreen buffer but not the positions of any of the windows + setNeedsRedraw(); + + repaintPortionOfDesktop(f); + } + + public void beginDraggingFrame(JComponent f) { + // Nothing to do any more because the DesktopPane handles this by + // redrawing from the off-screen buffer + } + + public void dragFrame(JComponent f, int newX, int newY) { + f.setLocation(newX, newY); + repaintPortionOfDesktop(f); + } + + public void endDraggingFrame(JComponent f) { + // NOTE: nothing to do any more because OffscreenDesktopPane + // subclasses handle this + } + + public void beginResizingFrame(JComponent f, int direction) { + } + + public void resizeFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) { + setBoundsForFrame(f, newX, newY, newWidth, newHeight); + repaintPortionOfDesktop(f); + } + + public void endResizingFrame(JComponent f) { + repaintPortionOfDesktop(f); + } + + public void setBoundsForFrame(JComponent f, int newX, int newY, int newWidth, int newHeight) { + boolean didResize = (f.getWidth() != newWidth || f.getHeight() != newHeight); + f.setBounds(newX, newY, newWidth, newHeight); + if(didResize) { + f.validate(); + } + setNeedsReLayout(); + } + + protected void removeIconFor(JInternalFrame f) { + JInternalFrame.JDesktopIcon di = f.getDesktopIcon(); + JDesktopPane c = getDesktopPaneParent(di); + if(c != null) { + c.remove(di); + repaintPortionOfDesktop(c, di); + } + } + + protected Rectangle getBoundsForIconOf(JInternalFrame f) { + // + // Get the icon for this internal frame and its preferred size + // + + JInternalFrame.JDesktopIcon icon = f.getDesktopIcon(); + Dimension prefSize = icon.getPreferredSize(); + // + // Get the parent bounds and child components. + // + + Container c = getDesktopPaneParent(f); + if (c == null) { + c = getDesktopPaneParent(f.getDesktopIcon()); + } + + if (c == null) { + /* the frame has not yet been added to the parent; how about (0,0) ?*/ + return new Rectangle(0, 0, prefSize.width, prefSize.height); + } + + Rectangle parentBounds = c.getBounds(); + Component [] components = c.getComponents(); + + + // + // Iterate through valid default icon locations and return the + // first one that does not intersect any other icons. + // + + Rectangle availableRectangle = null; + JInternalFrame.JDesktopIcon currentIcon = null; + + int x = 0; + int y = parentBounds.height - prefSize.height; + int w = prefSize.width; + int h = prefSize.height; + + boolean found = false; + + while (!found) { + + availableRectangle = new Rectangle(x,y,w,h); + + found = true; + + for ( int i=0; i<components.length; i++ ) { + + // + // Get the icon for this component + // + + if ( components[i] instanceof JInternalFrame ) { + currentIcon = ((JInternalFrame)components[i]).getDesktopIcon(); + } + else if ( components[i] instanceof JInternalFrame.JDesktopIcon ){ + currentIcon = (JInternalFrame.JDesktopIcon)components[i]; + } else + /* found a child that's neither an internal frame nor + an icon. I don't believe this should happen, but at + present it does and causes a null pointer exception. + Even when that gets fixed, this code protects against + the npe. hania */ + continue; + + // + // If this icon intersects the current location, get next location. + // + + if ( !currentIcon.equals(icon) ) { + if ( availableRectangle.intersects(currentIcon.getBounds()) ) { + found = false; + break; + } + } + } + + if (currentIcon == null) + /* didn't find any useful children above. This probably shouldn't + happen, but this check protects against an npe if it ever does + (and it's happening now) */ + return availableRectangle; + + x += currentIcon.getBounds().width; + + if ( x + w > parentBounds.width ) { + x = 0; + y -= h; + } + } + + return(availableRectangle); + } + + protected void setWasIcon(JInternalFrame f, Boolean value) { + if (value != null) { + f.putClientProperty(HAS_BEEN_ICONIFIED_PROPERTY, value); + } + } + + protected boolean wasIcon(JInternalFrame f) { + return (f.getClientProperty(HAS_BEEN_ICONIFIED_PROPERTY) == Boolean.TRUE); + } + + protected JDesktopPane getDesktopPaneParent(Component f) { + Container c = f.getParent(); + if (c == null) { + return null; + } + if (!(c instanceof OffscreenComponentWrapper)) { + throw new RuntimeException("Illegal component structure"); + } + Container parent = c.getParent(); + if (parent == null) { + return null; + } + if (!(parent instanceof JDesktopPane)) { + throw new RuntimeException("Illegal component structure"); + } + return (JDesktopPane) parent; + } + + private void moveToFront(Component f) { + Container c = getDesktopPaneParent(f); + if (c instanceof JDesktopPane) { + ((JDesktopPane) c).moveToFront(f.getParent()); + } + } + + private static int nextPowerOf2(int number) { + // Workaround for problems where 0 width or height are transiently + // seen during layout + if (number == 0) { + return 2; + } + + if (((number-1) & number) == 0) { + //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0 + return number; + } + int power = 0; + while (number > 0) { + number = number>>1; + power++; + } + return (1<<power); + } + + /** Repaints the portion of the desktop pane parent corresponding to + the given component. */ + protected void repaintPortionOfDesktop(Component comp) { + repaintPortionOfDesktop(getDesktopPaneParent(comp), comp); + } + + /** Repaints the portion of the passed desktop pane corresponding to + the given component. */ + protected void repaintPortionOfDesktop(JDesktopPane desktop, Component comp) { + // Indicate to the desktop pane that a certain portion of the + // on-screen representation is dirty. The desktop can map these + // coordinates to the positions of the windows if they are + // different. + Rectangle r = comp.getBounds(); + desktop.repaint(r.x, r.y, r.width, r.height); + } + + /** Helper function to force the double-buffering of an entire + component hierarchy to the on or off state. */ + public static void switchDoubleBuffering(Component root, boolean val) { + if (root instanceof JComponent) { + ((JComponent) root).setDoubleBuffered(val); + } + if (root instanceof Container) { + Container container = (Container) root; + for (int i = 0; i < container.getComponentCount(); i++) { + switchDoubleBuffering(container.getComponent(i), val); + } + } + } +} diff --git a/src/demos/xtrans/OffscreenDesktopPane.java b/src/demos/xtrans/OffscreenDesktopPane.java new file mode 100755 index 0000000..7800666 --- /dev/null +++ b/src/demos/xtrans/OffscreenDesktopPane.java @@ -0,0 +1,189 @@ +package demos.xtrans; + +import java.awt.*; +import java.awt.geom.*; +import java.util.*; +import javax.swing.*; + +// Internal JOGL API references +import com.sun.opengl.impl.Debug; + +/** A subclass of JDesktopPane which performs all of the rendering of + its child components into an off-screen buffer. Provides access to + this back buffer so subclasses can determine how to draw the + contents of the child windows to the screen. */ + +public class OffscreenDesktopPane extends JDesktopPane { + // + // Debugging functionality only + // + private static final boolean DEBUG = Debug.debug("OffscreenDesktopPane"); + private static final Color[] colors = { + Color.LIGHT_GRAY, + Color.CYAN, + Color.PINK, + Color.GRAY, + Color.MAGENTA, + Color.BLUE, + Color.ORANGE, + Color.DARK_GRAY, + Color.RED, + Color.YELLOW + }; + private int colorIdx; + + private Color getNextColor() { + Color c = colors[colorIdx]; + colorIdx = (colorIdx + 1) % colors.length; + return c; + } + + private Map/*<Component, Color>*/ componentColorMap; + + /** Constructs a new OffscreenDesktopPane. */ + public OffscreenDesktopPane() { + super(); + if (DEBUG) { + componentColorMap = new WeakHashMap(); + } + // Only use an OffscreenDesktopManager instance directly if we + // have not been subclassed + if (getClass() == OffscreenDesktopPane.class) { + setDesktopManager(new OffscreenDesktopManager()); + } + } + + /** Overrides superclass's addImpl to insert an + OffscreenComponentWrapper between the added component and this + one. The wrapper component produces Graphics objects used when + children repaint themselves directly. */ + protected void addImpl(Component c, Object constraints, int index) { + if (c instanceof OffscreenComponentWrapper) { + throw new RuntimeException("Should not add OffscreenComponentWrappers directly"); + } + OffscreenComponentWrapper wrapper = new OffscreenComponentWrapper(c); + // Note: this is essential in order to keep mouse events + // propagating correctly down the hierarchy + wrapper.setBounds(getBounds()); + OffscreenDesktopManager.switchDoubleBuffering(wrapper, false); + super.addImpl(wrapper, constraints, index); + if (DEBUG) { + componentColorMap.put(c, getNextColor()); + } + getOffscreenDesktopManager().setNeedsReLayout(); + repaint(); + } + + // In order to hide the presence of the OffscreenComponentWrapper a + // little more, we override remove to make it look like we can + // simply pass in the JInternalFrames inside the + // OffscreenComponentWrappers. There are some situations where we + // can't hide the presence of the OffscreenComponentWrapper (such as + // when calling getParent() of the JInternalFrame) so to avoid + // incorrect behavior of the rest of the toolkit we don't override + // getComponent() to skip the OffscreenComponentWrappers. + + /** Removes the component at the given index. */ + public void remove(int index) { + Component c = getComponent(index); + super.remove(index); + OffscreenDesktopManager.switchDoubleBuffering(c, true); + } + + /** Removes the specified component from this + OffscreenDesktopPane. This method accepts either the components + added by the application (which are not direct children of this + one) or the OffscreenComponentWrappers added implicitly by the + add() method. */ + public void remove(Component comp) { + comp = getWrapper(comp); + if (comp == null) { + // This component must not be one of our children + return; + } + super.remove(comp); + OffscreenDesktopManager.switchDoubleBuffering(comp, true); + } + + public void reshape(int x, int y, int w, int h) { + super.reshape(x, y, w, h); + Rectangle rect = new Rectangle(x, y, w, h); + Component[] cs = getComponents(); + for (int i = 0; i < cs.length; i++) { + // Note: this is essential in order to keep mouse events + // propagating correctly down the hierarchy + ((OffscreenComponentWrapper) cs[i]).setBounds(rect); + } + } + + /** Overridden from JLayeredPane for convenience when manipulating + child components. Accepts either the component added by the + application or the OffscreenComponentWrapper added implicitly by + the add() method. */ + public void setPosition(Component c, int position) { + super.setPosition(getWrapper(c), position); + } + + /** Paints all children of this OffscreenDesktopPane to the internal + off-screen buffer. Does no painting to the passed Graphics + object; this is the responsibility of subclasses. */ + protected void paintChildren(Graphics g) { + // Update desktop manager's offscreen buffer if necessary + getOffscreenDesktopManager().updateOffscreenBuffer(this); + + if (DEBUG) { + // Subclasses will need to override this behavior anyway, so + // only enable an on-screen representation if debugging is + // enabled. For now, simply paint colored rectangles indicating + // the on-screen locations of the windows. + final Component[] components = getRealChildComponents(); + int compCount = components.length; + for (int i = compCount - 1; i >= 0; i--) { + Component c = components[i]; + Rectangle r = c.getBounds(); + Color col = (Color) componentColorMap.get(c); + g.setColor(col); + g.fillRect(r.x, r.y, r.width, r.height); + } + } + } + + /** Fetches the real child components of this OffscreenDesktopPane, + skipping all OffscreenComponentWrappers implicitly added. */ + protected Component[] getRealChildComponents() { + Component[] cs = getComponents(); + for (int i = 0; i < cs.length; i++) { + cs[i] = ((OffscreenComponentWrapper) cs[i]).getChild(); + } + return cs; + } + + /** Returns the OffscreenDesktopManager associated with this + pane. */ + public OffscreenDesktopManager getOffscreenDesktopManager() { + return (OffscreenDesktopManager) getDesktopManager(); + } + + /** Returns the real child component of this OffscreenDesktopPane, + skipping the OffscreenComponentWrapper implicitly added. */ + protected static Component getRealComponent(Component c) { + if (c instanceof OffscreenComponentWrapper) { + return ((OffscreenComponentWrapper) c).getChild(); + } + return c; + } + + /** Returns the OffscreenComponentWrapper corresponding to the given + child component, or the passed component if it is already the + wrapper. */ + protected static Component getWrapper(Component c) { + if (c instanceof OffscreenComponentWrapper) { + return c; + } + Component parent = c.getParent(); + if (parent instanceof OffscreenComponentWrapper) { + return parent; + } + return null; + } +} diff --git a/src/demos/xtrans/Quad2f.java b/src/demos/xtrans/Quad2f.java new file mode 100755 index 0000000..008c3df --- /dev/null +++ b/src/demos/xtrans/Quad2f.java @@ -0,0 +1,74 @@ +package demos.xtrans; + +import gleem.linalg.*; + +/** A quadrilateral in which the vertices are two-dimensional + floating-point values. */ + +public class Quad2f { + private Vec2f[] vecs; + + public static final int UPPER_LEFT = 0; + public static final int LOWER_LEFT = 1; + public static final int LOWER_RIGHT = 2; + public static final int UPPER_RIGHT = 2; + + private static final int NUM_VECS = 4; + + /** Constructs a Quad2f in which all the vertices are set to the + origin. */ + public Quad2f() { + vecs = new Vec2f[NUM_VECS]; + for (int i = 0; i < NUM_VECS; i++) { + vecs[i] = new Vec2f(); + } + } + + /** Constructs a Quad2f in which the vertices are set to the + specified values. */ + public Quad2f(Vec2f upperLeft, + Vec2f lowerLeft, + Vec2f lowerRight, + Vec2f upperRight) { + this(); + setVec(0, upperLeft); + setVec(1, lowerLeft); + setVec(2, lowerRight); + setVec(3, upperRight); + } + + /** Sets the specified vertex to the specified value. */ + public void setVec(int which, Vec2f val) { + vecs[which].set(val); + } + + /** Returns the specified vertex. */ + public Vec2f getVec(int which) { + return vecs[which]; + } + + /** Sets all four points of this quadrilateral. */ + public void set(Quad2f quad) { + for (int i = 0; i < NUM_VECS; i++) { + setVec(i, quad.getVec(i)); + } + } + + /** Returns a newly-constructed Quad2f in which all vertices have + been multiplied in scalar fashion by the passed value. */ + public Quad2f times(float val) { + return new Quad2f(getVec(0).times(val), + getVec(1).times(val), + getVec(2).times(val), + getVec(3).times(val)); + } + + /** Returns a newly-constructed Quad2f in which the vertices are the + component-wise sums of this quad and the passed quad. */ + public Quad2f plus(Quad2f val) { + return new Quad2f(getVec(0).plus(val.getVec(0)), + getVec(1).plus(val.getVec(1)), + getVec(2).plus(val.getVec(2)), + getVec(3).plus(val.getVec(3))); + } +} diff --git a/src/demos/xtrans/Quad3f.java b/src/demos/xtrans/Quad3f.java new file mode 100755 index 0000000..a9f0dd7 --- /dev/null +++ b/src/demos/xtrans/Quad3f.java @@ -0,0 +1,74 @@ +package demos.xtrans; + +import gleem.linalg.*; + +/** A quadrilateral in which the vertices are three-dimensional + floating-point values. */ + +public class Quad3f { + private Vec3f[] vecs; + + public static final int UPPER_LEFT = 0; + public static final int LOWER_LEFT = 1; + public static final int LOWER_RIGHT = 2; + public static final int UPPER_RIGHT = 3; + + private static final int NUM_VECS = 4; + + /** Constructs a Quad3f in which all the vertices are set to the + origin. */ + public Quad3f() { + vecs = new Vec3f[NUM_VECS]; + for (int i = 0; i < NUM_VECS; i++) { + vecs[i] = new Vec3f(); + } + } + + /** Constructs a Quad3f in which the vertices are set to the + specified values. */ + public Quad3f(Vec3f upperLeft, + Vec3f lowerLeft, + Vec3f lowerRight, + Vec3f upperRight) { + this(); + setVec(0, upperLeft); + setVec(1, lowerLeft); + setVec(2, lowerRight); + setVec(3, upperRight); + } + + /** Sets the specified vertex to the specified value. */ + public void setVec(int which, Vec3f val) { + vecs[which].set(val); + } + + /** Returns the specified vertex. */ + public Vec3f getVec(int which) { + return vecs[which]; + } + + /** Sets all four points of this quadrilateral. */ + public void set(Quad3f quad) { + for (int i = 0; i < NUM_VECS; i++) { + setVec(i, quad.getVec(i)); + } + } + + /** Returns a newly-constructed Quad2f in which all vertices have + been multiplied in scalar fashion by the passed value. */ + public Quad3f times(float val) { + return new Quad3f(getVec(0).times(val), + getVec(1).times(val), + getVec(2).times(val), + getVec(3).times(val)); + } + + /** Returns a newly-constructed Quad2f in which the vertices are the + component-wise sums of this quad and the passed quad. */ + public Quad3f plus(Quad3f val) { + return new Quad3f(getVec(0).plus(val.getVec(0)), + getVec(1).plus(val.getVec(1)), + getVec(2).plus(val.getVec(2)), + getVec(3).plus(val.getVec(3))); + } +} diff --git a/src/demos/xtrans/XTBasicTransition.java b/src/demos/xtrans/XTBasicTransition.java new file mode 100755 index 0000000..a6bfd0f --- /dev/null +++ b/src/demos/xtrans/XTBasicTransition.java @@ -0,0 +1,151 @@ +package demos.xtrans; + +import javax.media.opengl.*; +import gleem.linalg.*; + +/** A basic transition supporting animated translation, rotation about + a pivot point, scrolling and fading effects. */ + +public class XTBasicTransition implements XTTransition { + protected Vec3f pivot = new Vec3f(); + protected Vec3f axis = new Vec3f(); + protected InterpolatedFloat angle; + protected InterpolatedVec3f translation; + protected InterpolatedQuad3f vertices; + protected InterpolatedQuad2f texcoords; + protected InterpolatedFloat alpha; + protected float percentage; + + /** Constructs a new transition object with all of its initial state + set to zero. */ + public XTBasicTransition() { + } + + public void update(float percentage) { + this.percentage = percentage; + } + + public void draw(GL gl) { + float percent = percentage; + Quad3f vts = vertices.getCurrent(percent); + Quad2f tex = texcoords.getCurrent(percent); + + if (translation != null) { + Vec3f trans = translation.getCurrent(percent); + gl.glTranslatef(trans.x(), trans.y(), trans.z()); + } + // Rotate about pivot point + gl.glTranslatef(pivot.x(), pivot.y(), pivot.z()); + if (angle != null) { + gl.glRotatef(angle.getCurrent(percent), axis.x(), axis.y(), axis.z()); + } + gl.glTranslatef(-pivot.x(), -pivot.y(), -pivot.z()); + + gl.glBegin(GL.GL_TRIANGLES); + float a = 1.0f; + if (alpha != null) { + a = alpha.getCurrent(percent); + } + gl.glColor4f(1, 1, 1, a); + // Triangle 1 + gl.glTexCoord2f(tex.getVec(0).x(), tex.getVec(0).y()); + gl.glVertex3f (vts.getVec(0).x(), vts.getVec(0).y(), vts.getVec(0).z()); + gl.glTexCoord2f(tex.getVec(1).x(), tex.getVec(1).y()); + gl.glVertex3f (vts.getVec(1).x(), vts.getVec(1).y(), vts.getVec(1).z()); + gl.glTexCoord2f(tex.getVec(3).x(), tex.getVec(3).y()); + gl.glVertex3f (vts.getVec(3).x(), vts.getVec(3).y(), vts.getVec(3).z()); + // Triangle 2 + gl.glTexCoord2f(tex.getVec(3).x(), tex.getVec(3).y()); + gl.glVertex3f (vts.getVec(3).x(), vts.getVec(3).y(), vts.getVec(3).z()); + gl.glTexCoord2f(tex.getVec(1).x(), tex.getVec(1).y()); + gl.glVertex3f (vts.getVec(1).x(), vts.getVec(1).y(), vts.getVec(1).z()); + gl.glTexCoord2f(tex.getVec(2).x(), tex.getVec(2).y()); + gl.glVertex3f (vts.getVec(2).x(), vts.getVec(2).y(), vts.getVec(2).z()); + gl.glEnd(); + } + + /** Returns the rotation axis for this transition. By default this + axis is not set, so if an interpolator is specified for the + rotation angle the axis of rotation must be specified as + well. */ + public Vec3f getRotationAxis() { return axis; } + + /** Sets the rotation axis for this transition. By default this axis + is not set, so if an interpolator is specified for the rotation + angle the axis of rotation must be specified as well. */ + public void setRotationAxis(Vec3f axis) { this.axis.set(axis); } + + /** Returns the interpolator for the rotation angle for this + transition. By default this interpolator is null, meaning that + the transition does not perform any rotation. */ + public InterpolatedFloat getRotationAngle() { return angle; } + + /** Sets the interpolator for the rotation angle for this + transition. By default this interpolator is null, meaning that + the transition does not perform any rotation. */ + public void setRotationAngle(InterpolatedFloat angle) { this.angle = angle; } + + /** Returns the pivot point for this transition's rotation. By + default this is set to the origin, which corresponds to the + upper-left corner of the component being animated. */ + public Vec3f getPivotPoint() { return pivot; } + + /** Sets the pivot point for this transition's rotation. By default + this is set to the origin, which corresponds to the upper-left + corner of the component being animated. */ + public void setPivotPoint(Vec3f point) { pivot.set(point); } + + /** Returns the interpolator for this transition's translation. By + default the translation is a fixed vector from the origin to the + upper left corner of the component being animated; the vertices + are specified relative to that point in the +x and -y + directions. */ + public InterpolatedVec3f getTranslation() { return translation; } + + /** Sets the interpolator for this transition's translation. By + default the translation is a fixed vector from the origin to the + upper left corner of the component being animated; the vertices + are specified relative to that point in the +x and -y + directions. */ + public void setTranslation(InterpolatedVec3f interp) { translation = interp; } + + /** Returns the interpolator for the vertices of this transition's + component when drawn on screen. By default the vertices are + specified with the upper-left corner of the component at the + origin and the component extending in the +x (right) and -y + (down) directions; the units of the vertices correspond to the + on-screen size of the component in pixels. The component's + location is specified using the translation interpolator. */ + public InterpolatedQuad3f getVertices() { return vertices; } + + /** Sets the interpolator for the vertices of this transition's + component when drawn on screen. By default the vertices are + specified with the upper-left corner of the component at the + origin and the component extending in the +x (right) and -y + (down) directions; the units of the vertices correspond to the + on-screen size of the component in pixels. The component's + location is specified using the translation interpolator. */ + public void setVertices(InterpolatedQuad3f interp) { vertices = interp; } + + /** Returns the interpolator for the texture coordinates of this + transition's component when drawn on screen. By default these + are set so that at either the start or end point (depending on + whether this is an "in" or "out" transition) the texture + coordinates specify rendering of the component's entire + contents. */ + public InterpolatedQuad2f getTexCoords() { return texcoords; } + + /** Sets the interpolator for the texture coordinates of this + transition's component when drawn on screen. By default these + are set so that at either the start or end point (depending on + whether this is an "in" or "out" transition) the texture + coordinates specify rendering of the component's entire + contents. */ + public void setTexCoords(InterpolatedQuad2f interp) { texcoords = interp; } + + /** Returns the interpolator for this component's alpha value. */ + public InterpolatedFloat getAlpha() { return alpha; } + + /** Sets the interpolator for this component's alpha value. */ + public void setAlpha(InterpolatedFloat interp) { alpha = interp; } +} diff --git a/src/demos/xtrans/XTBasicTransitionManager.java b/src/demos/xtrans/XTBasicTransitionManager.java new file mode 100755 index 0000000..85a94fb --- /dev/null +++ b/src/demos/xtrans/XTBasicTransitionManager.java @@ -0,0 +1,344 @@ +package demos.xtrans; + +import java.awt.*; +import java.awt.geom.*; +import java.util.*; +import gleem.linalg.*; + +/** A basic transition manager supporting animated scrolling, rotating + and fading of components. */ + +public class XTBasicTransitionManager implements XTTransitionManager { + /** Indicates the style of the transition (either no motion, + scrolling, or rotating). */ + public static class Style { + private Style() {} + } + + /** Indicates the component has no motion (scrolling or rotation) in + its animation. */ + public static Style STYLE_NO_MOTION = new Style(); + + /** Indicates the component is to be scrolled in to or out of + place. */ + public static Style STYLE_SCROLL = new Style(); + + /** Indicates the component is to be rotated in to or out of + place. */ + public static Style STYLE_ROTATE = new Style(); + + /** Indicates the direction of the transition if it contains any + motion (either up, down, left, or right). */ + public static class Direction { + private Direction() {} + } + + /** Indicates the component's animation is from or toward the left, + depending on whether the transition is an "in" or "out" + transition. */ + public static Direction DIR_LEFT = new Direction(); + + /** Indicates the component's animation is from or toward the right, + depending on whether the transition is an "in" or "out" + transition. */ + public static Direction DIR_RIGHT = new Direction(); + + /** Indicates the component's animation is in the upward + direction. */ + public static Direction DIR_UP = new Direction(); + + /** Indicates the component's animation is in the downward + direction. */ + public static Direction DIR_DOWN = new Direction(); + + private Style nextTransitionStyle; + private Direction nextTransitionDirection; + private boolean nextTransitionFade; + + private Random random; + + /** Sets the next transition to be used by this transition manager + for either an "in" or an "out" transition. By default the + transition manager selects random transitions from those + available. */ + public void setNextTransition(Style style, + Direction direction, + boolean fade) { + if (style == null) { + throw new IllegalArgumentException("Must supply a style"); + } + nextTransitionStyle = style; + nextTransitionDirection = direction; + nextTransitionFade = fade; + } + + /** Creates an XTBasicTransition for the given component. By default + this transition manager chooses a random transition from those + available if one is not specified via {@link #setNextTransition + setNextTransition}. */ + public XTTransition createTransitionForComponent(Component c, + boolean isAddition, + Rectangle oglViewportOfDesktop, + Point viewportOffsetFromOrigin, + Rectangle2D oglTexCoordsOnBackBuffer) { + if (nextTransitionStyle == null) { + chooseRandomTransition(); + } + + // Figure out the final positions of everything + // Keep in mind that the Java2D origin is at the upper left and + // the OpenGL origin is at the lower left + Rectangle bounds = c.getBounds(); + int x = bounds.x; + int y = bounds.y; + int w = bounds.width; + int h = bounds.height; + float tx = (float) oglTexCoordsOnBackBuffer.getX(); + float ty = (float) oglTexCoordsOnBackBuffer.getY(); + float tw = (float) oglTexCoordsOnBackBuffer.getWidth(); + float th = (float) oglTexCoordsOnBackBuffer.getHeight(); + float vx = oglViewportOfDesktop.x; + float vy = oglViewportOfDesktop.y; + float vw = oglViewportOfDesktop.width; + float vh = oglViewportOfDesktop.height; + Quad3f verts = new Quad3f(new Vec3f(0, 0, 0), + new Vec3f(0, -h, 0), + new Vec3f(w, -h, 0), + new Vec3f(w, 0, 0)); + Quad2f texcoords = new Quad2f(new Vec2f(tx, ty + th), + new Vec2f(tx, ty), + new Vec2f(tx + tw, ty), + new Vec2f(tx + tw, ty + th)); + + XTBasicTransition trans = new XTBasicTransition(); + + Vec3f translation = new Vec3f(x - viewportOffsetFromOrigin.x, + vh - y - viewportOffsetFromOrigin.y, + 0); + InterpolatedVec3f transInterp = new InterpolatedVec3f(); + transInterp.setStart(translation); + transInterp.setEnd(translation); + + InterpolatedQuad3f quadInterp = new InterpolatedQuad3f(); + quadInterp.setStart(verts); + quadInterp.setEnd(verts); + + InterpolatedQuad2f texInterp = new InterpolatedQuad2f(); + texInterp.setStart(texcoords); + texInterp.setEnd(texcoords); + + trans.setTranslation(transInterp); + trans.setVertices(quadInterp); + trans.setTexCoords(texInterp); + + // Now decide how we are going to handle this transition + Style transitionStyle = nextTransitionStyle; + Direction transitionDirection = nextTransitionDirection; + boolean fade = nextTransitionFade; + nextTransitionStyle = null; + nextTransitionDirection = null; + nextTransitionFade = false; + + int[] vtIdxs = null; + int[] ttIdxs = null; + Vec3f rotAxis = null; + Vec3f pivot = null; + float startAngle = 0; + float endAngle = 0; + + if (fade) { + InterpolatedFloat alpha = new InterpolatedFloat(); + float start = (isAddition ? 0.0f : 1.0f); + float end = (isAddition ? 1.0f : 0.0f); + alpha.setStart(start); + alpha.setEnd(end); + trans.setAlpha(alpha); + } + + if (transitionDirection != null) { + if (transitionStyle == STYLE_SCROLL) { + if (transitionDirection == DIR_LEFT) { + vtIdxs = new int[] { 3, 2, 2, 3 }; + ttIdxs = new int[] { 0, 1, 1, 0 }; + } else if (transitionDirection == DIR_RIGHT) { + vtIdxs = new int[] { 0, 1, 1, 0 }; + ttIdxs = new int[] { 3, 2, 2, 3 }; + } else if (transitionDirection == DIR_UP) { + vtIdxs = new int[] { 1, 1, 2, 2 }; + ttIdxs = new int[] { 0, 0, 3, 3 }; + } else { + // DIR_DOWN + vtIdxs = new int[] { 0, 0, 3, 3 }; + ttIdxs = new int[] { 1, 1, 2, 2 }; + } + } else if (transitionStyle == STYLE_ROTATE) { + if (transitionDirection == DIR_LEFT) { + rotAxis = new Vec3f(0, 1, 0); + pivot = new Vec3f(); + startAngle = -90; + endAngle = 0; + } else if (transitionDirection == DIR_RIGHT) { + rotAxis = new Vec3f(0, 1, 0); + pivot = new Vec3f(w, 0, 0); + startAngle = 90; + endAngle = 0; + } else if (transitionDirection == DIR_UP) { + rotAxis = new Vec3f(1, 0, 0); + pivot = new Vec3f(0, -h, 0); + startAngle = 90; + endAngle = 0; + } else { + // DIR_DOWN + rotAxis = new Vec3f(1, 0, 0); + pivot = new Vec3f(); + startAngle = -90; + endAngle = 0; + } + } + } + + + /* + switch (transitionType) { + case FADE: + { + InterpolatedFloat alpha = new InterpolatedFloat(); + float start = (isAddition ? 0.0f : 1.0f); + float end = (isAddition ? 1.0f : 0.0f); + alpha.setStart(start); + alpha.setEnd(end); + trans.setAlpha(alpha); + break; + } + case SCROLL_LEFT: + { + vtIdxs = new int[] { 3, 2, 2, 3 }; + ttIdxs = new int[] { 0, 1, 1, 0 }; + break; + } + case SCROLL_RIGHT: + { + vtIdxs = new int[] { 0, 1, 1, 0 }; + ttIdxs = new int[] { 3, 2, 2, 3 }; + break; + } + case SCROLL_UP: + { + vtIdxs = new int[] { 1, 1, 2, 2 }; + ttIdxs = new int[] { 0, 0, 3, 3 }; + break; + } + case SCROLL_DOWN: + { + vtIdxs = new int[] { 0, 0, 3, 3 }; + ttIdxs = new int[] { 1, 1, 2, 2 }; + break; + } + case ROTATE_LEFT: + { + rotAxis = new Vec3f(0, 1, 0); + pivot = new Vec3f(); + startAngle = -90; + endAngle = 0; + break; + } + case ROTATE_RIGHT: + { + rotAxis = new Vec3f(0, 1, 0); + // pivot = translation.plus(new Vec3f(w, 0, 0)); + pivot = new Vec3f(w, 0, 0); + startAngle = 90; + endAngle = 0; + break; + } + case ROTATE_UP: + { + rotAxis = new Vec3f(1, 0, 0); + // pivot = translation.plus(new Vec3f(0, -h, 0)); + pivot = new Vec3f(0, -h, 0); + startAngle = 90; + endAngle = 0; + break; + } + case ROTATE_DOWN: + { + rotAxis = new Vec3f(1, 0, 0); + pivot = new Vec3f(); + startAngle = -90; + endAngle = 0; + break; + } + } + + */ + + if (vtIdxs != null) { + if (isAddition) { + quadInterp.setStart(new Quad3f(verts.getVec(vtIdxs[0]), + verts.getVec(vtIdxs[1]), + verts.getVec(vtIdxs[2]), + verts.getVec(vtIdxs[3]))); + texInterp.setStart(new Quad2f(texcoords.getVec(ttIdxs[0]), + texcoords.getVec(ttIdxs[1]), + texcoords.getVec(ttIdxs[2]), + texcoords.getVec(ttIdxs[3]))); + } else { + // Note: swapping the vertex and texture indices happens to + // have the correct effect + int[] tmp = vtIdxs; + vtIdxs = ttIdxs; + ttIdxs = tmp; + + quadInterp.setEnd(new Quad3f(verts.getVec(vtIdxs[0]), + verts.getVec(vtIdxs[1]), + verts.getVec(vtIdxs[2]), + verts.getVec(vtIdxs[3]))); + texInterp.setEnd(new Quad2f(texcoords.getVec(ttIdxs[0]), + texcoords.getVec(ttIdxs[1]), + texcoords.getVec(ttIdxs[2]), + texcoords.getVec(ttIdxs[3]))); + } + } else if (rotAxis != null) { + if (!isAddition) { + float tmp = endAngle; + endAngle = -startAngle; + startAngle = tmp; + } + + trans.setPivotPoint(pivot); + trans.setRotationAxis(rotAxis); + InterpolatedFloat rotInterp = new InterpolatedFloat(); + rotInterp.setStart(startAngle); + rotInterp.setEnd(endAngle); + trans.setRotationAngle(rotInterp); + } + + return trans; + } + + /** Chooses a random transition from those available. */ + protected void chooseRandomTransition() { + if (random == null) { + random = new Random(); + } + nextTransitionFade = random.nextBoolean(); + nextTransitionStyle = null; + do { + int style = random.nextInt(3); + switch (style) { + // Make no-motion transitions always use fades for effect + // without biasing transitions toward no-motion transitions + case 0: if (nextTransitionFade) nextTransitionStyle = STYLE_NO_MOTION; break; + case 1: nextTransitionStyle = STYLE_SCROLL; break; + default: nextTransitionStyle = STYLE_ROTATE; break; + } + } while (nextTransitionStyle == null); + int dir = random.nextInt(4); + switch (dir) { + case 0: nextTransitionDirection = DIR_LEFT; break; + case 1: nextTransitionDirection = DIR_RIGHT; break; + case 2: nextTransitionDirection = DIR_UP; break; + default: nextTransitionDirection = DIR_DOWN; break; + } + } +} diff --git a/src/demos/xtrans/XTDesktopManager.java b/src/demos/xtrans/XTDesktopManager.java new file mode 100755 index 0000000..3b8828a --- /dev/null +++ b/src/demos/xtrans/XTDesktopManager.java @@ -0,0 +1,164 @@ +package demos.xtrans; + +import java.awt.*; +import java.awt.geom.*; +import java.awt.image.*; +import java.beans.*; +import java.nio.*; +import java.util.*; +import javax.swing.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.impl.*; + +/** A desktop manager implementation supporting accelerated + transitions of the components on the desktop via OpenGL. This + class does not need to be instantiated by end users; it is + installed automatically when an XTDesktopPane is constructed. */ +public class XTDesktopManager extends OffscreenDesktopManager { + private GLContext j2dContext; + private Object j2dContextSurfaceIdentifier; + private int oglTextureId; + private int prevBackBufferWidth; + private int prevBackBufferHeight; + + private int textureTarget = GL.GL_TEXTURE_2D; + + /** Returns the OpenGL texture object ID associated with the + off-screen back buffer for all of the components on the + desktop. */ + public int getOpenGLTextureObject() { + return oglTextureId; + } + + /** Returns a rectangle specifying the OpenGL texture coordinates of + the passed component in the texture object. The x and y + coordinates of the returned rectangle specify the lower left + corner of the component's image. */ + public Rectangle2D getOpenGLTextureCoords(Component c) { + Rectangle rect = getBoundsOnBackBuffer(c); + if (rect == null) { + throw new RuntimeException("Unknown component " + c); + } + double offscreenWidth = getOffscreenBackBufferWidth(); + double offscreenHeight = getOffscreenBackBufferHeight(); + return new Rectangle2D.Double(rect.x / offscreenWidth, + (offscreenHeight - rect.y - rect.height) / offscreenHeight, + rect.width / offscreenWidth, + rect.height / offscreenHeight); + } + + /** Updates the off-screen buffer of this desktop manager and makes + the rendering results available to OpenGL in the form of a + texture object. */ + public void updateOffscreenBuffer(OffscreenDesktopPane parent) { + boolean needsCopy = needsCopyBack(); + boolean hadPrevBackBuffer = false; + super.updateOffscreenBuffer(parent); + Image img = getOffscreenBackBuffer(); + final boolean mustResizeOGLTexture = ((oglTextureId == 0) || + (img == null) || + (prevBackBufferWidth != img.getWidth(null)) || + (prevBackBufferHeight != img.getHeight(null))); + if (needsCopy) { + final Graphics g = getOffscreenGraphics(); + // Capture off-screen buffer contents into OpenGL texture + Java2D.invokeWithOGLContextCurrent(g, new Runnable() { + public void run() { + // Get valid Java2D context + if (j2dContext == null || + j2dContextSurfaceIdentifier != Java2D.getOGLSurfaceIdentifier(g)) { + j2dContext = GLDrawableFactory.getFactory().createExternalGLContext(); + j2dContext.setGL(new DebugGL(j2dContext.getGL())); + j2dContextSurfaceIdentifier = Java2D.getOGLSurfaceIdentifier(g); + } + + j2dContext.makeCurrent(); // No-op + try { + GL gl = j2dContext.getGL(); + + if (oglTextureId == 0) { + // Set up and initialize texture + int[] tmp = new int[1]; + + gl.glGenTextures(1, tmp, 0); + oglTextureId = tmp[0]; + if (oglTextureId == 0) { + throw new RuntimeException("Error generating OpenGL back buffer texture"); + } + assert mustResizeOGLTexture : "Must know we need to resize"; + } + + gl.glBindTexture(textureTarget, oglTextureId); + + int offscreenWidth = getOffscreenBackBufferWidth(); + int offscreenHeight = getOffscreenBackBufferHeight(); + + if (mustResizeOGLTexture) { + prevBackBufferWidth = offscreenWidth; + prevBackBufferHeight = offscreenHeight; + + gl.glTexImage2D(textureTarget, + 0, + GL.GL_RGBA8, + offscreenWidth, + offscreenHeight, + 0, + GL.GL_RGBA, + GL.GL_UNSIGNED_BYTE, + null); + } + + // Copy texture from offscreen buffer + // NOTE: assumes read buffer is set up + // FIXME: could be more efficient by copying only bounding rectangle + + gl.glPixelStorei(GL.GL_UNPACK_SWAP_BYTES, GL.GL_FALSE); + gl.glPixelStorei(GL.GL_PACK_SWAP_BYTES, GL.GL_FALSE); + gl.glPixelStorei(GL.GL_UNPACK_LSB_FIRST, GL.GL_FALSE); + gl.glPixelStorei(GL.GL_PACK_LSB_FIRST, GL.GL_FALSE); + gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, 0); + gl.glPixelStorei(GL.GL_PACK_ROW_LENGTH, 0); + gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, 0); + gl.glPixelStorei(GL.GL_PACK_SKIP_ROWS, 0); + gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, 0); + gl.glPixelStorei(GL.GL_PACK_SKIP_PIXELS, 0); + gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); + gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1); + gl.glPixelTransferf(GL.GL_RED_SCALE, 1); + gl.glPixelTransferf(GL.GL_GREEN_SCALE, 1); + gl.glPixelTransferf(GL.GL_BLUE_SCALE, 1); + gl.glPixelTransferf(GL.GL_ALPHA_SCALE, 1); + gl.glPixelTransferf(GL.GL_RED_BIAS, 0); + gl.glPixelTransferf(GL.GL_GREEN_BIAS, 0); + gl.glPixelTransferf(GL.GL_BLUE_BIAS, 0); + gl.glPixelTransferf(GL.GL_ALPHA_BIAS, 0); + + // long start = System.currentTimeMillis(); + gl.glCopyTexSubImage2D(textureTarget, + 0, + 0, + 0, + 0, + 0, + offscreenWidth, + offscreenHeight); + // long end = System.currentTimeMillis(); + // System.err.println("glCopyTexSubImage2D " + offscreenWidth + "x" + offscreenHeight + " took " + (end - start) + " ms"); + + } finally { + j2dContext.release(); + } + } + }); + } + } + + // Ideally we would force a repaint only of the 2D bounds of the 3D + // component projected onto the desktop. However for expedience + // we'll currently just repaint the entire desktop to get correct + // results. + protected void repaintPortionOfDesktop(JDesktopPane desktop, Component comp) { + desktop.repaint(); + } +} diff --git a/src/demos/xtrans/XTDesktopPane.java b/src/demos/xtrans/XTDesktopPane.java new file mode 100755 index 0000000..2df6c5e --- /dev/null +++ b/src/demos/xtrans/XTDesktopPane.java @@ -0,0 +1,444 @@ +package demos.xtrans; + +import java.awt.*; +import java.awt.geom.*; +import java.util.*; +import javax.swing.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.impl.*; + +/** A JDesktopPane subclass supporting Accelerated Transitions (XT) of + the components contained within. */ + +public class XTDesktopPane extends OffscreenDesktopPane { + private GLContext j2dContext; + private Object j2dContextSurfaceIdentifier; + + private Rectangle oglViewport; + + private XTTransitionManager transitionManager = new XTBasicTransitionManager(); + + private boolean reallyRemove; + + private boolean alwaysRedraw; + + static class TransitionInfo { + boolean isIn; + Component target; + long startTime; + XTTransition trans; + + TransitionInfo(boolean isIn, + Component target, + long startTime, + XTTransition trans) { + this.isIn = isIn; + this.target = target; + this.startTime = startTime; + this.trans = trans; + } + } + + private java.util.List/*<TransitionInfo>*/ transitions = new ArrayList(); + + private float TRANSITION_DURATION = 300.0f; + + private int textureTarget = GL.GL_TEXTURE_2D; + private GLU glu = new GLU(); + + /** Creates a new accelerated transition desktop pane. */ + public XTDesktopPane() { + super(); + if (!Java2D.isOGLPipelineActive()) { + throw new RuntimeException("XTDesktopPane requires new Java2D/JOGL support in Java SE 6 and -Dsun.java2d.opengl=true"); + } + setDesktopManager(new XTDesktopManager()); + } + + /** Overridden to use a transition to display the given + component. */ + protected void addImpl(Component c, Object constraints, int index) { + super.addImpl(c, constraints, index); + getOffscreenDesktopManager().layoutOffscreenBuffer(this); + + // When animating the component's transition, center the + // perspective projection around the center of the newly-added + // component so that the perspective effects appear symmetric. + // This amounts to moving the viewport so the component is in the + // center. + addTransition(true, c, + transitionManager.createTransitionForComponent(c, + true, + getOGLViewport(), + computeViewportOffsetToCenterComponent(c, getOGLViewport()), + getXTDesktopManager().getOpenGLTextureCoords(c))); + } + + /** Overridden to use an animated transition to remove the passed + component. */ + public void remove(int index) { + if (reallyRemove) { + super.remove(index); + } else { + addRemoveTransition(getRealComponent(getComponent(index))); + } + } + + /** Overridden to use an animated transition to remove the passed + component. */ + public void remove(Component c) { + if (reallyRemove) { + super.remove(c); + } else { + addRemoveTransition(getRealComponent(c)); + } + } + + /** Causes the given component to really be removed from this + desktop pane. Called when the removal transition is complete. */ + protected void removeImpl(Component c) { + reallyRemove = true; + try { + remove(c); + } finally { + reallyRemove = false; + } + } + + /** Overridden to draw the child components, including any animated + transitions, using OpenGL. */ + protected void paintChildren(final Graphics g) { + // FIXME: this is a hack to get repainting behavior to work + // properly when we specify that optimized drawing is disabled (so + // that childrens' repaint requests will trickle up to us via the + // Animator) but need to descend to repaint our children -- + // currently don't know how to distinguish between repaint events + // propagated up to us and those initiated by the children (which + // typically go through the OffscreenComponentWrapper's + // getGraphics() method and implicitly cause a redraw of all child + // components as well as the desktop) + if (alwaysRedraw) { + getOffscreenDesktopManager().setNeedsRedraw(); + } + + // Update desktop manager's offscreen buffer if necessary + getOffscreenDesktopManager().updateOffscreenBuffer(this); + + // Draw textured quads using JOGL over current contents of back + // buffer + final Component[] components = getRealChildComponents(); + final ArrayList expiredTransitions = new ArrayList(); + Java2D.invokeWithOGLContextCurrent(g, new Runnable() { + public void run() { + // Get valid Java2D context + if (j2dContext == null || + j2dContextSurfaceIdentifier != Java2D.getOGLSurfaceIdentifier(g)) { + j2dContext = GLDrawableFactory.getFactory().createExternalGLContext(); + j2dContext.setGL(new DebugGL(j2dContext.getGL())); + j2dContextSurfaceIdentifier = Java2D.getOGLSurfaceIdentifier(g); + } + + j2dContext.makeCurrent(); // No-op + try { + GL gl = j2dContext.getGL(); + + // Figure out where JDesktopPane is on the Swing back buffer + Rectangle oglRect = Java2D.getOGLViewport(g, getWidth(), getHeight()); + // Cache this value for adding transitions later + oglViewport = new Rectangle(oglRect); + + // Set up perspective projection so we can do some subtle + // 3D effects. We set up the view volume so that at z=0 + // the lower-left coordinates of the desktop are (0, 0) + // and the upper right coordinates are + // (oglRect.getWidth(), oglRect.getHeight()). The key here + // is to decide on the field of view and then figure out + // how far back we have to put the eye point in order for + // this to occur. + double fovy = 30.0; // degrees + double w = oglRect.getWidth(); + double h = oglRect.getHeight(); + // d is the distance from the eye point to the image plane + // (z=0) + double d = (h / 2) / Math.tan(Math.toRadians(fovy) / 2); + double near = d - (h / 2); + double far = d + (h / 2); + gl.glViewport(oglRect.x, oglRect.y, oglRect.width, oglRect.height); + gl.glMatrixMode(GL.GL_PROJECTION); + gl.glPushMatrix(); + gl.glLoadIdentity(); + glu.gluPerspective(fovy, (w / h), near, far); + gl.glMatrixMode(GL.GL_TEXTURE); + gl.glPushMatrix(); + gl.glLoadIdentity(); + gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glPushMatrix(); + gl.glLoadIdentity(); + double eyeX = w / 2; + double eyeY = h / 2; + // Object x and y are the same as eye x and y since we're + // looking in the -z direction + glu.gluLookAt(eyeX, eyeY, d, + eyeX, eyeY, 0, + 0, 1, 0); + + // Set up a scissor box so we don't blow away other + // components if we shift around the viewport to get the + // animated transitions' perspective effects to be + // centered + gl.glEnable(GL.GL_SCISSOR_TEST); + Rectangle r = Java2D.getOGLScissorBox(g); + if (r != null) { + gl.glScissor(r.x, r.y, r.width, r.height); + } + + /* + + // Orthographic projection for debugging + gl.glViewport(oglRect.x, oglRect.y, oglRect.width, oglRect.height); + // Set up coordinate system for easy access + gl.glMatrixMode(GL.GL_PROJECTION); + // System.err.println("oglRect x = " + oglRect.getX()); + // System.err.println("oglRect y = " + oglRect.getY()); + // System.err.println("oglRect w = " + oglRect.getWidth()); + // System.err.println("oglRect h = " + oglRect.getHeight()); + gl.glPushMatrix(); + gl.glLoadIdentity(); + gl.glOrtho(oglRect.getX(), oglRect.getX() + oglRect.getWidth(), + oglRect.getY(), oglRect.getY() + oglRect.getHeight(), + -1, + 1); + gl.glMatrixMode(GL.GL_TEXTURE); + gl.glPushMatrix(); + gl.glLoadIdentity(); + gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glPushMatrix(); + gl.glLoadIdentity(); + + */ + + // Enable and bind texture corresponding to internal frames' back buffer + gl.glBindTexture(textureTarget, getXTDesktopManager().getOpenGLTextureObject()); + + gl.glEnable(textureTarget); + gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP); + gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP); + gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); + gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); + + gl.glEnable(GL.GL_BLEND); + gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE); + gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); + + // Iterate down children in z order bottom-to-top + int compCount = components.length; + long curTime = currentTimeMillis(); + for (int i = compCount - 1; i >= 0; i--) { + Component c = components[i]; + + // Find transition for this component + TransitionInfo info = transitionForComponent(c); + + if (info != null) { + gl.glPushMatrix(); + // When animating the component's transition, center the + // perspective projection around the center of the newly-added + // component so that the perspective effects appear symmetric. + // This amounts to moving the viewport so the component is in the + // center. + Point viewportOffset = computeViewportOffsetToCenterComponent(c, getOGLViewport()); + gl.glViewport(oglRect.x + viewportOffset.x, + oglRect.y + viewportOffset.y, + oglRect.width, + oglRect.height); + + // Update it + float percent = clamp((curTime - info.startTime) / TRANSITION_DURATION, 0.0f, 1.0f); + XTTransition trans = info.trans; + trans.update(percent); + trans.draw(gl); + // See whether the transition has expired + if (percent == 1.0f) { + transitions.remove(info); + expiredTransitions.add(info); + } + gl.glPopMatrix(); + // Put the viewport back where it was + gl.glViewport(oglRect.x, oglRect.y, oglRect.width, oglRect.height); + } else { + // For each one, get the OpenGL texture coordinates on the offscreen OpenGL texture + Rectangle2D oglTexCoords = getXTDesktopManager().getOpenGLTextureCoords(c); + Rectangle bounds = c.getBounds(); + + int cx = bounds.x; + int cy = bounds.y; + int cw = bounds.width; + int ch = bounds.height; + float tx = (float) oglTexCoords.getX(); + float ty = (float) oglTexCoords.getY(); + float tw = (float) oglTexCoords.getWidth(); + float th = (float) oglTexCoords.getHeight(); + float vx = oglRect.x; + float vy = oglRect.y; + float vw = oglRect.width; + float vh = oglRect.height; + + // Draw a quad per component + gl.glBegin(GL.GL_TRIANGLES); + gl.glColor4f(1, 1, 1, 1); + + // Triangle 1 + gl.glTexCoord2f(tx, ty + th); + gl.glVertex3f (cx, vh - cy, 0); + gl.glTexCoord2f(tx, ty); + gl.glVertex3f (cx, vh - cy - ch, 0); + gl.glTexCoord2f(tx + tw, ty + th); + gl.glVertex3f (cx + cw, vh - cy, 0); + // Triangle 2 + gl.glTexCoord2f(tx + tw, ty + th); + gl.glVertex3f (cx + cw, vh - cy, 0); + gl.glTexCoord2f(tx, ty); + gl.glVertex3f (cx, vh - cy - ch, 0); + gl.glTexCoord2f(tx + tw, ty); + gl.glVertex3f (cx + cw, vh - cy - ch, 0); + + gl.glEnd(); + } + } + gl.glFlush(); + gl.glDisable(textureTarget); + gl.glDisable(GL.GL_BLEND); + + gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE); + gl.glMatrixMode(GL.GL_PROJECTION); + gl.glPopMatrix(); + gl.glMatrixMode(GL.GL_TEXTURE); + gl.glPopMatrix(); + gl.glMatrixMode(GL.GL_MODELVIEW); + gl.glPopMatrix(); + gl.glFinish(); + } finally { + j2dContext.release(); + } + } + }); + + for (Iterator iter = expiredTransitions.iterator(); iter.hasNext(); ) { + TransitionInfo info = (TransitionInfo) iter.next(); + if (!info.isIn) { + removeImpl(info.target); + repaint(); + } + } + + if (!transitions.isEmpty()) { + repaint(); + } + } + + /** Overridden from parent to disable optimized drawing so that we + get correct rendering results with embedded GLJPanels */ + public boolean isOptimizedDrawingEnabled() { + return false; + } + + /** Returns the XTDesktopManager for this desktop pane. */ + public XTDesktopManager getXTDesktopManager() { + return (XTDesktopManager) getDesktopManager(); + } + + /** Returns the transition manager for this desktop pane. By default + this is an XTBasicTransitionManager. */ + public XTTransitionManager getTransitionManager() { + return transitionManager; + } + + /** Sets the transition manager for this desktop pane. By default + this is an XTBasicTransitionManager. */ + public void setTransitionManager(XTTransitionManager manager) { + transitionManager = manager; + } + + /** Workaround to get painting behavior to work properly in some + situations. */ + public void setAlwaysRedraw(boolean onOrOff) { + alwaysRedraw = onOrOff; + } + + /** Workaround to get painting behavior to work properly in some + situations. */ + public boolean getAlwaysRedraw() { + return alwaysRedraw; + } + + /** Returns the transition corresponding to the passed Component, or + null if no transition is currently active for this component. */ + private TransitionInfo transitionForComponent(Component c) { + for (Iterator iter = transitions.iterator(); iter.hasNext(); ) { + TransitionInfo info = (TransitionInfo) iter.next(); + if (info.target == c) { + return info; + } + } + return null; + } + + /** Adds a transition for the specified component. An "out" + transition will automatically cause the component to be removed + after it has completed running. */ + protected void addTransition(boolean isIn, + Component target, + XTTransition trans) { + TransitionInfo info = new TransitionInfo(isIn, + target, + currentTimeMillis(), + trans); + transitions.add(info); + } + + /** Adds a removal transition for the given component. */ + protected void addRemoveTransition(Component target) { + addTransition(false, + target, + transitionManager.createTransitionForComponent(target, + false, + getOGLViewport(), + computeViewportOffsetToCenterComponent(target, getOGLViewport()), + getXTDesktopManager().getOpenGLTextureCoords(target))); + } + + /** Computes the offset applied to the OpenGL viewport to center the + given component in the viewport. This is used to make the + perspective effects appear symmetric about the component. */ + protected Point computeViewportOffsetToCenterComponent(Component c, + Rectangle oglViewport) { + Rectangle bounds = c.getBounds(); + return new Point(bounds.x + ((bounds.width - oglViewport.width) / 2), + -bounds.y + ((oglViewport.height - bounds.height) / 2)); + } + + /** Clamps the given value between the specified minimum and + maximum. */ + protected static float clamp(float val, float min, float max) { + return Math.min(max, Math.max(min, val)); + } + + /** Returns the current time in milliseconds. */ + protected static long currentTimeMillis() { + // Avoid 1.5 compilation dependencies since no perceived + // improvement by changing this + // return System.nanoTime() / 1000000; + return System.currentTimeMillis(); + } + + /** Returns the OpenGL viewport corresponding to this desktop pane. */ + protected Rectangle getOGLViewport() { + if (oglViewport != null) { + return oglViewport; + } + + Rectangle b = getBounds(); + return new Rectangle(0, 0, b.width, b.height); + } +} diff --git a/src/demos/xtrans/XTTransition.java b/src/demos/xtrans/XTTransition.java new file mode 100755 index 0000000..1c706fa --- /dev/null +++ b/src/demos/xtrans/XTTransition.java @@ -0,0 +1,15 @@ +package demos.xtrans; + +import javax.media.opengl.*; + +/** Specifies the interface by which a transition is updated and drawn + by the XTDesktopPane. */ + +public interface XTTransition { + /** Updates this transition's state to the given fraction in its + animation cycle (0.0 - 1.0). */ + public void update(float fraction); + + /** Draws this transition using the passed OpenGL object. */ + public void draw(GL gl); +} diff --git a/src/demos/xtrans/XTTransitionManager.java b/src/demos/xtrans/XTTransitionManager.java new file mode 100755 index 0000000..18e9da0 --- /dev/null +++ b/src/demos/xtrans/XTTransitionManager.java @@ -0,0 +1,45 @@ +package demos.xtrans; + +import java.awt.*; +import java.awt.geom.*; + +/** Specifies how the XTDesktopPane creates new transitions. */ + +public interface XTTransitionManager { + /** Create a new transition for the given component. + <ul> + + <li> The passed component's bounds indicate the location of the + component on the desktop. The (x,y) of the bounds correspond to + the upper left of the component; note that this differs from the + OpenGL coordinate system. + + <li> The <code>isAddition</code> parameter indicates whether + the component is being added to or removed from the desktop. + + <li> The <code>oglViewportOfDesktop</code> specifies the + rectangle corresponding to the entire desktop pane in the + default OpenGL coordinate system with the (x, y) origin of the + rectangle at the lower left. This rectangle should be used in + conjunction with the component's bounds and the + <code>viewportOffsetFromOrigin</code> to determine where to draw + the vertices for the component. + + <li> The <code>viewportOffsetFromOrigin</code> specifies the + current OpenGL viewport's offset from the origin of the OpenGL + coordinate system. The XTDesktopPane re-centers the OpenGL + viewport around each component so any perspective effects appear + symmetric. This offset should be subtracted from the translation + of the component or its vertex locations. + + <li> The <code>oglTexCoordsOnBackBuffer</code> specifies the + texture coordinates of the passed component on the back + buffer. The (x,y) of this rectangle specifies the lower-left + corner of the image corresponding to the component. </ul> + */ + public XTTransition createTransitionForComponent(Component c, + boolean isAddition, + Rectangle oglViewportOfDesktop, + Point viewportOffsetFromOrigin, + Rectangle2D oglTexCoordsOnBackBuffer); +} diff --git a/src/gleem/ExaminerViewer.java b/src/gleem/ExaminerViewer.java index 2cb2f05..61976b1 100644 --- a/src/gleem/ExaminerViewer.java +++ b/src/gleem/ExaminerViewer.java @@ -44,13 +44,14 @@ import java.awt.event.*; import java.util.*; import gleem.linalg.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** <P> This is an application-level class, not part of the manipulator hierarchy. It is an example of how you might integrate gleem with another application which uses the mouse. </P> - <P> For the given GLDrawable, the ExaminerViewer takes over the + <P> For the given GLAutoDrawable, the ExaminerViewer takes over the setting of the view position. It passes along mouse events it is not interested in to the ManipManager's mouse routines. </P> @@ -71,13 +72,14 @@ import net.java.games.jogl.*; button. </P> */ public class ExaminerViewer { - private GLDrawable window; + private GLAutoDrawable window; /** Simple state machine for figuring out whether we are grabbing events */ private boolean interactionUnderway; private boolean iOwnInteraction; private boolean noAltKeyMode; + private boolean autoRedrawMode = true; /** Simple state machine for computing distance dragged */ private boolean button1Down; @@ -125,12 +127,12 @@ public class ExaminerViewer { }; private GLEventListener glListener = new GLEventListener() { - public void init(GLDrawable drawable) {} - public void display(GLDrawable drawable) {} - public void reshape(GLDrawable drawable, int x, int y, int width, int height) { + public void init(GLAutoDrawable drawable) {} + public void display(GLAutoDrawable drawable) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { reshapeMethod(width, height); } - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} }; /** The constructor takes the number of mouse buttons on this system @@ -140,17 +142,17 @@ public class ExaminerViewer { oldNumMouseButtons = numMouseButtons; } - /** <P> Attaches this ExaminerViewer to the given GLDrawable. This + /** <P> Attaches this ExaminerViewer to the given GLAutoDrawable. This causes the ManipManager's mouse routines to be removed from the window (using ManipManager.removeMouseListeners) and the - ExaminerViewer's to be installed. The GLDrawable should be + ExaminerViewer's to be installed. The GLAutoDrawable should be registered with the ManipManager before the ExaminerViewer is attached to it. </P> <P> In order for the viewer to do anything useful, you need to provide a BSphereProvider to it to allow "view all" functionality. </P> */ - public void attach(GLDrawable window, BSphereProvider provider) { + public void attach(GLAutoDrawable window, BSphereProvider provider) { this.window = window; this.provider = provider; init(); @@ -158,7 +160,7 @@ public class ExaminerViewer { } /** Detaches from the given window. This causes the ManipManager's - mouse listeners to be reinstalled on the GLDrawable and the + mouse listeners to be reinstalled on the GLAutoDrawable and the ExaminerViewer's to be removed. */ public void detach() { removeListeners(); @@ -300,6 +302,20 @@ public class ExaminerViewer { return noAltKeyMode; } + /** Enables or disables the automatic redrawing of the + GLAutoDrawable to which this ExaminerViewer is attached. If the + GLAutoDrawable is already being animated, disabling auto redraw + mode may provide better performance. Defaults to on. */ + public void setAutoRedrawMode(boolean onOrOff) { + autoRedrawMode = onOrOff; + } + + /** Returns whether this ExaminerViewer automatically redraws the + GLAutoDrawable to which it is attached upon updates. */ + public boolean getAutoRedrawMode() { + return autoRedrawMode; + } + /** Rotates this ExaminerViewer about the focal point by the specified incremental rotation; performs postmultiplication, i.e. the incremental rotation is applied after the current @@ -355,9 +371,8 @@ public class ExaminerViewer { button1Down = false; button2Down = false; - Dimension size = window.getSize(); - int xSize = size.width; - int ySize = size.height; + int xSize = window.getWidth(); + int ySize = window.getHeight(); params.setOrientation(orientation); params.setPosition(computePosition(new Vec3f())); params.setForwardDirection(Vec3f.NEG_Z_AXIS); @@ -411,9 +426,9 @@ public class ExaminerViewer { } - // Force redraw if window will not do it automatically - if (!window.getNoAutoRedrawMode()) { - window.display(); + if (autoRedrawMode) { + // Force redraw + window.repaint(); } } } @@ -471,9 +486,9 @@ public class ExaminerViewer { iOwnInteraction = false; } - // Force redraw if window will not do it automatically - if (!window.getNoAutoRedrawMode()) { - window.display(); + if (autoRedrawMode) { + // Force redraw + window.repaint(); } } } @@ -581,11 +596,11 @@ public class ExaminerViewer { gl.glMatrixMode(GL.GL_MODELVIEW); float[] data = new float[16]; params.getModelviewMatrix().getColumnMajorData(data); - gl.glLoadMatrixf(data); + gl.glLoadMatrixf(data, 0); gl.glMatrixMode(GL.GL_PROJECTION); params.getProjectionMatrix().getColumnMajorData(data); - gl.glLoadMatrixf(data); + gl.glLoadMatrixf(data, 0); } private void recalcInverseRotation(GL gl) { diff --git a/src/gleem/HandleBoxManip.java b/src/gleem/HandleBoxManip.java index bedde65..73256c0 100644 --- a/src/gleem/HandleBoxManip.java +++ b/src/gleem/HandleBoxManip.java @@ -42,7 +42,8 @@ package gleem; import java.util.*; import gleem.linalg.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** Patterned after Inventor's HandleBoxManip (by Paul Isaacs and David Mott) and TransformerManip (by Paul Isaacs). Center box diff --git a/src/gleem/Manip.java b/src/gleem/Manip.java index b037430..919b805 100644 --- a/src/gleem/Manip.java +++ b/src/gleem/Manip.java @@ -42,7 +42,8 @@ package gleem; import java.util.*; import gleem.linalg.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** The base class for all manipulators. Fundamentally a manipulator must support a ray cast operation with itself and logic to diff --git a/src/gleem/ManipManager.java b/src/gleem/ManipManager.java index 0a0d86d..b959e74 100644 --- a/src/gleem/ManipManager.java +++ b/src/gleem/ManipManager.java @@ -44,7 +44,8 @@ import java.util.*; import gleem.linalg.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** The ManipManager handles making manipulators visible in a window. */ @@ -55,7 +56,7 @@ public class ManipManager { private static ManipManager soleInstance; // Maps GLDrawables to WindowInfos private Map windowToInfoMap = new HashMap(); - // Maps Manips to Set<GLDrawable> + // Maps Manips to Set<GLAutoDrawable> private Map manipToWindowMap = new HashMap(); // MouseAdapter for this @@ -78,10 +79,8 @@ public class ManipManager { } }; private WindowUpdateListener defaultWindowListener = new WindowUpdateListener() { - public void update(GLDrawable window) { - if (!window.getNoAutoRedrawMode()) { - window.display(); - } + public void update(GLAutoDrawable window) { + window.repaint(); } }; private WindowUpdateListener windowListener; @@ -110,25 +109,31 @@ public class ManipManager { /** Make the ManipManager aware of the existence of a given window. This causes mouse and mouse motion listeners to be installed on this window; see setupMouseListeners, below. */ - public synchronized void registerWindow(GLDrawable window) { + public synchronized void registerWindow(GLAutoDrawable window) { windowToInfoMap.put(window, new WindowInfo()); setupMouseListeners(window); } /** Remove all references to a given window, including removing all manipulators from it. */ - public synchronized void unregisterWindow(GLDrawable window) { + public synchronized void unregisterWindow(GLAutoDrawable window) { + if (window == null) { + return; + } WindowInfo info = (WindowInfo) windowToInfoMap.get(window); - for (Iterator iter = info.manips.iterator(); iter.hasNext(); ) { - removeManipFromWindow((Manip) iter.next(), window); + if (info != null) { + Object[] manips = info.manips.toArray(); + for (int i = 0; i < manips.length; i++) { + removeManipFromWindow((Manip) manips[i], window); + } + windowToInfoMap.remove(window); + removeMouseListeners(window); } - windowToInfoMap.remove(window); - removeMouseListeners(window); } /** Make a given manipulator visible and active in a given window. The window must be registered. */ - public synchronized void showManipInWindow(Manip manip, GLDrawable window) { + public synchronized void showManipInWindow(Manip manip, GLAutoDrawable window) { WindowInfo info = (WindowInfo) windowToInfoMap.get(window); if (info == null) { throw new RuntimeException("Window not registered"); @@ -144,7 +149,7 @@ public class ManipManager { /** Remove a given manipulator from a given window. The window must be registered. */ - public synchronized void removeManipFromWindow(Manip manip, GLDrawable window) { + public synchronized void removeManipFromWindow(Manip manip, GLAutoDrawable window) { WindowInfo info = (WindowInfo) windowToInfoMap.get(window); if (info == null) { throw new RuntimeException("Window not registered"); @@ -159,7 +164,7 @@ public class ManipManager { /** This must be called for a registered window every time the camera parameters of the window change. */ - public synchronized void updateCameraParameters(GLDrawable window, CameraParameters params) { + public synchronized void updateCameraParameters(GLAutoDrawable window, CameraParameters params) { WindowInfo info = (WindowInfo) windowToInfoMap.get(window); if (info == null) { throw new RuntimeException("Window not registered"); @@ -182,7 +187,7 @@ public class ManipManager { repainting of windows in which manipulators have moved. The default implementation, which can be restored by passing a null listener argument to this method, calls repaint() on the - GLDrawable if it is not a GLRunnable instance (i.e., a + GLAutoDrawable if it is not a GLRunnable instance (i.e., a GLAnimCanvas or GLAnimJPanel, which redraw themselves automatically). */ public synchronized void setWindowUpdateListener(WindowUpdateListener listener) { @@ -197,7 +202,7 @@ public class ManipManager { drawing occurs immediately; this routine must be called when an OpenGL context is valid, i.e., from within the display() method of a GLEventListener. */ - public synchronized void render(GLDrawable window, GL gl) { + public synchronized void render(GLAutoDrawable window, GL gl) { WindowInfo info = (WindowInfo) windowToInfoMap.get(window); if (info == null) { throw new RuntimeException("Window not registered"); @@ -214,7 +219,7 @@ public class ManipManager { listeners for the canvas (see the ExaminerViewer class), the setupMouseListeners and removeMouseListeners routines, as well as the appropriate delegate routines, are made public here. */ - public synchronized void setupMouseListeners(GLDrawable window) { + public synchronized void setupMouseListeners(GLAutoDrawable window) { window.addMouseMotionListener(mouseMotionListener); window.addMouseListener(mouseListener); } @@ -222,7 +227,7 @@ public class ManipManager { /** Removes the automatically-installed mouse listeners for the given window. This allows application code to determine the policy for intercepting mouse events. */ - public synchronized void removeMouseListeners(GLDrawable window) { + public synchronized void removeMouseListeners(GLAutoDrawable window) { window.removeMouseMotionListener(mouseMotionListener); window.removeMouseListener(mouseListener); } @@ -232,7 +237,7 @@ public class ManipManager { are exposed so application-level code can intercept events when certain modifier keys are depressed. */ public synchronized void mouseMoved(MouseEvent e) { - passiveMotionMethod((GLDrawable) e.getComponent(), e.getX(), e.getY()); + passiveMotionMethod((GLAutoDrawable) e.getComponent(), e.getX(), e.getY()); } /** The ManipManager watches for the following events: mouseMoved, @@ -240,7 +245,7 @@ public class ManipManager { are exposed so application-level code can intercept events when certain modifier keys are depressed. */ public synchronized void mouseDragged(MouseEvent e) { - motionMethod((GLDrawable) e.getComponent(), e.getX(), e.getY()); + motionMethod((GLAutoDrawable) e.getComponent(), e.getX(), e.getY()); } /** The ManipManager watches for the following events: mouseMoved, @@ -248,7 +253,7 @@ public class ManipManager { are exposed so application-level code can intercept events when certain modifier keys are depressed. */ public synchronized void mousePressed(MouseEvent e) { - mouseMethod((GLDrawable) e.getComponent(), e.getModifiers(), + mouseMethod((GLAutoDrawable) e.getComponent(), e.getModifiers(), true, e.getX(), e.getY()); } @@ -257,7 +262,7 @@ public class ManipManager { are exposed so application-level code can intercept events when certain modifier keys are depressed. */ public synchronized void mouseReleased(MouseEvent e) { - mouseMethod((GLDrawable) e.getComponent(), e.getModifiers(), + mouseMethod((GLAutoDrawable) e.getComponent(), e.getModifiers(), false, e.getX(), e.getY()); } @@ -270,7 +275,7 @@ public class ManipManager { setWindowUpdateListener(null); } - private void motionMethod(GLDrawable window, int x, int y) { + private void motionMethod(GLAutoDrawable window, int x, int y) { WindowInfo info = (WindowInfo) windowToInfoMap.get(window); if (info.dragging) { // Compute ray in 3D @@ -282,7 +287,7 @@ public class ManipManager { } } - private void passiveMotionMethod(GLDrawable window, int x, int y) { + private void passiveMotionMethod(GLAutoDrawable window, int x, int y) { WindowInfo info = (WindowInfo) windowToInfoMap.get(window); // Compute ray in 3D Vec3f rayStart = new Vec3f(); @@ -322,7 +327,7 @@ public class ManipManager { } } - private void mouseMethod(GLDrawable window, int modifiers, + private void mouseMethod(GLAutoDrawable window, int modifiers, boolean isPress, int x, int y) { if ((modifiers & InputEvent.BUTTON1_MASK) != 0) { WindowInfo info = (WindowInfo) windowToInfoMap.get(window); @@ -398,7 +403,7 @@ public class ManipManager { Set windows = (Set) manipToWindowMap.get(manip); assert windows != null; for (Iterator iter = windows.iterator(); iter.hasNext(); ) { - windowListener.update((GLDrawable) iter.next()); + windowListener.update((GLAutoDrawable) iter.next()); } } } diff --git a/src/gleem/ManipPart.java b/src/gleem/ManipPart.java index 50fbe61..83f21cf 100644 --- a/src/gleem/ManipPart.java +++ b/src/gleem/ManipPart.java @@ -42,7 +42,8 @@ package gleem; import java.util.*; import gleem.linalg.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** A ManipPart is a visible or invisible sub-part of a manipulator. ManipParts are organized into trees. */ diff --git a/src/gleem/ManipPartGroup.java b/src/gleem/ManipPartGroup.java index 859a8a3..97a31ec 100644 --- a/src/gleem/ManipPartGroup.java +++ b/src/gleem/ManipPartGroup.java @@ -42,7 +42,8 @@ package gleem; import java.util.*; import gleem.linalg.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** This class groups a set of ManipParts. Makes a set of ManipParts look like one. */ diff --git a/src/gleem/ManipPartLineSeg.java b/src/gleem/ManipPartLineSeg.java index 8278533..ea34b5c 100644 --- a/src/gleem/ManipPartLineSeg.java +++ b/src/gleem/ManipPartLineSeg.java @@ -42,7 +42,8 @@ package gleem; import java.util.*; import gleem.linalg.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** A line segment from (-1, 0, 0) to (1, 0, 0). */ diff --git a/src/gleem/ManipPartTriBased.java b/src/gleem/ManipPartTriBased.java index 97f8ae3..208c8ea 100644 --- a/src/gleem/ManipPartTriBased.java +++ b/src/gleem/ManipPartTriBased.java @@ -42,7 +42,8 @@ package gleem; import java.util.*; import gleem.linalg.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** Triangle-based manipulator part. This is the base class for most of the ManipParts that GLEEM uses internally. You can feel free to diff --git a/src/gleem/TestExaminerViewer.java b/src/gleem/TestExaminerViewer.java index 55d0283..7e52992 100644 --- a/src/gleem/TestExaminerViewer.java +++ b/src/gleem/TestExaminerViewer.java @@ -41,7 +41,9 @@ package gleem; import java.awt.*; import java.awt.event.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; import gleem.linalg.*; /** Tests the Examiner Viewer. */ @@ -72,22 +74,20 @@ public class TestExaminerViewer { } static class Listener implements GLEventListener { - private GL gl; - private GLU glu; + private GLU glu = new GLU(); private CameraParameters params = new CameraParameters(); private ExaminerViewer viewer; - public void init(GLDrawable drawable) { - gl = drawable.getGL(); - glu = drawable.getGLU(); + public void init(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); gl.glClearColor(0, 0, 0, 0); float[] lightPosition = new float[] {1, 1, 1, 0}; float[] ambient = new float[] { 0.0f, 0.0f, 0.0f, 1.0f }; float[] diffuse = new float[] { 1.0f, 1.0f, 1.0f, 1.0f }; - gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition, 0); gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_LIGHT0); @@ -122,7 +122,8 @@ public class TestExaminerViewer { viewer.viewAll(gl); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); viewer.update(gl); ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters()); @@ -130,8 +131,8 @@ public class TestExaminerViewer { } // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int w, int h) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } public static void main(String[] args) { diff --git a/src/gleem/TestHandleBox.java b/src/gleem/TestHandleBox.java index adf8e32..e06d004 100644 --- a/src/gleem/TestHandleBox.java +++ b/src/gleem/TestHandleBox.java @@ -41,7 +41,9 @@ package gleem; import java.awt.*; import java.awt.event.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; import gleem.linalg.*; /** Tests the HandleBox Manip. */ @@ -51,21 +53,19 @@ public class TestHandleBox { private static final int Y_SIZE = 400; static class Listener implements GLEventListener { - private GL gl; - private GLU glu; + private GLU glu = new GLU(); private CameraParameters params = new CameraParameters(); - public void init(GLDrawable drawable) { - gl = drawable.getGL(); - glu = drawable.getGLU(); + public void init(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); gl.glClearColor(0, 0, 0, 0); float[] lightPosition = new float[] {1, 1, 1, 0}; float[] ambient = new float[] { 0.0f, 0.0f, 0.0f, 1.0f }; float[] diffuse = new float[] { 1.0f, 1.0f, 1.0f, 1.0f }; - gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition, 0); gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_LIGHT0); @@ -95,13 +95,15 @@ public class TestHandleBox { manager.showManipInWindow(manip, drawable); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); ManipManager.getManipManager().updateCameraParameters(drawable, params); ManipManager.getManipManager().render(drawable, gl); } - public void reshape(GLDrawable drawable, int x, int y, int w, int h) { + public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { + GL gl = drawable.getGL(); float aspect, theta; aspect = (float) w / (float) h; if (w >= h) @@ -120,7 +122,7 @@ public class TestHandleBox { } // Unused routines - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } public static void main(String[] args) { diff --git a/src/gleem/TestMultiWin.java b/src/gleem/TestMultiWin.java index ce2c257..1a1fcf1 100644 --- a/src/gleem/TestMultiWin.java +++ b/src/gleem/TestMultiWin.java @@ -41,7 +41,9 @@ package gleem; import java.awt.*; import java.awt.event.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; import gleem.linalg.*; /** Tests viewing manipulators in multiple winodws. */ @@ -74,22 +76,20 @@ public class TestMultiWin { } static class Listener implements GLEventListener { - private GL gl; - private GLU glu; + private GLU glu = new GLU(); private CameraParameters params = new CameraParameters(); private ExaminerViewer viewer; - public void init(GLDrawable drawable) { - gl = drawable.getGL(); - glu = drawable.getGLU(); + public void init(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); gl.glClearColor(0, 0, 0, 0); float[] lightPosition = new float[] {1, 1, 1, 0}; float[] ambient = new float[] { 0.0f, 0.0f, 0.0f, 1.0f }; float[] diffuse = new float[] { 1.0f, 1.0f, 1.0f, 1.0f }; - gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition, 0); gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_LIGHT0); @@ -121,7 +121,8 @@ public class TestMultiWin { viewer.viewAll(gl); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); viewer.update(gl); ManipManager.getManipManager().updateCameraParameters(drawable, viewer.getCameraParameters()); @@ -129,8 +130,8 @@ public class TestMultiWin { } // Unused routines - public void reshape(GLDrawable drawable, int x, int y, int w, int h) {} - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } private static void showFrame(String name, Point location) { diff --git a/src/gleem/TestTranslate1.java b/src/gleem/TestTranslate1.java index 131fa0c..b9eb81a 100644 --- a/src/gleem/TestTranslate1.java +++ b/src/gleem/TestTranslate1.java @@ -41,7 +41,9 @@ package gleem; import java.awt.*; import java.awt.event.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; import gleem.linalg.*; /** Tests the Translate1 Manip. */ @@ -51,21 +53,19 @@ public class TestTranslate1 { private static final int Y_SIZE = 400; static class Listener implements GLEventListener { - private GL gl; - private GLU glu; + private GLU glu = new GLU(); private CameraParameters params = new CameraParameters(); - public void init(GLDrawable drawable) { - gl = drawable.getGL(); - glu = drawable.getGLU(); + public void init(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); gl.glClearColor(0, 0, 0, 0); float[] lightPosition = new float[] {1, 1, 1, 0}; float[] ambient = new float[] { 0.0f, 0.0f, 0.0f, 1.0f }; float[] diffuse = new float[] { 1.0f, 1.0f, 1.0f, 1.0f }; - gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition, 0); gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_LIGHT0); @@ -96,13 +96,15 @@ public class TestTranslate1 { manager.showManipInWindow(manip, drawable); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); ManipManager.getManipManager().updateCameraParameters(drawable, params); ManipManager.getManipManager().render(drawable, gl); } - public void reshape(GLDrawable drawable, int x, int y, int w, int h) { + public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { + GL gl = drawable.getGL(); float aspect, theta; aspect = (float) w / (float) h; if (w >= h) @@ -121,7 +123,7 @@ public class TestTranslate1 { } // Unused routines - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } public static void main(String[] args) { diff --git a/src/gleem/TestTranslate2.java b/src/gleem/TestTranslate2.java index 1789575..96f5684 100644 --- a/src/gleem/TestTranslate2.java +++ b/src/gleem/TestTranslate2.java @@ -41,7 +41,9 @@ package gleem; import java.awt.*; import java.awt.event.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import javax.media.opengl.glu.*; +import com.sun.opengl.utils.*; import gleem.linalg.*; /** Tests the Translate2 Manip. */ @@ -51,21 +53,19 @@ public class TestTranslate2 { private static final int Y_SIZE = 400; static class Listener implements GLEventListener { - private GL gl; - private GLU glu; + private GLU glu = new GLU(); private CameraParameters params = new CameraParameters(); - public void init(GLDrawable drawable) { - gl = drawable.getGL(); - glu = drawable.getGLU(); + public void init(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); gl.glClearColor(0, 0, 0, 0); float[] lightPosition = new float[] {1, 1, 1, 0}; float[] ambient = new float[] { 0.0f, 0.0f, 0.0f, 1.0f }; float[] diffuse = new float[] { 1.0f, 1.0f, 1.0f, 1.0f }; - gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse); - gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0); + gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition, 0); gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_LIGHT0); @@ -96,13 +96,15 @@ public class TestTranslate2 { manager.showManipInWindow(manip, drawable); } - public void display(GLDrawable drawable) { + public void display(GLAutoDrawable drawable) { + GL gl = drawable.getGL(); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); ManipManager.getManipManager().updateCameraParameters(drawable, params); ManipManager.getManipManager().render(drawable, gl); } - public void reshape(GLDrawable drawable, int x, int y, int w, int h) { + public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { + GL gl = drawable.getGL(); float aspect, theta; aspect = (float) w / (float) h; if (w >= h) @@ -121,7 +123,7 @@ public class TestTranslate2 { } // Unused routines - public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {} } public static void main(String[] args) { diff --git a/src/gleem/Translate1Manip.java b/src/gleem/Translate1Manip.java index 541173f..49c4087 100644 --- a/src/gleem/Translate1Manip.java +++ b/src/gleem/Translate1Manip.java @@ -42,7 +42,8 @@ package gleem; import java.util.*; import gleem.linalg.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** A Translate1Manip is a Manip which translates in only one dimension and whose default representation is a two-way arrow. */ diff --git a/src/gleem/Translate2Manip.java b/src/gleem/Translate2Manip.java index a76df48..101b1e4 100644 --- a/src/gleem/Translate2Manip.java +++ b/src/gleem/Translate2Manip.java @@ -42,7 +42,8 @@ package gleem; import java.util.*; import gleem.linalg.*; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** A Translate2Manip is a Manip which translates in two dimensions and whose default representation is two arrows. */ diff --git a/src/gleem/WindowUpdateListener.java b/src/gleem/WindowUpdateListener.java index b91ee05..793f051 100644 --- a/src/gleem/WindowUpdateListener.java +++ b/src/gleem/WindowUpdateListener.java @@ -39,13 +39,14 @@ package gleem; -import net.java.games.jogl.*; +import javax.media.opengl.*; +import com.sun.opengl.utils.*; /** A WindowUpdateListener is used by the ManipManager to transmit repaint() notifications to windows containing Manips. When a Manip is moved, the ManipManager sends update notifications to all - GLDrawables in which that Manip is shown. */ + GLAutoDrawables in which that Manip is shown. */ public interface WindowUpdateListener { - public void update(GLDrawable window); + public void update(GLAutoDrawable window); } diff --git a/src/gleem/linalg/Vec2f.java b/src/gleem/linalg/Vec2f.java index 2e02701..4c02b61 100644 --- a/src/gleem/linalg/Vec2f.java +++ b/src/gleem/linalg/Vec2f.java @@ -59,6 +59,10 @@ public class Vec2f { return new Vec2f(this); } + public void set(Vec2f arg) { + set(arg.x, arg.y); + } + public void set(float x, float y) { this.x = x; this.y = y; |