Jogamp
Bump scripts to jre1.8.0_66
[jogl.git] / src / test / com / jogamp / opengl / test / junit / jogl / demos / es2 / GearsES2.java
1 /**
2  * Copyright (C) 2011 JogAmp Community. All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20  */
21 package com.jogamp.opengl.test.junit.jogl.demos.es2;
22
23 import com.jogamp.common.nio.Buffers;
24 import com.jogamp.newt.Window;
25 import com.jogamp.newt.event.GestureHandler;
26 import com.jogamp.newt.event.KeyAdapter;
27 import com.jogamp.newt.event.KeyEvent;
28 import com.jogamp.newt.event.KeyListener;
29 import com.jogamp.newt.event.MouseEvent;
30 import com.jogamp.newt.event.MouseListener;
31 import com.jogamp.newt.event.PinchToZoomGesture;
32 import com.jogamp.newt.event.GestureHandler.GestureEvent;
33 import com.jogamp.opengl.GLRendererQuirks;
34 import com.jogamp.opengl.JoglVersion;
35 import com.jogamp.opengl.math.FloatUtil;
36 import com.jogamp.opengl.math.Quaternion;
37 import com.jogamp.opengl.math.VectorUtil;
38 import com.jogamp.opengl.test.junit.jogl.demos.GearsObject;
39 import com.jogamp.opengl.util.CustomGLEventListener;
40 import com.jogamp.opengl.util.PMVMatrix;
41 import com.jogamp.opengl.util.TileRendererBase;
42 import com.jogamp.opengl.util.glsl.ShaderCode;
43 import com.jogamp.opengl.util.glsl.ShaderProgram;
44 import com.jogamp.opengl.util.glsl.ShaderState;
45 import com.jogamp.opengl.util.stereo.EyeParameter;
46 import com.jogamp.opengl.util.stereo.ViewerPose;
47 import com.jogamp.opengl.util.stereo.StereoGLEventListener;
48
49 import java.nio.FloatBuffer;
50
51 import com.jogamp.nativewindow.NativeWindow;
52 import com.jogamp.opengl.GL;
53 import com.jogamp.opengl.GL2ES2;
54 import com.jogamp.opengl.GLAnimatorControl;
55 import com.jogamp.opengl.GLAutoDrawable;
56 import com.jogamp.opengl.GLProfile;
57 import com.jogamp.opengl.GLUniformData;
58 import com.jogamp.opengl.fixedfunc.GLMatrixFunc;
59
60 /**
61  * GearsES2.java <BR>
62  * @author Brian Paul (converted to Java by Ron Cemer and Sven Gothel) <P>
63  */
64 public class GearsES2 implements StereoGLEventListener, TileRendererBase.TileRendererListener {
65     private final FloatBuffer lightPos = Buffers.newDirectFloatBuffer( new float[] { 5.0f, 5.0f, 10.0f } );
66
67     private ShaderState st = null;
68     private PMVMatrix pmvMatrix = null;
69     private GLUniformData pmvMatrixUniform = null;
70     private GLUniformData colorU = null;
71     private float view_rotx = 20.0f, view_roty = 30.0f;
72     private boolean flipVerticalInGLOrientation = false;
73     private final boolean customRendering = false;
74
75     private final float view_rotz = 0.0f;
76     private float panX = 0.0f, panY = 0.0f, panZ=0.0f;
77     private volatile GearsObjectES2 gear1=null, gear2=null, gear3=null;
78     private GearsES2 sharedGears = null;
79     private Object syncObjects = null;
80     private boolean useMappedBuffers = false;
81     private boolean validateBuffers = false;
82     private volatile boolean usesSharedGears = false;
83     private FloatBuffer gear1Color=GearsObject.red, gear2Color=GearsObject.green, gear3Color=GearsObject.blue;
84     private float angle = 0.0f;
85     private int swapInterval = 0;
86     // private MouseListener gearsMouse = new TraceMouseAdapter(new GearsMouseAdapter());
87     public MouseListener gearsMouse = new GearsMouseAdapter();
88     public KeyListener gearsKeys = new GearsKeyAdapter();
89     private TileRendererBase tileRendererInUse = null;
90     private boolean doRotateBeforePrinting;
91
92     private boolean doRotate = true;
93     private boolean ignoreFocus = false;
94     private float[] clearColor = null;
95     private boolean clearBuffers = true;
96     private boolean verbose = true;
97     private volatile boolean isInit = false;
98
99     private PinchToZoomGesture pinchToZoomGesture = null;
100
101
102     public GearsES2(final int swapInterval) {
103         this.swapInterval = swapInterval;
104     }
105
106     public GearsES2() {
107         this.swapInterval = 1;
108     }
109
110     @Override
111     public void addTileRendererNotify(final TileRendererBase tr) {
112         tileRendererInUse = tr;
113         doRotateBeforePrinting = doRotate;
114         setDoRotation(false);
115     }
116     @Override
117     public void removeTileRendererNotify(final TileRendererBase tr) {
118         tileRendererInUse = null;
119         setDoRotation(doRotateBeforePrinting);
120     }
121     @Override
122     public void startTileRendering(final TileRendererBase tr) {
123         System.err.println("GearsES2.startTileRendering: "+sid()+""+tr);
124     }
125     @Override
126     public void endTileRendering(final TileRendererBase tr) {
127         System.err.println("GearsES2.endTileRendering: "+sid()+""+tr);
128     }
129
130     public void setIgnoreFocus(final boolean v) { ignoreFocus = v; }
131     public void setDoRotation(final boolean rotate) { this.doRotate = rotate; }
132     public void setClearBuffers(final boolean v) { clearBuffers = v; }
133     public void setVerbose(final boolean v) { verbose = v; }
134     public void setFlipVerticalInGLOrientation(final boolean v) { flipVerticalInGLOrientation=v; }
135
136     /** float[4] */
137     public void setClearColor(final float[] clearColor) {
138         this.clearColor = clearColor;
139     }
140
141     public void setGearsColors(final FloatBuffer gear1Color, final FloatBuffer gear2Color, final FloatBuffer gear3Color) {
142         this.gear1Color = gear1Color;
143         this.gear2Color = gear2Color;
144         this.gear3Color = gear3Color;
145     }
146
147     public void setSharedGears(final GearsES2 shared) {
148         sharedGears = shared;
149     }
150
151     public void setSyncObjects(final Object sync) {
152         syncObjects = sync;
153     }
154
155     /**
156      * @return gear1
157      */
158     public GearsObjectES2 getGear1() { return gear1; }
159
160     /**
161      * @return gear2
162      */
163     public GearsObjectES2 getGear2() { return gear2; }
164
165     /**
166      * @return gear3
167      */
168     public GearsObjectES2 getGear3() { return gear3; }
169
170     public boolean usesSharedGears() { return usesSharedGears; }
171
172     public void setUseMappedBuffers(final boolean v) { useMappedBuffers = v; }
173     public void setValidateBuffers(final boolean v) { validateBuffers = v; }
174
175     public PMVMatrix getPMVMatrix() {
176         return pmvMatrix;
177     }
178
179     private static final int TIME_OUT     = 2000; // 2s
180     private static final int POLL_DIVIDER   = 20; // TO/20
181     private static final int TIME_SLICE   = TIME_OUT / POLL_DIVIDER ;
182
183     /**
184      * @return True if this GLEventListener became initialized within TIME_OUT 2s
185      */
186     public boolean waitForInit(final boolean initialized) throws InterruptedException {
187         int wait;
188         for (wait=0; wait<POLL_DIVIDER && initialized != isInit ; wait++) {
189             Thread.sleep(TIME_SLICE);
190         }
191         return wait<POLL_DIVIDER;
192     }
193
194     private final String sid() { return "0x"+Integer.toHexString(hashCode()); }
195
196     @Override
197     public void init(final GLAutoDrawable drawable) {
198         if(null != sharedGears && !sharedGears.isInit() ) {
199             System.err.println(Thread.currentThread()+" GearsES2.init.0 "+sid()+": pending shared Gears .. re-init later XXXXX");
200             drawable.setGLEventListenerInitState(this, false);
201             return;
202         }
203
204         final GL2ES2 gl = drawable.getGL().getGL2ES2();
205         if(verbose) {
206             System.err.println(Thread.currentThread()+" GearsES2.init.0 "+sid()+": tileRendererInUse "+tileRendererInUse+", "+this);
207             System.err.println("GearsES2 init "+sid()+" on "+Thread.currentThread());
208             System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
209             System.err.println("INIT GL IS: " + gl.getClass().getName());
210             System.err.println(JoglVersion.getGLStrings(gl, null, false).toString());
211         }
212         if( !gl.hasGLSL() ) {
213             System.err.println("No GLSL available, no rendering.");
214             return;
215         }
216
217         st = new ShaderState();
218         // st.setVerbose(true);
219         final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader",
220                 "shader/bin", "gears", true);
221         final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), "shader",
222                 "shader/bin", "gears", true);
223         vp0.defaultShaderCustomization(gl, true, true);
224         fp0.defaultShaderCustomization(gl, true, true);
225         final ShaderProgram sp0 = new ShaderProgram();
226         sp0.add(gl, vp0, System.err);
227         sp0.add(gl, fp0, System.err);
228         st.attachShaderProgram(gl, sp0, true);
229         // Use debug pipeline
230         // drawable.setGL(new DebugGL(drawable.getGL()));
231
232         pmvMatrix = new PMVMatrix();
233         st.attachObject("pmvMatrix", pmvMatrix);
234         pmvMatrixUniform = new GLUniformData("pmvMatrix", 4, 4, pmvMatrix.glGetPMvMvitMatrixf()); // P, Mv, Mvi and Mvit
235         st.ownUniform(pmvMatrixUniform);
236         st.uniform(gl, pmvMatrixUniform);
237
238         final GLUniformData lightU = new GLUniformData("lightPos", 3, lightPos);
239         st.ownUniform(lightU);
240         st.uniform(gl, lightU);
241
242         colorU = new GLUniformData("color", 4, GearsObject.red);
243         st.ownUniform(colorU);
244         st.uniform(gl, colorU);
245
246         if( null != sharedGears ) {
247             gear1 = new GearsObjectES2(sharedGears.getGear1(), st, pmvMatrix, pmvMatrixUniform, colorU);
248             gear2 = new GearsObjectES2(sharedGears.getGear2(), st, pmvMatrix, pmvMatrixUniform, colorU);
249             gear3 = new GearsObjectES2(sharedGears.getGear3(), st, pmvMatrix, pmvMatrixUniform, colorU);
250             usesSharedGears = true;
251             if(verbose) {
252                 System.err.println("gear1 "+sid()+" created w/ share: "+sharedGears.getGear1()+" -> "+gear1);
253                 System.err.println("gear2 "+sid()+" created w/ share: "+sharedGears.getGear2()+" -> "+gear2);
254                 System.err.println("gear3 "+sid()+" created w/ share: "+sharedGears.getGear3()+" -> "+gear3);
255             }
256             if( gl.getContext().hasRendererQuirk(GLRendererQuirks.NeedSharedObjectSync) ) {
257                 syncObjects = sharedGears;
258                 System.err.println("Shared GearsES2: Synchronized Objects due to quirk "+GLRendererQuirks.toString(GLRendererQuirks.NeedSharedObjectSync));
259             } else if( null == syncObjects ) {
260                 syncObjects = new Object();
261                 System.err.println("Shared GearsES2: Unsynchronized Objects");
262             }
263         } else {
264             gear1 = new GearsObjectES2(gl, useMappedBuffers, st, gear1Color, 1.0f, 4.0f, 1.0f, 20, 0.7f, pmvMatrix, pmvMatrixUniform, colorU, validateBuffers);
265             if(verbose) {
266                 System.err.println("gear1 "+sid()+" created: "+gear1);
267             }
268
269             gear2 = new GearsObjectES2(gl, useMappedBuffers, st, gear2Color, 0.5f, 2.0f, 2.0f, 10, 0.7f, pmvMatrix, pmvMatrixUniform, colorU, validateBuffers);
270             if(verbose) {
271                 System.err.println("gear2 "+sid()+" created: "+gear2);
272             }
273
274             gear3 = new GearsObjectES2(gl, useMappedBuffers, st, gear3Color, 1.3f, 2.0f, 0.5f, 10, 0.7f, pmvMatrix, pmvMatrixUniform, colorU, validateBuffers);
275             if(verbose) {
276                 System.err.println("gear3 "+sid()+" created: "+gear2);
277             }
278             if( null == syncObjects ) {
279                 syncObjects = new Object();
280             }
281         }
282
283         final Object upstreamWidget = drawable.getUpstreamWidget();
284         if (upstreamWidget instanceof Window) {
285             final Window window = (Window) upstreamWidget;
286             window.addMouseListener(gearsMouse);
287             window.addKeyListener(gearsKeys);
288             window.addGestureListener(pinchToZoomListener);
289             pinchToZoomGesture = new PinchToZoomGesture(drawable.getNativeSurface(), false);
290             window.addGestureHandler(pinchToZoomGesture);
291         } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) {
292             final java.awt.Component comp = (java.awt.Component) upstreamWidget;
293             new com.jogamp.newt.event.awt.AWTMouseAdapter(gearsMouse, drawable).addTo(comp);
294             new com.jogamp.newt.event.awt.AWTKeyAdapter(gearsKeys, drawable).addTo(comp);
295         }
296
297         st.useProgram(gl, false);
298
299         gl.glFinish(); // make sure .. for shared context (impacts OSX 10.9)
300
301         isInit = true;
302         if(verbose) {
303             System.err.println(Thread.currentThread()+" GearsES2.init.X "+sid()+" FIN "+this);
304         }
305     }
306
307     public final boolean isInit() { return isInit; }
308
309     private final GestureHandler.GestureListener pinchToZoomListener = new GestureHandler.GestureListener() {
310         @Override
311         public void gestureDetected(final GestureEvent gh) {
312             final PinchToZoomGesture.ZoomEvent ze = (PinchToZoomGesture.ZoomEvent) gh;
313             final float zoom = ze.getZoom(); //  * ( ze.getTrigger().getPointerCount() - 1 ); <- too much ..
314             panZ = zoom * 30f - 30f; // [0 .. 2] -> [-30f .. 30f]
315         }
316     };
317
318     @Override
319     public void reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height) {
320         if( !isInit ) { return; }
321         final GL2ES2 gl = glad.getGL().getGL2ES2();
322         gl.setSwapInterval(swapInterval);
323         reshapeImpl(gl, x, y, width, height, width, height);
324     }
325
326     @Override
327     public void reshapeTile(final TileRendererBase tr,
328                             final int tileX, final int tileY, final int tileWidth, final int tileHeight,
329                             final int imageWidth, final int imageHeight) {
330         if( !isInit ) { return; }
331         final GL2ES2 gl = tr.getAttachedDrawable().getGL().getGL2ES2();
332         gl.setSwapInterval(0);
333         reshapeImpl(gl, tileX, tileY, tileWidth, tileHeight, imageWidth, imageHeight);
334     }
335
336     private float zNear = 5f;
337     private float zFar = 10000f;
338     private float zViewDist = 40.0f;
339
340     public void setZ(final float zNear, final float zFar, final float zViewDist) {
341         this.zNear = zNear;
342         this.zFar = zFar;
343         this.zViewDist = zViewDist;
344     }
345
346     void reshapeImpl(final GL2ES2 gl, final int tileX, final int tileY, final int tileWidth, final int tileHeight, final int imageWidth, final int imageHeight) {
347         final boolean msaa = gl.getContext().getGLDrawable().getChosenGLCapabilities().getSampleBuffers();
348         if(verbose) {
349             System.err.println(Thread.currentThread()+" GearsES2.reshape "+sid()+" "+tileX+"/"+tileY+" "+tileWidth+"x"+tileHeight+" of "+imageWidth+"x"+imageHeight+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(gl.getContext().getGLDrawable().getHandle())+", msaa "+msaa+", tileRendererInUse "+tileRendererInUse);
350         }
351
352         if( !gl.hasGLSL() ) {
353             return;
354         }
355
356         // compute projection parameters 'normal'
357         float left, right, bottom, top;
358         if( imageHeight > imageWidth ) {
359             final float a = (float)imageHeight / (float)imageWidth;
360             left = -1.0f;
361             right = 1.0f;
362             bottom = -a;
363             top = a;
364         } else {
365             final float a = (float)imageWidth / (float)imageHeight;
366             left = -a;
367             right = a;
368             bottom = -1.0f;
369             top = 1.0f;
370         }
371         final float w = right - left;
372         final float h = top - bottom;
373
374         // compute projection parameters 'tiled'
375         final float l = left + tileX * w / imageWidth;
376         final float r = l + tileWidth * w / imageWidth;
377         final float b = bottom + tileY * h / imageHeight;
378         final float t = b + tileHeight * h / imageHeight;
379
380         final float _w = r - l;
381         final float _h = t - b;
382         if(verbose) {
383             System.err.println(">> GearsES2 "+sid()+", angle "+angle+", [l "+left+", r "+right+", b "+bottom+", t "+top+"] "+w+"x"+h+" -> [l "+l+", r "+r+", b "+b+", t "+t+"] "+_w+"x"+_h+", v-flip "+flipVerticalInGLOrientation);
384         }
385
386         pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
387         pmvMatrix.glLoadIdentity();
388         if( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ) {
389             pmvMatrix.glScalef(1f, -1f, 1f);
390         }
391         pmvMatrix.glFrustumf(l, r, b, t, zNear, zFar);
392
393         pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
394         pmvMatrix.glLoadIdentity();
395         pmvMatrix.glTranslatef(0.0f, 0.0f, -zViewDist);
396         st.useProgram(gl, true);
397         st.uniform(gl, pmvMatrixUniform);
398         st.useProgram(gl, false);
399     }
400     // private boolean useAndroidDebug = false;
401
402     private final float[] mat4Tmp1 = new float[16];
403     private final float[] mat4Tmp2 = new float[16];
404     private final float[] vec3Tmp1 = new float[3];
405     private final float[] vec3Tmp2 = new float[3];
406     private final float[] vec3Tmp3 = new float[3];
407
408     private static final float[] vec3ScalePos = new float[] { 20f, 20f, 20f };
409
410     @Override
411     public void reshapeForEye(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height,
412                               final EyeParameter eyeParam, final ViewerPose viewerPose) {
413         final GL2ES2 gl = drawable.getGL().getGL2ES2();
414         pmvMatrix.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
415         final float[] mat4Projection = FloatUtil.makePerspective(mat4Tmp1, 0, true, eyeParam.fovhv, zNear, zFar);
416         if( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ) {
417             pmvMatrix.glLoadIdentity();
418             pmvMatrix.glScalef(1f, -1f, 1f);
419             pmvMatrix.glMultMatrixf(mat4Projection, 0);
420         } else {
421             pmvMatrix.glLoadMatrixf(mat4Projection, 0);
422         }
423
424         pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
425
426         final Quaternion rollPitchYaw = new Quaternion();
427         // private final float eyeYaw = FloatUtil.PI; // 180 degrees in radians
428         // rollPitchYaw.rotateByAngleY(eyeYaw);
429         // final float[] shiftedEyePos = rollPitchYaw.rotateVector(vec3Tmp1, 0, viewerPose.position, 0);
430         final float[] shiftedEyePos = VectorUtil.copyVec3(vec3Tmp1, 0, viewerPose.position, 0);
431         VectorUtil.scaleVec3(shiftedEyePos, shiftedEyePos, vec3ScalePos); // amplify viewerPose position
432         VectorUtil.addVec3(shiftedEyePos, shiftedEyePos, eyeParam.positionOffset);
433
434         rollPitchYaw.mult(viewerPose.orientation);
435         final float[] up = rollPitchYaw.rotateVector(vec3Tmp2, 0, VectorUtil.VEC3_UNIT_Y, 0);
436         final float[] forward = rollPitchYaw.rotateVector(vec3Tmp3, 0, VectorUtil.VEC3_UNIT_Z_NEG, 0);
437         final float[] center = VectorUtil.addVec3(forward, shiftedEyePos, forward);
438
439         final float[] mLookAt = FloatUtil.makeLookAt(mat4Tmp1, 0, shiftedEyePos, 0, center, 0, up, 0, mat4Tmp2);
440         final float[] mViewAdjust = FloatUtil.makeTranslation(mat4Tmp2, true, eyeParam.distNoseToPupilX, eyeParam.distMiddleToPupilY, eyeParam.eyeReliefZ);
441         final float[] mat4Modelview = FloatUtil.multMatrix(mViewAdjust, mLookAt);
442
443         pmvMatrix.glLoadMatrixf(mat4Modelview, 0);
444         pmvMatrix.glTranslatef(0.0f, 0.0f, -zViewDist);
445         st.useProgram(gl, true);
446         st.uniform(gl, pmvMatrixUniform);
447         st.useProgram(gl, false);
448     }
449
450     @Override
451     public void dispose(final GLAutoDrawable drawable) {
452         if( !isInit ) { return; }
453         isInit = false;
454         if(verbose) {
455             System.err.println(Thread.currentThread()+" GearsES2.dispose "+sid()+": tileRendererInUse "+tileRendererInUse);
456         }
457         final Object upstreamWidget = drawable.getUpstreamWidget();
458         if (upstreamWidget instanceof Window) {
459             final Window window = (Window) upstreamWidget;
460             window.removeMouseListener(gearsMouse);
461             window.removeKeyListener(gearsKeys);
462             window.removeGestureHandler(pinchToZoomGesture);
463             pinchToZoomGesture = null;
464             window.removeGestureListener(pinchToZoomListener);
465         }
466         final GL2ES2 gl = drawable.getGL().getGL2ES2();
467         if( !gl.hasGLSL() ) {
468             return;
469         }
470         st.useProgram(gl, false);
471         gear1.destroy(gl);
472         gear1 = null;
473         gear2.destroy(gl);
474         gear2 = null;
475         gear3.destroy(gl);
476         gear3 = null;
477         pmvMatrix = null;
478         colorU = null;
479         st.destroy(gl);
480         st = null;
481         sharedGears = null;
482         syncObjects = null;
483
484         if(verbose) {
485             System.err.println(Thread.currentThread()+" GearsES2.dispose "+sid()+" FIN");
486         }
487     }
488
489     @Override
490     public void display(final GLAutoDrawable drawable) {
491         display(drawable, 0);
492     }
493
494     @Override
495     public void display(final GLAutoDrawable drawable, final int flags) {
496         if( !isInit ) { return; }
497         if(null != sharedGears && !sharedGears.isInit() ) { return; }
498         final GLAnimatorControl anim = drawable.getAnimator();
499         if( verbose && ( null == anim || !anim.isAnimating() ) ) {
500             System.err.println(Thread.currentThread()+" GearsES2.display "+sid()+" "+drawable.getSurfaceWidth()+"x"+drawable.getSurfaceHeight()+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(drawable.getHandle()));
501         }
502
503         final boolean repeatedFrame = 0 != ( CustomGLEventListener.DISPLAY_REPEAT & flags );
504         final boolean dontClear = 0 != ( CustomGLEventListener.DISPLAY_DONTCLEAR & flags );
505
506         // Turn the gears' teeth
507         if( doRotate && !repeatedFrame ) {
508             angle += 0.5f;
509         }
510
511         // Get the GL corresponding to the drawable we are animating
512         final GL2ES2 gl = drawable.getGL().getGL2ES2();
513
514         final boolean hasFocus;
515         final Object upstreamWidget = drawable.getUpstreamWidget();
516         if(upstreamWidget instanceof NativeWindow) {
517           hasFocus = ((NativeWindow)upstreamWidget).hasFocus();
518         } else {
519           hasFocus = true;
520         }
521
522         if( clearBuffers && !dontClear ) {
523             if( null != clearColor ) {
524               gl.glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
525             } else if( null != tileRendererInUse ) {
526               gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
527             } else if( ignoreFocus || hasFocus ) {
528               gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
529             } else {
530               gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
531             }
532             // Special handling for the case where the GLJPanel is translucent
533             // and wants to be composited with other Java 2D content
534             if (GLProfile.isAWTAvailable() &&
535                 (drawable instanceof com.jogamp.opengl.awt.GLJPanel) &&
536                 !((com.jogamp.opengl.awt.GLJPanel) drawable).isOpaque() &&
537                 ((com.jogamp.opengl.awt.GLJPanel) drawable).shouldPreserveColorBufferIfTranslucent()) {
538               gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
539             } else {
540               gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
541             }
542         }
543         if( !gl.hasGLSL() ) {
544             return;
545         }
546
547         setGLStates(gl, true);
548
549         st.useProgram(gl, true);
550         pmvMatrix.glPushMatrix();
551         pmvMatrix.glTranslatef(panX, panY, panZ);
552         pmvMatrix.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f);
553         pmvMatrix.glRotatef(view_roty, 0.0f, 1.0f, 0.0f);
554         pmvMatrix.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f);
555
556         synchronized ( syncObjects ) {
557             gear1.draw(gl, -3.0f, -2.0f,  1f * angle -    0f);
558             gear2.draw(gl,  3.1f, -2.0f, -2f * angle -  9.0f);
559             gear3.draw(gl, -3.1f,  4.2f, -2f * angle - 25.0f);
560         }
561         pmvMatrix.glPopMatrix();
562         st.useProgram(gl, false);
563
564         setGLStates(gl, false);
565     }
566
567     public void setGLStates(final GL2ES2 gl, final boolean enable) {
568         // Culling only possible if we do not flip the projection matrix
569         final boolean useCullFace = ! ( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() || customRendering );
570         if( enable ) {
571             gl.glEnable(GL.GL_DEPTH_TEST);
572             if( useCullFace ) {
573                 gl.glEnable(GL.GL_CULL_FACE);
574             }
575         } else {
576             gl.glDisable(GL.GL_DEPTH_TEST);
577             if( useCullFace ) {
578                 gl.glDisable(GL.GL_CULL_FACE);
579             }
580         }
581     }
582
583     @Override
584     public String toString() {
585         return "GearsES2[obj "+sid()+" isInit "+isInit+", usesShared "+usesSharedGears+", 1 "+gear1+", 2 "+gear2+", 3 "+gear3+", sharedGears "+sharedGears+"]";
586     }
587
588     class GearsKeyAdapter extends KeyAdapter {
589         public void keyPressed(final KeyEvent e) {
590             final int kc = e.getKeyCode();
591             if(KeyEvent.VK_LEFT == kc) {
592                 view_roty -= 1;
593             } else if(KeyEvent.VK_RIGHT == kc) {
594                 view_roty += 1;
595             } else if(KeyEvent.VK_UP == kc) {
596                 view_rotx -= 1;
597             } else if(KeyEvent.VK_DOWN == kc) {
598                 view_rotx += 1;
599             }
600         }
601     }
602
603     class GearsMouseAdapter implements MouseListener{
604         private int prevMouseX, prevMouseY;
605
606         @Override
607         public void mouseClicked(final MouseEvent e) {
608         }
609
610         @Override
611         public void mouseEntered(final MouseEvent e) {
612         }
613
614         @Override
615         public void mouseExited(final MouseEvent e) {
616         }
617
618         @Override
619         public void mouseWheelMoved(final MouseEvent e) {
620             final float[] rot = e.getRotation();
621             if( e.isControlDown() ) {
622                 // alternative zoom
623                 final float incr = e.isShiftDown() ? rot[0] : rot[1] * 0.5f ;
624                 panZ += incr;
625                 System.err.println("panZ.2: incr "+incr+", dblZoom "+e.isShiftDown()+" -> "+panZ);
626             } else {
627                 // panning
628                 panX -= rot[0]; // positive -> left
629                 panY += rot[1]; // positive -> up
630             }
631         }
632
633         public void mousePressed(final MouseEvent e) {
634             if( e.getPointerCount()==1 ) {
635                 prevMouseX = e.getX();
636                 prevMouseY = e.getY();
637             } else if( e.getPointerCount() == 4 ) {
638                 final Object src = e.getSource();
639                 if( e.getPressure(0, true) > 0.7f && src instanceof Window) { // show Keyboard
640                    ((Window) src).setKeyboardVisible(true);
641                 }
642             }
643         }
644
645         public void mouseReleased(final MouseEvent e) {
646         }
647
648         public void mouseMoved(final MouseEvent e) {
649             if( e.isConfined() ) {
650                 navigate(e);
651             } else {
652                 // track prev. position so we don't have 'jumps'
653                 // in case we move to confined navigation.
654                 prevMouseX = e.getX();
655                 prevMouseY = e.getY();
656             }
657         }
658
659         public void mouseDragged(final MouseEvent e) {
660             navigate(e);
661         }
662
663         private void navigate(final MouseEvent e) {
664             final int x = e.getX();
665             final int y = e.getY();
666
667             int width, height;
668             final Object source = e.getSource();
669             Window window = null;
670             if(source instanceof Window) {
671                 window = (Window) source;
672                 width=window.getSurfaceWidth();
673                 height=window.getSurfaceHeight();
674             } else if (source instanceof GLAutoDrawable) {
675                 final GLAutoDrawable glad = (GLAutoDrawable) source;
676                 width = glad.getSurfaceWidth();
677                 height = glad.getSurfaceHeight();
678             } else if (GLProfile.isAWTAvailable() && source instanceof java.awt.Component) {
679                 final java.awt.Component comp = (java.awt.Component) source;
680                 width=comp.getWidth(); // FIXME HiDPI: May need to convert window units -> pixel units!
681                 height=comp.getHeight();
682             } else {
683                 throw new RuntimeException("Event source neither Window nor Component: "+source);
684             }
685             final float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)width);
686             final float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)height);
687             view_rotx += thetaX;
688             view_roty += thetaY;
689             prevMouseX = x;
690             prevMouseY = y;
691             // System.err.println("rotXY.1: "+view_rotx+"/"+view_roty+", source "+e);
692         }
693     }
694 }
http://JogAmp.org git info: FAQ, tutorial and man pages.