/*
* 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.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.GLProfile;
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.jogamp.opengl.util.Animator;
import javax.swing.JOptionPane;
/**
* Water demonstration by NVidia Corporation - http://developer.nvidia.com/view.asp?IO=ogl_dynamic_bumpreflection
*
*
*
* Demonstrates pbuffers, vertex programs, fragment programs
*
*
*
* Ported to Java and ARB_fragment_program by Kenneth Russell
*
*/
public class ProceduralTexturePhysics extends Demo {
public static void main(String[] args) {
// set argument 'NotFirstUIActionOnProcess' in the JNLP's application-desc tag for example
//
// NotFirstUIActionOnProcess
//
boolean firstUIActionOnProcess = 0==args.length || !args[0].equals("NotFirstUIActionOnProcess") ;
GLProfile.initSingleton(firstUIActionOnProcess);
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();
viewer.setUpVector(Vec3f.Y_AXIS);
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();
}
}