aboutsummaryrefslogtreecommitdiffstats
path: root/demos
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2001-02-23 05:08:10 +0000
committerSven Gothel <[email protected]>2001-02-23 05:08:10 +0000
commit82cd20ed209f12e22e2f5a92719b3be2bb92d8ed (patch)
tree6db7f6e46a2195c49bd20e4c6b42c9b206a920fb /demos
parent70be669b0db3713117982dbeeadbb91ed670e901 (diff)
Version 2.6.0.0
Diffstat (limited to 'demos')
-rw-r--r--demos/HodglimsNeHe/Lesson18.java3
-rw-r--r--demos/HodglimsNeHe/Lesson8.java96
-rwxr-xr-xdemos/MiscDemos/TriangleRotate.java70
-rw-r--r--demos/MiscDemos/alpha3D.java42
-rw-r--r--demos/MiscDemos/gears.java85
-rw-r--r--demos/MiscDemos/stencil.java90
-rwxr-xr-xdemos/RonsDemos/dinoshade.java2209
-rw-r--r--demos/RonsDemos/shadowvol.java76
8 files changed, 1416 insertions, 1255 deletions
diff --git a/demos/HodglimsNeHe/Lesson18.java b/demos/HodglimsNeHe/Lesson18.java
index 98bc1cc..79c1393 100644
--- a/demos/HodglimsNeHe/Lesson18.java
+++ b/demos/HodglimsNeHe/Lesson18.java
@@ -458,6 +458,9 @@ public class Lesson18 extends Applet
}
}
public static void main(String as[]) {
+ GLContext.gljNativeDebug = true;
+ GLContext.gljThreadDebug = false;
+ GLContext.gljClassDebug = true;
Frame f=new Frame("Lesson18");
Lesson18 a=new Lesson18();
a.init();
diff --git a/demos/HodglimsNeHe/Lesson8.java b/demos/HodglimsNeHe/Lesson8.java
index f0dc1cc..f374f99 100644
--- a/demos/HodglimsNeHe/Lesson8.java
+++ b/demos/HodglimsNeHe/Lesson8.java
@@ -16,8 +16,9 @@ import java.awt.*;
import java.awt.event.*;
//GL4Java classes
-import gl4java.GLContext;
-import gl4java.awt.GLAnimCanvas;
+import gl4java.*;
+import gl4java.awt.*;
+import gl4java.drawable.*;
import gl4java.utils.textures.*;
@@ -27,6 +28,7 @@ public class Lesson8 extends Applet
//We are using GLAnimCanvas because we want the canvas
//to be constantly redrawn
renderCanvas canvas = null;
+ public static boolean isAnApplet = true;
/**
@@ -39,8 +41,23 @@ public class Lesson8 extends Applet
//We will use BorderLayout to layout the applet components
setLayout(new BorderLayout());
+ Dimension d = getSize();
+ GLCapabilities glCaps = new GLCapabilities();
+ glCaps.setAlphaBits(8);
+
+ gl4java.drawable.GLDrawableFactory df =
+ gl4java.drawable.GLDrawableFactory.getFactory();
+
//Create our canvas and add it to the center of the applet
- canvas = new renderCanvas(getSize().width, getSize().height);
+ if(df instanceof gl4java.drawable.SunJDK13GLDrawableFactory)
+ {
+ gl4java.drawable.SunJDK13GLDrawableFactory sdf =
+ (gl4java.drawable.SunJDK13GLDrawableFactory)df;
+ canvas = new renderCanvas
+ (sdf.getGraphicsConfiguration(glCaps), glCaps, d.width, d.height);
+ } else {
+ canvas = new renderCanvas(glCaps, d.width, d.height);
+ }
canvas.requestFocus();
add("Center", canvas);
}
@@ -84,6 +101,46 @@ public class Lesson8 extends Applet
}
+ public static void main( String args[] ) {
+ isAnApplet = false;
+ Lesson8 applet =
+ new Lesson8();
+
+ Frame f = new Frame("Lesson8");
+
+ GLContext.gljNativeDebug = true;
+ GLContext.gljThreadDebug = false;
+ GLContext.gljClassDebug = true;
+
+ f.addWindowListener( new WindowAdapter()
+ {
+ public void windowClosed(WindowEvent e)
+ {
+ System.exit(0);
+ }
+ public void windowClosing(WindowEvent e)
+ {
+ windowClosed(e);
+ }
+ }
+ );
+
+ f.setLayout(new BorderLayout());
+ f.add("Center", applet);
+ applet.setSize(500,300);
+ applet.init();
+ applet.start();
+ Dimension ps = applet.getPreferredSize();
+ f.setBounds(-100,-100,99,99);
+ f.setVisible(true);
+ f.setVisible(false);
+ f.setVisible(true);
+ Insets i = f.getInsets();
+ f.setBounds(0,0,
+ ps.width+i.left+i.right,
+ ps.height+i.top+i.bottom);
+ f.setVisible(true);
+ }
private class renderCanvas extends GLAnimCanvas
implements KeyListener, MouseListener
@@ -115,35 +172,23 @@ public class Lesson8 extends Applet
int[] texture = new int[3]; //Storage for 3 textures
- /**
- * renderCanvas(int w, int h)
- *
- * Constructor.
- */
- public renderCanvas(int w, int h)
+ public renderCanvas(GraphicsConfiguration g, GLCapabilities glCaps,
+ int w, int h)
{
- super(w, h);
-
+ super(g, glCaps, w, h);
//Registers this canvas to process keyboard events
addKeyListener(this);
addMouseListener(this);
}
-
- /**
- * void preInit()
- *
- * Called just BEFORE the GL-Context is created.
- */
- public void preInit()
+ public renderCanvas(GLCapabilities glCaps, int w, int h)
{
- //We want double buffering
- doubleBuffer = true;
- //But we dont want stereo view
- stereoView = false;
+ super(glCaps, w, h);
+ //Registers this canvas to process keyboard events
+ addKeyListener(this);
+ addMouseListener(this);
}
-
/**
* void LoadGLTextures()
*
@@ -152,7 +197,10 @@ public class Lesson8 extends Applet
public void LoadGLTextures()
{
PngTextureLoader texLoader = new PngTextureLoader(gl, glu);
- texLoader.readTexture(getCodeBase(), "data/glass.png");
+ if(isAnApplet)
+ texLoader.readTexture(getCodeBase(), "data/glass.png");
+ else
+ texLoader.readTexture("data/glass.png");
//Full Brightness, 50% Alpha
gl.glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
diff --git a/demos/MiscDemos/TriangleRotate.java b/demos/MiscDemos/TriangleRotate.java
index 25bccdd..1775b68 100755
--- a/demos/MiscDemos/TriangleRotate.java
+++ b/demos/MiscDemos/TriangleRotate.java
@@ -12,18 +12,32 @@ import java.lang.*;
import java.util.*;
import java.io.*;
import java.util.*;
-import gl4java.GLContext;
-import gl4java.awt.GLAnimCanvas;
-import gl4java.applet.SimpleGLAnimApplet1;
+
+import gl4java.*;
+import gl4java.drawable.*;
+import gl4java.awt.*;
+import gl4java.applet.*;
public class TriangleRotate extends SimpleGLAnimApplet1
{
public void init()
{
+ GLContext.gljNativeDebug = true;
+ GLContext.gljThreadDebug = false;
+ GLContext.gljClassDebug = true;
+
super.init();
Dimension d = getSize();
- canvas = new gldemo(d.width, d.height);
+ System.out.println("applet size: "+d);
+ GLCapabilities caps = new GLCapabilities();
+
+ canvas =
+ GLDrawableFactory.getFactory().createGLAnimCanvas(caps, d.width, d.height);
+
+ gldemo demo = new gldemo();
+ canvas.addGLEventListener(demo);
+
add("Center", canvas);
}
@@ -65,7 +79,8 @@ public class TriangleRotate extends SimpleGLAnimApplet1
f.setVisible(true);
}
- private class gldemo extends GLAnimCanvas
+ private class gldemo
+ implements GLEventListener
{
float rotate;
@@ -73,24 +88,25 @@ public class TriangleRotate extends SimpleGLAnimApplet1
float LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 0.9f};
float LightSpecular[] = { 0.8f, 0.8f, 0.8f, 1.0f};
- public gldemo(int w, int h)
- {
- super(w, h);
- GLContext.gljNativeDebug = false;
- GLContext.gljClassDebug = false;
- setAnimateFps(30.0);
- }
-
- public void preInit()
+ private GLFunc gl;
+ private GLUFunc glu;
+ private GLContext glj;
+
+ public gldemo()
{
- doubleBuffer = true;
- stereoView = false;
- createOwnWindow = true;
}
- public void init()
+ public void cleanup(GLDrawable drawable)
+ {
+ }
+
+ public void init(GLDrawable drawable)
{
- reshape(getSize().width, getSize().height);
+ gl = drawable.getGL();
+ glu = drawable.getGLU();
+ glj = drawable.getGLContext();
+
+ //drawable.reshape(getSize().width, getSize().height);
gl.glEnable(GL_LIGHT0);
gl.glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
@@ -100,7 +116,7 @@ public class TriangleRotate extends SimpleGLAnimApplet1
glj.gljCheckGL();
}
- public void reshape(int width, int height)
+ public void reshape(gl4java.drawable.GLDrawable d,int width,int height)
{
gl.glMatrixMode(GL_PROJECTION);
gl.glLoadIdentity();
@@ -110,10 +126,8 @@ public class TriangleRotate extends SimpleGLAnimApplet1
gl.glViewport(0,0,width,height);
}
- public void display()
+ public void display(GLDrawable drawable)
{
- if (glj.gljMakeCurrent() == false) return;
-
gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL_MODELVIEW);
@@ -132,9 +146,15 @@ public class TriangleRotate extends SimpleGLAnimApplet1
gl.glVertex3f( 1, -1, 0);
gl.glEnd();
- glj.gljSwap();
glj.gljCheckGL();
- glj.gljFree();
}
+
+ public void preDisplay(GLDrawable drawable)
+ {
+ }
+
+ public void postDisplay(GLDrawable drawable)
+ {
+ }
}
}
diff --git a/demos/MiscDemos/alpha3D.java b/demos/MiscDemos/alpha3D.java
index 5bd72ef..efbf433 100644
--- a/demos/MiscDemos/alpha3D.java
+++ b/demos/MiscDemos/alpha3D.java
@@ -15,9 +15,9 @@ import java.lang.*;
import java.util.*;
import java.io.*;
import java.util.*;
-import gl4java.GLContext;
-import gl4java.awt.GLCanvas;
-import gl4java.awt.GLAnimCanvas;
+import gl4java.*;
+import gl4java.awt.*;
+import gl4java.drawable.*;
import gl4java.applet.SimpleGLAnimApplet1;
import gl4java.utils.glut.*;
@@ -35,7 +35,23 @@ public class alpha3D extends SimpleGLAnimApplet1
{
super.init();
Dimension d = getSize();
- canvas = new alpha3DCanvas(d.width, d.height);
+ GLCapabilities glCaps = new GLCapabilities();
+ glCaps.setAlphaBits(8);
+ glCaps.setAccumAlphaBits(8);
+
+ gl4java.drawable.GLDrawableFactory df =
+ gl4java.drawable.GLDrawableFactory.getFactory();
+
+ if(df instanceof gl4java.drawable.SunJDK13GLDrawableFactory)
+ {
+ gl4java.drawable.SunJDK13GLDrawableFactory sdf =
+ (gl4java.drawable.SunJDK13GLDrawableFactory)df;
+ canvas = new alpha3DCanvas
+ (sdf.getGraphicsConfiguration(glCaps), glCaps, d.width, d.height);
+ } else {
+ canvas = new alpha3DCanvas(glCaps, d.width, d.height);
+ }
+
add("Center", canvas);
}
@@ -46,6 +62,10 @@ public class alpha3D extends SimpleGLAnimApplet1
Frame f = new Frame("alpha3D");
+ GLContext.gljNativeDebug = true;
+ GLContext.gljThreadDebug = false;
+ GLContext.gljClassDebug = true;
+
f.addWindowListener( new WindowAdapter()
{
public void windowClosed(WindowEvent e)
@@ -93,21 +113,19 @@ public class alpha3D extends SimpleGLAnimApplet1
float transparentZ = MINZ;
int sphereList, cubeList;
- public alpha3DCanvas(int w, int h)
+ public alpha3DCanvas(GraphicsConfiguration g, GLCapabilities glCaps,
+ int w, int h)
{
- super(w, h);
- GLContext.gljNativeDebug = false;
- GLContext.gljClassDebug = false;
+ super(g, glCaps, w, h);
setAnimateFps(30.0);
}
- public void preInit()
+ public alpha3DCanvas(GLCapabilities glCaps, int w, int h)
{
- doubleBuffer = true;
- stereoView = false;
+ super(glCaps, w, h);
+ setAnimateFps(30.0);
}
-
public void init()
{
glut = new GLUTFuncLightImpl(gl, glu);
diff --git a/demos/MiscDemos/gears.java b/demos/MiscDemos/gears.java
index e544a08..8775c6e 100644
--- a/demos/MiscDemos/gears.java
+++ b/demos/MiscDemos/gears.java
@@ -12,8 +12,8 @@ import java.lang.*;
import java.util.*;
import java.io.*;
import java.util.*;
-import gl4java.GLContext;
-import gl4java.GLEnum;
+import gl4java.*;
+import gl4java.drawable.*;
import gl4java.awt.GLAnimCanvas;
import gl4java.applet.SimpleGLAnimApplet1;
@@ -22,18 +22,8 @@ public class gears extends SimpleGLAnimApplet1
{
/* Initialize the applet */
- static {
- GLContext.gljNativeDebug = true;
- GLContext.gljThreadDebug = false;
- GLContext.gljClassDebug = true;
- }
-
-
public void init()
{
- GLContext.gljNativeDebug = true;
- GLContext.gljThreadDebug = false;
- GLContext.gljClassDebug = true;
init(false);
}
@@ -41,12 +31,19 @@ public class gears extends SimpleGLAnimApplet1
{
super.init();
Dimension d = getSize();
- canvas = new gearsCanvas(showGL, d.width, d.height);
+
+ GLCapabilities caps = new GLCapabilities();
+
+ canvas =
+ GLDrawableFactory.getFactory().createGLAnimCanvas(caps, d.width, d.height);
+
+ gearRenderer gear = new gearRenderer(showGL);
+ canvas.addGLEventListener(gear);
+
add("Center", canvas);
- addMouseListener(this);
+ addMouseListener(this);
}
-
public static void main( String args[] )
{
int i = 0;
@@ -110,6 +107,9 @@ public class gears extends SimpleGLAnimApplet1
);
gears applet = new gears();
+ mainFrame.add(applet);
+ applet.setSize(400,500);
+ applet.init();
if(perftest)
{
@@ -124,10 +124,8 @@ public class gears extends SimpleGLAnimApplet1
applet.canvas.getUseFpsSleep());
}
- mainFrame.add(applet);
- applet.setSize(400,500);
- applet.init();
applet.start();
+
Dimension ps = applet.getPreferredSize();
mainFrame.setBounds(-100,-100,99,99);
mainFrame.setVisible(true);
@@ -188,7 +186,7 @@ public class gears extends SimpleGLAnimApplet1
/* Local GLAnimCanvas extension class */
- public class gearsCanvas extends GLAnimCanvas implements MouseListener, MouseMotionListener
+ public class gearRenderer implements GLEventListener, MouseListener, MouseMotionListener
{
private static final float M_PI = 3.14159265f;
@@ -204,28 +202,20 @@ public class gears extends SimpleGLAnimApplet1
private boolean showGL = false;
- public gearsCanvas(int w, int h)
- {
- this(false, w, h);
- }
-
- public gearsCanvas(boolean showGL, int w, int h)
- {
- super(w, h);
- setAnimateFps(30.0);
+ private GLFunc gl;
+ private GLUFunc glu;
+ private GLContext glj;
- this.showGL=showGL;
- }
-
- public void preInit()
+ public gearRenderer(boolean showGL)
{
- doubleBuffer = true;
- stereoView = false;
+ this.showGL=showGL;
}
- public void init()
+ public void init(GLDrawable drawable)
{
- reshape(getSize().width, getSize().height);
+ gl = drawable.getGL();
+ glu = drawable.getGLU();
+ glj = drawable.getGLContext();
float pos[] = { 5.0f, 5.0f, 10.0f, 0.0f };
float red[] = { 0.8f, 0.1f, 0.0f, 1.0f };
@@ -261,21 +251,21 @@ public class gears extends SimpleGLAnimApplet1
glj.gljCheckGL();
- addMouseListener(this);
- addMouseMotionListener(this);
+ drawable.addMouseListener(this);
+ drawable.addMouseMotionListener(this);
T0=System.currentTimeMillis();
System.out.println("init ..");
}
- public void doCleanup()
+ public void cleanup(GLDrawable drawable)
{
System.out.println("destroy(): " + this);
removeMouseListener(this);
removeMouseMotionListener(this);
}
- public void reshape(int width, int height)
+ public void reshape(gl4java.drawable.GLDrawable gld,int width,int height)
{
float h = (float)height / (float)width;
@@ -288,10 +278,8 @@ public class gears extends SimpleGLAnimApplet1
gl.glTranslatef(0.0f, 0.0f, -40.0f);
}
- public void display()
+ public void display(GLDrawable drawable)
{
- if (glj.gljMakeCurrent() == false) return;
-
if(showGL)
{
showGL=false;
@@ -329,12 +317,15 @@ public class gears extends SimpleGLAnimApplet1
gl.glPopMatrix();
- glj.gljSwap();
- glj.gljCheckGL();
- glj.gljFree();
-
Frames++;
+ }
+ public void preDisplay(GLDrawable drawable)
+ {
+ }
+
+ public void postDisplay(GLDrawable drawable)
+ {
long t=System.currentTimeMillis();
if(t - T0 >= 5000)
{
diff --git a/demos/MiscDemos/stencil.java b/demos/MiscDemos/stencil.java
index b5f7fe7..09a2092 100644
--- a/demos/MiscDemos/stencil.java
+++ b/demos/MiscDemos/stencil.java
@@ -57,14 +57,12 @@ import java.lang.*;
import java.util.*;
import java.io.*;
import java.util.*;
-import gl4java.GLContext;
+import gl4java.*;
+import gl4java.drawable.*;
import gl4java.awt.GLCanvas;
public class stencil extends Applet
{
- stencilCanvas canvas1 = null;
- stencilCanvas canvas2 = null;
-
Panel cvs = null;
/* Initialize the applet */
@@ -75,10 +73,29 @@ public class stencil extends Applet
Dimension d = getSize();
setLayout(new BorderLayout());
- canvas1 = new stencilCanvas(d.width, d.height, 0, false);
- System.out.println("the left canvas has 0 stencil-bits, self-window");
- canvas2 = new stencilCanvas(d.width, d.height, 8, true);
- System.out.println("the right canvas should have 8 stencil-bits, ownWindow");
+ GLCapabilities caps1 = new GLCapabilities();
+ caps1.setStencilBits(0);
+
+ System.out.println("the left canvas has 0 stencil-bits");
+ System.out.println("caps1: "+caps1);
+
+ GLCanvas canvas1 =
+ GLDrawableFactory.getFactory().createGLCanvas(caps1, d.width, d.height);
+
+ stencilDemo demo1 = new stencilDemo(d.width, d.height);
+ canvas1.addGLEventListener(demo1);
+
+ GLCapabilities caps2 = new GLCapabilities();
+ caps2.setStencilBits(8);
+
+ System.out.println("the right canvas should have >=8 stencil-bits");
+ System.out.println("caps2: "+caps2);
+
+ GLCanvas canvas2 =
+ GLDrawableFactory.getFactory().createGLCanvas(caps2, d.width, d.height);
+
+ stencilDemo demo2 = new stencilDemo(d.width, d.height);
+ canvas2.addGLEventListener(demo2);
cvs = new Panel();
cvs.setLayout(new GridLayout(1,2));
@@ -131,37 +148,39 @@ public class stencil extends Applet
/* Local GLCanvas extension class */
- private class stencilCanvas extends GLCanvas
+ private class stencilDemo
+ implements GLEventListener
{
private static final float M_PI = 3.14159265359f;
private static final int YELLOWMAT = 1, BLUEMAT = 2;
private boolean initdone = false;
- public stencilCanvas(int w, int h,
- int _stencilBits,
- boolean _createOwnWindow)
- {
- super(w, h);
- stencilBits = _stencilBits;
- createOwnWindow = _createOwnWindow;
- }
-
- public void preInit()
+ private GLFunc gl;
+ private GLUFunc glu;
+ private GLContext glj;
+
+
+ public stencilDemo(int w, int h)
{
- doubleBuffer = true;
- stereoView = false;
}
- public void init()
+ public void cleanup(GLDrawable drawable)
+ {
+ }
+
+ public void init(GLDrawable drawable)
{
+ gl = drawable.getGL();
+ glu = drawable.getGLU();
+ glj = drawable.getGLContext();
+
// Examine some OpenGL properties
int [] res=new int[6];
gl.glGetIntegerv(GL_STENCIL_BITS,res);
System.out.println("init(): " + this + "\n\t" +
- "Stencil bits are "+res[0] +"\n\t" +
- "IsOwnCreatedWindow: "+createOwnWindow);
+ "Stencil bits are "+res[0] +"\n\t");
float yellow_diffuse[] = { 0.7f, 0.7f, 0.0f, 1.0f };
float yellow_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
@@ -195,16 +214,9 @@ public class stencil extends Applet
glj.gljCheckGL();
initdone = true;
- reshape(getSize().width, getSize().height);
}
- public void cvsDispose()
- {
- System.out.println("destroy(): " + this);
- super.cvsDispose();
- }
-
- public void reshape(int width, int height)
+ public void reshape(gl4java.drawable.GLDrawable d,int width,int height)
{
gl.glViewport(0,0,width,height);
@@ -247,10 +259,8 @@ public class stencil extends Applet
gl.glTranslatef(0.0f, 0.0f, -5.0f);
}
- public void display()
+ public void display(GLDrawable drawable)
{
- if (glj.gljMakeCurrent() == false) return;
-
/* Draw a sphere in a diamond-shaped section in the
* middle of a window with 2 torii.
*/
@@ -281,11 +291,17 @@ public class stencil extends Applet
gl.glPopMatrix();
gl.glPopMatrix();
- glj.gljSwap();
glj.gljCheckGL();
- glj.gljFree();
}
+ public void preDisplay(GLDrawable drawable)
+ {
+ }
+
+ public void postDisplay(GLDrawable drawable)
+ {
+ }
+
// Imported from glut.
private void glutSolidTorus
(float innerRadius,
diff --git a/demos/RonsDemos/dinoshade.java b/demos/RonsDemos/dinoshade.java
index 570ea12..f9ab381 100755
--- a/demos/RonsDemos/dinoshade.java
+++ b/demos/RonsDemos/dinoshade.java
@@ -1,328 +1,347 @@
-/**
- * @(#) dinoshade.java
- * @(#) author: Mark J. Kilgard (converted to Java by Ron Cemer)
- */
-
-/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
-
-/* This program is freely distributable without licensing fees
- and is provided without guarantee or warrantee expressed or
- implied. This program is -not- in the public domain. */
-
-/* Example for PC game developers to show how to *combine* texturing,
- reflections, and projected shadows all in real-time with OpenGL.
- Robust reflections use stenciling. Robust projected shadows
- use both stenciling and polygon offset. PC game programmers
- should realize that neither stenciling nor polygon offset are
- supported by Direct3D, so these real-time rendering algorithms
- are only really viable with OpenGL.
-
- The program has modes for disabling the stenciling and polygon
- offset uses. It is worth running this example with these features
- toggled off so you can see the sort of artifacts that result.
-
- Notice that the floor texturing, reflections, and shadowing
- all co-exist properly. */
-
-/* When you run this program: Left mouse button controls the
- view. Middle mouse button controls light position (left &
- right rotates light around dino; up & down moves light
- position up and down). Right mouse button pops up menu. */
-
-/* Check out the comments in the "redraw" routine to see how the
- reflection blending and surface stenciling is done. You can
- also see in "redraw" how the projected shadows are rendered,
- including the use of stenciling and polygon offset. */
-
-import java.applet.*;
-import java.awt.*;
-import java.awt.event.*;
-import java.lang.*;
-import java.util.*;
-import java.io.*;
-import java.util.*;
-import gl4java.GLContext;
-import gl4java.awt.GLAnimCanvas;
-import gl4java.applet.SimpleGLAnimApplet1;
-
-public class dinoshade extends SimpleGLAnimApplet1
-{
- static final float[][] bodyVerts =
- {
- { 0.0f, 3.0f, 0.0f},
- { 1.0f, 1.0f, 0.0f},
- { 5.0f, 1.0f, 0.0f},
- { 8.0f, 4.0f, 0.0f},
- { 10.0f, 4.0f, 0.0f},
- { 11.0f, 5.0f, 0.0f},
- { 11.0f, 11.5f, 0.0f},
- { 13.0f, 12.0f, 0.0f},
- { 13.0f, 13.0f, 0.0f},
- { 10.0f, 13.5f, 0.0f},
- { 13.0f, 14.0f, 0.0f},
- { 13.0f, 15.0f, 0.0f},
- { 11.0f, 16.0f, 0.0f},
- { 8.0f, 16.0f, 0.0f},
- { 7.0f, 15.0f, 0.0f},
- { 7.0f, 13.0f, 0.0f},
- { 8.0f, 12.0f, 0.0f},
- { 7.0f, 11.0f, 0.0f},
- { 6.0f, 6.0f, 0.0f},
- { 4.0f, 3.0f, 0.0f},
- { 3.0f, 2.0f, 0.0f},
- { 1.0f, 2.0f, 0.0f},
- };
-
- static final int[][] bodyTris =
- {
- { 1, 0, 21 },
- { 1, 21, 2 },
- { 21, 20, 2 },
- { 20, 19, 2 },
- { 19, 3, 2 },
- { 19, 18, 3 },
- { 18, 4, 3 },
- { 18, 5, 4 },
- { 18, 6, 5 },
- { 18, 17, 6 },
- { 17, 16, 6 },
- { 16, 7, 6 },
- { 16, 8, 7 },
- { 16, 15, 8 },
- { 15, 9, 8 },
- { 15, 14, 9 },
- { 14, 13, 9 },
- { 9, 13, 12 },
- { 9, 12, 11 },
- { 11, 10, 9 },
- };
-
- static final float[][] armVerts =
- {
- { 8.0f, 10.0f, 0.0f},
- { 9.0f, 9.0f, 0.0f},
- { 10.0f, 9.0f, 0.0f},
- { 13.0f, 8.0f, 0.0f},
- { 14.0f, 9.0f, 0.0f},
- { 16.0f, 9.0f, 0.0f},
- { 15.0f, 9.5f, 0.0f},
- { 16.0f, 10.0f, 0.0f},
- { 15.0f, 10.0f, 0.0f},
- { 15.5f, 11.0f, 0.0f},
- { 14.5f, 10.0f, 0.0f},
- { 14.0f, 11.0f, 0.0f},
- { 14.0f, 10.0f, 0.0f},
- { 13.0f, 9.0f, 0.0f},
- { 11.0f, 11.0f, 0.0f},
- { 9.0f, 11.0f, 0.0f},
- };
-
- static final int[][] armTris =
- {
- { 0, 15, 1 },
- { 15, 2, 1 },
- { 15, 14, 2 },
- { 14, 13, 2 },
- { 13, 3, 2 },
- { 13, 4, 3 },
- { 13, 12, 4 },
- { 12, 11, 10 },
- { 12, 10, 4 },
- { 10, 6, 4 },
- { 6, 5, 4 },
- { 8, 7, 6 },
- { 10, 8, 6 },
- { 10, 9, 8 },
- };
-
- static final float[][] legVerts =
- {
- { 8.0f, 6.0f, 0.0f},
- { 8.0f, 4.0f, 0.0f},
- { 9.0f, 3.0f, 0.0f},
- { 9.0f, 2.0f, 0.0f},
- { 8.0f, 1.0f, 0.0f},
- { 8.0f, 0.5f, 0.0f},
- { 9.0f, 0.0f, 0.0f},
- { 12.0f, 0.0f, 0.0f},
- { 10.0f, 1.0f, 0.0f},
- { 10.0f, 2.0f, 0.0f},
- { 12.0f, 4.0f, 0.0f},
- { 11.0f, 6.0f, 0.0f},
- { 10.0f, 7.0f, 0.0f},
- { 9.0f, 7.0f, 0.0f},
- };
-
- static final int[][] legTris =
- {
- { 6, 5, 7 },
- { 5, 8, 7 },
- { 5, 4, 8 },
- { 4, 3, 8 },
- { 3, 9, 8 },
- { 3, 2, 9 },
- { 2, 10, 9 },
- { 2, 1, 10 },
- { 1, 0, 10 },
- { 0, 11, 10 },
- { 0, 12, 11 },
- { 0, 13, 12 },
- };
-
- static final float[][] eyeVerts =
- {
- { 8.75f, 15.0f, 0.0f},
- { 9.0f, 14.7f, 0.0f},
- { 9.6f, 14.7f, 0.0f},
- { 10.1f, 15.0f, 0.0f},
- { 9.6f, 15.25f, 0.0f},
- { 9.0f, 15.25f, 0.0f},
- };
-
- static final int[][] eyeTris =
- {
- { 1, 0, 2 },
- { 0, 5, 2 },
- { 5, 4, 2 },
- { 4, 3, 2 },
- };
-
- static final float floorVertices[][] =
- {
- { -20.0f, 0.0f, 20.0f },
- { 20.0f, 0.0f, 20.0f },
- { 20.0f, 0.0f, -20.0f },
- { -20.0f, 0.0f, -20.0f },
- };
-
-
- /* Initialize the applet */
-
-
- public void init()
- {
- super.init();
- Dimension d = getSize();
- canvas = new dinoshadeCanvas(d.width, d.height);
- add("Center", canvas);
- }
-
-
- public static void main( String args[] ) {
- dinoshade applet =
- new dinoshade();
-
- Frame f = new Frame("dinoshade");
-
- f.addWindowListener( new WindowAdapter()
- {
- public void windowClosed(WindowEvent e)
- {
- System.exit(0);
- }
- public void windowClosing(WindowEvent e)
- {
- windowClosed(e);
- }
- }
- );
-
- f.setLayout(new BorderLayout());
- f.add("Center", applet);
- applet.setSize(500,300);
+/**
+ * @(#) dinoshade.java
+ * @(#) author: Mark J. Kilgard (converted to Java by Ron Cemer)
+ */
+
+/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
+
+/* This program is freely distributable without licensing fees
+ and is provided without guarantee or warrantee expressed or
+ implied. This program is -not- in the public domain. */
+
+/* Example for PC game developers to show how to *combine* texturing,
+ reflections, and projected shadows all in real-time with OpenGL.
+ Robust reflections use stenciling. Robust projected shadows
+ use both stenciling and polygon offset. PC game programmers
+ should realize that neither stenciling nor polygon offset are
+ supported by Direct3D, so these real-time rendering algorithms
+ are only really viable with OpenGL.
+
+ The program has modes for disabling the stenciling and polygon
+ offset uses. It is worth running this example with these features
+ toggled off so you can see the sort of artifacts that result.
+
+ Notice that the floor texturing, reflections, and shadowing
+ all co-exist properly. */
+
+/* When you run this program: Left mouse button controls the
+ view. Middle mouse button controls light position (left &
+ right rotates light around dino; up & down moves light
+ position up and down). Right mouse button pops up menu. */
+
+/* Check out the comments in the "redraw" routine to see how the
+ reflection blending and surface stenciling is done. You can
+ also see in "redraw" how the projected shadows are rendered,
+ including the use of stenciling and polygon offset. */
+
+import java.applet.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.lang.*;
+import java.util.*;
+import java.io.*;
+import java.util.*;
+
+import gl4java.*;
+import gl4java.awt.*;
+import gl4java.drawable.*;
+import gl4java.applet.SimpleGLAnimApplet1;
+
+public class dinoshade extends SimpleGLAnimApplet1
+{
+ static final float[][] bodyVerts =
+ {
+ { 0.0f, 3.0f, 0.0f},
+ { 1.0f, 1.0f, 0.0f},
+ { 5.0f, 1.0f, 0.0f},
+ { 8.0f, 4.0f, 0.0f},
+ { 10.0f, 4.0f, 0.0f},
+ { 11.0f, 5.0f, 0.0f},
+ { 11.0f, 11.5f, 0.0f},
+ { 13.0f, 12.0f, 0.0f},
+ { 13.0f, 13.0f, 0.0f},
+ { 10.0f, 13.5f, 0.0f},
+ { 13.0f, 14.0f, 0.0f},
+ { 13.0f, 15.0f, 0.0f},
+ { 11.0f, 16.0f, 0.0f},
+ { 8.0f, 16.0f, 0.0f},
+ { 7.0f, 15.0f, 0.0f},
+ { 7.0f, 13.0f, 0.0f},
+ { 8.0f, 12.0f, 0.0f},
+ { 7.0f, 11.0f, 0.0f},
+ { 6.0f, 6.0f, 0.0f},
+ { 4.0f, 3.0f, 0.0f},
+ { 3.0f, 2.0f, 0.0f},
+ { 1.0f, 2.0f, 0.0f},
+ };
+
+ static final int[][] bodyTris =
+ {
+ { 1, 0, 21 },
+ { 1, 21, 2 },
+ { 21, 20, 2 },
+ { 20, 19, 2 },
+ { 19, 3, 2 },
+ { 19, 18, 3 },
+ { 18, 4, 3 },
+ { 18, 5, 4 },
+ { 18, 6, 5 },
+ { 18, 17, 6 },
+ { 17, 16, 6 },
+ { 16, 7, 6 },
+ { 16, 8, 7 },
+ { 16, 15, 8 },
+ { 15, 9, 8 },
+ { 15, 14, 9 },
+ { 14, 13, 9 },
+ { 9, 13, 12 },
+ { 9, 12, 11 },
+ { 11, 10, 9 },
+ };
+
+ static final float[][] armVerts =
+ {
+ { 8.0f, 10.0f, 0.0f},
+ { 9.0f, 9.0f, 0.0f},
+ { 10.0f, 9.0f, 0.0f},
+ { 13.0f, 8.0f, 0.0f},
+ { 14.0f, 9.0f, 0.0f},
+ { 16.0f, 9.0f, 0.0f},
+ { 15.0f, 9.5f, 0.0f},
+ { 16.0f, 10.0f, 0.0f},
+ { 15.0f, 10.0f, 0.0f},
+ { 15.5f, 11.0f, 0.0f},
+ { 14.5f, 10.0f, 0.0f},
+ { 14.0f, 11.0f, 0.0f},
+ { 14.0f, 10.0f, 0.0f},
+ { 13.0f, 9.0f, 0.0f},
+ { 11.0f, 11.0f, 0.0f},
+ { 9.0f, 11.0f, 0.0f},
+ };
+
+ static final int[][] armTris =
+ {
+ { 0, 15, 1 },
+ { 15, 2, 1 },
+ { 15, 14, 2 },
+ { 14, 13, 2 },
+ { 13, 3, 2 },
+ { 13, 4, 3 },
+ { 13, 12, 4 },
+ { 12, 11, 10 },
+ { 12, 10, 4 },
+ { 10, 6, 4 },
+ { 6, 5, 4 },
+ { 8, 7, 6 },
+ { 10, 8, 6 },
+ { 10, 9, 8 },
+ };
+
+ static final float[][] legVerts =
+ {
+ { 8.0f, 6.0f, 0.0f},
+ { 8.0f, 4.0f, 0.0f},
+ { 9.0f, 3.0f, 0.0f},
+ { 9.0f, 2.0f, 0.0f},
+ { 8.0f, 1.0f, 0.0f},
+ { 8.0f, 0.5f, 0.0f},
+ { 9.0f, 0.0f, 0.0f},
+ { 12.0f, 0.0f, 0.0f},
+ { 10.0f, 1.0f, 0.0f},
+ { 10.0f, 2.0f, 0.0f},
+ { 12.0f, 4.0f, 0.0f},
+ { 11.0f, 6.0f, 0.0f},
+ { 10.0f, 7.0f, 0.0f},
+ { 9.0f, 7.0f, 0.0f},
+ };
+
+ static final int[][] legTris =
+ {
+ { 6, 5, 7 },
+ { 5, 8, 7 },
+ { 5, 4, 8 },
+ { 4, 3, 8 },
+ { 3, 9, 8 },
+ { 3, 2, 9 },
+ { 2, 10, 9 },
+ { 2, 1, 10 },
+ { 1, 0, 10 },
+ { 0, 11, 10 },
+ { 0, 12, 11 },
+ { 0, 13, 12 },
+ };
+
+ static final float[][] eyeVerts =
+ {
+ { 8.75f, 15.0f, 0.0f},
+ { 9.0f, 14.7f, 0.0f},
+ { 9.6f, 14.7f, 0.0f},
+ { 10.1f, 15.0f, 0.0f},
+ { 9.6f, 15.25f, 0.0f},
+ { 9.0f, 15.25f, 0.0f},
+ };
+
+ static final int[][] eyeTris =
+ {
+ { 1, 0, 2 },
+ { 0, 5, 2 },
+ { 5, 4, 2 },
+ { 4, 3, 2 },
+ };
+
+ static final float floorVertices[][] =
+ {
+ { -20.0f, 0.0f, 20.0f },
+ { 20.0f, 0.0f, 20.0f },
+ { 20.0f, 0.0f, -20.0f },
+ { -20.0f, 0.0f, -20.0f },
+ };
+
+
+ /* Initialize the applet */
+
+
+ public void init()
+ {
+ super.init();
+ Dimension d = getSize();
+
+ GLCapabilities glCaps = new GLCapabilities();
+ glCaps.setStencilBits(16);
+
+ gl4java.drawable.GLDrawableFactory df =
+ gl4java.drawable.GLDrawableFactory.getFactory();
+
+ if(df instanceof gl4java.drawable.SunJDK13GLDrawableFactory)
+ {
+ gl4java.drawable.SunJDK13GLDrawableFactory sdf =
+ (gl4java.drawable.SunJDK13GLDrawableFactory)df;
+ canvas = new dinoshadeCanvas
+ (sdf.getGraphicsConfiguration(glCaps), glCaps, d.width, d.height);
+ } else {
+ canvas = new dinoshadeCanvas(glCaps, d.width, d.height);
+ }
+
+ add("Center", canvas);
+ }
+
+
+ public static void main( String args[] ) {
+ GLContext.gljNativeDebug = true;
+ GLContext.gljThreadDebug = false;
+ GLContext.gljClassDebug = true;
+
+ dinoshade applet =
+ new dinoshade();
+
+ Frame f = new Frame("dinoshade");
+
+ f.addWindowListener( new WindowAdapter()
+ {
+ public void windowClosed(WindowEvent e)
+ {
+ System.exit(0);
+ }
+ public void windowClosing(WindowEvent e)
+ {
+ windowClosed(e);
+ }
+ }
+ );
+
+ f.setLayout(new BorderLayout());
+ f.add("Center", applet);
+ applet.setSize(500,300);
applet.init();
- applet.start();
- Dimension ps = applet.getPreferredSize();
- f.setBounds(-100,-100,99,99);
- f.setVisible(true);
- f.setVisible(false);
- Insets i = f.getInsets();
- f.setBounds(0,0,
- ps.width+i.left+i.right,
- ps.height+i.top+i.bottom);
- f.setVisible(true);
- }
-
- /* Local GLAnimCanvas extension class */
-
-
- private class dinoshadeCanvas extends GLAnimCanvas
- implements MouseListener, MouseMotionListener, ActionListener
- {
- private static final double M_PI = 3.14159265;
-
- // Menu options:
- private static final String M_NONE = "-----------------------";
- private static final String M_MOTION = "Toggle motion";
- private static final String M_LIGHT = "Toggle light";
- private static final String M_TEXTURE = "Toggle texture";
- private static final String M_SHADOWS = "Toggle shadows";
- private static final String M_REFLECTION = "Toggle reflection";
- private static final String M_DINOSAUR = "Toggle dinosaur";
- private static final String M_STENCIL_REFLECTION = "Toggle reflection stenciling";
- private static final String M_STENCIL_SHADOW = "Toggle shadow stenciling";
- private static final String M_OFFSET_SHADOW = "Toggle shadow offset";
- private static final String M_POSITIONAL = "Positional light";
- private static final String M_DIRECTIONAL = "Directional light";
-
- private PopupMenu menu = null;
- private boolean menu_showing = false;
- private boolean save_suspended = false;
-
- /* Variables controlling various rendering modes. */
- private boolean stencilReflection = true, stencilShadow = true, offsetShadow = true;
- private boolean renderShadow = true, renderDinosaur = true, renderReflection = true;
- private boolean linearFiltering = false, useTexture = true;
-// private boolean useMipmaps = false;
- private boolean lightSwitch = true;
- private boolean directionalLight = true;
-
- /* Time varying or user-controled variables. */
- private float jump = 0.0f;
- private float lightAngle = 0.0f, lightHeight = 20.0f;
- private float angle = -150.0f; /* in degrees */
- private float angle2 = 30.0f; /* in degrees */
-
- private boolean moving = false;
- private int startx, starty;
- private boolean lightMoving = false;
- private int lightStartX, lightStartY;
-
- private final float bodyWidth = 3.0f;
-
- private final float[] lightPosition = new float[4];
- private final float lightColor[] = {0.8f, 1.0f, 0.8f, 1.0f}; /* green-tinted */
- private final float skinColor[] = {0.1f, 1.0f, 0.1f, 1.0f};
- private final float eyeColor[] = {1.0f, 0.2f, 0.2f, 1.0f};
- private final int X = 0, Y = 1, Z = 2, W = 3;
- private final int A = 0, B = 1, C = 2, D = 3;
-
- /* Enumerants for refering to display lists. */
- private static final int
- BODY_SIDE = 1, BODY_EDGE = 2, BODY_WHOLE = 3,
- ARM_SIDE = 4, ARM_EDGE = 5, ARM_WHOLE = 6,
- LEG_SIDE = 7, LEG_EDGE = 8, LEG_WHOLE = 9,
- EYE_SIDE = 10, EYE_EDGE = 11, EYE_WHOLE = 12;
- private float floorPlane[] = new float[4];
- private float floorShadow[] = new float[16];
-
- public dinoshadeCanvas(int w, int h)
- {
- super(w, h);
- GLContext.gljNativeDebug = false;
- GLContext.gljClassDebug = false;
- setAnimateFps(30.0);
- }
-
- public void preInit()
- {
- doubleBuffer = true;
- stereoView = false;
- stencilBits = 3;
- }
-
- public void init()
- {
+ applet.start();
+ Dimension ps = applet.getPreferredSize();
+ f.setBounds(-100,-100,99,99);
+ f.setVisible(true);
+ f.setVisible(false);
+ f.setVisible(true);
+ Insets i = f.getInsets();
+ f.setBounds(0,0,
+ ps.width+i.left+i.right,
+ ps.height+i.top+i.bottom);
+ f.setVisible(true);
+ }
+
+ /* Local GLAnimCanvas extension class */
+
+
+ private class dinoshadeCanvas extends GLAnimCanvas
+ implements MouseListener, MouseMotionListener, ActionListener
+ {
+ private static final double M_PI = 3.14159265;
+
+ // Menu options:
+ private static final String M_NONE = "-----------------------";
+ private static final String M_MOTION = "Toggle motion";
+ private static final String M_LIGHT = "Toggle light";
+ private static final String M_TEXTURE = "Toggle texture";
+ private static final String M_SHADOWS = "Toggle shadows";
+ private static final String M_REFLECTION = "Toggle reflection";
+ private static final String M_DINOSAUR = "Toggle dinosaur";
+ private static final String M_STENCIL_REFLECTION = "Toggle reflection stenciling";
+ private static final String M_STENCIL_SHADOW = "Toggle shadow stenciling";
+ private static final String M_OFFSET_SHADOW = "Toggle shadow offset";
+ private static final String M_POSITIONAL = "Positional light";
+ private static final String M_DIRECTIONAL = "Directional light";
+
+ private PopupMenu menu = null;
+ private boolean menu_showing = false;
+ private boolean save_suspended = false;
+
+ /* Variables controlling various rendering modes. */
+ private boolean stencilReflection = true, stencilShadow = true, offsetShadow = true;
+ private boolean renderShadow = true, renderDinosaur = true, renderReflection = true;
+ private boolean linearFiltering = false, useTexture = true;
+// private boolean useMipmaps = false;
+ private boolean lightSwitch = true;
+ private boolean directionalLight = true;
+
+ /* Time varying or user-controled variables. */
+ private float jump = 0.0f;
+ private float lightAngle = 0.0f, lightHeight = 20.0f;
+ private float angle = -150.0f; /* in degrees */
+ private float angle2 = 30.0f; /* in degrees */
+
+ private boolean moving = false;
+ private int startx, starty;
+ private boolean lightMoving = false;
+ private int lightStartX, lightStartY;
+
+ private final float bodyWidth = 3.0f;
+
+ private final float[] lightPosition = new float[4];
+ private final float lightColor[] = {0.8f, 1.0f, 0.8f, 1.0f}; /* green-tinted */
+ private final float skinColor[] = {0.1f, 1.0f, 0.1f, 1.0f};
+ private final float eyeColor[] = {1.0f, 0.2f, 0.2f, 1.0f};
+ private final int X = 0, Y = 1, Z = 2, W = 3;
+ private final int A = 0, B = 1, C = 2, D = 3;
+
+ /* Enumerants for refering to display lists. */
+ private static final int
+ BODY_SIDE = 1, BODY_EDGE = 2, BODY_WHOLE = 3,
+ ARM_SIDE = 4, ARM_EDGE = 5, ARM_WHOLE = 6,
+ LEG_SIDE = 7, LEG_EDGE = 8, LEG_WHOLE = 9,
+ EYE_SIDE = 10, EYE_EDGE = 11, EYE_WHOLE = 12;
+ private float floorPlane[] = new float[4];
+ private float floorShadow[] = new float[16];
+
+ public dinoshadeCanvas(GraphicsConfiguration g, GLCapabilities glCaps,
+ int w, int h)
+ {
+ super(g, glCaps, w, h);
+ }
+
+ public dinoshadeCanvas(GLCapabilities glCaps, int w, int h)
+ {
+ super(glCaps, w, h);
+ }
+
+ public void init()
+ {
int [] res=new int[6];
gl.glGetIntegerv(GL_STENCIL_BITS,res);
@@ -331,774 +350,774 @@ public class dinoshade extends SimpleGLAnimApplet1
"Stencil bits are "+res[0] +"\n\t" +
"IsOwnCreatedWindow: "+createOwnWindow);
- reshape(getSize().width, getSize().height);
-
- makeDinosaur();
-
- gl.glPolygonOffset(-2.0f, -1.0f);
-
- gl.glEnable(GL_CULL_FACE);
- gl.glEnable(GL_DEPTH_TEST);
- gl.glEnable(GL_TEXTURE_2D);
- gl.glLineWidth(3.0f);
-
- gl.glMatrixMode(GL_PROJECTION);
- glu.gluPerspective
- ( /* field of view in degree */ 40.0f,
- /* aspect ratio */ 1.0f,
- /* Z near */ 20.0f,
- /* Z far */ 100.0f);
- gl.glMatrixMode(GL_MODELVIEW);
- glu.gluLookAt
- (0.0f, 8.0f, 60.0f, /* eye is at (0,8,60) */
- 0.0f, 8.0f, 0.0f, /* center is at (0,8,0) */
- 0.0f, 1.0f, 0.0f); /* up is in postivie Y direction */
-
- gl.glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
- gl.glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
- gl.glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1f);
- gl.glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05f);
- gl.glEnable(GL_LIGHT0);
- gl.glEnable(GL_LIGHTING);
-
- makeFloorTexture();
-
- /* Setup floor plane for projected shadow calculations. */
- findPlane
- (floorPlane,
- floorVertices[1],
- floorVertices[2],
- floorVertices[3]);
-
- glj.gljCheckGL();
-
- menu = new PopupMenu("Options");
- menu.add(M_MOTION);
- menu.add(M_NONE);
- menu.add(M_LIGHT);
- menu.add(M_TEXTURE);
- menu.add(M_SHADOWS);
- menu.add(M_REFLECTION);
- menu.add(M_DINOSAUR);
- menu.add(M_NONE);
- menu.add(M_STENCIL_REFLECTION);
- menu.add(M_STENCIL_SHADOW);
- menu.add(M_OFFSET_SHADOW);
- menu.add(M_NONE);
- menu.add(M_POSITIONAL);
- menu.add(M_DIRECTIONAL);
- menu.addActionListener(this);
- add(menu);
-
- addMouseListener(this);
- addMouseMotionListener(this);
- }
-
- public void doCleanup()
- {
- removeMouseListener(this);
- removeMouseMotionListener(this);
- menu.removeActionListener(this);
- }
-
- public void reshape(int width, int height)
- {
- gl.glViewport(0,0,width,height);
- }
-
- public void display()
- {
- if (glj.gljMakeCurrent() == false) return;
-
- if (!isSuspended())
- {
- long ltime =
- System.currentTimeMillis() % 3142L; //approximate 2*PI*500
- float time = (float)(((double)ltime)/500.0);
- jump = 4.0f * (float)Math.abs(Math.sin(time)*0.5);
- if (!lightMoving) lightAngle += 0.0f;
- }
-
- /* Clear; default stencil clears to zero. */
- if ((stencilReflection && renderReflection) || (stencilShadow && renderShadow))
- gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- else
- /* Avoid clearing stencil when not using it. */
- gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- /* Reposition the light source. */
- lightPosition[0] = 12*(float)Math.cos(lightAngle);
- lightPosition[1] = lightHeight;
- lightPosition[2] = 12*(float)Math.sin(lightAngle);
- if (directionalLight)
- lightPosition[3] = 0.0f;
- else
- lightPosition[3] = 1.0f;
-
- shadowMatrix(floorShadow, floorPlane, lightPosition);
-
- gl.glPushMatrix();
-
- /* Perform scene rotations based on user mouse input. */
- gl.glRotatef(angle2, 1.0f, 0.0f, 0.0f);
- gl.glRotatef(angle, 0.0f, 1.0f, 0.0f);
-
- /* Tell GL new light source position. */
- gl.glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
-
- if (renderReflection)
- {
- if (stencilReflection)
- {
- /* We can eliminate the visual "artifact" of seeing the "flipped"
- dinosaur underneath the floor by using stencil. The idea is
- draw the floor without color or depth update but so that
- a stencil value of one is where the floor will be. Later when
- rendering the dinosaur reflection, we will only update pixels
- with a stencil value of 1 to make sure the reflection only
- lives on the floor, not below the floor. */
-
- /* Don't update color or depth. */
- gl.glDisable(GL_DEPTH_TEST);
- gl.glColorMask(false, false, false, false);
-
- /* Draw 1 into the stencil buffer. */
- gl.glEnable(GL_STENCIL_TEST);
- gl.glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
- gl.glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
-
- /* Now render floor; floor pixels just get their stencil set to 1. */
- drawFloor();
-
- /* Re-enable update of color and depth. */
- gl.glColorMask(true, true, true, true);
- gl.glEnable(GL_DEPTH_TEST);
-
- /* Now, only render where stencil is set to 1. */
- gl.glStencilFunc(GL_EQUAL, 1, 0xffffffff); /* draw if ==1 */
- gl.glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- }
-
- gl.glPushMatrix();
-
- /* The critical reflection step: Reflect dinosaur through the floor
- (the Y=0 plane) to make a relection. */
-
- gl.glScalef(1.0f, -1.0f, 1.0f);
-
- /* Reflect the light position. */
- gl.glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
-
- /* To avoid our normals getting reversed and hence botched lighting
- on the reflection, turn on normalize. */
- gl.glEnable(GL_NORMALIZE);
- gl.glCullFace(GL_FRONT);
-
- /* Draw the reflected dinosaur. */
- drawDinosaur();
-
- /* Disable noramlize again and re-enable back face culling. */
- gl.glDisable(GL_NORMALIZE);
- gl.glCullFace(GL_BACK);
-
- gl.glPopMatrix();
-
- /* Switch back to the unreflected light position. */
- gl.glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
-
- if (stencilReflection) gl.glDisable(GL_STENCIL_TEST);
- }
-
- /* Back face culling will get used to only draw either the top or the
- bottom floor. This let's us get a floor with two distinct
- appearances. The top floor surface is reflective and kind of red.
- The bottom floor surface is not reflective and blue. */
-
- /* Draw "bottom" of floor in blue. */
- gl.glFrontFace(GL_CW); /* Switch face orientation. */
- gl.glColor4f(0.1f, 0.1f, 0.7f, 1.0f);
- drawFloor();
- gl.glFrontFace(GL_CCW);
-
- if (renderShadow)
- {
- if (stencilShadow)
- {
- /* Draw the floor with stencil value 3. This helps us only
- draw the shadow once per floor pixel (and only on the
- floor pixels). */
- gl.glEnable(GL_STENCIL_TEST);
- gl.glStencilFunc(GL_ALWAYS, 3, 0xffffffff);
- gl.glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
- }
- }
-
- /* Draw "top" of floor. Use blending to blend in reflection. */
- gl.glEnable(GL_BLEND);
- gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- gl.glColor4f(0.7f, 0.0f, 0.0f, 0.3f);
- gl.glColor4f(1.0f, 1.0f, 1.0f, 0.3f);
- drawFloor();
- gl.glDisable(GL_BLEND);
-
- /* Draw "actual" dinosaur, not its reflection. */
- if (renderDinosaur) drawDinosaur();
-
- if (renderShadow)
- {
- /* Render the projected shadow. */
- if (stencilShadow)
- {
- /* Now, only render where stencil is set above 2 (ie, 3 where
- the top floor is). Update stencil with 2 where the shadow
- gets drawn so we don't redraw (and accidently reblend) the
- shadow). */
- gl.glStencilFunc(GL_LESS, 2, 0xffffffff); /* draw if ==1 */
- gl.glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
- }
- /* To eliminate depth buffer artifacts, we use polygon offset
- to raise the depth of the projected shadow slightly so
- that it does not depth buffer alias with the floor. */
- if (offsetShadow) gl.glEnable(GL_POLYGON_OFFSET_FILL);
-
- /* Render 50% black shadow color on top of whatever the
- floor appareance is. */
- gl.glEnable(GL_BLEND);
- gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- gl.glDisable(GL_LIGHTING); /* Force the 50% black. */
- gl.glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
-
- gl.glPushMatrix();
- /* Project the shadow. */
- gl.glMultMatrixf(floorShadow);
- drawDinosaur();
- gl.glPopMatrix();
-
- gl.glDisable(GL_BLEND);
- gl.glEnable(GL_LIGHTING);
-
- if (offsetShadow) gl.glDisable(GL_POLYGON_OFFSET_FILL);
- if (stencilShadow) gl.glDisable(GL_STENCIL_TEST);
- }
-
- gl.glPushMatrix();
- gl.glDisable(GL_LIGHTING);
- gl.glColor3f(1.0f, 1.0f, 0.0f);
- if (directionalLight)
- {
- /* Draw an arrowhead. */
- gl.glDisable(GL_CULL_FACE);
- gl.glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]);
- gl.glRotatef(lightAngle * (float)(-180.0 / M_PI), 0, 1, 0);
- gl.glRotatef((float)Math.atan(lightHeight/12) * (float)(180.0 / M_PI), 0, 0, 1);
- gl.glBegin(GL_TRIANGLE_FAN);
- gl.glVertex3f(0, 0, 0);
- gl.glVertex3f(2, 1, 1);
- gl.glVertex3f(2, -1, 1);
- gl.glVertex3f(2, -1, -1);
- gl.glVertex3f(2, 1, -1);
- gl.glVertex3f(2, 1, 1);
- gl.glEnd();
- /* Draw a white line from light direction. */
- gl.glColor3f(1.0f, 1.0f, 1.0f);
- gl.glBegin(GL_LINES);
- gl.glVertex3f(0, 0, 0);
- gl.glVertex3f(5, 0, 0);
- gl.glEnd();
- gl.glEnable(GL_CULL_FACE);
- }
- else
- {
- /* Draw a yellow ball at the light source. */
- gl.glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]);
- long qobj = glu.gluNewQuadric();
- glu.gluQuadricOrientation(qobj,GLU_OUTSIDE);
- glu.gluQuadricNormals(qobj,GLU_SMOOTH);
- glu.gluQuadricTexture(qobj,false);
- glu.gluSphere(qobj,1.0f,5,5);
- glu.gluDeleteQuadric(qobj);
- }
- gl.glEnable(GL_LIGHTING);
- gl.glPopMatrix();
-
- gl.glPopMatrix();
-
- glj.gljSwap();
- glj.gljCheckGL();
- glj.gljFree();
-
- // if (!isSuspended()) repaint(); // Animate at full speed.
- }
-
- private void makeDinosaur()
- {
- extrudeSolidFromPolygon
- (bodyVerts,
- bodyTris,
- bodyWidth,
- BODY_SIDE,
- BODY_EDGE,
- BODY_WHOLE);
- extrudeSolidFromPolygon
- (armVerts,
- armTris,
- bodyWidth/4,
- ARM_SIDE,
- ARM_EDGE,
- ARM_WHOLE);
- extrudeSolidFromPolygon
- (legVerts,
- legTris,
- bodyWidth/2,
- LEG_SIDE,
- LEG_EDGE,
- LEG_WHOLE);
- extrudeSolidFromPolygon
- (eyeVerts,
- eyeTris,
- bodyWidth+0.2f,
- EYE_SIDE,
- EYE_EDGE,
- EYE_WHOLE);
- }
-
- private void drawDinosaur()
- {
- gl.glPushMatrix();
- /* Translate the dinosaur to be at (0,8,0). */
- gl.glTranslatef(-8, 0, -bodyWidth / 2);
- gl.glTranslatef(0.0f, jump, 0.0f);
- gl.glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);
- gl.glCallList(BODY_WHOLE);
- gl.glTranslatef(0.0f, 0.0f, bodyWidth);
- gl.glCallList(ARM_WHOLE);
- gl.glCallList(LEG_WHOLE);
- gl.glTranslatef(0.0f, 0.0f, -bodyWidth - bodyWidth / 4);
- gl.glCallList(ARM_WHOLE);
- gl.glTranslatef(0.0f, 0.0f, -bodyWidth / 4);
- gl.glCallList(LEG_WHOLE);
- gl.glTranslatef(0.0f, 0.0f, bodyWidth / 2 - 0.1f);
- gl.glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);
- gl.glCallList(EYE_WHOLE);
- gl.glPopMatrix();
- }
-
- private void makeFloorTexture()
- {
- /* Nice floor texture tiling pattern. */
- String circles[] =
- {
- "....xxxx........",
- "..xxxxxxxx......",
- ".xxxxxxxxxx.....",
- ".xxx....xxx.....",
- "xxx......xxx....",
- "xxx......xxx....",
- "xxx......xxx....",
- "xxx......xxx....",
- ".xxx....xxx.....",
- ".xxxxxxxxxx.....",
- "..xxxxxxxx......",
- "....xxxx........",
- "................",
- "................",
- "................",
- "................"
- };
- byte floorTexture[] = new byte[16*16*3];
-
- /* Setup RGB image for the texture. */
- int idx = 0;
- for (int t = 0; t < 16; t++)
- {
- for (int s = 0; s < 16; s++)
- {
- if (circles[t].charAt(s) == 'x')
- {
- /* Nice blue. */
- floorTexture[idx++] = (byte)0x1f;
- floorTexture[idx++] = (byte)0x1f;
- floorTexture[idx++] = (byte)0x8f;
- }
- else
- {
- /* Light gray. */
- floorTexture[idx++] = (byte)0xca;
- floorTexture[idx++] = (byte)0xca;
- floorTexture[idx++] = (byte)0xca;
- }
- }
- }
-
- gl.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
-// if (useMipmaps)
-// {
-// gl.glTexParameteri
-// (GL_TEXTURE_2D,
-// GL_TEXTURE_MIN_FILTER,
-// GL_LINEAR_MIPMAP_LINEAR);
-// glu.gluBuild2DMipmaps
-// (GL_TEXTURE_2D,3,16,16,GL_RGB,GL_UNSIGNED_BYTE,floorTexture);
-// }
-// else
- {
- if (linearFiltering)
- {
- gl.glTexParameteri
- (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl.glTexParameteri
- (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
- else
- {
- gl.glTexParameteri
- (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- gl.glTexParameteri
- (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- }
- gl.glTexImage2D
- (GL_TEXTURE_2D,0,3,16,16,0,GL_RGB,GL_UNSIGNED_BYTE,floorTexture);
- }
- }
-
- /* Draw a floor (possibly textured). */
- private void drawFloor()
- {
- gl.glDisable(GL_LIGHTING);
- if (useTexture) gl.glEnable(GL_TEXTURE_2D);
- gl.glBegin(GL_QUADS);
- gl.glTexCoord2f(0.0f, 0.0f);
- gl.glVertex3fv(floorVertices[0]);
- gl.glTexCoord2f(0.0f, 16.0f);
- gl.glVertex3fv(floorVertices[1]);
- gl.glTexCoord2f(16.0f, 16.0f);
- gl.glVertex3fv(floorVertices[2]);
- gl.glTexCoord2f(16.0f, 0.0f);
- gl.glVertex3fv(floorVertices[3]);
- gl.glEnd();
- if (useTexture) gl.glDisable(GL_TEXTURE_2D);
- gl.glEnable(GL_LIGHTING);
- }
-
- /* create a matrix that will project the desired shadow */
- void shadowMatrix(float shadowMat[], float groundplane[], float lightpos[])
- {
- float dot;
-
- /* find dot product between light position vector
- and ground plane normal */
- dot =
- groundplane[0] * lightpos[0] +
- groundplane[1] * lightpos[1] +
- groundplane[2] * lightpos[2] +
- groundplane[3] * lightpos[3];
-
- shadowMat[0] = dot - lightpos[0] * groundplane[0];
- shadowMat[4] = -lightpos[0] * groundplane[1];
- shadowMat[8] = -lightpos[0] * groundplane[2];
- shadowMat[12] = -lightpos[0] * groundplane[3];
-
- shadowMat[1] = -lightpos[1] * groundplane[0];
- shadowMat[5] = dot - lightpos[1] * groundplane[1];
- shadowMat[9] = -lightpos[1] * groundplane[2];
- shadowMat[13] = -lightpos[1] * groundplane[3];
-
- shadowMat[2] = -lightpos[2] * groundplane[0];
- shadowMat[6] = -lightpos[2] * groundplane[1];
- shadowMat[10] = dot - lightpos[2] * groundplane[2];
- shadowMat[14] = -lightpos[2] * groundplane[3];
-
- shadowMat[3] = -lightpos[3] * groundplane[0];
- shadowMat[7] = -lightpos[3] * groundplane[1];
- shadowMat[11] = -lightpos[3] * groundplane[2];
- shadowMat[15] = dot - lightpos[3] * groundplane[3];
- }
-
- /* find the plane equation given 3 points */
- void findPlane(float plane[], float v0[], float v1[], float v2[])
- {
- float vec0[] = new float[3], vec1[] = new float[3];
-
- /* need 2 vectors to find cross product */
- vec0[X] = v1[X] - v0[X];
- vec0[Y] = v1[Y] - v0[Y];
- vec0[Z] = v1[Z] - v0[Z];
-
- vec1[X] = v2[X] - v0[X];
- vec1[Y] = v2[Y] - v0[Y];
- vec1[Z] = v2[Z] - v0[Z];
-
- /* find cross product to get A, B, and C of plane equation */
- plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y];
- plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]);
- plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X];
- plane[D] = -(plane[A]*v0[X] + plane[B]*v0[Y] + plane[C]*v0[Z]);
- }
-
- /* Mark Kilgard's tessellation code from the "dino" demos.
- Bug fixes and re-write without GLU tesselator
- by Ronald B. Cemer */
- private void extrudeSolidFromPolygon
- (float data[][],
- int outlineTriIndices[][],
- float thickness,
- int side,
- int edge,
- int whole)
- {
- double dx, dy, len;
- int i, j0, j1, j2;
- int min, max, range;
- float x0, y0, x1, y1;
- int count = data.length;
- int tricount = outlineTriIndices.length;
-
- gl.glNewList(side, GL_COMPILE);
- gl.glShadeModel(GL_SMOOTH);
- gl.glBegin(GL_TRIANGLES);
- for (i = 0; i < tricount; i++)
- {
-/* *+*+* Note that we use the triangle indices in reverse order here
- because they are specified in reverse order in the arrays. */
- j0 = outlineTriIndices[i][2];
- j1 = outlineTriIndices[i][1];
- j2 = outlineTriIndices[i][0];
- gl.glVertex3f(data[j0][0],data[j0][1],0.0f);
- gl.glVertex3f(data[j1][0],data[j1][1],0.0f);
- gl.glVertex3f(data[j2][0],data[j2][1],0.0f);
- }
- gl.glEnd();
- gl.glEndList();
-
- gl.glNewList(edge, GL_COMPILE);
- gl.glShadeModel(GL_FLAT); /* flat shade keeps angular hands
- from being "smoothed" */
- for (min = max = 0; min < count; min = max)
- {
- for (max = min+1; max < count; max++)
- if (data[max][2] != 0.0f) break;
- range = max-min;
- gl.glBegin(GL_QUAD_STRIP);
- for (i = min; i <= max; i++)
- {
- j0 = i;
- j1 = i+1;
- if (j0 >= max) j0 -= range;
- if (j1 >= max) j1 -= range;
- x0 = data[j0][0];
- y0 = data[j0][1];
- x1 = data[j1][0];
- y1 = data[j1][1];
- gl.glVertex3f(x0, y0, 0.0f);
- gl.glVertex3f(x0, y0, thickness);
- // Normals
- dx = y1 - y0;
- dy = x0 - x1;
- len = Math.sqrt(dx * dx + dy * dy);
- gl.glNormal3f((float)(dx / len), (float)(dy / len), 0.0f);
- }
- gl.glEnd();
- }
- gl.glEndList();
-
- gl.glNewList(whole, GL_COMPILE);
- gl.glFrontFace(GL_CW);
-
- gl.glCallList(edge);
-
- gl.glNormal3f(0.0f, 0.0f, -1.0f);
- gl.glCallList(side);
- gl.glPushMatrix();
- gl.glTranslatef(0.0f, 0.0f, thickness);
- gl.glFrontFace(GL_CCW);
- gl.glNormal3f(0.0f, 0.0f, 1.0f);
- gl.glCallList(side);
- gl.glPopMatrix();
-
- gl.glEndList();
- }
-
- // Methods required for the implementation of MouseListener
- public void mouseEntered(MouseEvent evt)
- {
- }
-
- public void mouseExited(MouseEvent evt)
- {
- }
-
- public void mousePressed(MouseEvent evt)
- {
- // Left button moves view.
- // Both buttons moves light.
- // Right button pops up menu.
- if (!menu_showing)
- {
- if ((evt.getModifiers() & evt.BUTTON3_MASK) == 0)
- {
- moving = true;
- startx = evt.getX();
- starty = evt.getY();
- }
- else if (moving)
- {
- moving = false;
- lightMoving = true;
- lightStartX = evt.getX();
- lightStartY = evt.getY();
- }
- else
- {
- // Must be right mouse button.
- menu_showing = true;
- save_suspended = isSuspended();
- if (!save_suspended)
- {
- setSuspended(true);
- repaint(100);
- try
- {
- Thread.currentThread().sleep(200);
- }
- catch (Exception e)
- { }
- }
- menu.show(this,evt.getX(),evt.getY());
- }
- }
- else
- {
- menu_showing = false;
- setSuspended(save_suspended);
- }
- }
-
- public void mouseReleased(MouseEvent evt)
- {
- lightMoving = false;
- if ((evt.getModifiers() & evt.BUTTON3_MASK) == 0)
- {
- // Must be left button.
- moving = false;
- }
- }
-
- public void mouseClicked(MouseEvent evt)
- {
- }
-
- // Methods required for the implementation of MouseMotionListener
- public void mouseDragged(MouseEvent evt)
- {
- int x = evt.getX(), y = evt.getY();
- if (moving)
- {
- angle += (x - startx);
- while (angle < 0.0f) angle += 360.0f;
- while (angle >= 360.0f) angle -= 360.0f;
- angle2 += (y - starty);
- if (angle2 < -180.0f)
- angle2 = -180.0f;
- else if (angle2 > 180.0f)
- angle2 = 180.0f;
- startx = x;
- starty = y;
- if (isSuspended()) repaint();
- }
- else if (lightMoving)
- {
- lightAngle += (lightStartX - x)/40.0f;
- while (lightAngle < 0.0f) lightAngle += 360.0f;
- while (lightAngle >= 360.0f) lightAngle -= 360.0f;
- lightHeight += (lightStartY - y)/20.0f;
- lightStartX = x;
- lightStartY = y;
- if (isSuspended()) repaint();
- }
- }
-
- public void mouseMoved(MouseEvent evt)
- {
- }
-
- // Method required for the implementation of ActionListener
- public void actionPerformed(ActionEvent evt)
- {
- if (glj.gljMakeCurrent() == false) return;
- boolean dorepaint = false;
- String c = evt.getActionCommand();
-
- if (c.equals(M_MOTION))
- {
- if (menu_showing)
- save_suspended = !save_suspended;
- else
- setSuspended(!isSuspended());
- dorepaint = true;
- }
- else if (c.equals(M_LIGHT))
- {
- lightSwitch = !lightSwitch;
- if (lightSwitch)
- gl.glEnable(GL_LIGHT0);
- else
- gl.glDisable(GL_LIGHT0);
- dorepaint = true;
- }
- else if (c.equals(M_TEXTURE))
- {
- useTexture = !useTexture;
- dorepaint = true;
- }
- else if (c.equals(M_SHADOWS))
- {
- renderShadow = !renderShadow;
- dorepaint = true;
- }
- else if (c.equals(M_REFLECTION))
- {
- renderReflection = !renderReflection;
- dorepaint = true;
- }
- else if (c.equals(M_DINOSAUR))
- {
- renderDinosaur = !renderDinosaur;
- dorepaint = true;
- }
- else if (c.equals(M_STENCIL_REFLECTION))
- {
- stencilReflection = !stencilReflection;
- dorepaint = true;
- }
- else if (c.equals(M_STENCIL_SHADOW))
- {
- stencilShadow = !stencilShadow;
- dorepaint = true;
- }
- else if (c.equals(M_OFFSET_SHADOW))
- {
- offsetShadow = !offsetShadow;
- dorepaint = true;
- }
- else if (c.equals(M_POSITIONAL))
- {
- directionalLight = false;
- dorepaint = true;
- }
- else if (c.equals(M_DIRECTIONAL))
- {
- directionalLight = true;
- dorepaint = true;
- }
-
- glj.gljFree();
- if (menu_showing)
- {
- menu_showing = false;
- setSuspended(save_suspended);
- }
- if ( (isSuspended()) && (dorepaint) ) repaint();
- }
- }
-}
+ reshape(getSize().width, getSize().height);
+
+ makeDinosaur();
+
+ gl.glPolygonOffset(-2.0f, -1.0f);
+
+ gl.glEnable(GL_CULL_FACE);
+ gl.glEnable(GL_DEPTH_TEST);
+ gl.glEnable(GL_TEXTURE_2D);
+ gl.glLineWidth(3.0f);
+
+ gl.glMatrixMode(GL_PROJECTION);
+ glu.gluPerspective
+ ( /* field of view in degree */ 40.0f,
+ /* aspect ratio */ 1.0f,
+ /* Z near */ 20.0f,
+ /* Z far */ 100.0f);
+ gl.glMatrixMode(GL_MODELVIEW);
+ glu.gluLookAt
+ (0.0f, 8.0f, 60.0f, /* eye is at (0,8,60) */
+ 0.0f, 8.0f, 0.0f, /* center is at (0,8,0) */
+ 0.0f, 1.0f, 0.0f); /* up is in postivie Y direction */
+
+ gl.glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
+ gl.glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
+ gl.glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1f);
+ gl.glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05f);
+ gl.glEnable(GL_LIGHT0);
+ gl.glEnable(GL_LIGHTING);
+
+ makeFloorTexture();
+
+ /* Setup floor plane for projected shadow calculations. */
+ findPlane
+ (floorPlane,
+ floorVertices[1],
+ floorVertices[2],
+ floorVertices[3]);
+
+ glj.gljCheckGL();
+
+ menu = new PopupMenu("Options");
+ menu.add(M_MOTION);
+ menu.add(M_NONE);
+ menu.add(M_LIGHT);
+ menu.add(M_TEXTURE);
+ menu.add(M_SHADOWS);
+ menu.add(M_REFLECTION);
+ menu.add(M_DINOSAUR);
+ menu.add(M_NONE);
+ menu.add(M_STENCIL_REFLECTION);
+ menu.add(M_STENCIL_SHADOW);
+ menu.add(M_OFFSET_SHADOW);
+ menu.add(M_NONE);
+ menu.add(M_POSITIONAL);
+ menu.add(M_DIRECTIONAL);
+ menu.addActionListener(this);
+ add(menu);
+
+ addMouseListener(this);
+ addMouseMotionListener(this);
+ }
+
+ public void doCleanup()
+ {
+ removeMouseListener(this);
+ removeMouseMotionListener(this);
+ menu.removeActionListener(this);
+ }
+
+ public void reshape(int width, int height)
+ {
+ gl.glViewport(0,0,width,height);
+ }
+
+ public void display()
+ {
+ if (glj.gljMakeCurrent() == false) return;
+
+ if (!isSuspended())
+ {
+ long ltime =
+ System.currentTimeMillis() % 3142L; //approximate 2*PI*500
+ float time = (float)(((double)ltime)/500.0);
+ jump = 4.0f * (float)Math.abs(Math.sin(time)*0.5);
+ if (!lightMoving) lightAngle += 0.0f;
+ }
+
+ /* Clear; default stencil clears to zero. */
+ if ((stencilReflection && renderReflection) || (stencilShadow && renderShadow))
+ gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ else
+ /* Avoid clearing stencil when not using it. */
+ gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ /* Reposition the light source. */
+ lightPosition[0] = 12*(float)Math.cos(lightAngle);
+ lightPosition[1] = lightHeight;
+ lightPosition[2] = 12*(float)Math.sin(lightAngle);
+ if (directionalLight)
+ lightPosition[3] = 0.0f;
+ else
+ lightPosition[3] = 1.0f;
+
+ shadowMatrix(floorShadow, floorPlane, lightPosition);
+
+ gl.glPushMatrix();
+
+ /* Perform scene rotations based on user mouse input. */
+ gl.glRotatef(angle2, 1.0f, 0.0f, 0.0f);
+ gl.glRotatef(angle, 0.0f, 1.0f, 0.0f);
+
+ /* Tell GL new light source position. */
+ gl.glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
+
+ if (renderReflection)
+ {
+ if (stencilReflection)
+ {
+ /* We can eliminate the visual "artifact" of seeing the "flipped"
+ dinosaur underneath the floor by using stencil. The idea is
+ draw the floor without color or depth update but so that
+ a stencil value of one is where the floor will be. Later when
+ rendering the dinosaur reflection, we will only update pixels
+ with a stencil value of 1 to make sure the reflection only
+ lives on the floor, not below the floor. */
+
+ /* Don't update color or depth. */
+ gl.glDisable(GL_DEPTH_TEST);
+ gl.glColorMask(false, false, false, false);
+
+ /* Draw 1 into the stencil buffer. */
+ gl.glEnable(GL_STENCIL_TEST);
+ gl.glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+ gl.glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
+
+ /* Now render floor; floor pixels just get their stencil set to 1. */
+ drawFloor();
+
+ /* Re-enable update of color and depth. */
+ gl.glColorMask(true, true, true, true);
+ gl.glEnable(GL_DEPTH_TEST);
+
+ /* Now, only render where stencil is set to 1. */
+ gl.glStencilFunc(GL_EQUAL, 1, 0xffffffff); /* draw if ==1 */
+ gl.glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ }
+
+ gl.glPushMatrix();
+
+ /* The critical reflection step: Reflect dinosaur through the floor
+ (the Y=0 plane) to make a relection. */
+
+ gl.glScalef(1.0f, -1.0f, 1.0f);
+
+ /* Reflect the light position. */
+ gl.glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
+
+ /* To avoid our normals getting reversed and hence botched lighting
+ on the reflection, turn on normalize. */
+ gl.glEnable(GL_NORMALIZE);
+ gl.glCullFace(GL_FRONT);
+
+ /* Draw the reflected dinosaur. */
+ drawDinosaur();
+
+ /* Disable noramlize again and re-enable back face culling. */
+ gl.glDisable(GL_NORMALIZE);
+ gl.glCullFace(GL_BACK);
+
+ gl.glPopMatrix();
+
+ /* Switch back to the unreflected light position. */
+ gl.glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
+
+ if (stencilReflection) gl.glDisable(GL_STENCIL_TEST);
+ }
+
+ /* Back face culling will get used to only draw either the top or the
+ bottom floor. This let's us get a floor with two distinct
+ appearances. The top floor surface is reflective and kind of red.
+ The bottom floor surface is not reflective and blue. */
+
+ /* Draw "bottom" of floor in blue. */
+ gl.glFrontFace(GL_CW); /* Switch face orientation. */
+ gl.glColor4f(0.1f, 0.1f, 0.7f, 1.0f);
+ drawFloor();
+ gl.glFrontFace(GL_CCW);
+
+ if (renderShadow)
+ {
+ if (stencilShadow)
+ {
+ /* Draw the floor with stencil value 3. This helps us only
+ draw the shadow once per floor pixel (and only on the
+ floor pixels). */
+ gl.glEnable(GL_STENCIL_TEST);
+ gl.glStencilFunc(GL_ALWAYS, 3, 0xffffffff);
+ gl.glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ }
+ }
+
+ /* Draw "top" of floor. Use blending to blend in reflection. */
+ gl.glEnable(GL_BLEND);
+ gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ gl.glColor4f(0.7f, 0.0f, 0.0f, 0.3f);
+ gl.glColor4f(1.0f, 1.0f, 1.0f, 0.3f);
+ drawFloor();
+ gl.glDisable(GL_BLEND);
+
+ /* Draw "actual" dinosaur, not its reflection. */
+ if (renderDinosaur) drawDinosaur();
+
+ if (renderShadow)
+ {
+ /* Render the projected shadow. */
+ if (stencilShadow)
+ {
+ /* Now, only render where stencil is set above 2 (ie, 3 where
+ the top floor is). Update stencil with 2 where the shadow
+ gets drawn so we don't redraw (and accidently reblend) the
+ shadow). */
+ gl.glStencilFunc(GL_LESS, 2, 0xffffffff); /* draw if ==1 */
+ gl.glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+ }
+ /* To eliminate depth buffer artifacts, we use polygon offset
+ to raise the depth of the projected shadow slightly so
+ that it does not depth buffer alias with the floor. */
+ if (offsetShadow) gl.glEnable(GL_POLYGON_OFFSET_FILL);
+
+ /* Render 50% black shadow color on top of whatever the
+ floor appareance is. */
+ gl.glEnable(GL_BLEND);
+ gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ gl.glDisable(GL_LIGHTING); /* Force the 50% black. */
+ gl.glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
+
+ gl.glPushMatrix();
+ /* Project the shadow. */
+ gl.glMultMatrixf(floorShadow);
+ drawDinosaur();
+ gl.glPopMatrix();
+
+ gl.glDisable(GL_BLEND);
+ gl.glEnable(GL_LIGHTING);
+
+ if (offsetShadow) gl.glDisable(GL_POLYGON_OFFSET_FILL);
+ if (stencilShadow) gl.glDisable(GL_STENCIL_TEST);
+ }
+
+ gl.glPushMatrix();
+ gl.glDisable(GL_LIGHTING);
+ gl.glColor3f(1.0f, 1.0f, 0.0f);
+ if (directionalLight)
+ {
+ /* Draw an arrowhead. */
+ gl.glDisable(GL_CULL_FACE);
+ gl.glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]);
+ gl.glRotatef(lightAngle * (float)(-180.0 / M_PI), 0, 1, 0);
+ gl.glRotatef((float)Math.atan(lightHeight/12) * (float)(180.0 / M_PI), 0, 0, 1);
+ gl.glBegin(GL_TRIANGLE_FAN);
+ gl.glVertex3f(0, 0, 0);
+ gl.glVertex3f(2, 1, 1);
+ gl.glVertex3f(2, -1, 1);
+ gl.glVertex3f(2, -1, -1);
+ gl.glVertex3f(2, 1, -1);
+ gl.glVertex3f(2, 1, 1);
+ gl.glEnd();
+ /* Draw a white line from light direction. */
+ gl.glColor3f(1.0f, 1.0f, 1.0f);
+ gl.glBegin(GL_LINES);
+ gl.glVertex3f(0, 0, 0);
+ gl.glVertex3f(5, 0, 0);
+ gl.glEnd();
+ gl.glEnable(GL_CULL_FACE);
+ }
+ else
+ {
+ /* Draw a yellow ball at the light source. */
+ gl.glTranslatef(lightPosition[0], lightPosition[1], lightPosition[2]);
+ long qobj = glu.gluNewQuadric();
+ glu.gluQuadricOrientation(qobj,GLU_OUTSIDE);
+ glu.gluQuadricNormals(qobj,GLU_SMOOTH);
+ glu.gluQuadricTexture(qobj,false);
+ glu.gluSphere(qobj,1.0f,5,5);
+ glu.gluDeleteQuadric(qobj);
+ }
+ gl.glEnable(GL_LIGHTING);
+ gl.glPopMatrix();
+
+ gl.glPopMatrix();
+
+ glj.gljSwap();
+ glj.gljCheckGL();
+ glj.gljFree();
+
+ // if (!isSuspended()) repaint(); // Animate at full speed.
+ }
+
+ private void makeDinosaur()
+ {
+ extrudeSolidFromPolygon
+ (bodyVerts,
+ bodyTris,
+ bodyWidth,
+ BODY_SIDE,
+ BODY_EDGE,
+ BODY_WHOLE);
+ extrudeSolidFromPolygon
+ (armVerts,
+ armTris,
+ bodyWidth/4,
+ ARM_SIDE,
+ ARM_EDGE,
+ ARM_WHOLE);
+ extrudeSolidFromPolygon
+ (legVerts,
+ legTris,
+ bodyWidth/2,
+ LEG_SIDE,
+ LEG_EDGE,
+ LEG_WHOLE);
+ extrudeSolidFromPolygon
+ (eyeVerts,
+ eyeTris,
+ bodyWidth+0.2f,
+ EYE_SIDE,
+ EYE_EDGE,
+ EYE_WHOLE);
+ }
+
+ private void drawDinosaur()
+ {
+ gl.glPushMatrix();
+ /* Translate the dinosaur to be at (0,8,0). */
+ gl.glTranslatef(-8, 0, -bodyWidth / 2);
+ gl.glTranslatef(0.0f, jump, 0.0f);
+ gl.glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor);
+ gl.glCallList(BODY_WHOLE);
+ gl.glTranslatef(0.0f, 0.0f, bodyWidth);
+ gl.glCallList(ARM_WHOLE);
+ gl.glCallList(LEG_WHOLE);
+ gl.glTranslatef(0.0f, 0.0f, -bodyWidth - bodyWidth / 4);
+ gl.glCallList(ARM_WHOLE);
+ gl.glTranslatef(0.0f, 0.0f, -bodyWidth / 4);
+ gl.glCallList(LEG_WHOLE);
+ gl.glTranslatef(0.0f, 0.0f, bodyWidth / 2 - 0.1f);
+ gl.glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor);
+ gl.glCallList(EYE_WHOLE);
+ gl.glPopMatrix();
+ }
+
+ private void makeFloorTexture()
+ {
+ /* Nice floor texture tiling pattern. */
+ String circles[] =
+ {
+ "....xxxx........",
+ "..xxxxxxxx......",
+ ".xxxxxxxxxx.....",
+ ".xxx....xxx.....",
+ "xxx......xxx....",
+ "xxx......xxx....",
+ "xxx......xxx....",
+ "xxx......xxx....",
+ ".xxx....xxx.....",
+ ".xxxxxxxxxx.....",
+ "..xxxxxxxx......",
+ "....xxxx........",
+ "................",
+ "................",
+ "................",
+ "................"
+ };
+ byte floorTexture[] = new byte[16*16*3];
+
+ /* Setup RGB image for the texture. */
+ int idx = 0;
+ for (int t = 0; t < 16; t++)
+ {
+ for (int s = 0; s < 16; s++)
+ {
+ if (circles[t].charAt(s) == 'x')
+ {
+ /* Nice blue. */
+ floorTexture[idx++] = (byte)0x1f;
+ floorTexture[idx++] = (byte)0x1f;
+ floorTexture[idx++] = (byte)0x8f;
+ }
+ else
+ {
+ /* Light gray. */
+ floorTexture[idx++] = (byte)0xca;
+ floorTexture[idx++] = (byte)0xca;
+ floorTexture[idx++] = (byte)0xca;
+ }
+ }
+ }
+
+ gl.glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+// if (useMipmaps)
+// {
+// gl.glTexParameteri
+// (GL_TEXTURE_2D,
+// GL_TEXTURE_MIN_FILTER,
+// GL_LINEAR_MIPMAP_LINEAR);
+// glu.gluBuild2DMipmaps
+// (GL_TEXTURE_2D,3,16,16,GL_RGB,GL_UNSIGNED_BYTE,floorTexture);
+// }
+// else
+ {
+ if (linearFiltering)
+ {
+ gl.glTexParameteri
+ (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl.glTexParameteri
+ (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+ else
+ {
+ gl.glTexParameteri
+ (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ gl.glTexParameteri
+ (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+ gl.glTexImage2D
+ (GL_TEXTURE_2D,0,3,16,16,0,GL_RGB,GL_UNSIGNED_BYTE,floorTexture);
+ }
+ }
+
+ /* Draw a floor (possibly textured). */
+ private void drawFloor()
+ {
+ gl.glDisable(GL_LIGHTING);
+ if (useTexture) gl.glEnable(GL_TEXTURE_2D);
+ gl.glBegin(GL_QUADS);
+ gl.glTexCoord2f(0.0f, 0.0f);
+ gl.glVertex3fv(floorVertices[0]);
+ gl.glTexCoord2f(0.0f, 16.0f);
+ gl.glVertex3fv(floorVertices[1]);
+ gl.glTexCoord2f(16.0f, 16.0f);
+ gl.glVertex3fv(floorVertices[2]);
+ gl.glTexCoord2f(16.0f, 0.0f);
+ gl.glVertex3fv(floorVertices[3]);
+ gl.glEnd();
+ if (useTexture) gl.glDisable(GL_TEXTURE_2D);
+ gl.glEnable(GL_LIGHTING);
+ }
+
+ /* create a matrix that will project the desired shadow */
+ void shadowMatrix(float shadowMat[], float groundplane[], float lightpos[])
+ {
+ float dot;
+
+ /* find dot product between light position vector
+ and ground plane normal */
+ dot =
+ groundplane[0] * lightpos[0] +
+ groundplane[1] * lightpos[1] +
+ groundplane[2] * lightpos[2] +
+ groundplane[3] * lightpos[3];
+
+ shadowMat[0] = dot - lightpos[0] * groundplane[0];
+ shadowMat[4] = -lightpos[0] * groundplane[1];
+ shadowMat[8] = -lightpos[0] * groundplane[2];
+ shadowMat[12] = -lightpos[0] * groundplane[3];
+
+ shadowMat[1] = -lightpos[1] * groundplane[0];
+ shadowMat[5] = dot - lightpos[1] * groundplane[1];
+ shadowMat[9] = -lightpos[1] * groundplane[2];
+ shadowMat[13] = -lightpos[1] * groundplane[3];
+
+ shadowMat[2] = -lightpos[2] * groundplane[0];
+ shadowMat[6] = -lightpos[2] * groundplane[1];
+ shadowMat[10] = dot - lightpos[2] * groundplane[2];
+ shadowMat[14] = -lightpos[2] * groundplane[3];
+
+ shadowMat[3] = -lightpos[3] * groundplane[0];
+ shadowMat[7] = -lightpos[3] * groundplane[1];
+ shadowMat[11] = -lightpos[3] * groundplane[2];
+ shadowMat[15] = dot - lightpos[3] * groundplane[3];
+ }
+
+ /* find the plane equation given 3 points */
+ void findPlane(float plane[], float v0[], float v1[], float v2[])
+ {
+ float vec0[] = new float[3], vec1[] = new float[3];
+
+ /* need 2 vectors to find cross product */
+ vec0[X] = v1[X] - v0[X];
+ vec0[Y] = v1[Y] - v0[Y];
+ vec0[Z] = v1[Z] - v0[Z];
+
+ vec1[X] = v2[X] - v0[X];
+ vec1[Y] = v2[Y] - v0[Y];
+ vec1[Z] = v2[Z] - v0[Z];
+
+ /* find cross product to get A, B, and C of plane equation */
+ plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y];
+ plane[B] = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X]);
+ plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X];
+ plane[D] = -(plane[A]*v0[X] + plane[B]*v0[Y] + plane[C]*v0[Z]);
+ }
+
+ /* Mark Kilgard's tessellation code from the "dino" demos.
+ Bug fixes and re-write without GLU tesselator
+ by Ronald B. Cemer */
+ private void extrudeSolidFromPolygon
+ (float data[][],
+ int outlineTriIndices[][],
+ float thickness,
+ int side,
+ int edge,
+ int whole)
+ {
+ double dx, dy, len;
+ int i, j0, j1, j2;
+ int min, max, range;
+ float x0, y0, x1, y1;
+ int count = data.length;
+ int tricount = outlineTriIndices.length;
+
+ gl.glNewList(side, GL_COMPILE);
+ gl.glShadeModel(GL_SMOOTH);
+ gl.glBegin(GL_TRIANGLES);
+ for (i = 0; i < tricount; i++)
+ {
+/* *+*+* Note that we use the triangle indices in reverse order here
+ because they are specified in reverse order in the arrays. */
+ j0 = outlineTriIndices[i][2];
+ j1 = outlineTriIndices[i][1];
+ j2 = outlineTriIndices[i][0];
+ gl.glVertex3f(data[j0][0],data[j0][1],0.0f);
+ gl.glVertex3f(data[j1][0],data[j1][1],0.0f);
+ gl.glVertex3f(data[j2][0],data[j2][1],0.0f);
+ }
+ gl.glEnd();
+ gl.glEndList();
+
+ gl.glNewList(edge, GL_COMPILE);
+ gl.glShadeModel(GL_FLAT); /* flat shade keeps angular hands
+ from being "smoothed" */
+ for (min = max = 0; min < count; min = max)
+ {
+ for (max = min+1; max < count; max++)
+ if (data[max][2] != 0.0f) break;
+ range = max-min;
+ gl.glBegin(GL_QUAD_STRIP);
+ for (i = min; i <= max; i++)
+ {
+ j0 = i;
+ j1 = i+1;
+ if (j0 >= max) j0 -= range;
+ if (j1 >= max) j1 -= range;
+ x0 = data[j0][0];
+ y0 = data[j0][1];
+ x1 = data[j1][0];
+ y1 = data[j1][1];
+ gl.glVertex3f(x0, y0, 0.0f);
+ gl.glVertex3f(x0, y0, thickness);
+ // Normals
+ dx = y1 - y0;
+ dy = x0 - x1;
+ len = Math.sqrt(dx * dx + dy * dy);
+ gl.glNormal3f((float)(dx / len), (float)(dy / len), 0.0f);
+ }
+ gl.glEnd();
+ }
+ gl.glEndList();
+
+ gl.glNewList(whole, GL_COMPILE);
+ gl.glFrontFace(GL_CW);
+
+ gl.glCallList(edge);
+
+ gl.glNormal3f(0.0f, 0.0f, -1.0f);
+ gl.glCallList(side);
+ gl.glPushMatrix();
+ gl.glTranslatef(0.0f, 0.0f, thickness);
+ gl.glFrontFace(GL_CCW);
+ gl.glNormal3f(0.0f, 0.0f, 1.0f);
+ gl.glCallList(side);
+ gl.glPopMatrix();
+
+ gl.glEndList();
+ }
+
+ // Methods required for the implementation of MouseListener
+ public void mouseEntered(MouseEvent evt)
+ {
+ }
+
+ public void mouseExited(MouseEvent evt)
+ {
+ }
+
+ public void mousePressed(MouseEvent evt)
+ {
+ // Left button moves view.
+ // Both buttons moves light.
+ // Right button pops up menu.
+ if (!menu_showing)
+ {
+ if ((evt.getModifiers() & evt.BUTTON3_MASK) == 0)
+ {
+ moving = true;
+ startx = evt.getX();
+ starty = evt.getY();
+ }
+ else if (moving)
+ {
+ moving = false;
+ lightMoving = true;
+ lightStartX = evt.getX();
+ lightStartY = evt.getY();
+ }
+ else
+ {
+ // Must be right mouse button.
+ menu_showing = true;
+ save_suspended = isSuspended();
+ if (!save_suspended)
+ {
+ setSuspended(true);
+ repaint(100);
+ try
+ {
+ Thread.currentThread().sleep(200);
+ }
+ catch (Exception e)
+ { }
+ }
+ menu.show(this,evt.getX(),evt.getY());
+ }
+ }
+ else
+ {
+ menu_showing = false;
+ setSuspended(save_suspended);
+ }
+ }
+
+ public void mouseReleased(MouseEvent evt)
+ {
+ lightMoving = false;
+ if ((evt.getModifiers() & evt.BUTTON3_MASK) == 0)
+ {
+ // Must be left button.
+ moving = false;
+ }
+ }
+
+ public void mouseClicked(MouseEvent evt)
+ {
+ }
+
+ // Methods required for the implementation of MouseMotionListener
+ public void mouseDragged(MouseEvent evt)
+ {
+ int x = evt.getX(), y = evt.getY();
+ if (moving)
+ {
+ angle += (x - startx);
+ while (angle < 0.0f) angle += 360.0f;
+ while (angle >= 360.0f) angle -= 360.0f;
+ angle2 += (y - starty);
+ if (angle2 < -180.0f)
+ angle2 = -180.0f;
+ else if (angle2 > 180.0f)
+ angle2 = 180.0f;
+ startx = x;
+ starty = y;
+ if (isSuspended()) repaint();
+ }
+ else if (lightMoving)
+ {
+ lightAngle += (lightStartX - x)/40.0f;
+ while (lightAngle < 0.0f) lightAngle += 360.0f;
+ while (lightAngle >= 360.0f) lightAngle -= 360.0f;
+ lightHeight += (lightStartY - y)/20.0f;
+ lightStartX = x;
+ lightStartY = y;
+ if (isSuspended()) repaint();
+ }
+ }
+
+ public void mouseMoved(MouseEvent evt)
+ {
+ }
+
+ // Method required for the implementation of ActionListener
+ public void actionPerformed(ActionEvent evt)
+ {
+ if (glj.gljMakeCurrent() == false) return;
+ boolean dorepaint = false;
+ String c = evt.getActionCommand();
+
+ if (c.equals(M_MOTION))
+ {
+ if (menu_showing)
+ save_suspended = !save_suspended;
+ else
+ setSuspended(!isSuspended());
+ dorepaint = true;
+ }
+ else if (c.equals(M_LIGHT))
+ {
+ lightSwitch = !lightSwitch;
+ if (lightSwitch)
+ gl.glEnable(GL_LIGHT0);
+ else
+ gl.glDisable(GL_LIGHT0);
+ dorepaint = true;
+ }
+ else if (c.equals(M_TEXTURE))
+ {
+ useTexture = !useTexture;
+ dorepaint = true;
+ }
+ else if (c.equals(M_SHADOWS))
+ {
+ renderShadow = !renderShadow;
+ dorepaint = true;
+ }
+ else if (c.equals(M_REFLECTION))
+ {
+ renderReflection = !renderReflection;
+ dorepaint = true;
+ }
+ else if (c.equals(M_DINOSAUR))
+ {
+ renderDinosaur = !renderDinosaur;
+ dorepaint = true;
+ }
+ else if (c.equals(M_STENCIL_REFLECTION))
+ {
+ stencilReflection = !stencilReflection;
+ dorepaint = true;
+ }
+ else if (c.equals(M_STENCIL_SHADOW))
+ {
+ stencilShadow = !stencilShadow;
+ dorepaint = true;
+ }
+ else if (c.equals(M_OFFSET_SHADOW))
+ {
+ offsetShadow = !offsetShadow;
+ dorepaint = true;
+ }
+ else if (c.equals(M_POSITIONAL))
+ {
+ directionalLight = false;
+ dorepaint = true;
+ }
+ else if (c.equals(M_DIRECTIONAL))
+ {
+ directionalLight = true;
+ dorepaint = true;
+ }
+
+ glj.gljFree();
+ if (menu_showing)
+ {
+ menu_showing = false;
+ setSuspended(save_suspended);
+ }
+ if ( (isSuspended()) && (dorepaint) ) repaint();
+ }
+ }
+}
diff --git a/demos/RonsDemos/shadowvol.java b/demos/RonsDemos/shadowvol.java
index f25d6dc..0344cfa 100644
--- a/demos/RonsDemos/shadowvol.java
+++ b/demos/RonsDemos/shadowvol.java
@@ -13,8 +13,11 @@ import java.lang.*;
import java.util.*;
import java.io.*;
import java.util.*;
-import gl4java.GLContext;
-import gl4java.awt.GLCanvas;
+import gl4java.*;
+import gl4java.awt.*;
+import gl4java.drawable.*;
+import gl4java.applet.SimpleGLAnimApplet1;
+
public class shadowvol extends Applet
{
@@ -28,12 +31,27 @@ public class shadowvol extends Applet
/* Initialize the applet */
-
public void init()
{
Dimension d = getSize();
setLayout(new BorderLayout());
- canvas = new shadowvolCanvas(d.width, d.height);
+
+ GLCapabilities glCaps = new GLCapabilities();
+ glCaps.setStencilBits(16);
+
+ gl4java.drawable.GLDrawableFactory df =
+ gl4java.drawable.GLDrawableFactory.getFactory();
+
+ if(df instanceof gl4java.drawable.SunJDK13GLDrawableFactory)
+ {
+ gl4java.drawable.SunJDK13GLDrawableFactory sdf =
+ (gl4java.drawable.SunJDK13GLDrawableFactory)df;
+ canvas = new shadowvolCanvas
+ (sdf.getGraphicsConfiguration(glCaps), glCaps, d.width, d.height);
+ } else {
+ canvas = new shadowvolCanvas(glCaps, d.width, d.height);
+ }
+
add("Center", canvas);
}
@@ -69,6 +87,27 @@ public class shadowvol extends Applet
int n;
}
+ public static void main( String args[] )
+ {
+ GLContext.gljNativeDebug = true;
+ GLContext.gljThreadDebug = false;
+ GLContext.gljClassDebug = true;
+
+ Frame mainFrame = new Frame("shadowvol");
+
+ shadowvol applet = new shadowvol();
+
+ applet.setSize(400, 400);
+ applet.init();
+ applet.start();
+
+ mainFrame.add(applet);
+
+ mainFrame.pack();
+ mainFrame.setVisible(true);
+ }
+
+
/* Local GLCanvas extension class */
@@ -91,18 +130,15 @@ public class shadowvol extends Applet
private ShadObj shadower = new ShadObj();
private int rendermode = SHADOW;
- public shadowvolCanvas(int w, int h)
+ public shadowvolCanvas(GraphicsConfiguration g, GLCapabilities glCaps,
+ int w, int h)
{
- super(w, h);
- GLContext.gljNativeDebug = false;
- GLContext.gljClassDebug = false;
+ super(g, glCaps, w, h);
}
- public void preInit()
+ public shadowvolCanvas(GLCapabilities glCaps, int w, int h)
{
- doubleBuffer = true;
- stereoView = false;
- stencilBits = 3;
+ super(glCaps, w, h);
}
public void init()
@@ -121,6 +157,8 @@ public class shadowvol extends Applet
gl.glEnable(GL_LIGHT0);
gl.glEnable(GL_CULL_FACE);
+ gl.glClearColor(0.0f, 0.1f, 0.1f, 0.0f);
+
/* place light 0 in the right place */
gl.glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
@@ -205,15 +243,15 @@ public class shadowvol extends Applet
public void display()
{
+ System.out.println("display ..");
if (glj.gljMakeCurrent() == false) return;
+ System.out.println("display .. doit ");
-
-
-
gl.glClear
(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);
+ glj.gljCheckGL();
switch (rendermode)
{
case NONE:
@@ -256,6 +294,9 @@ public class shadowvol extends Applet
break;
}
+ System.out.println("display .. done ");
+
+ glj.gljCheckGL();
glj.gljSwap();
glj.gljCheckGL();
glj.gljFree();
@@ -274,6 +315,7 @@ public class shadowvol extends Applet
{
rendermode++;
if (rendermode > SHADOW) rendermode = NONE;
+ System.out.println("mouse .. render mode: "+rendermode+", -> repaint");
repaint();
}
@@ -367,6 +409,7 @@ public class shadowvol extends Applet
/* render while jittering the shadows */
private void render(ShadObj obj)
{
+ glj.gljCheckGL();
float shad_mat[] = {10.f, 0.1f, 0.1f, 1.0f};
float v[] = new float[3];
/* material properties for objects in scene */
@@ -384,6 +427,7 @@ public class shadowvol extends Applet
/* Since we want to turn texturing on for floor only, we have
to make floor a separate glBegin()/glEnd() sequence. You
can't turn texturing on and off between begin and end calls */
+ glj.gljCheckGL();
gl.glBegin(GL_QUADS);
gl.glNormal3f(0.0f, 1.0f, 0.0f);
gl.glTexCoord2i(0, 0);
@@ -431,6 +475,7 @@ public class shadowvol extends Applet
gl.glEnd();
+ glj.gljCheckGL();
cone();
sphere();
@@ -453,6 +498,7 @@ public class shadowvol extends Applet
gl.glVertex3fv(v);
}
gl.glEnd();
+ glj.gljCheckGL();
}
}
}