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.
52 /* Some <math.h> files do not define M_PI... */
54 #define M_PI 3.14159265358979323846
57 static GLUquadricObj
*quadObj
;
59 #define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
64 quadObj
= gluNewQuadric();
66 __glutFatalError("out of memory."); */
71 glutWireSphere(GLdouble radius
, GLint slices
, GLint stacks
)
74 gluQuadricDrawStyle(quadObj
, GLU_LINE
);
75 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
76 /* If we ever changed/used the texture or orientation state
77 of quadObj, we'd need to change it to the defaults here
78 with gluQuadricTexture and/or gluQuadricOrientation. */
79 gluSphere(quadObj
, radius
, slices
, stacks
);
83 glutSolidSphere(GLdouble radius
, GLint slices
, GLint stacks
)
86 gluQuadricDrawStyle(quadObj
, GLU_FILL
);
87 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
88 /* If we ever changed/used the texture or orientation state
89 of quadObj, we'd need to change it to the defaults here
90 with gluQuadricTexture and/or gluQuadricOrientation. */
91 gluSphere(quadObj
, radius
, slices
, stacks
);
95 glutWireCone(GLdouble base
, GLdouble height
,
96 GLint slices
, GLint stacks
)
99 gluQuadricDrawStyle(quadObj
, GLU_LINE
);
100 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
101 /* If we ever changed/used the texture or orientation state
102 of quadObj, we'd need to change it to the defaults here
103 with gluQuadricTexture and/or gluQuadricOrientation. */
104 gluCylinder(quadObj
, base
, 0.0, height
, slices
, stacks
);
108 glutSolidCone(GLdouble base
, GLdouble height
,
109 GLint slices
, GLint stacks
)
112 gluQuadricDrawStyle(quadObj
, GLU_FILL
);
113 gluQuadricNormals(quadObj
, GLU_SMOOTH
);
114 /* If we ever changed/used the texture or orientation state
115 of quadObj, we'd need to change it to the defaults here
116 with gluQuadricTexture and/or gluQuadricOrientation. */
117 gluCylinder(quadObj
, base
, 0.0, height
, slices
, stacks
);
123 drawBox(GLfloat size
, GLenum type
)
125 static GLfloat n
[6][3] =
134 static GLint faces
[6][4] =
146 v
[0][0] = v
[1][0] = v
[2][0] = v
[3][0] = -size
/ 2;
147 v
[4][0] = v
[5][0] = v
[6][0] = v
[7][0] = size
/ 2;
148 v
[0][1] = v
[1][1] = v
[4][1] = v
[5][1] = -size
/ 2;
149 v
[2][1] = v
[3][1] = v
[6][1] = v
[7][1] = size
/ 2;
150 v
[0][2] = v
[3][2] = v
[4][2] = v
[7][2] = -size
/ 2;
151 v
[1][2] = v
[2][2] = v
[5][2] = v
[6][2] = size
/ 2;
153 for (i
= 5; i
>= 0; i
--) {
155 /* glNormal3fv(&n[i][0]); */
156 glVertex3fv(&v
[faces
[i
][0]][0]);
157 glVertex3fv(&v
[faces
[i
][1]][0]);
158 glVertex3fv(&v
[faces
[i
][2]][0]);
159 glVertex3fv(&v
[faces
[i
][3]][0]);
166 glutWireCube(GLdouble size
)
168 drawBox(size
, GL_LINE_LOOP
);
172 glutSolidCube(GLdouble size
)
174 drawBox(size
, GL_QUADS
);
180 doughnut(GLfloat r
, GLfloat R
, GLint nsides
, GLint rings
)
183 GLfloat theta
, phi
, theta1
;
184 GLfloat cosTheta
, sinTheta
;
185 GLfloat cosTheta1
, sinTheta1
;
186 GLfloat ringDelta
, sideDelta
;
188 ringDelta
= 2.0 * M_PI
/ rings
;
189 sideDelta
= 2.0 * M_PI
/ nsides
;
194 for (i
= rings
- 1; i
>= 0; i
--) {
195 theta1
= theta
+ ringDelta
;
196 cosTheta1
= cos(theta1
);
197 sinTheta1
= sin(theta1
);
198 glBegin(GL_QUAD_STRIP
);
200 for (j
= nsides
; j
>= 0; j
--) {
201 GLfloat cosPhi
, sinPhi
, dist
;
206 dist
= R
+ r
* cosPhi
;
208 /* glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi); */
209 glVertex3f(cosTheta1
* dist
, -sinTheta1
* dist
, r
* sinPhi
);
210 /* glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi); */
211 glVertex3f(cosTheta
* dist
, -sinTheta
* dist
, r
* sinPhi
);
215 cosTheta
= cosTheta1
;
216 sinTheta
= sinTheta1
;
222 glutWireTorus(GLdouble innerRadius
, GLdouble outerRadius
,
223 GLint nsides
, GLint rings
)
225 /* glPushAttrib(GL_POLYGON_BIT); */
226 /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */
227 doughnut(innerRadius
, outerRadius
, nsides
, rings
);
232 glutSolidTorus(GLdouble innerRadius
, GLdouble outerRadius
,
233 GLint nsides
, GLint rings
)
235 doughnut(innerRadius
, outerRadius
, nsides
, rings
);
240 static GLfloat dodec
[20][3];
243 initDodecahedron(void)
247 alpha
= sqrt(2.0 / (3.0 + sqrt(5.0)));
248 beta
= 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
249 2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
251 dodec
[0][0] = -alpha
; dodec
[0][1] = 0; dodec
[0][2] = beta
;
252 dodec
[1][0] = alpha
; dodec
[1][1] = 0; dodec
[1][2] = beta
;
253 dodec
[2][0] = -1; dodec
[2][1] = -1; dodec
[2][2] = -1;
254 dodec
[3][0] = -1; dodec
[3][1] = -1; dodec
[3][2] = 1;
255 dodec
[4][0] = -1; dodec
[4][1] = 1; dodec
[4][2] = -1;
256 dodec
[5][0] = -1; dodec
[5][1] = 1; dodec
[5][2] = 1;
257 dodec
[6][0] = 1; dodec
[6][1] = -1; dodec
[6][2] = -1;
258 dodec
[7][0] = 1; dodec
[7][1] = -1; dodec
[7][2] = 1;
259 dodec
[8][0] = 1; dodec
[8][1] = 1; dodec
[8][2] = -1;
260 dodec
[9][0] = 1; dodec
[9][1] = 1; dodec
[9][2] = 1;
261 dodec
[10][0] = beta
; dodec
[10][1] = alpha
; dodec
[10][2] = 0;
262 dodec
[11][0] = beta
; dodec
[11][1] = -alpha
; dodec
[11][2] = 0;
263 dodec
[12][0] = -beta
; dodec
[12][1] = alpha
; dodec
[12][2] = 0;
264 dodec
[13][0] = -beta
; dodec
[13][1] = -alpha
; dodec
[13][2] = 0;
265 dodec
[14][0] = -alpha
; dodec
[14][1] = 0; dodec
[14][2] = -beta
;
266 dodec
[15][0] = alpha
; dodec
[15][1] = 0; dodec
[15][2] = -beta
;
267 dodec
[16][0] = 0; dodec
[16][1] = beta
; dodec
[16][2] = alpha
;
268 dodec
[17][0] = 0; dodec
[17][1] = beta
; dodec
[17][2] = -alpha
;
269 dodec
[18][0] = 0; dodec
[18][1] = -beta
; dodec
[18][2] = alpha
;
270 dodec
[19][0] = 0; dodec
[19][1] = -beta
; dodec
[19][2] = -alpha
;
275 #define DIFF3(_a,_b,_c) { \
276 (_c)[0] = (_a)[0] - (_b)[0]; \
277 (_c)[1] = (_a)[1] - (_b)[1]; \
278 (_c)[2] = (_a)[2] - (_b)[2]; \
282 crossprod(GLfloat v1
[3], GLfloat v2
[3], GLfloat prod
[3])
284 GLfloat p
[3]; /* in case prod == v1 or v2 */
286 p
[0] = v1
[1] * v2
[2] - v2
[1] * v1
[2];
287 p
[1] = v1
[2] * v2
[0] - v2
[2] * v1
[0];
288 p
[2] = v1
[0] * v2
[1] - v2
[0] * v1
[1];
295 normalize(GLfloat v
[3])
299 d
= sqrt(v
[0] * v
[0] + v
[1] * v
[1] + v
[2] * v
[2]);
301 /* __glutWarning("normalize: zero length vector"); */
311 pentagon(int a
, int b
, int c
, int d
, int e
, GLenum shadeType
)
313 GLfloat n0
[3], d1
[3], d2
[3];
315 DIFF3(dodec
[a
], dodec
[b
], d1
);
316 DIFF3(dodec
[b
], dodec
[c
], d2
);
317 crossprod(d1
, d2
, n0
);
321 /* glNormal3fv(n0); */
322 glVertex3fv(&dodec
[a
][0]);
323 glVertex3fv(&dodec
[b
][0]);
324 glVertex3fv(&dodec
[c
][0]);
325 glVertex3fv(&dodec
[d
][0]);
326 glVertex3fv(&dodec
[e
][0]);
331 dodecahedron(GLenum type
)
333 static int inited
= 0;
339 pentagon(0, 1, 9, 16, 5, type
);
340 pentagon(1, 0, 3, 18, 7, type
);
341 pentagon(1, 7, 11, 10, 9, type
);
342 pentagon(11, 7, 18, 19, 6, type
);
343 pentagon(8, 17, 16, 9, 10, type
);
344 pentagon(2, 14, 15, 6, 19, type
);
345 pentagon(2, 13, 12, 4, 14, type
);
346 pentagon(2, 19, 18, 3, 13, type
);
347 pentagon(3, 0, 5, 12, 13, type
);
348 pentagon(6, 15, 8, 10, 11, type
);
349 pentagon(4, 17, 8, 15, 14, type
);
350 pentagon(4, 12, 5, 16, 17, type
);
355 glutWireDodecahedron(void)
357 dodecahedron(GL_LINE_LOOP
);
361 glutSolidDodecahedron(void)
363 dodecahedron(GL_TRIANGLE_FAN
);
369 recorditem(GLfloat
* n1
, GLfloat
* n2
, GLfloat
* n3
,
372 GLfloat q0
[3], q1
[3];
376 crossprod(q0
, q1
, q1
);
380 /* glNormal3fv(q1); */
388 subdivide(GLfloat
* v0
, GLfloat
* v1
, GLfloat
* v2
,
392 GLfloat w0
[3], w1
[3], w2
[3];
397 for (i
= 0; i
< depth
; i
++) {
398 for (j
= 0; i
+ j
< depth
; j
++) {
400 for (n
= 0; n
< 3; n
++) {
401 w0
[n
] = (i
* v0
[n
] + j
* v1
[n
] + k
* v2
[n
]) / depth
;
402 w1
[n
] = ((i
+ 1) * v0
[n
] + j
* v1
[n
] + (k
- 1) * v2
[n
])
404 w2
[n
] = (i
* v0
[n
] + (j
+ 1) * v1
[n
] + (k
- 1) * v2
[n
])
407 l
= sqrt(w0
[0] * w0
[0] + w0
[1] * w0
[1] + w0
[2] * w0
[2]);
411 l
= sqrt(w1
[0] * w1
[0] + w1
[1] * w1
[1] + w1
[2] * w1
[2]);
415 l
= sqrt(w2
[0] * w2
[0] + w2
[1] * w2
[1] + w2
[2] * w2
[2]);
419 recorditem(w1
, w0
, w2
, shadeType
);
425 drawtriangle(int i
, GLfloat data
[][3], int ndx
[][3],
428 GLfloat
*x0
, *x1
, *x2
;
430 x0
= data
[ndx
[i
][0]];
431 x1
= data
[ndx
[i
][1]];
432 x2
= data
[ndx
[i
][2]];
433 subdivide(x0
, x1
, x2
, shadeType
);
436 /* octahedron data: The octahedron produced is centered at the
437 origin and has radius 1.0 */
438 static GLfloat odata
[6][3] =
448 static int ondex
[8][3] =
461 octahedron(GLenum shadeType
)
465 for (i
= 7; i
>= 0; i
--) {
466 drawtriangle(i
, odata
, ondex
, shadeType
);
472 glutWireOctahedron(void)
474 octahedron(GL_LINE_LOOP
);
478 glutSolidOctahedron(void)
480 octahedron(GL_TRIANGLES
);
485 /* icosahedron data: These numbers are rigged to make an
486 icosahedron of radius 1.0 */
488 #define X .525731112119133606
489 #define Z .850650808352039932
491 static GLfloat idata
[12][3] =
507 static int index
[20][3] =
532 icosahedron(GLenum shadeType
)
536 for (i
= 19; i
>= 0; i
--) {
537 drawtriangle(i
, idata
, index
, shadeType
);
543 glutWireIcosahedron(void)
545 icosahedron(GL_LINE_LOOP
);
549 glutSolidIcosahedron(void)
551 icosahedron(GL_TRIANGLES
);
556 /* tetrahedron data: */
558 #define T 1.73205080756887729
560 static GLfloat tdata
[4][3] =
568 static int tndex
[4][3] =
577 tetrahedron(GLenum shadeType
)
581 for (i
= 3; i
>= 0; i
--)
582 drawtriangle(i
, tdata
, tndex
, shadeType
);
587 glutWireTetrahedron(void)
589 tetrahedron(GL_LINE_LOOP
);
593 glutSolidTetrahedron(void)
595 tetrahedron(GL_TRIANGLES
);