JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
GLUT.java
Go to the documentation of this file.
1/*
2 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * - Redistribution of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistribution in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * Neither the name of Sun Microsystems, Inc. or the names of
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * This software is provided "AS IS," without a warranty of any kind. ALL
20 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
23 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
24 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
25 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
26 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
27 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
28 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
29 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
30 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31 *
32 * You acknowledge that this software is not designed or intended for use
33 * in the design, construction, operation or maintenance of any nuclear
34 * facility.
35 *
36 * Sun gratefully acknowledges that this software was originally authored
37 * and developed by Kenneth Bradley Russell and Christopher John Kline.
38 */
39
40package com.jogamp.opengl.util.gl2;
41
42import com.jogamp.opengl.*;
43import com.jogamp.opengl.fixedfunc.GLLightingFunc;
44import com.jogamp.opengl.glu.*;
45import com.jogamp.opengl.glu.gl2.*;
46
47/** Subset of the routines provided by the GLUT interface. Note the
48 signatures of many of the methods are necessarily different than
49 the corresponding C version. A GLUT object must only be used from
50 one particular thread at a time. <P>
51
52 Copyright (c) Mark J. Kilgard, 1994, 1997. <P>
53
54 (c) Copyright 1993, Silicon Graphics, Inc. <P>
55
56 ALL RIGHTS RESERVED <P>
57
58 Permission to use, copy, modify, and distribute this software
59 for any purpose and without fee is hereby granted, provided
60 that the above copyright notice appear in all copies and that
61 both the copyright notice and this permission notice appear in
62 supporting documentation, and that the name of Silicon
63 Graphics, Inc. not be used in advertising or publicity
64 pertaining to distribution of the software without specific,
65 written prior permission. <P>
66
67 THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
68 "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
69 OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
70 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
71 EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
72 ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
73 CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
74 INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
75 SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
76 NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
77 OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
78 ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
79 PERFORMANCE OF THIS SOFTWARE. <P>
80
81 US Government Users Restricted Rights <P>
82
83 Use, duplication, or disclosure by the Government is subject to
84 restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
85 (c)(1)(ii) of the Rights in Technical Data and Computer
86 Software clause at DFARS 252.227-7013 and/or in similar or
87 successor clauses in the FAR or the DOD or NASA FAR
88 Supplement. Unpublished-- rights reserved under the copyright
89 laws of the United States. Contractor/manufacturer is Silicon
90 Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
91 94039-7311. <P>
92
93 OpenGL(TM) is a trademark of Silicon Graphics, Inc. <P>
94*/
95
96public class GLUT {
97 public static final int STROKE_ROMAN = 0;
98 public static final int STROKE_MONO_ROMAN = 1;
99 public static final int BITMAP_9_BY_15 = 2;
100 public static final int BITMAP_8_BY_13 = 3;
101 public static final int BITMAP_TIMES_ROMAN_10 = 4;
102 public static final int BITMAP_TIMES_ROMAN_24 = 5;
103 public static final int BITMAP_HELVETICA_10 = 6;
104 public static final int BITMAP_HELVETICA_12 = 7;
105 public static final int BITMAP_HELVETICA_18 = 8;
106
107 private final GLUgl2 glu = new GLUgl2();
108
109 //----------------------------------------------------------------------
110 // Shapes
111 //
112
113 public void glutWireSphere(final double radius, final int slices, final int stacks) {
114 quadObjInit(glu);
115 glu.gluQuadricDrawStyle(quadObj, GLU.GLU_LINE);
116 glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
117 /* If we ever changed/used the texture or orientation state
118 of quadObj, we'd need to change it to the defaults here
119 with gluQuadricTexture and/or gluQuadricOrientation. */
120 glu.gluSphere(quadObj, radius, slices, stacks);
121 }
122
123 public void glutSolidSphere(final double radius, final int slices, final int stacks) {
124 quadObjInit(glu);
125 glu.gluQuadricDrawStyle(quadObj, GLU.GLU_FILL);
126 glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
127 /* If we ever changed/used the texture or orientation state
128 of quadObj, we'd need to change it to the defaults here
129 with gluQuadricTexture and/or gluQuadricOrientation. */
130 glu.gluSphere(quadObj, radius, slices, stacks);
131 }
132
133 public void glutWireCone(final double base, final double height,
134 final int slices, final int stacks) {
135 quadObjInit(glu);
136 glu.gluQuadricDrawStyle(quadObj, GLU.GLU_LINE);
137 glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
138 /* If we ever changed/used the texture or orientation state
139 of quadObj, we'd need to change it to the defaults here
140 with gluQuadricTexture and/or gluQuadricOrientation. */
141 glu.gluCylinder(quadObj, base, 0.0, height, slices, stacks);
142 }
143
144 public void glutSolidCone(final double base, final double height,
145 final int slices, final int stacks) {
146 quadObjInit(glu);
147 glu.gluQuadricDrawStyle(quadObj, GLU.GLU_FILL);
148 glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
149 /* If we ever changed/used the texture or orientation state
150 of quadObj, we'd need to change it to the defaults here
151 with gluQuadricTexture and/or gluQuadricOrientation. */
152 glu.gluCylinder(quadObj, base, 0.0, height, slices, stacks);
153 }
154
155 public void glutWireCylinder(final double radius, final double height, final int slices, final int stacks) {
156 quadObjInit(glu);
157 glu.gluQuadricDrawStyle(quadObj, GLU.GLU_LINE);
158 glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
159 /* If we ever changed/used the texture or orientation state
160 of quadObj, we'd need to change it to the defaults here
161 with gluQuadricTexture and/or gluQuadricOrientation. */
162 glu.gluCylinder(quadObj, radius, radius, height, slices, stacks);
163 }
164
165 public void glutSolidCylinder(final double radius, final double height, final int slices, final int stacks) {
166 final GL2 gl = GLUgl2.getCurrentGL2();
167
168 // Prepare table of points for drawing end caps
169 final double [] x = new double[slices];
170 final double [] y = new double[slices];
171 final double angleDelta = Math.PI * 2 / slices;
172 double angle = 0;
173 for (int i = 0 ; i < slices ; i ++) {
174 angle = i * angleDelta;
175 x[i] = Math.cos(angle) * radius;
176 y[i] = Math.sin(angle) * radius;
177 }
178
179 // Draw bottom cap
181 gl.glNormal3d(0,0,-1);
182 gl.glVertex3d(0,0,0);
183 for (int i = 0 ; i < slices ; i ++) {
184 gl.glVertex3d(x[i], y[i], 0);
185 }
186 gl.glVertex3d(x[0], y[0], 0);
187 gl.glEnd();
188
189 // Draw top cap
191 gl.glNormal3d(0,0,1);
192 gl.glVertex3d(0,0,height);
193 for (int i = 0 ; i < slices ; i ++) {
194 gl.glVertex3d(x[i], y[i], height);
195 }
196 gl.glVertex3d(x[0], y[0], height);
197 gl.glEnd();
198
199 // Draw walls
200 quadObjInit(glu);
201 glu.gluQuadricDrawStyle(quadObj, GLU.GLU_FILL);
202 glu.gluQuadricNormals(quadObj, GLU.GLU_SMOOTH);
203 /* If we ever changed/used the texture or orientation state
204 of quadObj, we'd need to change it to the defaults here
205 with gluQuadricTexture and/or gluQuadricOrientation. */
206 glu.gluCylinder(quadObj, radius, radius, height, slices, stacks);
207 }
208
209 public void glutWireCube(final float size) {
210 drawBox(GLUgl2.getCurrentGL2(), size, GL.GL_LINE_LOOP);
211 }
212
213 public void glutSolidCube(final float size) {
214 drawBox(GLUgl2.getCurrentGL2(), size, GL2GL3.GL_QUADS);
215 }
216
217 public void glutWireTorus(final double innerRadius, final double outerRadius,
218 final int nsides, final int rings) {
219 final GL2 gl = GLUgl2.getCurrentGL2();
222 doughnut(gl, innerRadius, outerRadius, nsides, rings);
223 gl.glPopAttrib();
224 }
225
226 public void glutSolidTorus(final double innerRadius, final double outerRadius,
227 final int nsides, final int rings) {
228 doughnut(GLUgl2.getCurrentGL2(), innerRadius, outerRadius, nsides, rings);
229 }
230
231 public void glutWireDodecahedron() {
232 dodecahedron(GLUgl2.getCurrentGL2(), GL.GL_LINE_LOOP);
233 }
234
235 public void glutSolidDodecahedron() {
236 dodecahedron(GLUgl2.getCurrentGL2(), GL.GL_TRIANGLE_FAN);
237 }
238
239 public void glutWireOctahedron() {
240 octahedron(GLUgl2.getCurrentGL2(), GL.GL_LINE_LOOP);
241 }
242
243 public void glutSolidOctahedron() {
244 octahedron(GLUgl2.getCurrentGL2(), GL.GL_TRIANGLES);
245 }
246
247 public void glutWireIcosahedron() {
248 icosahedron(GLUgl2.getCurrentGL2(), GL.GL_LINE_LOOP);
249 }
250
251 public void glutSolidIcosahedron() {
252 icosahedron(GLUgl2.getCurrentGL2(), GL.GL_TRIANGLES);
253 }
254
255 public void glutWireTetrahedron() {
256 tetrahedron(GLUgl2.getCurrentGL2(), GL.GL_LINE_LOOP);
257 }
258
259 public void glutSolidTetrahedron() {
260 tetrahedron(GLUgl2.getCurrentGL2(), GL.GL_TRIANGLES);
261 }
262
263/**
264 * Renders the teapot as a solid shape of the specified size. The teapot is
265 * created in a way that replicates the C GLUT implementation.
266 *
267 * @param scale
268 * the factor by which to scale the teapot
269 */
270 public void glutSolidTeapot(final double scale) {
271 glutSolidTeapot(scale, true);
272 }
273
274 /**
275 * Renders the teapot as a solid shape of the specified size. The teapot can
276 * either be created in a way that is backward-compatible with the standard
277 * C glut library (i.e. broken), or in a more pleasing way (i.e. with
278 * surfaces whose front-faces point outwards and standing on the z=0 plane,
279 * instead of the y=-1 plane). Both surface normals and texture coordinates
280 * for the teapot are generated. The teapot is generated with OpenGL
281 * evaluators.
282 *
283 * @param scale
284 * the factor by which to scale the teapot
285 * @param cStyle
286 * whether to create the teapot in exactly the same way as in the C
287 * implementation of GLUT
288 */
289 public void glutSolidTeapot(final double scale, final boolean cStyle) {
290 teapot(GLUgl2.getCurrentGL2(), 14, scale, GL2GL3.GL_FILL, cStyle);
291 }
292
293 /**
294 * Renders the teapot as a wireframe shape of the specified size. The teapot
295 * is created in a way that replicates the C GLUT implementation.
296 *
297 * @param scale
298 * the factor by which to scale the teapot
299 */
300 public void glutWireTeapot(final double scale) {
301 glutWireTeapot(scale, true);
302 }
303
304 /**
305 * Renders the teapot as a wireframe shape of the specified size. The teapot
306 * can either be created in a way that is backward-compatible with the
307 * standard C glut library (i.e. broken), or in a more pleasing way (i.e.
308 * with surfaces whose front-faces point outwards and standing on the z=0
309 * plane, instead of the y=-1 plane). Both surface normals and texture
310 * coordinates for the teapot are generated. The teapot is generated with
311 * OpenGL evaluators.
312 *
313 * @param scale
314 * the factor by which to scale the teapot
315 * @param cStyle
316 * whether to create the teapot in exactly the same way as in the C
317 * implementation of GLUT
318 */
319 public void glutWireTeapot(final double scale, final boolean cStyle) {
320 teapot(GLUgl2.getCurrentGL2(), 10, scale, GL2GL3.GL_LINE, cStyle);
321 }
322
323 //----------------------------------------------------------------------
324 // Fonts
325 //
326
327 public void glutBitmapCharacter(final int font, final char character) {
328 final GL2 gl = GLUgl2.getCurrentGL2();
329 final int[] swapbytes = new int[1];
330 final int[] lsbfirst = new int[1];
331 final int[] rowlength = new int[1];
332 final int[] skiprows = new int[1];
333 final int[] skippixels = new int[1];
334 final int[] alignment = new int[1];
335 beginBitmap(gl,
336 swapbytes,
337 lsbfirst,
338 rowlength,
339 skiprows,
340 skippixels,
341 alignment);
342 bitmapCharacterImpl(gl, font, character);
343 endBitmap(gl,
344 swapbytes,
345 lsbfirst,
346 rowlength,
347 skiprows,
348 skippixels,
349 alignment);
350 }
351
352 public void glutBitmapString (final int font, final String string) {
353 final GL2 gl = GLUgl2.getCurrentGL2();
354 final int[] swapbytes = new int[1];
355 final int[] lsbfirst = new int[1];
356 final int[] rowlength = new int[1];
357 final int[] skiprows = new int[1];
358 final int[] skippixels = new int[1];
359 final int[] alignment = new int[1];
360 beginBitmap(gl,
361 swapbytes,
362 lsbfirst,
363 rowlength,
364 skiprows,
365 skippixels,
366 alignment);
367 final int len = string.length();
368 for (int i = 0; i < len; i++) {
369 bitmapCharacterImpl(gl, font, string.charAt(i));
370 }
371 endBitmap(gl,
372 swapbytes,
373 lsbfirst,
374 rowlength,
375 skiprows,
376 skippixels,
377 alignment);
378 }
379
380 public int glutBitmapWidth (final int font, final char character) {
381 final BitmapFontRec fontinfo = getBitmapFont(font);
382 final int c = character & 0xFFFF;
383 if (c < fontinfo.first || c >= fontinfo.first + fontinfo.num_chars)
384 return 0;
385 final BitmapCharRec ch = fontinfo.ch[c - fontinfo.first];
386 if (ch != null)
387 return (int) ch.advance;
388 else
389 return 0;
390 }
391
392 public void glutStrokeCharacter(final int font, final char character) {
393 final GL2 gl = GLUgl2.getCurrentGL2();
394 final StrokeFontRec fontinfo = getStrokeFont(font);
395 final int c = character & 0xFFFF;
396 if (c < 0 || c >= fontinfo.num_chars)
397 return;
398 final StrokeCharRec ch = fontinfo.ch[c];
399 if (ch != null) {
400 for (int i = 0; i < ch.num_strokes; i++) {
401 final StrokeRec stroke = ch.stroke[i];
403 for (int j = 0; j < stroke.num_coords; j++) {
404 final CoordRec coord = stroke.coord[j];
405 gl.glVertex2f(coord.x, coord.y);
406 }
407 gl.glEnd();
408 }
409 gl.glTranslatef(ch.right, 0.0f, 0.0f);
410 }
411 }
412
413 public void glutStrokeString(final int font, final String string) {
414 final GL2 gl = GLUgl2.getCurrentGL2();
415 final StrokeFontRec fontinfo = getStrokeFont(font);
416 final int len = string.length();
417 for (int pos = 0; pos < len; pos++) {
418 final int c = string.charAt(pos) & 0xFFFF;
419 if (c < 0 || c >= fontinfo.num_chars)
420 continue;
421 final StrokeCharRec ch = fontinfo.ch[c];
422 if (ch != null) {
423 for (int i = 0; i < ch.num_strokes; i++) {
424 final StrokeRec stroke = ch.stroke[i];
426 for (int j = 0; j < stroke.num_coords; j++) {
427 final CoordRec coord = stroke.coord[j];
428 gl.glVertex2f(coord.x, coord.y);
429 }
430 gl.glEnd();
431 }
432 gl.glTranslatef(ch.right, 0.0f, 0.0f);
433 }
434 }
435 }
436
437 public int glutStrokeWidth (final int font, final char character) {
438 return (int) glutStrokeWidthf(font, character);
439 }
440
441 public float glutStrokeWidthf (final int font, final char character) {
442 final StrokeFontRec fontinfo = getStrokeFont(font);
443 final int c = character & 0xFFFF;
444 if (c < 0 || c >= fontinfo.num_chars)
445 return 0;
446 final StrokeCharRec ch = fontinfo.ch[c];
447 if (ch != null)
448 return ch.right;
449 else
450 return 0;
451 }
452
453 public int glutBitmapLength (final int font, final String string) {
454 final BitmapFontRec fontinfo = getBitmapFont(font);
455 int length = 0;
456 final int len = string.length();
457 for (int pos = 0; pos < len; pos++) {
458 final int c = string.charAt(pos) & 0xFFFF;
459 if (c >= fontinfo.first && c < fontinfo.first + fontinfo.num_chars) {
460 final BitmapCharRec ch = fontinfo.ch[c - fontinfo.first];
461 if (ch != null)
462 length += ch.advance;
463 }
464 }
465 return length;
466 }
467
468 public int glutStrokeLength (final int font, final String string) {
469 return (int) glutStrokeLengthf(font, string);
470 }
471
472 public float glutStrokeLengthf (final int font, final String string) {
473 final StrokeFontRec fontinfo = getStrokeFont(font);
474 float length = 0;
475 final int len = string.length();
476 for (int i = 0; i < len; i++) {
477 final char c = string.charAt(i);
478 if (c >= 0 && c < fontinfo.num_chars) {
479 final StrokeCharRec ch = fontinfo.ch[c];
480 if (ch != null)
481 length += ch.right;
482 }
483 }
484 return length;
485 }
486
487 /**
488 This function draws a wireframe dodecahedron whose
489 facets are rhombic and
490 whose vertices are at unit radius.
491 No facet lies normal to any coordinate axes.
492 The polyhedron is centered at the origin.
493 */
495 final GL2 gl = GLUgl2.getCurrentGL2();
496 for( int i = 0; i < 12; i++ ) {
497 gl.glBegin( GL.GL_LINE_LOOP );
498 gl.glNormal3dv( rdod_n[ i ],0 );
499 gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 0 ] ],0 );
500 gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 1 ] ],0 );
501 gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 2 ] ],0 );
502 gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 3 ] ],0 );
503 gl.glEnd( );
504 }
505 }
506
507 /**
508 This function draws a solid-shaded dodecahedron
509 whose facets are rhombic and
510 whose vertices are at unit radius.
511 No facet lies normal to any coordinate axes.
512 The polyhedron is centered at the origin.
513 */
515 final GL2 gl = GLUgl2.getCurrentGL2();
516 gl.glBegin( GL2GL3.GL_QUADS );
517 for( int i = 0; i < 12; i++ ) {
518 gl.glNormal3dv( rdod_n[ i ],0 );
519 gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 0 ] ],0 );
520 gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 1 ] ],0 );
521 gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 2 ] ],0 );
522 gl.glVertex3dv( rdod_r[ rdod_v[ i ][ 3 ] ],0 );
523 }
524 gl.glEnd( );
525 }
526
527 //----------------------------------------------------------------------
528 // Internals only below this point
529 //
530
531 //----------------------------------------------------------------------
532 // Shape implementation
533 //
534
535 private GLUquadric quadObj;
536 private void quadObjInit(final GLUgl2 glu) {
537 if (quadObj == null) {
538 quadObj = glu.gluNewQuadric();
539 }
540 if (quadObj == null) {
541 throw new GLException("Out of memory");
542 }
543 }
544
545 private static void doughnut(final GL2 gl, final double r, final double R, final int nsides, final int rings) {
546 int i, j;
547 float theta, phi, theta1;
548 float cosTheta, sinTheta;
549 float cosTheta1, sinTheta1;
550 float ringDelta, sideDelta;
551
552 ringDelta = (float) (2.0 * Math.PI / rings);
553 sideDelta = (float) (2.0 * Math.PI / nsides);
554
555 theta = 0.0f;
556 cosTheta = 1.0f;
557 sinTheta = 0.0f;
558 for (i = rings - 1; i >= 0; i--) {
559 theta1 = theta + ringDelta;
560 cosTheta1 = (float) Math.cos(theta1);
561 sinTheta1 = (float) Math.sin(theta1);
563 phi = 0.0f;
564 for (j = nsides; j >= 0; j--) {
565 float cosPhi, sinPhi, dist;
566
567 phi += sideDelta;
568 cosPhi = (float) Math.cos(phi);
569 sinPhi = (float) Math.sin(phi);
570 dist = (float) (R + r * cosPhi);
571
572 gl.glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
573 gl.glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, (float) r * sinPhi);
574 gl.glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
575 gl.glVertex3f(cosTheta * dist, -sinTheta * dist, (float) r * sinPhi);
576 }
577 gl.glEnd();
578 theta = theta1;
579 cosTheta = cosTheta1;
580 sinTheta = sinTheta1;
581 }
582 }
583
584 private static float[][] boxVertices;
585 private static final float[][] boxNormals = {
586 {-1.0f, 0.0f, 0.0f},
587 {0.0f, 1.0f, 0.0f},
588 {1.0f, 0.0f, 0.0f},
589 {0.0f, -1.0f, 0.0f},
590 {0.0f, 0.0f, 1.0f},
591 {0.0f, 0.0f, -1.0f}
592 };
593 private static final int[][] boxFaces = {
594 {0, 1, 2, 3},
595 {3, 2, 6, 7},
596 {7, 6, 5, 4},
597 {4, 5, 1, 0},
598 {5, 6, 2, 1},
599 {7, 4, 0, 3}
600 };
601 private void drawBox(final GL2 gl, final float size, final int type) {
602 if (boxVertices == null) {
603 final float[][] v = new float[8][];
604 for (int i = 0; i < 8; i++) {
605 v[i] = new float[3];
606 }
607 v[0][0] = v[1][0] = v[2][0] = v[3][0] = -0.5f;
608 v[4][0] = v[5][0] = v[6][0] = v[7][0] = 0.5f;
609 v[0][1] = v[1][1] = v[4][1] = v[5][1] = -0.5f;
610 v[2][1] = v[3][1] = v[6][1] = v[7][1] = 0.5f;
611 v[0][2] = v[3][2] = v[4][2] = v[7][2] = -0.5f;
612 v[1][2] = v[2][2] = v[5][2] = v[6][2] = 0.5f;
613 boxVertices = v;
614 }
615 final float[][] v = boxVertices;
616 final float[][] n = boxNormals;
617 final int[][] faces = boxFaces;
618 for (int i = 5; i >= 0; i--) {
619 gl.glBegin(type);
620 gl.glNormal3fv(n[i], 0);
621 float[] vt = v[faces[i][0]];
622 gl.glVertex3f(vt[0] * size, vt[1] * size, vt[2] * size);
623 vt = v[faces[i][1]];
624 gl.glVertex3f(vt[0] * size, vt[1] * size, vt[2] * size);
625 vt = v[faces[i][2]];
626 gl.glVertex3f(vt[0] * size, vt[1] * size, vt[2] * size);
627 vt = v[faces[i][3]];
628 gl.glVertex3f(vt[0] * size, vt[1] * size, vt[2] * size);
629 gl.glEnd();
630 }
631 }
632
633 private float[][] dodec;
634
635 private void initDodecahedron() {
636 dodec = new float[20][];
637 for (int i = 0; i < dodec.length; i++) {
638 dodec[i] = new float[3];
639 }
640
641 float alpha, beta;
642
643 alpha = (float) Math.sqrt(2.0f / (3.0f + Math.sqrt(5.0)));
644 beta = 1.0f + (float) Math.sqrt(6.0 / (3.0 + Math.sqrt(5.0)) -
645 2.0 + 2.0 * Math.sqrt(2.0 / (3.0 + Math.sqrt(5.0))));
646 dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
647 dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
648 dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
649 dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
650 dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
651 dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
652 dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
653 dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
654 dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
655 dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
656 dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
657 dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
658 dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
659 dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
660 dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
661 dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
662 dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
663 dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
664 dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
665 dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
666 }
667
668 private static void diff3(final float[] a, final float[] b, final float[] c) {
669 c[0] = a[0] - b[0];
670 c[1] = a[1] - b[1];
671 c[2] = a[2] - b[2];
672 }
673
674 private static void crossprod(final float[] v1, final float[] v2, final float[] prod) {
675 final float[] p = new float[3]; /* in case prod == v1 or v2 */
676
677 p[0] = v1[1] * v2[2] - v2[1] * v1[2];
678 p[1] = v1[2] * v2[0] - v2[2] * v1[0];
679 p[2] = v1[0] * v2[1] - v2[0] * v1[1];
680 prod[0] = p[0];
681 prod[1] = p[1];
682 prod[2] = p[2];
683 }
684
685 private static void normalize(final float[] v) {
686 float d;
687
688 d = (float) Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
689 if (d == 0.0) {
690 v[0] = d = 1.0f;
691 }
692 d = 1 / d;
693 v[0] *= d;
694 v[1] *= d;
695 v[2] *= d;
696 }
697
698 private void pentagon(final GL2 gl, final int a, final int b, final int c, final int d, final int e, final int shadeType) {
699 final float[] n0 = new float[3];
700 final float[] d1 = new float[3];
701 final float[] d2 = new float[3];
702
703 diff3(dodec[a], dodec[b], d1);
704 diff3(dodec[b], dodec[c], d2);
705 crossprod(d1, d2, n0);
706 normalize(n0);
707
708 gl.glBegin(shadeType);
709 gl.glNormal3fv(n0, 0);
710 gl.glVertex3fv(dodec[a], 0);
711 gl.glVertex3fv(dodec[b], 0);
712 gl.glVertex3fv(dodec[c], 0);
713 gl.glVertex3fv(dodec[d], 0);
714 gl.glVertex3fv(dodec[e], 0);
715 gl.glEnd();
716 }
717
718 private void dodecahedron(final GL2 gl, final int type) {
719 if (dodec == null) {
720 initDodecahedron();
721 }
722 pentagon(gl, 0, 1, 9, 16, 5, type);
723 pentagon(gl, 1, 0, 3, 18, 7, type);
724 pentagon(gl, 1, 7, 11, 10, 9, type);
725 pentagon(gl, 11, 7, 18, 19, 6, type);
726 pentagon(gl, 8, 17, 16, 9, 10, type);
727 pentagon(gl, 2, 14, 15, 6, 19, type);
728 pentagon(gl, 2, 13, 12, 4, 14, type);
729 pentagon(gl, 2, 19, 18, 3, 13, type);
730 pentagon(gl, 3, 0, 5, 12, 13, type);
731 pentagon(gl, 6, 15, 8, 10, 11, type);
732 pentagon(gl, 4, 17, 8, 15, 14, type);
733 pentagon(gl, 4, 12, 5, 16, 17, type);
734 }
735
736 private static void recorditem(final GL2 gl, final float[] n1, final float[] n2, final float[] n3, final int shadeType) {
737 final float[] q0 = new float[3];
738 final float[] q1 = new float[3];
739
740 diff3(n1, n2, q0);
741 diff3(n2, n3, q1);
742 crossprod(q0, q1, q1);
743 normalize(q1);
744
745 gl.glBegin(shadeType);
746 gl.glNormal3fv(q1, 0);
747 gl.glVertex3fv(n1, 0);
748 gl.glVertex3fv(n2, 0);
749 gl.glVertex3fv(n3, 0);
750 gl.glEnd();
751 }
752
753 private static void subdivide(final GL2 gl, final float[] v0, final float[] v1, final float[] v2, final int shadeType) {
754 int depth;
755 final float[] w0 = new float[3];
756 final float[] w1 = new float[3];
757 final float[] w2 = new float[3];
758 float l;
759 int i, j, k, n;
760
761 depth = 1;
762 for (i = 0; i < depth; i++) {
763 for (j = 0; i + j < depth; j++) {
764 k = depth - i - j;
765 for (n = 0; n < 3; n++) {
766 w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
767 w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
768 / depth;
769 w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
770 / depth;
771 }
772 l = (float) Math.sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
773 w0[0] /= l;
774 w0[1] /= l;
775 w0[2] /= l;
776 l = (float) Math.sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
777 w1[0] /= l;
778 w1[1] /= l;
779 w1[2] /= l;
780 l = (float) Math.sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
781 w2[0] /= l;
782 w2[1] /= l;
783 w2[2] /= l;
784 recorditem(gl, w1, w0, w2, shadeType);
785 }
786 }
787 }
788
789 private static void drawtriangle(final GL2 gl, final int i, final float[][] data, final int[][] ndx, final int shadeType) {
790 final float[] x0 = data[ndx[i][0]];
791 final float[] x1 = data[ndx[i][1]];
792 final float[] x2 = data[ndx[i][2]];
793 subdivide(gl, x0, x1, x2, shadeType);
794 }
795
796 /* octahedron data: The octahedron produced is centered at the
797 origin and has radius 1.0 */
798 private static final float[][] odata =
799 {
800 {1.0f, 0.0f, 0.0f},
801 {-1.0f, 0.0f, 0.0f},
802 {0.0f, 1.0f, 0.0f},
803 {0.0f, -1.0f, 0.0f},
804 {0.0f, 0.0f, 1.0f},
805 {0.0f, 0.0f, -1.0f}
806 };
807
808 private static final int[][] ondex =
809 {
810 {0, 4, 2},
811 {1, 2, 4},
812 {0, 3, 4},
813 {1, 4, 3},
814 {0, 2, 5},
815 {1, 5, 2},
816 {0, 5, 3},
817 {1, 3, 5}
818 };
819
820 private static void octahedron(final GL2 gl, final int shadeType) {
821 int i;
822
823 for (i = 7; i >= 0; i--) {
824 drawtriangle(gl, i, odata, ondex, shadeType);
825 }
826 }
827
828 /* icosahedron data: These numbers are rigged to make an
829 icosahedron of radius 1.0 */
830
831 private static final float X = .525731112119133606f;
832 private static final float Z = .850650808352039932f;
833
834 private static final float[][] idata =
835 {
836 {-X, 0, Z},
837 {X, 0, Z},
838 {-X, 0, -Z},
839 {X, 0, -Z},
840 {0, Z, X},
841 {0, Z, -X},
842 {0, -Z, X},
843 {0, -Z, -X},
844 {Z, X, 0},
845 {-Z, X, 0},
846 {Z, -X, 0},
847 {-Z, -X, 0}
848 };
849
850 private static final int[][] index =
851 {
852 {0, 4, 1},
853 {0, 9, 4},
854 {9, 5, 4},
855 {4, 5, 8},
856 {4, 8, 1},
857 {8, 10, 1},
858 {8, 3, 10},
859 {5, 3, 8},
860 {5, 2, 3},
861 {2, 7, 3},
862 {7, 10, 3},
863 {7, 6, 10},
864 {7, 11, 6},
865 {11, 0, 6},
866 {0, 1, 6},
867 {6, 1, 10},
868 {9, 0, 11},
869 {9, 11, 2},
870 {9, 2, 5},
871 {7, 2, 11},
872 };
873
874 private static void icosahedron(final GL2 gl, final int shadeType) {
875 int i;
876
877 for (i = 19; i >= 0; i--) {
878 drawtriangle(gl, i, idata, index, shadeType);
879 }
880 }
881
882 /* rhombic dodecahedron data: */
883
884 private static final double rdod_r[][] =
885 {
886 { 0.0, 0.0, 1.0 },
887 { 0.707106781187, 0.000000000000, 0.5 },
888 { 0.000000000000, 0.707106781187, 0.5 },
889 { -0.707106781187, 0.000000000000, 0.5 },
890 { 0.000000000000, -0.707106781187, 0.5 },
891 { 0.707106781187, 0.707106781187, 0.0 },
892 { -0.707106781187, 0.707106781187, 0.0 },
893 { -0.707106781187, -0.707106781187, 0.0 },
894 { 0.707106781187, -0.707106781187, 0.0 },
895 { 0.707106781187, 0.000000000000, -0.5 },
896 { 0.000000000000, 0.707106781187, -0.5 },
897 { -0.707106781187, 0.000000000000, -0.5 },
898 { 0.000000000000, -0.707106781187, -0.5 },
899 { 0.0, 0.0, -1.0 }
900 };
901
902 private static final int rdod_v[][] =
903 {
904 { 0, 1, 5, 2 },
905 { 0, 2, 6, 3 },
906 { 0, 3, 7, 4 },
907 { 0, 4, 8, 1 },
908 { 5, 10, 6, 2 },
909 { 6, 11, 7, 3 },
910 { 7, 12, 8, 4 },
911 { 8, 9, 5, 1 },
912 { 5, 9, 13, 10 },
913 { 6, 10, 13, 11 },
914 { 7, 11, 13, 12 },
915 { 8, 12, 13, 9 }
916 };
917
918 private static final double rdod_n[][] =
919 {
920 { 0.353553390594, 0.353553390594, 0.5 },
921 { -0.353553390594, 0.353553390594, 0.5 },
922 { -0.353553390594, -0.353553390594, 0.5 },
923 { 0.353553390594, -0.353553390594, 0.5 },
924 { 0.000000000000, 1.000000000000, 0.0 },
925 { -1.000000000000, 0.000000000000, 0.0 },
926 { 0.000000000000, -1.000000000000, 0.0 },
927 { 1.000000000000, 0.000000000000, 0.0 },
928 { 0.353553390594, 0.353553390594, -0.5 },
929 { -0.353553390594, 0.353553390594, -0.5 },
930 { -0.353553390594, -0.353553390594, -0.5 },
931 { 0.353553390594, -0.353553390594, -0.5 }
932 };
933
934 /* tetrahedron data: */
935
936 private static final float T = 1.73205080756887729f;
937
938 private static final float[][] tdata =
939 {
940 {T, T, T},
941 {T, -T, -T},
942 {-T, T, -T},
943 {-T, -T, T}
944 };
945
946 private static final int[][] tndex =
947 {
948 {0, 1, 3},
949 {2, 1, 0},
950 {3, 2, 0},
951 {1, 2, 3}
952 };
953
954 private static final void tetrahedron(final GL2 gl, final int shadeType) {
955 for (int i = 3; i >= 0; i--)
956 drawtriangle(gl, i, tdata, tndex, shadeType);
957 }
958
959 // Teapot implementation (a modified port of glut_teapot.c)
960 //
961 // Rim, body, lid, and bottom data must be reflected in x and
962 // y; handle and spout data across the y axis only.
963 private static final int[][] teapotPatchData = {
964 /* rim */
965 {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
966 /* body */
967 {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27},
968 {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40},
969 /* lid */
970 {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3,},
971 {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117},
972 /* bottom */
973 {118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37},
974 /* handle */
975 {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56},
976 {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67},
977 /* spout */
978 {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83},
979 {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95}
980 };
981 private static final float[][] teapotCPData = {
982 {0.2f, 0f, 2.7f},
983 {0.2f, -0.112f, 2.7f},
984 {0.112f, -0.2f, 2.7f},
985 {0f, -0.2f, 2.7f},
986 {1.3375f, 0f, 2.53125f},
987 {1.3375f, -0.749f, 2.53125f},
988 {0.749f, -1.3375f, 2.53125f},
989 {0f, -1.3375f, 2.53125f},
990 {1.4375f, 0f, 2.53125f},
991 {1.4375f, -0.805f, 2.53125f},
992 {0.805f, -1.4375f, 2.53125f},
993 {0f, -1.4375f, 2.53125f},
994 {1.5f, 0f, 2.4f},
995 {1.5f, -0.84f, 2.4f},
996 {0.84f, -1.5f, 2.4f},
997 {0f, -1.5f, 2.4f},
998 {1.75f, 0f, 1.875f},
999 {1.75f, -0.98f, 1.875f},
1000 {0.98f, -1.75f, 1.875f},
1001 {0f, -1.75f, 1.875f},
1002 {2f, 0f, 1.35f},
1003 {2f, -1.12f, 1.35f},
1004 {1.12f, -2f, 1.35f},
1005 {0f, -2f, 1.35f},
1006 {2f, 0f, 0.9f},
1007 {2f, -1.12f, 0.9f},
1008 {1.12f, -2f, 0.9f},
1009 {0f, -2f, 0.9f},
1010 {-2f, 0f, 0.9f},
1011 {2f, 0f, 0.45f},
1012 {2f, -1.12f, 0.45f},
1013 {1.12f, -2f, 0.45f},
1014 {0f, -2f, 0.45f},
1015 {1.5f, 0f, 0.225f},
1016 {1.5f, -0.84f, 0.225f},
1017 {0.84f, -1.5f, 0.225f},
1018 {0f, -1.5f, 0.225f},
1019 {1.5f, 0f, 0.15f},
1020 {1.5f, -0.84f, 0.15f},
1021 {0.84f, -1.5f, 0.15f},
1022 {0f, -1.5f, 0.15f},
1023 {-1.6f, 0f, 2.025f},
1024 {-1.6f, -0.3f, 2.025f},
1025 {-1.5f, -0.3f, 2.25f},
1026 {-1.5f, 0f, 2.25f},
1027 {-2.3f, 0f, 2.025f},
1028 {-2.3f, -0.3f, 2.025f},
1029 {-2.5f, -0.3f, 2.25f},
1030 {-2.5f, 0f, 2.25f},
1031 {-2.7f, 0f, 2.025f},
1032 {-2.7f, -0.3f, 2.025f},
1033 {-3f, -0.3f, 2.25f},
1034 {-3f, 0f, 2.25f},
1035 {-2.7f, 0f, 1.8f},
1036 {-2.7f, -0.3f, 1.8f},
1037 {-3f, -0.3f, 1.8f},
1038 {-3f, 0f, 1.8f},
1039 {-2.7f, 0f, 1.575f},
1040 {-2.7f, -0.3f, 1.575f},
1041 {-3f, -0.3f, 1.35f},
1042 {-3f, 0f, 1.35f},
1043 {-2.5f, 0f, 1.125f},
1044 {-2.5f, -0.3f, 1.125f},
1045 {-2.65f, -0.3f, 0.9375f},
1046 {-2.65f, 0f, 0.9375f},
1047 {-2f, -0.3f, 0.9f},
1048 {-1.9f, -0.3f, 0.6f},
1049 {-1.9f, 0f, 0.6f},
1050 {1.7f, 0f, 1.425f},
1051 {1.7f, -0.66f, 1.425f},
1052 {1.7f, -0.66f, 0.6f},
1053 {1.7f, 0f, 0.6f},
1054 {2.6f, 0f, 1.425f},
1055 {2.6f, -0.66f, 1.425f},
1056 {3.1f, -0.66f, 0.825f},
1057 {3.1f, 0f, 0.825f},
1058 {2.3f, 0f, 2.1f},
1059 {2.3f, -0.25f, 2.1f},
1060 {2.4f, -0.25f, 2.025f},
1061 {2.4f, 0f, 2.025f},
1062 {2.7f, 0f, 2.4f},
1063 {2.7f, -0.25f, 2.4f},
1064 {3.3f, -0.25f, 2.4f},
1065 {3.3f, 0f, 2.4f},
1066 {2.8f, 0f, 2.475f},
1067 {2.8f, -0.25f, 2.475f},
1068 {3.525f, -0.25f, 2.49375f},
1069 {3.525f, 0f, 2.49375f},
1070 {2.9f, 0f, 2.475f},
1071 {2.9f, -0.15f, 2.475f},
1072 {3.45f, -0.15f, 2.5125f},
1073 {3.45f, 0f, 2.5125f},
1074 {2.8f, 0f, 2.4f},
1075 {2.8f, -0.15f, 2.4f},
1076 {3.2f, -0.15f, 2.4f},
1077 {3.2f, 0f, 2.4f},
1078 {0f, 0f, 3.15f},
1079 {0.8f, 0f, 3.15f},
1080 {0.8f, -0.45f, 3.15f},
1081 {0.45f, -0.8f, 3.15f},
1082 {0f, -0.8f, 3.15f},
1083 {0f, 0f, 2.85f},
1084 {1.4f, 0f, 2.4f},
1085 {1.4f, -0.784f, 2.4f},
1086 {0.784f, -1.4f, 2.4f},
1087 {0f, -1.4f, 2.4f},
1088 {0.4f, 0f, 2.55f},
1089 {0.4f, -0.224f, 2.55f},
1090 {0.224f, -0.4f, 2.55f},
1091 {0f, -0.4f, 2.55f},
1092 {1.3f, 0f, 2.55f},
1093 {1.3f, -0.728f, 2.55f},
1094 {0.728f, -1.3f, 2.55f},
1095 {0f, -1.3f, 2.55f},
1096 {1.3f, 0f, 2.4f},
1097 {1.3f, -0.728f, 2.4f},
1098 {0.728f, -1.3f, 2.4f},
1099 {0f, -1.3f, 2.4f},
1100 {0f, 0f, 0f},
1101 {1.425f, -0.798f, 0f},
1102 {1.5f, 0f, 0.075f},
1103 {1.425f, 0f, 0f},
1104 {0.798f, -1.425f, 0f},
1105 {0f, -1.5f, 0.075f},
1106 {0f, -1.425f, 0f},
1107 {1.5f, -0.84f, 0.075f},
1108 {0.84f, -1.5f, 0.075f}
1109 };
1110 // Since GL2.glMap2f expects a packed array of floats, we must convert
1111 // from a 3-dimensional array to a 1-dimensional array
1112 private static final float[] teapotTex = {
1113 0, 0, 1, 0, 0, 1, 1, 1
1114 };
1115
1116 private static void teapot(final GL2 gl,
1117 final int grid,
1118 final double scale,
1119 final int type,
1120 final boolean backCompatible)
1121 {
1122 // As mentioned above, GL2.glMap2f expects a packed array of floats
1123 final float[] p = new float[4*4*3];
1124 final float[] q = new float[4*4*3];
1125 final float[] r = new float[4*4*3];
1126 final float[] s = new float[4*4*3];
1127 int i, j, k, l;
1128
1131 gl.glEnable(GLLightingFunc.GL_NORMALIZE);
1134 gl.glPushMatrix();
1135 if (!backCompatible) {
1136 // The time has come to have the teapot no longer be inside out
1137 gl.glFrontFace(GL.GL_CW);
1138 gl.glScaled(0.5*scale, 0.5*scale, 0.5*scale);
1139 } else {
1140 // We want the teapot in it's backward compatible position and
1141 // orientation
1142 gl.glRotatef(270.0f, 1, 0, 0);
1143 gl.glScalef((float)(0.5 * scale),
1144 (float)(0.5 * scale),
1145 (float)(0.5 * scale));
1146 gl.glTranslatef(0.0f, 0.0f, -1.5f);
1147 }
1148 for (i = 0; i < 10; i++) {
1149 for (j = 0; j < 4; j++) {
1150 for (k = 0; k < 4; k++) {
1151 for (l = 0; l < 3; l++) {
1152 p[(j*4+k)*3+l] = teapotCPData[teapotPatchData[i][j * 4 + k]][l];
1153 q[(j*4+k)*3+l] =
1154 teapotCPData[teapotPatchData[i][j * 4 + (3 - k)]][l];
1155 if (l == 1)
1156 q[(j*4+k)*3+l] *= -1.0;
1157 if (i < 6) {
1158 r[(j*4+k)*3+l] =
1159 teapotCPData[teapotPatchData[i][j * 4 + (3 - k)]][l];
1160 if (l == 0)
1161 r[(j*4+k)*3+l] *= -1.0;
1162 s[(j*4+k)*3+l] = teapotCPData[teapotPatchData[i][j * 4 + k]][l];
1163 if (l == 0)
1164 s[(j*4+k)*3+l] *= -1.0;
1165 if (l == 1)
1166 s[(j*4+k)*3+l] *= -1.0;
1167 }
1168 }
1169 }
1170 }
1171 gl.glMap2f(GL2.GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, teapotTex, 0);
1172 gl.glMap2f(GL2.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, p, 0);
1173 gl.glMapGrid2f(grid, 0.0f, 1.0f, grid, 0.0f, 1.0f);
1174 evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
1175 gl.glMap2f(GL2.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, q, 0);
1176 evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
1177 if (i < 6) {
1178 gl.glMap2f(GL2.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, r, 0);
1179 evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
1180 gl.glMap2f(GL2.GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, s, 0);
1181 evaluateTeapotMesh(gl, grid, type, i, !backCompatible);
1182 }
1183 }
1184 gl.glPopMatrix();
1185 gl.glPopAttrib();
1186 }
1187
1188 private static void evaluateTeapotMesh(final GL2 gl,
1189 final int grid,
1190 final int type,
1191 final int partNum,
1192 final boolean repairSingularities)
1193 {
1194 if (repairSingularities && (partNum == 5 || partNum == 3)) {
1195 // Instead of using evaluators that give bad results at singularities,
1196 // evaluate by hand
1198 for (int nv = 0; nv < grid; nv++) {
1199 if (nv == 0) {
1200 // Draw a small triangle-fan to fill the hole
1202 gl.glNormal3f(0, 0, partNum == 3 ? 1 : -1);
1204 {
1205 gl.glEvalCoord2f(0, 0);
1206 // Note that we draw in clock-wise order to match the evaluator
1207 // method
1208 for (int nu = 0; nu <= grid; nu++)
1209 {
1210 gl.glEvalCoord2f(nu / (float)grid, (1f / grid) / grid);
1211 }
1212 }
1213 gl.glEnd();
1215 }
1216 // Draw the rest of the piece as an evaluated quad-strip
1218 {
1219 // Note that we draw in clock-wise order to match the evaluator method
1220 for (int nu = grid; nu >= 0; nu--) {
1221 gl.glEvalCoord2f(nu / (float)grid, (nv + 1) / (float)grid);
1222 gl.glEvalCoord2f(nu / (float)grid, Math.max(nv, 1f / grid)
1223 / grid);
1224 }
1225 }
1226 gl.glEnd();
1227 }
1228 } else {
1229 gl.glEvalMesh2(type, 0, grid, 0, grid);
1230 }
1231 }
1232
1233 //----------------------------------------------------------------------
1234 // Font implementation
1235 //
1236
1237 private static void bitmapCharacterImpl(final GL2 gl, final int font, final char cin) {
1238 final BitmapFontRec fontinfo = getBitmapFont(font);
1239 final int c = cin & 0xFFFF;
1240 if (c < fontinfo.first ||
1241 c >= fontinfo.first + fontinfo.num_chars)
1242 return;
1243 final BitmapCharRec ch = fontinfo.ch[c - fontinfo.first];
1244 if (ch != null) {
1245 gl.glBitmap(ch.width, ch.height, ch.xorig, ch.yorig,
1246 ch.advance, 0, ch.bitmap, 0);
1247 }
1248 }
1249
1250 private static final BitmapFontRec[] bitmapFonts = new BitmapFontRec[9];
1251 private static final StrokeFontRec[] strokeFonts = new StrokeFontRec[9];
1252
1253 private static BitmapFontRec getBitmapFont(final int font) {
1254 BitmapFontRec rec = bitmapFonts[font];
1255 if (rec == null) {
1256 switch (font) {
1257 case BITMAP_9_BY_15:
1258 rec = GLUTBitmap9x15.glutBitmap9By15;
1259 break;
1260 case BITMAP_8_BY_13:
1261 rec = GLUTBitmap8x13.glutBitmap8By13;
1262 break;
1264 rec = GLUTBitmapTimesRoman10.glutBitmapTimesRoman10;
1265 break;
1267 rec = GLUTBitmapTimesRoman24.glutBitmapTimesRoman24;
1268 break;
1270 rec = GLUTBitmapHelvetica10.glutBitmapHelvetica10;
1271 break;
1273 rec = GLUTBitmapHelvetica12.glutBitmapHelvetica12;
1274 break;
1276 rec = GLUTBitmapHelvetica18.glutBitmapHelvetica18;
1277 break;
1278 default:
1279 throw new GLException("Unknown bitmap font number " + font);
1280 }
1281 bitmapFonts[font] = rec;
1282 }
1283 return rec;
1284 }
1285
1286 private static StrokeFontRec getStrokeFont(final int font) {
1287 StrokeFontRec rec = strokeFonts[font];
1288 if (rec == null) {
1289 switch (font) {
1290 case STROKE_ROMAN:
1291 rec = GLUTStrokeRoman.glutStrokeRoman;
1292 break;
1293 case STROKE_MONO_ROMAN:
1294 rec = GLUTStrokeMonoRoman.glutStrokeMonoRoman;
1295 break;
1296 default:
1297 throw new GLException("Unknown stroke font number " + font);
1298 }
1299 }
1300 return rec;
1301 }
1302
1303 private static void beginBitmap(final GL2 gl,
1304 final int[] swapbytes,
1305 final int[] lsbfirst,
1306 final int[] rowlength,
1307 final int[] skiprows,
1308 final int[] skippixels,
1309 final int[] alignment) {
1310 gl.glGetIntegerv(GL2GL3.GL_UNPACK_SWAP_BYTES, swapbytes, 0);
1311 gl.glGetIntegerv(GL2GL3.GL_UNPACK_LSB_FIRST, lsbfirst, 0);
1312 gl.glGetIntegerv(GL2ES2.GL_UNPACK_ROW_LENGTH, rowlength, 0);
1313 gl.glGetIntegerv(GL2ES2.GL_UNPACK_SKIP_ROWS, skiprows, 0);
1314 gl.glGetIntegerv(GL2ES2.GL_UNPACK_SKIP_PIXELS, skippixels, 0);
1315 gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, alignment, 0);
1316 /* Little endian machines (DEC Alpha for example) could
1317 benefit from setting GL_UNPACK_LSB_FIRST to GL_TRUE
1318 instead of GL_FALSE, but this would require changing the
1319 generated bitmaps too. */
1326 }
1327
1328 private static void endBitmap(final GL2 gl,
1329 final int[] swapbytes,
1330 final int[] lsbfirst,
1331 final int[] rowlength,
1332 final int[] skiprows,
1333 final int[] skippixels,
1334 final int[] alignment) {
1335 /* Restore saved modes. */
1336 gl.glPixelStorei(GL2GL3.GL_UNPACK_SWAP_BYTES, swapbytes[0]);
1337 gl.glPixelStorei(GL2GL3.GL_UNPACK_LSB_FIRST, lsbfirst[0]);
1338 gl.glPixelStorei(GL2ES2.GL_UNPACK_ROW_LENGTH, rowlength[0]);
1339 gl.glPixelStorei(GL2ES2.GL_UNPACK_SKIP_ROWS, skiprows[0]);
1340 gl.glPixelStorei(GL2ES2.GL_UNPACK_SKIP_PIXELS, skippixels[0]);
1341 gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, alignment[0]);
1342 }
1343}
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Provides access to the OpenGL Utility Library (GLU).
Definition: GLU.java:43
static final int GLU_FILL
Definition: GLU.java:1076
static final int GLU_SMOOTH
Definition: GLU.java:1083
final void gluQuadricNormals(GLUquadric quad, int normal)
Option (throws GLException if not available in profile).
Definition: GLU.java:1329
final GLUquadric gluNewQuadric()
Option (throws GLException if not available in profile).
Definition: GLU.java:1295
final void gluCylinder(GLUquadric quad, double base, double top, double height, int slices, int stacks)
Option (throws GLException if not available in profile).
Definition: GLU.java:1278
final void gluQuadricDrawStyle(GLUquadric quad, int draw)
Option (throws GLException if not available in profile).
Definition: GLU.java:1323
final void gluSphere(GLUquadric quad, double radius, int slices, int stacks)
Option (throws GLException if not available in profile).
Definition: GLU.java:1347
static final int GLU_LINE
Definition: GLU.java:1075
static final GL2 getCurrentGL2()
Definition: GLUgl2.java:195
Subset of the routines provided by the GLUT interface.
Definition: GLUT.java:96
void glutSolidCone(final double base, final double height, final int slices, final int stacks)
Definition: GLUT.java:144
void glutSolidTeapot(final double scale)
Renders the teapot as a solid shape of the specified size.
Definition: GLUT.java:270
void glutSolidCylinder(final double radius, final double height, final int slices, final int stacks)
Definition: GLUT.java:165
static final int BITMAP_TIMES_ROMAN_24
Definition: GLUT.java:102
static final int BITMAP_HELVETICA_12
Definition: GLUT.java:104
void glutWireTeapot(final double scale)
Renders the teapot as a wireframe shape of the specified size.
Definition: GLUT.java:300
void glutWireCone(final double base, final double height, final int slices, final int stacks)
Definition: GLUT.java:133
void glutBitmapCharacter(final int font, final char character)
Definition: GLUT.java:327
int glutBitmapWidth(final int font, final char character)
Definition: GLUT.java:380
void glutSolidCube(final float size)
Definition: GLUT.java:213
static final int BITMAP_HELVETICA_10
Definition: GLUT.java:103
void glutWireTeapot(final double scale, final boolean cStyle)
Renders the teapot as a wireframe shape of the specified size.
Definition: GLUT.java:319
void glutWireRhombicDodecahedron()
This function draws a wireframe dodecahedron whose facets are rhombic and whose vertices are at unit ...
Definition: GLUT.java:494
int glutStrokeLength(final int font, final String string)
Definition: GLUT.java:468
static final int STROKE_ROMAN
Definition: GLUT.java:97
void glutSolidSphere(final double radius, final int slices, final int stacks)
Definition: GLUT.java:123
void glutWireCylinder(final double radius, final double height, final int slices, final int stacks)
Definition: GLUT.java:155
void glutSolidRhombicDodecahedron()
This function draws a solid-shaded dodecahedron whose facets are rhombic and whose vertices are at un...
Definition: GLUT.java:514
void glutWireTorus(final double innerRadius, final double outerRadius, final int nsides, final int rings)
Definition: GLUT.java:217
float glutStrokeLengthf(final int font, final String string)
Definition: GLUT.java:472
void glutWireSphere(final double radius, final int slices, final int stacks)
Definition: GLUT.java:113
void glutWireCube(final float size)
Definition: GLUT.java:209
void glutBitmapString(final int font, final String string)
Definition: GLUT.java:352
int glutStrokeWidth(final int font, final char character)
Definition: GLUT.java:437
static final int BITMAP_8_BY_13
Definition: GLUT.java:100
float glutStrokeWidthf(final int font, final char character)
Definition: GLUT.java:441
int glutBitmapLength(final int font, final String string)
Definition: GLUT.java:453
static final int BITMAP_TIMES_ROMAN_10
Definition: GLUT.java:101
static final int BITMAP_9_BY_15
Definition: GLUT.java:99
static final int STROKE_MONO_ROMAN
Definition: GLUT.java:98
static final int BITMAP_HELVETICA_18
Definition: GLUT.java:105
void glutStrokeString(final int font, final String string)
Definition: GLUT.java:413
void glutStrokeCharacter(final int font, final char character)
Definition: GLUT.java:392
void glutSolidTorus(final double innerRadius, final double outerRadius, final int nsides, final int rings)
Definition: GLUT.java:226
void glutSolidTeapot(final double scale, final boolean cStyle)
Renders the teapot as a solid shape of the specified size.
Definition: GLUT.java:289
void glNormal3f(float nx, float ny, float nz)
Entry point to C language function: void {@native glNormal3f}(GLfloat nx, GLfloat ny,...
static final int GL_UNPACK_ROW_LENGTH
GL_ES_VERSION_3_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_EXT_unpack_subimage Alias for: GL_UNPACK_ROW_LE...
Definition: GL2ES2.java:336
static final int GL_UNPACK_SKIP_PIXELS
GL_ES_VERSION_3_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_EXT_unpack_subimage Alias for: GL_UNPACK_SKIP_P...
Definition: GL2ES2.java:297
static final int GL_UNPACK_SKIP_ROWS
GL_ES_VERSION_3_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_EXT_unpack_subimage Alias for: GL_UNPACK_SKIP_R...
Definition: GL2ES2.java:370
static final int GL_QUADS
GL_ES_VERSION_3_2, GL_VERSION_1_1, GL_VERSION_1_0, GL_OES_tessellation_shader, GL_EXT_tessellation_sh...
Definition: GL2ES3.java:734
static final int GL_UNPACK_LSB_FIRST
GL_VERSION_1_1, GL_VERSION_1_0 Define "GL_UNPACK_LSB_FIRST" with expression '0x0CF1',...
Definition: GL2GL3.java:748
static final int GL_UNPACK_SWAP_BYTES
GL_VERSION_1_1, GL_VERSION_1_0 Define "GL_UNPACK_SWAP_BYTES" with expression '0x0CF0',...
Definition: GL2GL3.java:381
static final int GL_FILL
GL_VERSION_1_1, GL_VERSION_1_0, GL_NV_polygon_mode Alias for: GL_FILL_NV Define "GL_FILL" with expre...
Definition: GL2GL3.java:573
void glPolygonMode(int face, int mode)
Entry point to C language function: void {@native glPolygonMode}(GLenum face, GLenum mode) Part of...
static final int GL_LINE
GL_VERSION_1_1, GL_VERSION_1_0, GL_NV_polygon_mode Alias for: GL_LINE_NV Define "GL_LINE" with expre...
Definition: GL2GL3.java:394
void glVertex3d(double x, double y, double z)
Entry point to C language function: void {@native glVertex3d}(GLdouble x, GLdouble y,...
static final int GL_POLYGON_BIT
GL_VERSION_1_0 Define "GL_POLYGON_BIT" with expression '0x00000008', CType: int
Definition: GL2.java:2474
void glPopAttrib()
Entry point to C language function: void {@native glPopAttrib}() Part of GL_VERSION_1_0
void glVertex3fv(FloatBuffer v)
Entry point to C language function: void {@native glVertex3fv}(const GLfloat * v) Part of GL_VERSI...
void glBitmap(int width, int height, float xorig, float yorig, float xmove, float ymove, ByteBuffer bitmap)
Entry point to C language function: void {@native glBitmap}(GLsizei width, GLsizei height,...
void glVertex3dv(DoubleBuffer v)
Entry point to C language function: void {@native glVertex3dv}(const GLdouble * v) Part of GL_VERS...
static final int GL_MAP2_VERTEX_3
GL_VERSION_1_0 Define "GL_MAP2_VERTEX_3" with expression '0x0DB7', CType: int
Definition: GL2.java:1210
void glEvalCoord2f(float u, float v)
Entry point to C language function: void {@native glEvalCoord2f}(GLfloat u, GLfloat v) Part of GL_...
static final int GL_ENABLE_BIT
GL_VERSION_1_0 Define "GL_ENABLE_BIT" with expression '0x00002000', CType: int
Definition: GL2.java:2039
void glBegin(int mode)
Entry point to C language function: void {@native glBegin}(GLenum mode) Part of GL_VERSION_1_0
static final int GL_MAP2_TEXTURE_COORD_2
GL_VERSION_1_0 Define "GL_MAP2_TEXTURE_COORD_2" with expression '0x0DB4', CType: int
Definition: GL2.java:2533
static final int GL_AUTO_NORMAL
GL_VERSION_1_0 Define "GL_AUTO_NORMAL" with expression '0x0D80', CType: int
Definition: GL2.java:587
void glVertex3f(float x, float y, float z)
Entry point to C language function: void {@native glVertex3f}(GLfloat x, GLfloat y,...
void glVertex2f(float x, float y)
Entry point to C language function: void {@native glVertex2f}(GLfloat x, GLfloat y) Part of GL_VER...
void glNormal3fv(FloatBuffer v)
Entry point to C language function: void {@native glNormal3fv}(const GLfloat * v) Part of GL_VERSI...
void glEvalMesh2(int mode, int i1, int i2, int j1, int j2)
Entry point to C language function: void {@native glEvalMesh2}(GLenum mode, GLint i1,...
void glEnd()
Entry point to C language function: void {@native glEnd}() Part of GL_VERSION_1_0
void glMapGrid2f(int un, float u1, float u2, int vn, float v1, float v2)
Entry point to C language function: void {@native glMapGrid2f}(GLint un, GLfloat u1,...
void glNormal3dv(DoubleBuffer v)
Entry point to C language function: void {@native glNormal3dv}(const GLdouble * v) Part of GL_VERS...
void glMap2f(int target, float u1, float u2, int ustride, int uorder, float v1, float v2, int vstride, int vorder, FloatBuffer points)
Entry point to C language function: void {@native glMap2f}(GLenum target, GLfloat u1,...
void glNormal3d(double nx, double ny, double nz)
Entry point to C language function: void {@native glNormal3d}(GLdouble nx, GLdouble ny,...
void glScaled(double x, double y, double z)
Entry point to C language function: void {@native glScaled}(GLdouble x, GLdouble y,...
void glPushAttrib(int mask)
Entry point to C language function: void {@native glPushAttrib}(GLbitfield mask) Part of GL_VERSIO...
static final int GL_EVAL_BIT
GL_VERSION_1_0 Define "GL_EVAL_BIT" with expression '0x00010000', CType: int
Definition: GL2.java:961
static final int GL_QUAD_STRIP
GL_VERSION_1_0 Define "GL_QUAD_STRIP" with expression '0x0008', CType: int
Definition: GL2.java:2548
void glPixelStorei(int pname, int param)
Entry point to C language function: void {@native glPixelStorei}(GLenum pname, GLint param) Part o...
void glGetIntegerv(int pname, IntBuffer data)
Entry point to C language function: void {@native glGetIntegerv}(GLenum pname, GLint * data) Part ...
static final int GL_LINE_LOOP
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_LINE_LOOP" with expre...
Definition: GL.java:508
static final int GL_UNPACK_ALIGNMENT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_UNPACK_ALIGNMENT" wit...
Definition: GL.java:746
static final int GL_TRIANGLES
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TRIANGLES" with expre...
Definition: GL.java:145
void glDisable(int cap)
Entry point to C language function: void {@native glDisable}(GLenum cap) Part of GL_ES_VERSION_2_0...
static final int GL_TRIANGLE_FAN
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TRIANGLE_FAN" with ex...
Definition: GL.java:513
static final int GL_LINE_STRIP
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_LINE_STRIP" with expr...
Definition: GL.java:310
void glEnable(int cap)
Entry point to C language function: void {@native glEnable}(GLenum cap) Part of GL_ES_VERSION_2_0,...
static final int GL_FRONT_AND_BACK
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_FRONT_AND_BACK" with ...
Definition: GL.java:619
static final int GL_FALSE
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_FALSE" with expressio...
Definition: GL.java:251
static final int GL_CW
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_CW" with expression '...
Definition: GL.java:467
void glFrontFace(int mode)
Entry point to C language function: void {@native glFrontFace}(GLenum mode) Part of GL_ES_VERSION_...
void glPushMatrix()
Push the current matrix to it's stack, while preserving it's values.
void glPopMatrix()
Pop the current matrix from it's stack.
void glTranslatef(float x, float y, float z)
Translate the current matrix.
void glRotatef(float angle, float x, float y, float z)
Rotate the current matrix.
void glScalef(float x, float y, float z)
Scale the current matrix.
Wrapper for a GLU quadric object.
Definition: GLUquadric.java:10