/*
* 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.vertexProgWarp;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.nio.*;
import java.util.*;
import javax.swing.*;
import net.java.games.jogl.*;
import demos.util.*;
import gleem.*;
import gleem.linalg.*;
/**
Simple space-warp/distortion vertex program demo
(Press the space bar to switch through programs)
sgreen@nvidia.com 9/2000, based on Cass's vtxprog_silhouette
Ported to Java by Kenneth Russell
*/
public class VertexProgWarp {
private GLCanvas canvas;
private Frame frame;
private Animator animator;
private volatile boolean quit;
private DurationTimer timer = new DurationTimer();
private boolean firstRender = true;
private int frameCount;
public static void main(String[] args) {
new VertexProgWarp().run(args);
}
public void run(String[] args) {
canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
canvas.addGLEventListener(new Listener());
animator = new Animator(canvas);
frame = new Frame();
frame.setLayout(new BorderLayout());
canvas.setSize(512, 512);
frame.add(canvas, BorderLayout.CENTER);
frame.pack();
frame.show();
canvas.requestFocus();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
animator.stop();
System.exit(0);
}
});
animator.start();
}
class Listener implements GLEventListener {
// period of 4-term Taylor approximation to sin isn't quite 2*M_PI
private static final float SIN_PERIOD = 3.079f;
private static final int NUM_OBJS = 5;
private static final int NUM_PROGS = 7;
private int[] programs = new int[NUM_PROGS];
private float zNear = 0.1f;
private float zFar = 10.0f;
private int program = 2;
private int obj = 2;
private boolean[] b = new boolean[256];
private boolean wire = false;
private boolean toggleWire = false;
private boolean animating = true;
private boolean doViewAll = true;
private Time time = new SystemTime();
private float anim = 0.0f;
private float animScale = 7.0f;
private float amp = 0.05f;
private float freq = 8.0f;
private float d = 4.0f;
private ExaminerViewer viewer;
public void init(GLDrawable drawable) {
GL gl = drawable.getGL();
GLU glu = drawable.getGLU();
float cc = 0.0f;
gl.glClearColor(cc, cc, cc, 1);
gl.glColor3f(1,1,1);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDisable(GL.GL_CULL_FACE);
try {
initExtension(gl, "GL_NV_vertex_program");
} catch (RuntimeException e) {
runExit();
throw(e);
}
for(int i=0; i clip\n" +
"DP4 o[HPOS].y, c[1], v[OPOS] ;\n" +
"DP4 o[HPOS].z, c[2], v[OPOS] ;\n" +
"DP4 o[HPOS].w, c[3], v[OPOS] ;\n" +
"\n" +
"DP3 R1.x, c[4], v[NRML] ; # normal x MV-1T -> lighting normal\n" +
"DP3 R1.y, c[5], v[NRML] ;\n" +
"DP3 R1.z, c[6], v[NRML] ;\n" +
"\n" +
"DP3 R0, c[32], R1 ; # L.N\n" +
"MUL o[COL0].xyz, R0, c[35] ; # col = L.N * diffuse\n" +
"MOV o[TEX0], v[TEX0];\n" +
"END",
//
// Pulsate
//
"!!VP1.0\n" +
"#Displace geometry along normal based on sine function of distance from origin\n" +
"#(in object space)\n" +
"#c[61].x = wave frequency\n" +
"#c[61].y = wave amplitude\n" +
"#c[62] = PI constants\n" +
"#c[63] = Taylor series constants (see below)\n" +
"\n" +
"MOV R0, v[OPOS]; \n" +
"\n" +
"#calculate distance from (0, 0, 0)\n" +
"DP3 R3.x, R0, R0;\n" +
"RSQ R3.x, R3.x;\n" +
"RCP R3.x, R3.x;\n" +
"\n" +
"MUL R3.x, R3.x, c[61].x; # wave frequency\n" +
"ADD R3.x, R3.x, c[60].x; # phase animation\n" +
"\n" +
"#reduce to period of 2*PI\n" +
"MUL R2, R3.x, c[62].x;\n" +
"EXP R4, R2.x; # R4.y = R2.x - floor(R2.x)\n" +
"MUL R3.x, R4.y, c[62].y;\n" +
"\n" +
"# offset to -PI - PI\n" +
"ADD R3.x, R3.x, -c[62].z;\n" +
"\n" +
"#Sine approximation using Taylor series (accurate between -PI and PI) :\n" +
"#sin(x) = x - (x^3)/3! + (x^5)/5! - (x^7)/7! + ...\n" +
"#sin(x) ~= x*(1 - (x^2)*(1/3! - (x^2)(1/5! - (x^2)/7! )))\n" +
"# = x * (a - y*(b - y*(c - y*d)))\n" +
"#where\n" +
"#a = 1.0 c[63].x\n" +
"#b = 1/3! c[63].y\n" +
"#c = 1/5! c[63].z\n" +
"#d = 1/7! c[63].w\n" +
"#y = x^2 R2\n" +
"\n" +
"#R1.x = sin(R3.x);\n" +
"\n" +
"MUL R2, R3.x, R3.x;\n" +
"MAD R1, -R2, c[63].w, c[63].z;\n" +
"MAD R1, R1, -R2, c[63].y;\n" +
"MAD R1, R1, -R2, c[63].x;\n" +
"MUL R1, R1, R3.x;\n" +
"\n" +
"#displace vertex along normal\n" +
"MUL R1.x, R1.x, c[61].y;\n" +
"MAX R1.x, R1.x, c[64].x; # r1.x = max(r1.x, 0.0);\n" +
"MUL R2.xyz, v[NRML], R1.x;\n" +
"ADD R0.xyz, R0, R2;\n" +
"\n" +
"#simple lighting\n" +
"DP3 R1.x, c[4], v[NRML] ; # normal x MV-1T -> lighting normal\n" +
"DP3 R1.y, c[5], v[NRML] ;\n" +
"DP3 R1.z, c[6], v[NRML] ;\n" +
"\n" +
"DP3 R2, c[32], R1 ; # light position DOT normal\n" +
"MUL o[COL0].xyz, R2, c[35] ; # col = ldotn * diffuse\n" +
"\n" +
"MOV o[TEX0], v[TEX0];\n" +
"\n" +
"DP4 o[HPOS].x, c[0], R0 ; # object x MVP -> clip\n" +
"DP4 o[HPOS].y, c[1], R0 ;\n" +
"DP4 o[HPOS].z, c[2], R0 ;\n" +
"DP4 o[HPOS].w, c[3], R0 ;\n" +
"\n" +
"END",
//
// Wave
//
"!!VP1.0\n" +
"# Perturb vertices in clip space with sine wave\n" +
"# x += sin((y*freq)+anim) * amp\n" +
"DP4 R0.x, c[0], v[OPOS] ;\n" +
"DP4 R0.y, c[1], v[OPOS] ;\n" +
"DP4 R0.z, c[2], v[OPOS] ;\n" +
"DP4 R0.w, c[3], v[OPOS] ;\n" +
"\n" +
"MUL R3.x, R0.y, c[61].x; # wave frequency\n" +
"ADD R3.x, R3.x, c[60].x; # phase animation\n" +
"\n" +
"# reduce to period of 2*PI\n" +
"MUL R2, R3.x, c[62].x;\n" +
"EXP R4, R2.x; # R4.y = R2.x - floor(R2.x)\n" +
"MUL R3.x, R4.y, c[62].y;\n" +
"\n" +
"# offset to -PI - PI\n" +
"ADD R3.x, R3.x, -c[62].z;\n" +
"\n" +
"# R1.x = sin(R3.x);\n" +
"MUL R2, R3.x, R3.x;\n" +
"MAD R1, -R2, c[63].w, c[63].z;\n" +
"MAD R1, R1, -R2, c[63].y;\n" +
"MAD R1, R1, -R2, c[63].x;\n" +
"MUL R1, R1, R3.x;\n" +
"\n" +
"MAD R0.x, R1.x, c[61].y, R0.x;\n" +
"\n" +
"# simple lighting\n" +
"DP3 R1.x, c[4], v[NRML] ; # normal x MV-1T -> lighting normal\n" +
"DP3 R1.y, c[5], v[NRML] ;\n" +
"DP3 R1.z, c[6], v[NRML] ;\n" +
"DP3 R2, c[32], R1 ; # light position DOT normal\n" +
"MUL o[COL0].xyz, R2, c[35] ; # col = ldotn * diffuse\n" +
"MOV o[TEX0], v[TEX0];\n" +
"\n" +
"MOV o[HPOS], R0;\n" +
"\n" +
"END",
//
// Fisheye
//
"!!VP1.0\n" +
"#Fisheye distortion based on function:\n" +
"#f(x)=(d+1)/(d+(1/x))\n" +
"#maps the [0,1] interval monotonically onto [0,1]\n" +
"\n" +
"#c[61].z = d\n" +
"#c[61].w = d+1\n" +
"\n" +
"DP4 R0.x, c[0], v[OPOS] ;\n" +
"DP4 R0.y, c[1], v[OPOS] ;\n" +
"DP4 R0.z, c[2], v[OPOS] ;\n" +
"DP4 R0.w, c[3], v[OPOS] ;\n" +
"\n" +
"# do perspective divide\n" +
"RCP R1, R0.w;\n" +
"MUL R0, R0, R1.w;\n" +
"\n" +
"MAX R1, R0, -R0; # r1 = abs(r0)\n" +
"\n" +
"SLT R2, R0, c[64].x; # r2 = (r0 < 0.0) ? 1.0 : 0.0\n" +
"SGE R3, R0, c[64].x; # r3 = (r0 >= 0.0) ? 1.0 : 0.0\n" +
"\n" +
"# distort x\n" +
"# h(x)=(d+1)/(d+(1/x))\n" +
"RCP R1.x, R1.x; # r1 = 1 / r1\n" +
"ADD R1.x, R1.x, c[61].z; # r1 += d\n" +
"RCP R1.x, R1.x; # r1 = 1 / r1\n" +
"MUL R1.x, R1.x, c[61].w; # r1 *= d + 1\n" +
"\n" +
"# distort y\n" +
"RCP R1.y, R1.y; # r1 = 1 / r1\n" +
"ADD R1.y, R1.y, c[61].z; # r1 += d\n" +
"RCP R1.y, R1.y; # r1 = 1 / r1\n" +
"MUL R1.y, R1.y, c[61].w; # r1 *= d + 1\n" +
"\n" +
"# handle negative cases\n" +
"MUL R4.xy, R1, R3; # r4 = r1 * r3\n" +
"MAD R1.xy, R1, -R2, R4; # r1 = r1 * -r2 + r4\n" +
"\n" +
"# simple lighting\n" +
"DP3 R2.x, c[4], v[NRML] ; # normal x MV-1T -> lighting normal\n" +
"DP3 R2.y, c[5], v[NRML] ;\n" +
"DP3 R2.z, c[6], v[NRML] ;\n" +
"DP3 R3, c[32], R2 ; # light position DOT normal\n" +
"MUL o[COL0].xyz, R3, c[35] ; # col = ldotn * diffuse\n" +
"\n" +
"MOV o[TEX0], v[TEX0];\n" +
"\n" +
"MOV o[HPOS], R1;\n" +
"\n" +
"END",
//
// Spherize
//
"!!VP1.0\n" +
"# Spherical fish-eye distortion\n" +
"# in clip space\n" +
"DP4 R0.x, c[0], v[OPOS];\n" +
"DP4 R0.y, c[1], v[OPOS];\n" +
"DP4 R0.z, c[2], v[OPOS];\n" +
"DP4 R0.w, c[3], v[OPOS];\n" +
"\n" +
"# do perspective divide\n" +
"RCP R1.x, R0.w;\n" +
"MUL R2, R0, R1.x;\n" +
"\n" +
"# calculate distance from centre\n" +
"MUL R1.x, R2.x, R2.x;\n" +
"MAD R1.x, R2.y, R2.y, R1.x;\n" +
"RSQ R1.x, R1.x; # r1.x = 1 / sqrt(x*x+y*y)\n" +
"\n" +
"# calculate r3 = normalized direction vector\n" +
"MUL R3.xy, R0, R1.x;\n" +
"\n" +
"RCP R1.x, R1.x; # r1.x = actual distance\n" +
"MIN R1.x, R1.x, c[64].y; # r1.x = min(r1.x, 1.0)\n" +
"\n" +
"# remap based on: f(x) = sqrt(1-x^2)\n" +
"ADD R1.x, c[64].y, -R1.x;\n" +
"MAD R1.x, -R1.x, R1.x, c[64].y;\n" +
"RSQ R1.x, R1.x;\n" +
"RCP R1.x, R1.x;\n" +
"\n" +
"# move vertex to new distance from centre\n" +
"MUL R0.xy, R3, R1.x;\n" +
"\n" +
"# simple lighting\n" +
"DP3 R2.x, c[4], v[NRML]; # normal x MV-1T -> lighting normal\n" +
"DP3 R2.y, c[5], v[NRML];\n" +
"DP3 R2.z, c[6], v[NRML];\n" +
"DP3 R3, c[32], R2 ; # light position DOT normal\n" +
"MUL o[COL0].xyz, R3, c[35] ; # col = ldotn * diffuse\n" +
"\n" +
"MOV o[TEX0], v[TEX0];\n" +
"\n" +
"MOV o[HPOS], R0;\n" +
"\n" +
"END",
//
// Ripple
//
"!!VP1.0\n" +
"# Ripple distortion\n" +
"DP4 R0.x, c[0], v[OPOS];\n" +
"DP4 R0.y, c[1], v[OPOS];\n" +
"DP4 R0.z, c[2], v[OPOS];\n" +
"DP4 R0.w, c[3], v[OPOS];\n" +
"\n" +
"# do perspective divide\n" +
"RCP R1.x, R0.w;\n" +
"MUL R4, R0, R1.x;\n" +
"\n" +
"# calculate distance from centre\n" +
"MUL R1.x, R4.x, R4.x;\n" +
"MAD R1.x, R4.y, R4.y, R1.x;\n" +
"RSQ R1.x, R1.x; " +
"\n" +
"RCP R1.x, R1.x; " +
"\n" +
"MUL R1.x, R1.x, c[61].x; # wave frequency\n" +
"ADD R1.x, R1.x, c[60].x; # phase animation\n" +
"\n" +
"# reduce to period of 2*PI\n" +
"MUL R2, R1.x, c[62].x; # R2 = R1 / 2.0 * PI\n" +
"EXP R4, R2.x; # R4.y = R2.x - floor(R2.x)\n" +
"MUL R1.x, R4.y, c[62].y;\n" +
"\n" +
"# offset to -PI - PI\n" +
"ADD R1.x, R1.x, -c[62].z;\n" +
"\n" +
"# R3.x = sin(R1.x)\n" +
"MUL R2, R1.x, R1.x;\n" +
"MAD R3, -R2, c[63].w, c[63].z;\n" +
"MAD R3, R3, -R2, c[63].y;\n" +
"MAD R3, R3, -R2, c[63].x;\n" +
"MUL R3, R3, R1.x;\n" +
"\n" +
"MUL R3.x, R3.x, c[61].y;\n" +
"\n" +
"# move vertex towards centre based on distance\n" +
"MAD R0.xy, R0, -R3.x, R0;\n" +
"\n" +
"# lighting\n" +
"DP3 R2.x, c[4], v[NRML]; # normal x MV-1T -> lighting normal\n" +
"DP3 R2.y, c[5], v[NRML];\n" +
"DP3 R2.z, c[6], v[NRML];\n" +
"DP3 R3, c[32], R2; # light position DOT normal\n" +
"MUL o[COL0].xyz, R3, c[35]; # col = ldotn * diffuse\n" +
"\n" +
"MOV o[TEX0], v[TEX0];\n" +
"\n" +
"MOV o[HPOS], R0;\n" +
"\n" +
"END",
//
// Twist
//
"!!VP1.0 # Twist\n" +
"MOV R0, v[OPOS];\n" +
"\n" +
"MUL R1.x, R0.x, c[61].x; # frequency\n" +
"\n" +
"# calculate sin(angle) and cos(angle)\n" +
"ADD R1.y, R1.x, -c[62].w; # R1.y = R1.x + PI/2.0\n" +
"\n" +
"# reduce to period of 2*PI\n" +
"MUL R2, R1, c[62].x; # R2 = R1 / 2.0 * PI\n" +
"EXP R3.y, R2.x; # R2.y = R2.x - floor(R2.x)\n" +
"MOV R3.x, R3.y;\n" +
"EXP R3.y, R2.y; # R2.y = R2.x - floor(R2.x)\n" +
"MAD R2, R3, c[62].y, -c[62].z; # R2 = (R3 * 2.0*PI) - M_PI\n" +
"\n" +
"# R4.x = sin(R2.x);\n" +
"# R4.y = cos(R2.y);\n" +
"# parallel taylor series\n" +
"MUL R3, R2, R2;\n" +
"MAD R4, -R3, c[63].w, c[63].z;\n" +
"MAD R4, R4, -R3, c[63].y;\n" +
"MAD R4, R4, -R3, c[63].x;\n" +
"MUL R4, R4, R2;\n" +
"\n" +
"# x y z w\n" +
"# R:\n" +
"# 1 0 0 0\n" +
"# 0 c -s 0\n" +
"# 0 s c 0\n" +
"# 0 0 0 1\n" +
"\n" +
"# c = cos(a)\n" +
"# s = sin(a)\n" +
"\n" +
"# calculate rotation around X\n" +
"MOV R1, R0;\n" +
"\n" +
"MUL R1.y, R0.y, R4.y;\n" +
"MAD R1.y, R0.z, -R4.x, R1.y; # ny = y*cos(a) - z*sin(a)\n" +
"\n" +
"MUL R1.z, R0.y, R4.x;\n" +
"MAD R1.z, R0.z, R4.y, R1.z; # nz = y*sin(a) + z*cos(a)\n" +
"\n" +
"DP4 o[HPOS].x, c[0], R1; # object x MVP -> clip\n" +
"DP4 o[HPOS].y, c[1], R1;\n" +
"DP4 o[HPOS].z, c[2], R1;\n" +
"DP4 o[HPOS].w, c[3], R1;\n" +
"\n" +
"# rotate normal\n" +
"MOV R2, v[NRML];\n" +
"MUL R2.y, v[NRML].y, R4.y;\n" +
"MAD R2.y, v[NRML].z, -R4.x, R2.y; # ny = y*cos(a) - z*sin(a)\n" +
"\n" +
"MUL R2.z, v[NRML].y, R4.x;\n" +
"MAD R2.z, v[NRML].z, R4.y, R2.z; # nz = y*sin(a) + z*cos(a)\n" +
"\n" +
"# diffuse lighting\n" +
"DP3 R1.x, c[4], R2; # normal x MV-1T -> lighting normal\n" +
"DP3 R1.y, c[5], R2;\n" +
"DP3 R1.z, c[6], R2;\n" +
"\n" +
"DP3 R3, c[32], R1; # light position DOT normal\n" +
"MUL o[COL0].xyz, R3, c[35]; # col = ldotn * diffuse\n" +
"\n" +
"MOV o[TEX0], v[TEX0];\n" +
"\n" +
"END"
};
private void runExit() {
quit = true;
// 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. Instead run
// the exit routine in another thread.
new Thread(new Runnable() {
public void run() {
animator.stop();
System.exit(0);
}
}).start();
}
}