diff options
Diffstat (limited to 'src/demos/infiniteShadowVolumes/InfiniteShadowVolumes.java')
-rw-r--r-- | src/demos/infiniteShadowVolumes/InfiniteShadowVolumes.java | 1904 |
1 files changed, 956 insertions, 948 deletions
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 |