diff options
Diffstat (limited to 'src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java')
-rw-r--r-- | src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java | 425 |
1 files changed, 425 insertions, 0 deletions
diff --git a/src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java b/src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java new file mode 100644 index 0000000..427d645 --- /dev/null +++ b/src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java @@ -0,0 +1,425 @@ +/* + * Portions Copyright (C) 2003 Sun Microsystems, Inc. + * All rights reserved. + */ + +/* + * + * COPYRIGHT NVIDIA CORPORATION 2003. ALL RIGHTS RESERVED. + * BY ACCESSING OR USING THIS SOFTWARE, YOU AGREE TO: + * + * 1) ACKNOWLEDGE NVIDIA'S EXCLUSIVE OWNERSHIP OF ALL RIGHTS + * IN AND TO THE SOFTWARE; + * + * 2) NOT MAKE OR DISTRIBUTE COPIES OF THE SOFTWARE WITHOUT + * INCLUDING THIS NOTICE AND AGREEMENT; + * + * 3) ACKNOWLEDGE THAT TO THE MAXIMUM EXTENT PERMITTED BY + * APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* AND + * THAT NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, + * EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED + * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY + * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES + * WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS + * OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS + * INFORMATION, OR ANY OTHER PECUNIARY LOSS), INCLUDING ATTORNEYS' + * FEES, RELATING TO THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ +package demos.proceduralTexturePhysics; + +import demos.common.Demo; +import demos.common.DemoListener; +import demos.util.DurationTimer; +import gleem.BSphere; +import gleem.BSphereProvider; +import gleem.CameraParameters; +import gleem.ExaminerViewer; +import gleem.ManipManager; +import gleem.MouseButtonHelper; +import gleem.linalg.Vec3f; +import java.awt.BorderLayout; +import java.awt.Frame; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.media.opengl.GL; +import javax.media.opengl.GL2ES1; +import javax.media.opengl.GL2; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLException; +import javax.media.opengl.awt.AWTGLAutoDrawable; +import javax.media.opengl.awt.GLCanvas; +import com.sun.opengl.util.Animator; +import javax.swing.JOptionPane; + +/** + * Water demonstration by NVidia Corporation - <a href = + * "http://developer.nvidia.com/view.asp?IO=ogl_dynamic_bumpreflection">http://developer.nvidia.com/view.asp?IO=ogl_dynamic_bumpreflection</a> + * + * <P> + * + * Demonstrates pbuffers, vertex programs, fragment programs + * + * <P> + * + * Ported to Java and ARB_fragment_program by Kenneth Russell + * + */ +public class ProceduralTexturePhysics extends Demo { + + public static void main(String[] args) { + GLCanvas canvas = new GLCanvas(); + final ProceduralTexturePhysics demo = new ProceduralTexturePhysics(); + canvas.addGLEventListener(demo); + + canvas.addKeyListener(new KeyAdapter() { + + public void keyPressed(KeyEvent e) { + demo.dispatchKey(e.getKeyChar()); + } + }); + + canvas.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + demo.dispatchMousePress(e); + } + + public void mouseReleased(MouseEvent e) { + demo.dispatchMouseRelease(e); + } + }); + + canvas.addMouseMotionListener(new MouseMotionAdapter() { + + public void mouseDragged(MouseEvent e) { + demo.dispatchMouseDrag(e); + } + }); + + final Animator animator = new Animator(canvas); + demo.setDemoListener(new DemoListener() { + + public void shutdownDemo() { + runExit(animator); + } + + public void repaint() { + } + }); + + Frame frame = new Frame("Procedural Texture Waves"); + frame.setLayout(new BorderLayout()); + canvas.setSize(512, 512); + frame.add(canvas, BorderLayout.CENTER); + frame.pack(); + frame.setVisible(true); + canvas.requestFocus(); + + frame.addWindowListener(new WindowAdapter() { + + public void windowClosing(WindowEvent e) { + runExit(animator); + } + }); + + animator.start(); + } + + public void shutdownDemo() { + viewer.detach(); + ManipManager.getManipManager().unregisterWindow((AWTGLAutoDrawable) drawable); + drawable.removeGLEventListener(this); + super.shutdownDemo(); + } + private volatile boolean drawing; + private volatile int mousePosX; + private volatile int mousePosY; + private GLAutoDrawable drawable; + private Water water = new Water(); + private volatile ExaminerViewer viewer; + private boolean[] b = new boolean[256]; + private boolean doViewAll = true; + private float zNear = 0.1f; + private float zFar = 10.0f; + private DurationTimer timer = new DurationTimer(); + private boolean firstRender = true; + private int frameCount; + private float blurIncrement = 0.01f; + private float bumpIncrement = 0.01f; + private float frequencyIncrement = 0.1f; + + public void init(GLAutoDrawable drawable) { + water.destroy(); + water.initialize("demos/data/images/nvfixed.tga", + "demos/data/images/nvspin.tga", + "demos/data/images/droplet.tga", + "demos/data/cubemaps/CloudyHills_", + "tga", + drawable); + + GL gl = drawable.getGL(); + gl.setSwapInterval(1); + + try { + checkExtension(gl, "GL_VERSION_1_3"); // For multitexture + checkExtension(gl, "GL_ARB_vertex_program"); + checkExtension(gl, "GL_ARB_fragment_program"); + checkExtension(gl, "GL_ARB_pbuffer"); + checkExtension(gl, "GL_ARB_pixel_format"); + } catch (GLException e) { + e.printStackTrace(); + throw (e); + } + + gl.glClearColor(0, 0.2f, 0.5f, 0); + gl.glDisable(GL2ES1.GL_LIGHTING); + gl.glDisable(GL.GL_DEPTH_TEST); + gl.glDisable(GL.GL_CULL_FACE); + + doViewAll = true; + + if (firstRender) { + firstRender = false; + + // Register the window with the ManipManager + ManipManager manager = ManipManager.getManipManager(); + manager.registerWindow((AWTGLAutoDrawable) drawable); + this.drawable = drawable; + + viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer.setAutoRedrawMode(false); + viewer.attach((AWTGLAutoDrawable) drawable, new BSphereProvider() { + + public BSphere getBoundingSphere() { + return new BSphere(new Vec3f(0, 0, 0), 1.2f); + } + }); + viewer.setVertFOV((float) (15.0f * Math.PI / 32.0f)); + viewer.setZNear(zNear); + viewer.setZFar(zFar); + + timer.start(); + } + } + + public void dispose(GLAutoDrawable drawable) { + water.destroy(); + water = null; + viewer = null; + timer = null; + } + + public void display(GLAutoDrawable drawable) { + if (++frameCount == 30) { + timer.stop(); + System.err.println("Frames per second: " + (30.0f / timer.getDurationAsSeconds())); + timer.reset(); + timer.start(); + frameCount = 0; + } + + GL2 gl = drawable.getGL().getGL2(); + + gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); + + if (doViewAll) { + viewer.viewAll(gl); + doViewAll = false; + } + + viewer.update(gl); + ManipManager.getManipManager().updateCameraParameters((AWTGLAutoDrawable) drawable, viewer.getCameraParameters()); + ManipManager.getManipManager().render((AWTGLAutoDrawable) drawable, gl); + + if (drawing) { + int w = drawable.getWidth(); + int h = drawable.getHeight(); + water.addDroplet(new Water.Droplet(2 * (mousePosX / (float) w - 0.5f), + -2 * (mousePosY / (float) h - 0.5f), + 0.08f)); + } + water.tick(); + + CameraParameters params = viewer.getCameraParameters(); + water.draw(gl, params.getOrientation().inverse()); + } + + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { + } + + // Unused routines + public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { + } + + private void setFlag(char key, boolean val) { + b[((int) key) & 0xFF] = val; + } + + private boolean getFlag(char key) { + return b[((int) key) & 0xFF]; + } + + private void checkExtension(GL gl, String extensionName) { + if (!gl.isExtensionAvailable(extensionName)) { + String message = "Unable to initialize " + extensionName + " OpenGL extension"; + JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE); + shutdownDemo(); + } + } + + private void dispatchKey(char k) { + setFlag(k, !getFlag(k)); + + switch (k) { + case 27: + case 'q': + shutdownDemo(); + break; + case 'w': + water.enableWireframe(getFlag('w')); + break; + case 'd': + // FIXME + /* + + if (getKey('d')) { + glutMouseFunc(glh::glut_mouse_function); + glutMotionFunc(glh::glut_motion_function); + } + else + { + glutMouseFunc(Mouse); + glutMotionFunc(Motion); + } + */ + break; + case ' ': + water.enableAnimation(getFlag(' ')); + break; + case 'b': + water.enableBorderWrapping(getFlag('b')); + break; + case 'n': + water.singleStep(); + break; + case 's': + water.enableSlowAnimation(getFlag('s')); + break; + case '1': + water.setRenderMode(Water.CA_FULLSCREEN_REFLECT); + break; + case '2': + water.setRenderMode(Water.CA_FULLSCREEN_HEIGHT); + break; + case '3': + water.setRenderMode(Water.CA_FULLSCREEN_FORCE); + break; + case '4': + water.setRenderMode(Water.CA_FULLSCREEN_NORMALMAP); + break; + case '5': + water.setRenderMode(Water.CA_TILED_THREE_WINDOWS); + break; + case 'r': + water.reset(); + break; + case 'i': + // FIXME: make sure this is what this does + doViewAll = true; + // gluPerspective(90, 1, .01, 10); + break; + case 'c': { + float dist = water.getBlurDistance(); + if (dist > blurIncrement) { + water.setBlurDistance(dist - blurIncrement); + } + break; + } + case 'v': { + float dist = water.getBlurDistance(); + if (dist < 1) { + water.setBlurDistance(dist + blurIncrement); + } + break; + } + case '-': { + float scale = water.getBumpScale(); + if (scale > -1) { + water.setBumpScale(scale - bumpIncrement); + } + break; + } + case '=': { + float scale = water.getBumpScale(); + if (scale < 1) { + water.setBumpScale(scale + bumpIncrement); + } + break; + } + case 'l': + water.enableBoundaryApplication(getFlag('l')); + break; + case 'o': + water.enableSpinningLogo(getFlag('o')); + break; + case '.': { + float frequency = water.getBumpScale(); + if (frequency < 1) { + water.setDropFrequency(frequency + frequencyIncrement); + } + break; + } + case ',': { + float frequency = water.getBumpScale(); + if (frequency > 0) { + water.setDropFrequency(frequency - frequencyIncrement); + } + break; + } + default: + break; + } + } + + private void dispatchMousePress(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON1 && + !e.isAltDown() && !e.isMetaDown()) { + drawing = true; + } + } + + private void dispatchMouseRelease(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON1) { + drawing = false; + } + } + + public void dispatchMouseDrag(MouseEvent e) { + mousePosX = e.getX(); + mousePosY = e.getY(); + } + + private static void runExit(final Animator animator) { + // Note: calling System.exit() synchronously inside the draw, + // reshape or init callbacks can lead to deadlocks on certain + // platforms (in particular, X11) because the JAWT's locking + // routines cause a global AWT lock to be grabbed. Run the + // exit routine in another thread. + new Thread(new Runnable() { + + public void run() { + animator.stop(); + System.exit(0); + } + }).start(); + } +} |