2 /* Copyright (c) Mark J. Kilgard, 1994, 1997. */
5 (c) Copyright 1993, Silicon Graphics, Inc.
9 Permission to use, copy, modify, and distribute this software
10 for any purpose and without fee is hereby granted, provided
11 that the above copyright notice appear in all copies and that
12 both the copyright notice and this permission notice appear in
13 supporting documentation, and that the name of Silicon
14 Graphics, Inc. not be used in advertising or publicity
15 pertaining to distribution of the software without specific,
16 written prior permission.
18 THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
19 "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
20 OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
21 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
22 EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
23 ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
24 CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
25 INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
26 SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
27 NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
28 OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
30 PERFORMANCE OF THIS SOFTWARE.
32 US Government Users Restricted Rights
34 Use, duplication, or disclosure by the Government is subject to
35 restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
36 (c)(1)(ii) of the Rights in Technical Data and Computer
37 Software clause at DFARS 252.227-7013 and/or in similar or
38 successor clauses in the FAR or the DOD or NASA FAR
39 Supplement. Unpublished-- rights reserved under the copyright
40 laws of the United States. Contractor/manufacturer is Silicon
41 Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
44 OpenGL(TM) is a trademark of Silicon Graphics, Inc.
53 /* Some <math.h> files do not define M_PI... */
55 #define M_PI 3.14159265358979323846
58 static GLUquadricObj
*quadObj
;
60 #define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
65 quadObj
= gluNewQuadric();
67 __glutFatalError("out of memory");
72 glutWireSphere(GLdouble radius
, GLint slices
, GLint stacks
)
75 gluQuadricDrawStyle(quadObj
, GLU_LINE
);
76 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
77 /* If we ever changed/used the texture or orientation state
78 of quadObj, we'd need to change it to the defaults here
79 with gluQuadricTexture and/or gluQuadricOrientation. */
80 gluSphere(quadObj
, radius
, slices
, stacks
);
84 glutSolidSphere(GLdouble radius
, GLint slices
, GLint stacks
)
87 gluQuadricDrawStyle(quadObj
, GLU_FILL
);
88 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
89 /* If we ever changed/used the texture or orientation state
90 of quadObj, we'd need to change it to the defaults here
91 with gluQuadricTexture and/or gluQuadricOrientation. */
92 gluSphere(quadObj
, radius
, slices
, stacks
);
96 glutWireCone(GLdouble base
, GLdouble height
,
97 GLint slices
, GLint stacks
)
100 gluQuadricDrawStyle(quadObj
, GLU_LINE
);
101 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
102 /* If we ever changed/used the texture or orientation state
103 of quadObj, we'd need to change it to the defaults here
104 with gluQuadricTexture and/or gluQuadricOrientation. */
105 gluCylinder(quadObj
, base
, 0.0, height
, slices
, stacks
);
109 glutSolidCone(GLdouble base
, GLdouble height
,
110 GLint slices
, GLint stacks
)
113 gluQuadricDrawStyle(quadObj
, GLU_FILL
);
114 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
115 /* If we ever changed/used the texture or orientation state
116 of quadObj, we'd need to change it to the defaults here
117 with gluQuadricTexture and/or gluQuadricOrientation. */
118 gluCylinder(quadObj
, base
, 0.0, height
, slices
, stacks
);
124 drawBox(GLfloat size
, GLenum type
)
126 static GLfloat n
[6][3] =
135 static GLint faces
[6][4] =
147 v
[0][0] = v
[1][0] = v
[2][0] = v
[3][0] = -size
/ 2;
148 v
[4][0] = v
[5][0] = v
[6][0] = v
[7][0] = size
/ 2;
149 v
[0][1] = v
[1][1] = v
[4][1] = v
[5][1] = -size
/ 2;
150 v
[2][1] = v
[3][1] = v
[6][1] = v
[7][1] = size
/ 2;
151 v
[0][2] = v
[3][2] = v
[4][2] = v
[7][2] = -size
/ 2;
152 v
[1][2] = v
[2][2] = v
[5][2] = v
[6][2] = size
/ 2;
154 for (i
= 5; i
>= 0; i
--) {
156 /* glNormal3fv(&n[i][0]); */
157 glVertex3fv(&v
[faces
[i
][0]][0]);
158 glVertex3fv(&v
[faces
[i
][1]][0]);
159 glVertex3fv(&v
[faces
[i
][2]][0]);
160 glVertex3fv(&v
[faces
[i
][3]][0]);
167 glutWireCube(GLdouble size
)
169 drawBox(size
, GL_LINE_LOOP
);
173 glutSolidCube(GLdouble size
)
175 drawBox(size
, GL_QUADS
);
181 doughnut(GLfloat r
, GLfloat R
, GLint nsides
, GLint rings
)
184 GLfloat theta
, phi
, theta1
;
185 GLfloat cosTheta
, sinTheta
;
186 GLfloat cosTheta1
, sinTheta1
;
187 GLfloat ringDelta
, sideDelta
;
189 ringDelta
= 2.0 * M_PI
/ rings
;
190 sideDelta
= 2.0 * M_PI
/ nsides
;
195 for (i
= rings
- 1; i
>= 0; i
--) {
196 theta1
= theta
+ ringDelta
;
197 cosTheta1
= cos(theta1
);
198 sinTheta1
= sin(theta1
);
199 glBegin(GL_QUAD_STRIP
);
201 for (j
= nsides
; j
>= 0; j
--) {
202 GLfloat cosPhi
, sinPhi
, dist
;
207 dist
= R
+ r
* cosPhi
;
209 /* glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); */
210 glVertex3f(cosTheta1
* dist
, -sinTheta1
* dist
, r
* sinPhi
);
211 /* glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); */
212 glVertex3f(cosTheta
* dist
, -sinTheta
* dist
, r
* sinPhi
);
216 cosTheta
= cosTheta1
;
217 sinTheta
= sinTheta1
;
223 glutWireTorus(GLdouble innerRadius
, GLdouble outerRadius
,
224 GLint nsides
, GLint rings
)
226 /* glPushAttrib(GL_POLYGON_BIT); */
227 /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */
228 doughnut(innerRadius
, outerRadius
, nsides
, rings
);
233 glutSolidTorus(GLdouble innerRadius
, GLdouble outerRadius
,
234 GLint nsides
, GLint rings
)
236 doughnut(innerRadius
, outerRadius
, nsides
, rings
);
241 static GLfloat dodec
[20][3];
244 initDodecahedron(void)
248 alpha
= sqrt(2.0 / (3.0 + sqrt(5.0)));
249 beta
= 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
250 2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
252 dodec
[0][0] = -alpha
; dodec
[0][1] = 0; dodec
[0][2] = beta
;
253 dodec
[1][0] = alpha
; dodec
[1][1] = 0; dodec
[1][2] = beta
;
254 dodec
[2][0] = -1; dodec
[2][1] = -1; dodec
[2][2] = -1;
255 dodec
[3][0] = -1; dodec
[3][1] = -1; dodec
[3][2] = 1;
256 dodec
[4][0] = -1; dodec
[4][1] = 1; dodec
[4][2] = -1;
257 dodec
[5][0] = -1; dodec
[5][1] = 1; dodec
[5][2] = 1;
258 dodec
[6][0] = 1; dodec
[6][1] = -1; dodec
[6][2] = -1;
259 dodec
[7][0] = 1; dodec
[7][1] = -1; dodec
[7][2] = 1;
260 dodec
[8][0] = 1; dodec
[8][1] = 1; dodec
[8][2] = -1;
261 dodec
[9][0] = 1; dodec
[9][1] = 1; dodec
[9][2] = 1;
262 dodec
[10][0] = beta
; dodec
[10][1] = alpha
; dodec
[10][2] = 0;
263 dodec
[11][0] = beta
; dodec
[11][1] = -alpha
; dodec
[11][2] = 0;
264 dodec
[12][0] = -beta
; dodec
[12][1] = alpha
; dodec
[12][2] = 0;
265 dodec
[13][0] = -beta
; dodec
[13][1] = -alpha
; dodec
[13][2] = 0;
266 dodec
[14][0] = -alpha
; dodec
[14][1] = 0; dodec
[14][2] = -beta
;
267 dodec
[15][0] = alpha
; dodec
[15][1] = 0; dodec
[15][2] = -beta
;
268 dodec
[16][0] = 0; dodec
[16][1] = beta
; dodec
[16][2] = alpha
;
269 dodec
[17][0] = 0; dodec
[17][1] = beta
; dodec
[17][2] = -alpha
;
270 dodec
[18][0] = 0; dodec
[18][1] = -beta
; dodec
[18][2] = alpha
;
271 dodec
[19][0] = 0; dodec
[19][1] = -beta
; dodec
[19][2] = -alpha
;
276 #define DIFF3(_a,_b,_c) { \
277 (_c)[0] = (_a)[0] - (_b)[0]; \
278 (_c)[1] = (_a)[1] - (_b)[1]; \
279 (_c)[2] = (_a)[2] - (_b)[2]; \
283 crossprod(GLfloat v1
[3], GLfloat v2
[3], GLfloat prod
[3])
285 GLfloat p
[3]; /* in case prod == v1 or v2 */
287 p
[0] = v1
[1] * v2
[2] - v2
[1] * v1
[2];
288 p
[1] = v1
[2] * v2
[0] - v2
[2] * v1
[0];
289 p
[2] = v1
[0] * v2
[1] - v2
[0] * v1
[1];
296 normalize(GLfloat v
[3])
300 d
= sqrt(v
[0] * v
[0] + v
[1] * v
[1] + v
[2] * v
[2]);
302 /* __glutWarning("normalize: zero length vector"); */
312 pentagon(int a
, int b
, int c
, int d
, int e
, GLenum shadeType
)
314 GLfloat n0
[3], d1
[3], d2
[3];
316 DIFF3(dodec
[a
], dodec
[b
], d1
);
317 DIFF3(dodec
[b
], dodec
[c
], d2
);
318 crossprod(d1
, d2
, n0
);
322 /* glNormal3fv(n0); */
323 glVertex3fv(&dodec
[a
][0]);
324 glVertex3fv(&dodec
[b
][0]);
325 glVertex3fv(&dodec
[c
][0]);
326 glVertex3fv(&dodec
[d
][0]);
327 glVertex3fv(&dodec
[e
][0]);
332 dodecahedron(GLenum type
)
334 static int inited
= 0;
340 pentagon(0, 1, 9, 16, 5, type
);
341 pentagon(1, 0, 3, 18, 7, type
);
342 pentagon(1, 7, 11, 10, 9, type
);
343 pentagon(11, 7, 18, 19, 6, type
);
344 pentagon(8, 17, 16, 9, 10, type
);
345 pentagon(2, 14, 15, 6, 19, type
);
346 pentagon(2, 13, 12, 4, 14, type
);
347 pentagon(2, 19, 18, 3, 13, type
);
348 pentagon(3, 0, 5, 12, 13, type
);
349 pentagon(6, 15, 8, 10, 11, type
);
350 pentagon(4, 17, 8, 15, 14, type
);
351 pentagon(4, 12, 5, 16, 17, type
);
356 glutWireDodecahedron(void)
358 dodecahedron(GL_LINE_LOOP
);
362 glutSolidDodecahedron(void)
364 dodecahedron(GL_TRIANGLE_FAN
);
370 recorditem(GLfloat
* n1
, GLfloat
* n2
, GLfloat
* n3
,
373 GLfloat q0
[3], q1
[3];
377 crossprod(q0
, q1
, q1
);
381 /* glNormal3fv(q1); */
389 subdivide(GLfloat
* v0
, GLfloat
* v1
, GLfloat
* v2
,
393 GLfloat w0
[3], w1
[3], w2
[3];
398 for (i
= 0; i
< depth
; i
++) {
399 for (j
= 0; i
+ j
< depth
; j
++) {
401 for (n
= 0; n
< 3; n
++) {
402 w0
[n
] = (i
* v0
[n
] + j
* v1
[n
] + k
* v2
[n
]) / depth
;
403 w1
[n
] = ((i
+ 1) * v0
[n
] + j
* v1
[n
] + (k
- 1) * v2
[n
])
405 w2
[n
] = (i
* v0
[n
] + (j
+ 1) * v1
[n
] + (k
- 1) * v2
[n
])
408 l
= sqrt(w0
[0] * w0
[0] + w0
[1] * w0
[1] + w0
[2] * w0
[2]);
412 l
= sqrt(w1
[0] * w1
[0] + w1
[1] * w1
[1] + w1
[2] * w1
[2]);
416 l
= sqrt(w2
[0] * w2
[0] + w2
[1] * w2
[1] + w2
[2] * w2
[2]);
420 recorditem(w1
, w0
, w2
, shadeType
);
426 drawtriangle(int i
, GLfloat data
[][3], int ndx
[][3],
429 GLfloat
*x0
, *x1
, *x2
;
431 x0
= data
[ndx
[i
][0]];
432 x1
= data
[ndx
[i
][1]];
433 x2
= data
[ndx
[i
][2]];
434 subdivide(x0
, x1
, x2
, shadeType
);
437 /* octahedron data: The octahedron produced is centered at the
438 origin and has radius 1.0 */
439 static GLfloat odata
[6][3] =
449 static int ondex
[8][3] =
462 octahedron(GLenum shadeType
)
466 for (i
= 7; i
>= 0; i
--) {
467 drawtriangle(i
, odata
, ondex
, shadeType
);
473 glutWireOctahedron(void)
475 octahedron(GL_LINE_LOOP
);
479 glutSolidOctahedron(void)
481 octahedron(GL_TRIANGLES
);
486 /* icosahedron data: These numbers are rigged to make an
487 icosahedron of radius 1.0 */
489 #define X .525731112119133606
490 #define Z .850650808352039932
492 static GLfloat idata
[12][3] =
508 static int index
[20][3] =
533 icosahedron(GLenum shadeType
)
537 for (i
= 19; i
>= 0; i
--) {
538 drawtriangle(i
, idata
, index
, shadeType
);
544 glutWireIcosahedron(void)
546 icosahedron(GL_LINE_LOOP
);
550 glutSolidIcosahedron(void)
552 icosahedron(GL_TRIANGLES
);
557 /* tetrahedron data: */
559 #define T 1.73205080756887729
561 static GLfloat tdata
[4][3] =
569 static int tndex
[4][3] =
578 tetrahedron(GLenum shadeType
)
582 for (i
= 3; i
>= 0; i
--)
583 drawtriangle(i
, tdata
, tndex
, shadeType
);
588 glutWireTetrahedron(void)
590 tetrahedron(GL_LINE_LOOP
);
594 glutSolidTetrahedron(void)
596 tetrahedron(GL_TRIANGLES
);