Jogamp
9b4b35883dae909a9e21d9b175482a2432a426c8
[jogl-demos.git] / src / demos / vertexProgRefract / VertexProgRefract.java
1 /*
2  * Portions Copyright (C) 2003 Sun Microsystems, Inc.
3  * All rights reserved.
4  */
5
6 /*
7  *
8  * COPYRIGHT NVIDIA CORPORATION 2003. ALL RIGHTS RESERVED.
9  * BY ACCESSING OR USING THIS SOFTWARE, YOU AGREE TO:
10  *
11  *  1) ACKNOWLEDGE NVIDIA'S EXCLUSIVE OWNERSHIP OF ALL RIGHTS
12  *     IN AND TO THE SOFTWARE;
13  *
14  *  2) NOT MAKE OR DISTRIBUTE COPIES OF THE SOFTWARE WITHOUT
15  *     INCLUDING THIS NOTICE AND AGREEMENT;
16  *
17  *  3) ACKNOWLEDGE THAT TO THE MAXIMUM EXTENT PERMITTED BY
18  *     APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS* AND
19  *     THAT NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES,
20  *     EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED
21  *     TO, IMPLIED WARRANTIES OF MERCHANTABILITY  AND FITNESS
22  *     FOR A PARTICULAR PURPOSE.
23  *
24  * IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
25  * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
26  * WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS
27  * OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
28  * INFORMATION, OR ANY OTHER PECUNIARY LOSS), INCLUDING ATTORNEYS'
29  * FEES, RELATING TO THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30  * EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31  *
32  */
33
34 package demos.vertexProgRefract;
35
36 import com.jogamp.opengl.util.gl2.GLUT;
37 import com.jogamp.opengl.util.texture.Texture;
38 import demos.common.Demo;
39 import demos.common.DemoListener;
40 import demos.util.Bunny;
41 import demos.util.Cubemap;
42 import demos.util.SystemTime;
43 import demos.util.Time;
44 import gleem.BSphere;
45 import gleem.BSphereProvider;
46 import gleem.ExaminerViewer;
47 import gleem.ManipManager;
48 import gleem.linalg.Rotf;
49 import gleem.linalg.Vec3f;
50 import java.awt.BorderLayout;
51 import java.awt.Frame;
52 import java.awt.event.KeyAdapter;
53 import java.awt.event.KeyEvent;
54 import java.awt.event.WindowAdapter;
55 import java.awt.event.WindowEvent;
56 import java.io.IOException;
57 import javax.media.opengl.*;
58 import javax.media.opengl.awt.*;
59 import com.jogamp.opengl.util.Animator;
60 import javax.swing.JOptionPane;
61
62
63
64 /**
65   Wavelength-dependent refraction demo<br>
66   It's a chromatic aberration!<br>
67   sgreen@nvidia.com 4/2001<br><p>
68
69   Currently 3 passes - could do it in 1 with 4 texture units<p>
70
71   Cubemap courtesy of Paul Debevec<p>
72
73   Ported to Java and ARB_fragment_program by Kenneth Russell
74 */
75
76 public class VertexProgRefract extends Demo {
77   public static void main(String[] args) {
78     GLCanvas canvas = new GLCanvas();
79     final VertexProgRefract demo = new VertexProgRefract();
80
81     canvas.addGLEventListener(demo);
82     canvas.addKeyListener(new KeyAdapter() {
83           public void keyTyped(KeyEvent e) {
84             demo.dispatchKey(e.getKeyChar());
85           }
86     });
87
88     final Animator animator = new Animator(canvas);
89     demo.setDemoListener(new DemoListener() {
90         public void shutdownDemo() {
91           runExit(animator);
92         }
93         public void repaint() {}
94       });
95
96     Frame frame = new Frame("Refraction Using Vertex Programs");
97     frame.setLayout(new BorderLayout());
98     canvas.setSize(512, 512);
99     frame.add(canvas, BorderLayout.CENTER);
100     frame.pack();
101     frame.setVisible(true);
102     canvas.requestFocus();
103
104     frame.addWindowListener(new WindowAdapter() {
105         public void windowClosing(WindowEvent e) {
106           runExit(animator);
107         }
108       });
109
110     animator.start();
111   }
112
113 //  private boolean useRegisterCombiners;
114   private boolean initComplete;
115   private boolean firstRender = true;
116   private int vtxProg;
117   private int fragProg;
118   private Texture cubemap;
119   private int bunnydl;
120   private int obj;
121
122   private GLUT glut = new GLUT();
123
124   private GLAutoDrawable drawable;
125   private ExaminerViewer viewer;
126   private boolean doViewAll = true;
127
128   private Time  time = new SystemTime();
129   private float animRate = (float) Math.toRadians(-6.0f); // Radians / sec
130
131   private float refract = 1.1f;           // ratio of indicies of refraction
132   private float wavelengthDelta = 0.05f;  // difference in refraction for each "wavelength" (R,G,B)
133   private float fresnel = 2.0f;           // Fresnel multiplier
134
135   private boolean wire = false;
136   private boolean toggleWire = false;
137
138   private static final String transformRefract = 
139 "!!ARBvp1.0\n" +
140 "# Refraction\n" +
141 "\n" +
142 "# Parameters\n" +
143 "PARAM mvp [4]       = { state.matrix.mvp };     # modelview projection matrix\n" +
144 "PARAM mvit[4]       = { state.matrix.modelview.invtrans }; # modelview matrix inverse transpose\n" +
145 "PARAM mv  [4]       = { state.matrix.modelview }; # modelview matrix\n" +
146 "PARAM tex [4]       = { state.matrix.texture }; # texture matrix\n" +
147 "PARAM eyePosition   = program.env[0];           # eye position\n" +
148 "PARAM fresnel       = program.env[1];           # fresnel multiplier\n" +
149 "PARAM texScale      = program.env[2];           # texture scale\n" +
150 "PARAM misc          = program.env[3];           # misc. constants\n" +
151 "PARAM refraction    = program.env[4];           # refractive index\n" +
152 "\n" +
153 "# Per vertex inputs\n" +
154 "ATTRIB iPos         = vertex.position;          #position\n" +
155 "ATTRIB iCol0        = vertex.color;             #color\n" +
156 "ATTRIB iNorm        = vertex.normal;            #normal\n" +
157 "\n" +
158 "# Temporaries\n" +
159 "TEMP r0;\n" +
160 "TEMP r1;\n" +
161 "TEMP r2;\n" +
162 "TEMP r3;\n" +
163 "TEMP r8;\n" +
164 "TEMP r9;\n" +
165 "TEMP r11;\n" +
166 "\n" +
167 "# Outputs\n" +
168 "OUTPUT oPos         = result.position;          #position\n" +
169 "OUTPUT oCol0        = result.color;             #primary color\n" +
170 "OUTPUT oTex0        = result.texcoord[0];       #texture coordinate set 0\n" +
171 "OUTPUT oTex1        = result.texcoord[1];       #texture coordinate set 1\n" +
172 "\n" +
173 "\n" +
174 "# transform vertex position to eye space\n" +
175 "DP4    r9.x, mv[0], iPos ;\n" +
176 "DP4    r9.y, mv[1], iPos ;\n" +
177 "DP4    r9.z, mv[2], iPos ;\n" +
178 "DP4    r9.w, mv[3], iPos ;\n" +
179 "\n" +
180 "# transform normal to eye space\n" +
181 "DP3    r11.x, mvit[0], iNorm ;\n" +
182 "DP3    r11.y, mvit[1], iNorm ;\n" +
183 "DP3    r11.z, mvit[2], iNorm ;\n" +
184 "\n" +
185 "# vertex->eye vector\n" +
186 "ADD    r0, -r9, eyePosition;\n" +
187 "\n" +
188 "# normalize\n" +
189 "DP3    r8.w, r0, r0;\n" +
190 "RSQ    r8.w, r8.w;\n" +
191 "MUL    r8, r0, r8.w;       # r8 = eye/incident vector\n" +
192 "\n" +
193 "# refraction, Renderman style\n" +
194 "\n" +
195 "# float IdotN = I.N;\n" +
196 "# float k = 1 - eta*eta*(1 - IdotN*IdotN);\n" +
197 "# return k < 0 ? (0,0,0) : eta*I - (eta*IdotN + sqrt(k))*N;\n" +
198 "\n" +
199 "DP3    r0.x, r11, -r8;             # r0 = N.I\n" +
200 "\n" +
201 "MAD    r1.x, -r0.x, r0.x, misc.y;  # r1 = -IdotN*IdotN + 1\n" +
202 "MUL    r1.x, r1.x, refraction.y;   # r1 = -(r1*eta*eta)+1\n" +
203 "ADD    r1.x, misc.y, -r1.x;\n" +
204 "\n" +
205 "RSQ    r2.x, r1.x;\n" +
206 "RCP    r2.x, r2.x;\n" +
207 "MAD    r2.x, refraction.x, r0.x, r2.x;\n" +
208 "MUL    r2, r11, r2.x;\n" +
209 "MAD    r2, refraction.x, -r8, r2;\n" +
210 "\n" +
211 "# transform refracted ray by cubemap transform\n" +
212 "DP3    oTex0.x, tex[0], r2;\n" +
213 "DP3    oTex0.y, tex[1], r2;\n" +
214 "DP3    oTex0.z, tex[2], r2;\n" +
215 "\n" +
216 "# calculate reflection\n" +
217 "MUL    r0, r11, misc.z;\n" +
218 "DP3    r3.w, r11, r8;\n" +
219 "MAD    r3, r3.w, r0, -r8;\n" +
220 "\n" +
221 "# transform reflected ray by cubemap transform\n" +
222 "DP3    oTex1.x, tex[0], r3;\n" +
223 "DP3    oTex1.y, tex[1], r3;\n" +
224 "DP3    oTex1.z, tex[2], r3;\n" +
225 "\n" +
226 "# cheesy Fresnel approximation = (1-(I.N))^p\n" +
227 "DP3    r0.x, r8, r11;\n" +
228 "ADD    r0.x, misc.y, -r0.x;\n" +
229 "MUL    r0.x, r0.x, r0.x;\n" +
230 "MUL    oCol0, r0.x, fresnel;\n" +
231 "\n" +
232 "# transform vertex to clip space\n" +
233 "DP4    oPos.x, mvp[0], iPos ;\n" +
234 "DP4    oPos.y, mvp[1], iPos ;\n" +
235 "DP4    oPos.z, mvp[2], iPos ;\n" +
236 "DP4    oPos.w, mvp[3], iPos ;\n" +
237 "\n" +
238 "END\n";
239
240   public void init(GLAutoDrawable drawable) {
241
242     drawable.setGL(new DebugGL2(drawable.getGL().getGL2()));
243
244     initComplete = false;
245
246     GL2 gl = drawable.getGL().getGL2();
247
248     float cc = 1.0f;
249     gl.glClearColor(cc, cc, cc, 1);
250     gl.glColor3f(1,1,1);
251     gl.glEnable(GL.GL_DEPTH_TEST);
252
253     try {
254       initExtension(gl, "GL_ARB_vertex_program");
255       initExtension(gl, "GL_VERSION_1_3"); // For multitexturing support
256       if (!gl.isExtensionAvailable("GL_ARB_fragment_program")) {
257 //        if (gl.isExtensionAvailable("GL_NV_register_combiners")) {
258 //          useRegisterCombiners = true;
259 //        } else {
260           final String message = "This demo requires the GL_ARB_fragment_program extension";
261 //                  +  "or GL_NV_register_combiners extension";
262           new Thread(new Runnable() {
263               public void run() {
264                 JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE);
265                 shutdownDemo();
266               }
267             }).start();
268           throw new RuntimeException(message);
269 //        }
270       }
271     } catch (RuntimeException e) {
272       shutdownDemo();
273       throw(e);
274     }
275
276     b[' '] = true; // animate by default
277
278     int[] vtxProgTmp = new int[1];
279     gl.glGenProgramsARB(1, vtxProgTmp, 0);
280     vtxProg = vtxProgTmp[0];
281     gl.glBindProgramARB(GL2.GL_VERTEX_PROGRAM_ARB, vtxProg);
282     gl.glProgramStringARB(GL2.GL_VERTEX_PROGRAM_ARB, GL2.GL_PROGRAM_FORMAT_ASCII_ARB, transformRefract.length(),
283                           transformRefract);
284
285     gl.glProgramEnvParameter4fARB(GL2.GL_VERTEX_PROGRAM_ARB, 0, 0.0f, 0.0f, 0.0f, 1.0f);    // eye position
286
287     gl.glProgramEnvParameter4fARB(GL2.GL_VERTEX_PROGRAM_ARB, 1, fresnel, fresnel, fresnel, 1.0f);    // fresnel multiplier
288
289     gl.glProgramEnvParameter4fARB(GL2.GL_VERTEX_PROGRAM_ARB, 2, 1.0f, -1.0f, 1.0f, 0.0f);   // texture scale
290     gl.glProgramEnvParameter4fARB(GL2.GL_VERTEX_PROGRAM_ARB, 3, 0.0f, 1.0f, 2.0f, 3.0f);    // misc constants
291
292     try {
293       cubemap = Cubemap.loadFromStreams(gl,
294                                         getClass().getClassLoader(),
295                                         "demos/data/cubemaps/uffizi_",
296                                         "png", true);
297     } catch (IOException e) {
298       shutdownDemo();
299       throw new RuntimeException(e);
300     }
301
302     gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
303
304     gl.glDisable(GL.GL_CULL_FACE);
305
306 //    if (useRegisterCombiners) {
307 //      initCombiners(gl);
308 //    } else {
309       initFragmentProgram(gl);
310 //    }
311
312     try {
313       bunnydl = Bunny.gen3DObjectList(gl);
314     } catch (IOException e) {
315       throw new RuntimeException(e);
316     }
317
318     doViewAll = true;
319
320     // Do this only once per drawable, not once each time the OpenGL
321     // context is created
322     if (firstRender) {
323       firstRender = false;
324
325       // Register the window with the ManipManager
326       ManipManager manager = ManipManager.getManipManager();
327       manager.registerWindow((AWTGLAutoDrawable) drawable);
328       this.drawable = drawable;
329
330       viewer = new ExaminerViewer();
331       viewer.setUpVector(Vec3f.Y_AXIS);
332       viewer.setNoAltKeyMode(true);
333       viewer.setAutoRedrawMode(false);
334       viewer.attach((AWTGLAutoDrawable) drawable, new BSphereProvider() {
335           public BSphere getBoundingSphere() {
336             return new BSphere(new Vec3f(0, 0, 0), 1.0f);
337           }
338         });
339       viewer.setVertFOV((float) (15.0f * Math.PI / 32.0f));
340       viewer.setZNear(0.1f);
341       viewer.setZFar(10.0f);
342     }
343
344     initComplete = true;
345   }
346
347   public void dispose(GLAutoDrawable drawable) {
348   }
349
350   public void display(GLAutoDrawable drawable) {
351     if (!initComplete) {
352       return;
353     }
354
355     time.update();
356
357     GL2 gl = drawable.getGL().getGL2();
358     gl.glClear(GL.GL_COLOR_BUFFER_BIT|GL.GL_DEPTH_BUFFER_BIT);
359
360     if (doViewAll) {
361       viewer.viewAll(gl);
362       doViewAll = false;
363     }
364
365     if (getFlag(' ')) {
366       viewer.rotateAboutFocalPoint(new Rotf(Vec3f.Y_AXIS, (float) (time.deltaT() * animRate)));
367     }
368
369     if (toggleWire) {
370       toggleWire = false;
371       wire = !wire;
372       if (wire) {
373         gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_LINE);
374       } else {
375         gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_FILL);
376       }
377     }
378
379     // draw background
380     gl.glDisable(GL.GL_DEPTH_TEST);
381     drawSkyBox(gl);
382     gl.glEnable(GL.GL_DEPTH_TEST);
383
384     gl.glPushMatrix();
385
386     viewer.update(gl);
387     ManipManager.getManipManager().updateCameraParameters((AWTGLAutoDrawable) drawable, viewer.getCameraParameters());
388     ManipManager.getManipManager().render((AWTGLAutoDrawable) drawable, gl);
389
390     gl.glBindProgramARB(GL2.GL_VERTEX_PROGRAM_ARB, vtxProg);
391
392     gl.glEnable(GL2.GL_VERTEX_PROGRAM_ARB);
393     gl.glProgramEnvParameter4fARB(GL2.GL_VERTEX_PROGRAM_ARB, 62, fresnel, fresnel, fresnel, 1.0f);
394
395     // set texture transforms
396     gl.glActiveTexture(GL.GL_TEXTURE0);
397     cubemap.bind(gl);
398     cubemap.enable(gl);
399     gl.glMatrixMode(GL.GL_TEXTURE);
400     gl.glLoadIdentity();
401     viewer.updateInverseRotation(gl);
402
403     gl.glActiveTexture(GL.GL_TEXTURE1);
404     cubemap.bind(gl);
405     cubemap.enable(gl);
406     gl.glMatrixMode(GL.GL_TEXTURE);
407     gl.glLoadIdentity();
408     viewer.updateInverseRotation(gl);
409
410 //    if (useRegisterCombiners) {
411 //      gl.glEnable(GL2.GL_REGISTER_COMBINERS_NV);
412 //    } else {
413       gl.glBindProgramARB(GL2.GL_FRAGMENT_PROGRAM_ARB, fragProg);
414       gl.glEnable(GL2.GL_FRAGMENT_PROGRAM_ARB);
415 //    }
416
417     gl.glColor3f(1.0f, 1.0f, 1.0f);
418
419     if (getFlag('s')) {
420       // single pass
421       setRefraction(gl, refract);
422       drawObj(gl, obj);
423
424     } else {
425       // red pass
426       gl.glColorMask(true, false, false, false);
427       setRefraction(gl, refract);
428       drawObj(gl, obj);
429   
430       gl.glDepthMask(false);
431       gl.glDepthFunc(GL.GL_EQUAL);
432
433       // green pass
434       gl.glColorMask(false, true, false, false);
435       setRefraction(gl, refract + wavelengthDelta);
436       drawObj(gl, obj);
437
438       // blue pass
439       gl.glColorMask(false, false, true, false);
440       setRefraction(gl, refract + (wavelengthDelta * 2));
441       drawObj(gl, obj);
442
443       gl.glDepthMask(true);
444       gl.glDepthFunc(GL.GL_LESS);
445       gl.glColorMask(true, true, true, false);
446     }
447
448 //    if (useRegisterCombiners) {
449 //      gl.glDisable(GL2.GL_REGISTER_COMBINERS_NV);
450 //    } else {
451       gl.glDisable(GL2.GL_FRAGMENT_PROGRAM_ARB);
452 //    }
453     gl.glDisable(GL2.GL_VERTEX_PROGRAM_ARB);
454
455     gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
456     gl.glPopMatrix();
457   }
458
459   // Unused routines
460   public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
461   public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
462
463   //----------------------------------------------------------------------
464   // Internals only below this point
465   //
466   public void shutdownDemo() {
467     if (drawable != null) {
468       viewer.detach();
469       ManipManager.getManipManager().unregisterWindow((AWTGLAutoDrawable) drawable);
470       drawable.removeGLEventListener(this);
471     }
472     super.shutdownDemo();
473   }
474
475   private boolean[] b = new boolean[256];
476   private void dispatchKey(char k) {
477     setFlag(k, !getFlag(k));
478
479     // Quit on escape or 'q'
480     if ((k == (char) 27) || (k == 'q')) {
481       shutdownDemo();
482       return;
483     }
484
485     switch (k) {
486     case '1':
487       obj = 0;
488       break;
489
490     case '2':
491       obj = 1;
492       break;
493
494     case '3':
495       obj = 2;
496       break;
497
498     case '4':
499       obj = 3;
500       break;
501
502     case 'v':
503       doViewAll = true;
504       break;
505
506     case 'w':
507       toggleWire = true;
508       break;
509
510     default:
511       break;
512     }
513   }
514
515   private void setFlag(char key, boolean val) {
516     b[((int) key) & 0xFF] = val;
517   }
518
519   private boolean getFlag(char key) {
520     return b[((int) key) & 0xFF];
521   }
522
523   private void initExtension(GL gl, String glExtensionName) {
524     if (!gl.isExtensionAvailable(glExtensionName)) {
525       final String message = "OpenGL extension \"" + glExtensionName + "\" not available";
526       new Thread(new Runnable() {
527           public void run() {
528             JOptionPane.showMessageDialog(null, message, "Unavailable extension", JOptionPane.ERROR_MESSAGE);
529             shutdownDemo();
530           }
531         }).start();
532       throw new RuntimeException(message);
533     }
534   }
535
536   // initalize texture combiners to compute:
537   // refraction*(1-fresnel) + reflection*fresnel
538 //  private void initCombiners(GL gl) {
539 //    gl.glCombinerParameteriNV(GL.GL_NUM_GENERAL_COMBINERS_NV, 1);
540 //
541 //    // combiner 0
542 //    // a*b+c*d
543 //    gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_A_NV, GL.GL_TEXTURE0, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
544 //    gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_B_NV, GL.GL_PRIMARY_COLOR_NV, GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB);
545 //    gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_C_NV, GL.GL_TEXTURE1, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
546 //    gl.glCombinerInputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_VARIABLE_D_NV, GL.GL_PRIMARY_COLOR_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
547 //
548 //    // output:
549 //    // (stage, portion, abOutput, cdOutput, sumOutput, scale, bias, abDotProduct, cdDotProduct, muxSum)
550 //    gl.glCombinerOutputNV(GL.GL_COMBINER0_NV, GL.GL_RGB, GL.GL_DISCARD_NV, GL.GL_DISCARD_NV, GL.GL_SPARE0_NV, GL.GL_NONE, GL.GL_NONE, false, false, false);
551 //
552 //    // final combiner
553 //    // output: Frgb = A*B + (1-A)*C + D
554 //    // (variable, input, mapping, componentUsage);
555 //    gl.glFinalCombinerInputNV(GL.GL_VARIABLE_A_NV, GL.GL_SPARE0_NV, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
556 //    gl.glFinalCombinerInputNV(GL.GL_VARIABLE_B_NV, GL.GL_ZERO, GL.GL_UNSIGNED_INVERT_NV, GL.GL_RGB);
557 //    gl.glFinalCombinerInputNV(GL.GL_VARIABLE_C_NV, GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
558 //    gl.glFinalCombinerInputNV(GL.GL_VARIABLE_D_NV, GL.GL_ZERO, GL.GL_UNSIGNED_IDENTITY_NV, GL.GL_RGB);
559 //  }
560
561   private void initFragmentProgram(GL2 gl) {
562     int[] fragProgTmp = new int[1];
563     gl.glGenProgramsARB(1, fragProgTmp, 0);
564     fragProg = fragProgTmp[0];
565     String combineFragProg =
566 "!!ARBfp1.0\n" +
567 "# compute refraction*(1-fresnel) + reflection*fresnel\n" +
568 "TEMP texSamp0, texSamp1;\n" +
569 "TEMP invFresnel;\n" +
570 "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n" +
571 "TEX texSamp0, fragment.texcoord[0], texture[0], CUBE;\n" +
572 "TEX texSamp1, fragment.texcoord[1], texture[1], CUBE;\n" +
573 "SUB invFresnel, one, fragment.color;\n" +
574 "MUL texSamp0, texSamp0, invFresnel;\n" +
575 "MUL texSamp1, texSamp1, fragment.color;\n" +
576 "ADD texSamp0, texSamp0, texSamp1;\n" +
577 "MOV result.color, texSamp0;\n" +
578 "END";
579
580     gl.glBindProgramARB(GL2.GL_FRAGMENT_PROGRAM_ARB, fragProg);
581     gl.glProgramStringARB(GL2.GL_FRAGMENT_PROGRAM_ARB, GL2.GL_PROGRAM_FORMAT_ASCII_ARB,
582                        combineFragProg.length(), combineFragProg);
583     int[] errPos = new int[1];
584     gl.glGetIntegerv(GL2.GL_PROGRAM_ERROR_POSITION_ARB, errPos, 0);
585     if (errPos[0] >= 0) {
586       System.out.println("Fragment program failed to load:");
587       String errMsg = gl.glGetString(GL2.GL_PROGRAM_ERROR_STRING_ARB);
588       if (errMsg == null) {
589         System.out.println("[No error message available]");
590       } else {
591         System.out.println("Error message: \"" + errMsg + "\"");
592       }
593       System.out.println("Error occurred at position " + errPos[0] + " in program:");
594       int endPos = errPos[0];
595       while (endPos < combineFragProg.length() && combineFragProg.charAt(endPos) != '\n') {
596         ++endPos;
597       }
598       System.out.println(combineFragProg.substring(errPos[0], endPos));
599     }
600   }
601
602   private void drawSkyBox(GL2 gl) {
603     // Compensates for ExaminerViewer's modification of modelview matrix
604     gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
605     gl.glLoadIdentity();
606
607     gl.glActiveTexture(GL.GL_TEXTURE1);
608     gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);
609   
610     gl.glActiveTexture(GL.GL_TEXTURE0);
611     cubemap.bind(gl);
612     cubemap.enable(gl);
613
614     // This is a workaround for a driver bug on Mac OS X where the
615     // normals are not being sent down to the hardware in
616     // GL_NORMAL_MAP texgen mode. Temporarily enabling lighting
617     // causes the normals to be sent down. Thanks to Ken Dyke.
618     gl.glEnable(GL2ES1.GL_LIGHTING);
619
620     gl.glTexGeni(GL2.GL_S, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP);
621     gl.glTexGeni(GL2.GL_T, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP);
622     gl.glTexGeni(GL2.GL_R, GL2.GL_TEXTURE_GEN_MODE, GL2.GL_NORMAL_MAP);
623
624     gl.glEnable(GL2.GL_TEXTURE_GEN_S);
625     gl.glEnable(GL2.GL_TEXTURE_GEN_T);
626     gl.glEnable(GL2.GL_TEXTURE_GEN_R);
627
628     gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
629
630     gl.glMatrixMode(GL.GL_TEXTURE);
631     gl.glPushMatrix();
632     gl.glLoadIdentity();
633     viewer.updateInverseRotation(gl);
634     
635     glut.glutSolidSphere(5.0, 40, 20);
636
637     gl.glDisable(GL2ES1.GL_LIGHTING);
638
639     gl.glPopMatrix();
640     gl.glMatrixMode(GL2ES1.GL_MODELVIEW);
641
642     gl.glDisable(GL2.GL_TEXTURE_GEN_S);
643     gl.glDisable(GL2.GL_TEXTURE_GEN_T);
644     gl.glDisable(GL2.GL_TEXTURE_GEN_R);
645   }
646
647   private void drawObj(GL2 gl, int obj) {
648     switch(obj) {
649     case 0:
650       gl.glCallList(bunnydl);
651       break;
652     
653     case 1:
654       glut.glutSolidSphere(0.5, 64, 64);
655       break;
656
657     case 2:
658       glut.glutSolidTorus(0.25, 0.5, 64, 64);
659       break;
660
661     case 3:
662       drawPlane(gl, 1.0f, 1.0f, 50, 50);
663       break;
664     }
665   }
666
667   private void setRefraction(GL2 gl, float index) {
668     gl.glProgramEnvParameter4fARB(GL2.GL_VERTEX_PROGRAM_ARB, 4, index, index*index, 0.0f, 0.0f);
669   }
670
671   // draw square subdivided into quad strips
672   private void drawPlane(GL2 gl, float w, float h, int rows, int cols) {
673     int x, y;
674     float vx, vy, s, t;
675     float ts, tt, tw, th;
676
677     ts = 1.0f / cols;
678     tt = 1.0f / rows;
679
680     tw = w / cols;
681     th = h / rows;
682
683     gl.glNormal3f(0.0f, 0.0f, 1.0f);
684
685     for(y=0; y<rows; y++) {
686       gl.glBegin(GL2.GL_QUAD_STRIP);
687       for(x=0; x<=cols; x++) {
688         vx = tw * x -(w/2.0f);
689         vy = th * y -(h/2.0f);
690         s = ts * x;
691         t = tt * y;
692
693         gl.glTexCoord2f(s, t);
694         gl.glColor3f(s, t, 0.0f);
695         gl.glVertex3f(vx, vy, 0.0f);
696
697         gl.glColor3f(s, t + tt, 0.0f);
698         gl.glTexCoord2f(s, t + tt);
699         gl.glVertex3f(vx, vy + th, 0.0f);
700       }
701       gl.glEnd();
702     }
703   }
704
705   private static void runExit(final Animator animator) {
706     // Note: calling System.exit() synchronously inside the draw,
707     // reshape or init callbacks can lead to deadlocks on certain
708     // platforms (in particular, X11) because the JAWT's locking
709     // routines cause a global AWT lock to be grabbed. Instead run
710     // the exit routine in another thread.
711     new Thread(new Runnable() {
712         public void run() {
713           animator.stop();
714           System.exit(0);
715         }
716       }).start();
717   }
718 }
http://JogAmp.org git info: FAQ, tutorial and man pages.