1 2 package com.jogamp.opengl.test.junit.jogl.demos.gl2; 3 4 import com.jogamp.opengl.GL; 5 import com.jogamp.opengl.GL2; 6 import com.jogamp.opengl.GL2GL3; 7 import com.jogamp.opengl.GLAutoDrawable; 8 import com.jogamp.opengl.GLEventListener; 9 import com.jogamp.opengl.GLProfile; 10 import com.jogamp.opengl.fixedfunc.GLLightingFunc; 11 import com.jogamp.opengl.fixedfunc.GLMatrixFunc; 12 13 import com.jogamp.newt.Window; 14 import com.jogamp.newt.event.InputEvent; 15 import com.jogamp.newt.event.KeyAdapter; 16 import com.jogamp.newt.event.KeyEvent; 17 import com.jogamp.newt.event.KeyListener; 18 import com.jogamp.newt.event.MouseAdapter; 19 import com.jogamp.newt.event.MouseEvent; 20 import com.jogamp.newt.event.MouseListener; 21 import com.jogamp.newt.event.awt.AWTKeyAdapter; 22 import com.jogamp.newt.event.awt.AWTMouseAdapter; 23 import com.jogamp.opengl.GLRendererQuirks; 24 import com.jogamp.opengl.JoglVersion; 25 import com.jogamp.opengl.util.TileRendererBase; 26 27 /** 28 * Gears.java <BR> 29 * author: Brian Paul (converted to Java by Ron Cemer and Sven Gothel) <P> 30 * 31 * This version is equal to Brian Paul's version 1.2 1999/10/21 32 */ 33 public class Gears implements GLEventListener, TileRendererBase.TileRendererListener { 34 private float view_rotx = 20.0f, view_roty = 30.0f; 35 private final float view_rotz = 0.0f; 36 private int gear1=0, gear2=0, gear3=0; 37 private Gears sharedGears = null; 38 private Object syncObjects = null; 39 private float angle = 0.0f; 40 private boolean doRotate = true; 41 private final int swapInterval; 42 private final MouseListener gearsMouse = new GearsMouseAdapter(); 43 private final KeyListener gearsKeys = new GearsKeyAdapter(); 44 private TileRendererBase tileRendererInUse = null; 45 private boolean doRotateBeforePrinting; 46 private boolean verbose = true; 47 private boolean flipVerticalInGLOrientation = false; 48 private volatile boolean isInit = false; 49 50 // private boolean mouseRButtonDown = false; 51 private int prevMouseX, prevMouseY; 52 Gears(final int swapInterval)53 public Gears(final int swapInterval) { 54 this.swapInterval = swapInterval; 55 } 56 Gears()57 public Gears() { 58 this.swapInterval = 1; 59 } 60 61 @Override addTileRendererNotify(final TileRendererBase tr)62 public void addTileRendererNotify(final TileRendererBase tr) { 63 tileRendererInUse = tr; 64 doRotateBeforePrinting = doRotate; 65 setDoRotation(false); 66 } 67 @Override removeTileRendererNotify(final TileRendererBase tr)68 public void removeTileRendererNotify(final TileRendererBase tr) { 69 tileRendererInUse = null; 70 setDoRotation(doRotateBeforePrinting); 71 } 72 @Override startTileRendering(final TileRendererBase tr)73 public void startTileRendering(final TileRendererBase tr) { 74 System.err.println("Gears.startTileRendering: "+tr); 75 } 76 @Override endTileRendering(final TileRendererBase tr)77 public void endTileRendering(final TileRendererBase tr) { 78 System.err.println("Gears.endTileRendering: "+tr); 79 } 80 setDoRotation(final boolean rotate)81 public void setDoRotation(final boolean rotate) { doRotate = rotate; } setVerbose(final boolean v)82 public void setVerbose(final boolean v) { verbose = v; } setFlipVerticalInGLOrientation(final boolean v)83 public void setFlipVerticalInGLOrientation(final boolean v) { flipVerticalInGLOrientation=v; } 84 setSharedGears(final Gears shared)85 public void setSharedGears(final Gears shared) { 86 sharedGears = shared; 87 } 88 89 /** 90 * @return display list gear1 91 */ getGear1()92 public int getGear1() { return gear1; } 93 94 /** 95 * @return display list gear2 96 */ getGear2()97 public int getGear2() { return gear2; } 98 99 /** 100 * @return display list gear3 101 */ getGear3()102 public int getGear3() { return gear3; } 103 104 @Override init(final GLAutoDrawable drawable)105 public void init(final GLAutoDrawable drawable) { 106 final GL2 gl = drawable.getGL().getGL2(); 107 108 if( init(gl) ) { 109 final Object upstreamWidget = drawable.getUpstreamWidget(); 110 if (upstreamWidget instanceof Window) { 111 final Window window = (Window) upstreamWidget; 112 window.addMouseListener(gearsMouse); 113 window.addKeyListener(gearsKeys); 114 } else if (GLProfile.isAWTAvailable() && upstreamWidget instanceof java.awt.Component) { 115 final java.awt.Component comp = (java.awt.Component) upstreamWidget; 116 new AWTMouseAdapter(gearsMouse, drawable).addTo(comp); 117 new AWTKeyAdapter(gearsKeys, drawable).addTo(comp); 118 } 119 } else { 120 drawable.setGLEventListenerInitState(this, false); 121 } 122 } 123 124 boolean enableCullFace = false; 125 enableStates(final GL gl, final boolean enable)126 private void enableStates(final GL gl, final boolean enable) { 127 final boolean msaa = gl.getContext().getGLDrawable().getChosenGLCapabilities().getSampleBuffers(); 128 if( enable ) { 129 if( enableCullFace ) { 130 gl.glEnable(GL.GL_CULL_FACE); 131 } 132 gl.glEnable(GLLightingFunc.GL_LIGHTING); 133 gl.glEnable(GLLightingFunc.GL_LIGHT0); 134 gl.glEnable(GL.GL_DEPTH_TEST); 135 gl.glDepthFunc(GL.GL_LESS); // default 136 gl.glEnable(GLLightingFunc.GL_NORMALIZE); 137 if( msaa ) { 138 gl.glEnable(GL.GL_MULTISAMPLE); 139 } 140 } else { 141 if( enableCullFace ) { 142 gl.glDisable(GL.GL_CULL_FACE); 143 } 144 gl.glDisable(GLLightingFunc.GL_LIGHTING); 145 gl.glDisable(GLLightingFunc.GL_LIGHT0); 146 gl.glDisable(GL.GL_DEPTH_TEST); 147 gl.glDisable(GLLightingFunc.GL_NORMALIZE); 148 if( msaa ) { 149 gl.glDisable(GL.GL_MULTISAMPLE); 150 } 151 } 152 } 153 init(final GL2 gl)154 public boolean init(final GL2 gl) { 155 if(null != sharedGears && !sharedGears.isInit() ) { 156 System.err.println(Thread.currentThread()+" GearsES1.init.0: pending shared Gears .. re-init later XXXXX"); 157 return false; 158 } 159 final float lightPos[] = { 5.0f, 5.0f, 10.0f, 0.0f }; 160 final float red[] = { 0.8f, 0.1f, 0.0f, 0.7f }; 161 final float green[] = { 0.0f, 0.8f, 0.2f, 0.7f }; 162 final float blue[] = { 0.2f, 0.2f, 1.0f, 0.7f }; 163 164 System.err.println(Thread.currentThread()+" Gears.init: tileRendererInUse "+tileRendererInUse); 165 if(verbose) { 166 System.err.println("GearsES2 init on "+Thread.currentThread()); 167 System.err.println("Chosen GLCapabilities: " + gl.getContext().getGLDrawable().getChosenGLCapabilities()); 168 System.err.println("INIT GL IS: " + gl.getClass().getName()); 169 System.err.println(JoglVersion.getGLStrings(gl, null, false).toString()); 170 } 171 172 gl.glLightfv(GLLightingFunc.GL_LIGHT0, GLLightingFunc.GL_POSITION, lightPos, 0); 173 if( ! ( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ) ) { 174 // Only possible if we do not flip the projection matrix 175 enableCullFace = true; 176 } else { 177 enableCullFace = false; 178 } 179 enableStates(gl, true); 180 181 /* make the gears */ 182 if( null != sharedGears ) { 183 gear1 = sharedGears.getGear1(); 184 gear2 = sharedGears.getGear2(); 185 gear3 = sharedGears.getGear3(); 186 System.err.println("gear1 list reused: "+gear1); 187 System.err.println("gear2 list reused: "+gear2); 188 System.err.println("gear3 list reused: "+gear3); 189 if( gl.getContext().hasRendererQuirk(GLRendererQuirks.NeedSharedObjectSync) ) { 190 syncObjects = sharedGears; 191 System.err.println("Shared Gears: Synchronized Objects due to quirk "+GLRendererQuirks.toString(GLRendererQuirks.NeedSharedObjectSync)); 192 } else { 193 syncObjects = new Object(); 194 System.err.println("Shared Gears: Unsynchronized Objects"); 195 } 196 } else { 197 gear1 = gl.glGenLists(1); 198 gl.glNewList(gear1, GL2.GL_COMPILE); 199 gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT_AND_DIFFUSE, red, 0); 200 gear(gl, 1.0f, 4.0f, 1.0f, 20, 0.7f); 201 gl.glEndList(); 202 System.err.println("gear1 list created: "+gear1); 203 204 gear2 = gl.glGenLists(1); 205 gl.glNewList(gear2, GL2.GL_COMPILE); 206 gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT_AND_DIFFUSE, green, 0); 207 gear(gl, 0.5f, 2.0f, 2.0f, 10, 0.7f); 208 gl.glEndList(); 209 System.err.println("gear2 list created: "+gear2); 210 211 gear3 = gl.glGenLists(1); 212 gl.glNewList(gear3, GL2.GL_COMPILE); 213 gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT_AND_DIFFUSE, blue, 0); 214 gear(gl, 1.3f, 2.0f, 0.5f, 10, 0.7f); 215 gl.glEndList(); 216 System.err.println("gear3 list created: "+gear3); 217 218 syncObjects = new Object(); 219 } 220 221 enableStates(gl, false); 222 223 isInit = true; 224 return true; 225 } 226 isInit()227 public final boolean isInit() { return isInit; } 228 229 @Override reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height)230 public void reshape(final GLAutoDrawable glad, final int x, final int y, final int width, final int height) { 231 if( !isInit ) { return; } 232 final GL2 gl = glad.getGL().getGL2(); 233 gl.setSwapInterval(swapInterval); 234 reshape(gl, x, y, width, height, width, height); 235 } 236 237 @Override reshapeTile(final TileRendererBase tr, final int tileX, final int tileY, final int tileWidth, final int tileHeight, final int imageWidth, final int imageHeight)238 public void reshapeTile(final TileRendererBase tr, 239 final int tileX, final int tileY, final int tileWidth, final int tileHeight, 240 final int imageWidth, final int imageHeight) { 241 if( !isInit ) { return; } 242 final GL2 gl = tr.getAttachedDrawable().getGL().getGL2(); 243 gl.setSwapInterval(0); 244 reshape(gl, tileX, tileY, tileWidth, tileHeight, imageWidth, imageHeight); 245 } 246 reshape(final GL2 gl, final int tileX, final int tileY, final int tileWidth, final int tileHeight, final int imageWidth, final int imageHeight)247 public void reshape(final GL2 gl, final int tileX, final int tileY, final int tileWidth, final int tileHeight, final int imageWidth, final int imageHeight) { 248 System.err.println(Thread.currentThread()+" Gears.reshape "+tileX+"/"+tileY+" "+tileWidth+"x"+tileHeight+" of "+imageWidth+"x"+imageHeight+", swapInterval "+swapInterval+", drawable 0x"+Long.toHexString(gl.getContext().getGLDrawable().getHandle())+", tileRendererInUse "+tileRendererInUse); 249 250 // compute projection parameters 'normal' 251 float left, right, bottom, top; 252 if( imageHeight > imageWidth ) { 253 final float a = (float)imageHeight / (float)imageWidth; 254 left = -1.0f; 255 right = 1.0f; 256 bottom = -a; 257 top = a; 258 } else { 259 final float a = (float)imageWidth / (float)imageHeight; 260 left = -a; 261 right = a; 262 bottom = -1.0f; 263 top = 1.0f; 264 } 265 final float w = right - left; 266 final float h = top - bottom; 267 268 // compute projection parameters 'tiled' 269 final float l = left + tileX * w / imageWidth; 270 final float r = l + tileWidth * w / imageWidth; 271 272 final float b = bottom + tileY * h / imageHeight; 273 final float t = b + tileHeight * h / imageHeight; 274 275 final float _w = r - l; 276 final float _h = t - b; 277 if(verbose) { 278 System.err.println(">> Gears 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); 279 } 280 281 gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION); 282 gl.glLoadIdentity(); 283 if( flipVerticalInGLOrientation && gl.getContext().getGLDrawable().isGLOriented() ) { 284 gl.glScalef(1f, -1f, 1f); 285 } 286 gl.glFrustum(l, r, b, t, 5.0f, 60.0f); 287 288 gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); 289 gl.glLoadIdentity(); 290 gl.glTranslatef(0.0f, 0.0f, -40.0f); 291 } 292 293 @Override dispose(final GLAutoDrawable drawable)294 public void dispose(final GLAutoDrawable drawable) { 295 if( !isInit ) { return; } 296 isInit = false; 297 System.err.println(Thread.currentThread()+" Gears.dispose: tileRendererInUse "+tileRendererInUse); 298 try { 299 final Object upstreamWidget = drawable.getUpstreamWidget(); 300 if (upstreamWidget instanceof Window) { 301 final Window window = (Window) upstreamWidget; 302 window.removeMouseListener(gearsMouse); 303 window.removeKeyListener(gearsKeys); 304 } 305 } catch (final Exception e) { System.err.println("Caught: "); e.printStackTrace(); } 306 gear1 = 0; 307 gear2 = 0; 308 gear3 = 0; 309 sharedGears = null; 310 syncObjects = null; 311 } 312 313 @Override display(final GLAutoDrawable drawable)314 public void display(final GLAutoDrawable drawable) { 315 if( !isInit ) { return; } 316 317 // Get the GL corresponding to the drawable we are animating 318 final GL2 gl = drawable.getGL().getGL2(); 319 320 enableStates(gl, true); 321 322 if( null == tileRendererInUse ) { 323 gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 324 } else { 325 gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f); 326 } 327 328 // Special handling for the case where the GLJPanel is translucent 329 // and wants to be composited with other Java 2D content 330 if (GLProfile.isAWTAvailable() && 331 (drawable instanceof com.jogamp.opengl.awt.GLJPanel) && 332 !((com.jogamp.opengl.awt.GLJPanel) drawable).isOpaque() && 333 ((com.jogamp.opengl.awt.GLJPanel) drawable).shouldPreserveColorBufferIfTranslucent()) { 334 gl.glClear(GL.GL_DEPTH_BUFFER_BIT); 335 } else { 336 gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); 337 } 338 displayImpl(gl); 339 340 enableStates(gl, false); 341 } 342 display(final GL2 gl)343 public void display(final GL2 gl) { 344 if( !isInit ) { return; } 345 enableStates(gl, true); 346 347 if( null == tileRendererInUse ) { 348 gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 349 } else { 350 gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f); 351 } 352 gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); 353 displayImpl(gl); 354 355 enableStates(gl, false); 356 } 357 displayImpl(final GL2 gl)358 private void displayImpl(final GL2 gl) { 359 if( doRotate ) { 360 // Turn the gears' teeth 361 angle += 0.5f; 362 } 363 // Rotate the entire assembly of gears based on how the user 364 // dragged the mouse around 365 gl.glPushMatrix(); 366 gl.glRotatef(view_rotx, 1.0f, 0.0f, 0.0f); 367 gl.glRotatef(view_roty, 0.0f, 1.0f, 0.0f); 368 gl.glRotatef(view_rotz, 0.0f, 0.0f, 1.0f); 369 370 // Place the first gear and call its display list 371 synchronized ( syncObjects ) { 372 gl.glPushMatrix(); 373 gl.glTranslatef(-3.0f, -2.0f, 0.0f); 374 gl.glRotatef(angle, 0.0f, 0.0f, 1.0f); 375 gl.glCallList(gear1); 376 gl.glPopMatrix(); 377 378 // Place the second gear and call its display list 379 gl.glPushMatrix(); 380 gl.glTranslatef(3.1f, -2.0f, 0.0f); 381 gl.glRotatef(-2.0f * angle - 9.0f, 0.0f, 0.0f, 1.0f); 382 gl.glCallList(gear2); 383 gl.glPopMatrix(); 384 385 // Place the third gear and call its display list 386 gl.glPushMatrix(); 387 gl.glTranslatef(-3.1f, 4.2f, 0.0f); 388 gl.glRotatef(-2.0f * angle - 25.0f, 0.0f, 0.0f, 1.0f); 389 gl.glCallList(gear3); 390 gl.glPopMatrix(); 391 } 392 393 // Remember that every push needs a pop; this one is paired with 394 // rotating the entire gear assembly 395 gl.glPopMatrix(); 396 } 397 gear(final GL2 gl, final float inner_radius, final float outer_radius, final float width, final int teeth, final float tooth_depth)398 public static void gear(final GL2 gl, 399 final float inner_radius, 400 final float outer_radius, 401 final float width, 402 final int teeth, 403 final float tooth_depth) 404 { 405 int i; 406 float r0, r1, r2; 407 float angle, da; 408 float u, v, len; 409 410 r0 = inner_radius; 411 r1 = outer_radius - tooth_depth / 2.0f; 412 r2 = outer_radius + tooth_depth / 2.0f; 413 414 da = 2.0f * (float) Math.PI / teeth / 4.0f; 415 416 gl.glShadeModel(GLLightingFunc.GL_FLAT); 417 418 gl.glNormal3f(0.0f, 0.0f, 1.0f); 419 420 /* draw front face */ 421 gl.glBegin(GL2.GL_QUAD_STRIP); 422 for (i = 0; i <= teeth; i++) 423 { 424 angle = i * 2.0f * (float) Math.PI / teeth; 425 gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); 426 gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); 427 if(i < teeth) 428 { 429 gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); 430 gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); 431 } 432 } 433 gl.glEnd(); 434 435 /* draw front sides of teeth */ 436 gl.glBegin(GL2GL3.GL_QUADS); 437 for (i = 0; i < teeth; i++) 438 { 439 angle = i * 2.0f * (float) Math.PI / teeth; 440 gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); 441 gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); 442 gl.glVertex3f(r2 * (float)Math.cos(angle + 2.0f * da), r2 * (float)Math.sin(angle + 2.0f * da), width * 0.5f); 443 gl.glVertex3f(r1 * (float)Math.cos(angle + 3.0f * da), r1 * (float)Math.sin(angle + 3.0f * da), width * 0.5f); 444 } 445 gl.glEnd(); 446 447 /* draw back face */ 448 gl.glBegin(GL2.GL_QUAD_STRIP); 449 for (i = 0; i <= teeth; i++) 450 { 451 angle = i * 2.0f * (float) Math.PI / teeth; 452 gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); 453 gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); 454 gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); 455 gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); 456 } 457 gl.glEnd(); 458 459 /* draw back sides of teeth */ 460 gl.glBegin(GL2GL3.GL_QUADS); 461 for (i = 0; i < teeth; i++) 462 { 463 angle = i * 2.0f * (float) Math.PI / teeth; 464 gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); 465 gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); 466 gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); 467 gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); 468 } 469 gl.glEnd(); 470 471 /* draw outward faces of teeth */ 472 gl.glBegin(GL2.GL_QUAD_STRIP); 473 for (i = 0; i < teeth; i++) 474 { 475 angle = i * 2.0f * (float) Math.PI / teeth; 476 gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), width * 0.5f); 477 gl.glVertex3f(r1 * (float)Math.cos(angle), r1 * (float)Math.sin(angle), -width * 0.5f); 478 u = r2 * (float)Math.cos(angle + da) - r1 * (float)Math.cos(angle); 479 v = r2 * (float)Math.sin(angle + da) - r1 * (float)Math.sin(angle); 480 len = (float)Math.sqrt(u * u + v * v); 481 u /= len; 482 v /= len; 483 gl.glNormal3f(v, -u, 0.0f); 484 gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), width * 0.5f); 485 gl.glVertex3f(r2 * (float)Math.cos(angle + da), r2 * (float)Math.sin(angle + da), -width * 0.5f); 486 gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); 487 gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), width * 0.5f); 488 gl.glVertex3f(r2 * (float)Math.cos(angle + 2 * da), r2 * (float)Math.sin(angle + 2 * da), -width * 0.5f); 489 u = r1 * (float)Math.cos(angle + 3 * da) - r2 * (float)Math.cos(angle + 2 * da); 490 v = r1 * (float)Math.sin(angle + 3 * da) - r2 * (float)Math.sin(angle + 2 * da); 491 gl.glNormal3f(v, -u, 0.0f); 492 gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), width * 0.5f); 493 gl.glVertex3f(r1 * (float)Math.cos(angle + 3 * da), r1 * (float)Math.sin(angle + 3 * da), -width * 0.5f); 494 gl.glNormal3f((float)Math.cos(angle), (float)Math.sin(angle), 0.0f); 495 } 496 gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), width * 0.5f); 497 gl.glVertex3f(r1 * (float)Math.cos(0), r1 * (float)Math.sin(0), -width * 0.5f); 498 gl.glEnd(); 499 500 gl.glShadeModel(GLLightingFunc.GL_SMOOTH); // default 501 502 /* draw inside radius cylinder */ 503 gl.glBegin(GL2.GL_QUAD_STRIP); 504 for (i = 0; i <= teeth; i++) 505 { 506 angle = i * 2.0f * (float) Math.PI / teeth; 507 gl.glNormal3f(-(float)Math.cos(angle), -(float)Math.sin(angle), 0.0f); 508 gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), -width * 0.5f); 509 gl.glVertex3f(r0 * (float)Math.cos(angle), r0 * (float)Math.sin(angle), width * 0.5f); 510 } 511 gl.glEnd(); 512 } 513 514 class GearsKeyAdapter extends KeyAdapter { keyPressed(final KeyEvent e)515 public void keyPressed(final KeyEvent e) { 516 final int kc = e.getKeyCode(); 517 if(KeyEvent.VK_LEFT == kc) { 518 view_roty -= 1; 519 } else if(KeyEvent.VK_RIGHT == kc) { 520 view_roty += 1; 521 } else if(KeyEvent.VK_UP == kc) { 522 view_rotx -= 1; 523 } else if(KeyEvent.VK_DOWN == kc) { 524 view_rotx += 1; 525 } 526 } 527 } 528 529 class GearsMouseAdapter extends MouseAdapter { mousePressed(final MouseEvent e)530 public void mousePressed(final MouseEvent e) { 531 prevMouseX = e.getX(); 532 prevMouseY = e.getY(); 533 if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { 534 // mouseRButtonDown = true; 535 } 536 } 537 mouseReleased(final MouseEvent e)538 public void mouseReleased(final MouseEvent e) { 539 if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { 540 // mouseRButtonDown = false; 541 } 542 } 543 mouseDragged(final MouseEvent e)544 public void mouseDragged(final MouseEvent e) { 545 final int x = e.getX(); 546 final int y = e.getY(); 547 int width=0, height=0; 548 final Object source = e.getSource(); 549 if(source instanceof Window) { 550 final Window window = (Window) source; 551 width=window.getSurfaceWidth(); 552 height=window.getSurfaceHeight(); 553 } else if (source instanceof GLAutoDrawable) { 554 final GLAutoDrawable glad = (GLAutoDrawable) source; 555 width = glad.getSurfaceWidth(); 556 height = glad.getSurfaceHeight(); 557 } else if (GLProfile.isAWTAvailable() && source instanceof java.awt.Component) { 558 final java.awt.Component comp = (java.awt.Component) source; 559 width=comp.getWidth(); // FIXME HiDPI: May need to convert window units -> pixel units! 560 height=comp.getHeight(); 561 } else { 562 throw new RuntimeException("Event source neither Window nor Component: "+source); 563 } 564 final float thetaY = 360.0f * ( (float)(x-prevMouseX)/(float)width); 565 final float thetaX = 360.0f * ( (float)(prevMouseY-y)/(float)height); 566 567 prevMouseX = x; 568 prevMouseY = y; 569 570 view_rotx += thetaX; 571 view_roty += thetaY; 572 } 573 } 574 } 575