Subversion Repositories shark

Rev

Rev 183 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
55 pj 1
 
2
/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
3
 
4
/**
5
(c) Copyright 1993, Silicon Graphics, Inc.
6
 
7
ALL RIGHTS RESERVED
8
 
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.
17
 
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.
31
 
32
US Government Users Restricted Rights
33
 
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
42
94039-7311.
43
 
44
OpenGL(TM) is a trademark of Silicon Graphics, Inc.
45
*/
46
 
47
#include <math.h>
48
#include <GL/gl.h>
49
#include <GL/glu.h>
50
#include "GL/glut.h"
51
 
52
/* Some <math.h> files do not define M_PI... */
53
#ifndef M_PI
54
#define M_PI 3.14159265358979323846
55
#endif
56
 
57
static GLUquadricObj *quadObj;
58
 
59
#define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
60
 
61
static void
62
initQuadObj(void)
63
{
64
  quadObj = gluNewQuadric();
65
/*  if (!quadObj)
66
    __glutFatalError("out of memory."); */
67
}
68
 
69
/* CENTRY */
70
void APIENTRY
71
glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
72
{
73
  QUAD_OBJ_INIT();
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);
80
}
81
 
82
void APIENTRY
83
glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
84
{
85
  QUAD_OBJ_INIT();
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);
92
}
93
 
94
void APIENTRY
95
glutWireCone(GLdouble base, GLdouble height,
96
  GLint slices, GLint stacks)
97
{
98
  QUAD_OBJ_INIT();
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);
105
}
106
 
107
void APIENTRY
108
glutSolidCone(GLdouble base, GLdouble height,
109
  GLint slices, GLint stacks)
110
{
111
  QUAD_OBJ_INIT();
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);
118
}
119
 
120
/* ENDCENTRY */
121
 
122
static void
123
drawBox(GLfloat size, GLenum type)
124
{
125
  static GLfloat n[6][3] =
126
  {
127
    {-1.0, 0.0, 0.0},
128
    {0.0, 1.0, 0.0},
129
    {1.0, 0.0, 0.0},
130
    {0.0, -1.0, 0.0},
131
    {0.0, 0.0, 1.0},
132
    {0.0, 0.0, -1.0}
133
  };
134
  static GLint faces[6][4] =
135
  {
136
    {0, 1, 2, 3},
137
    {3, 2, 6, 7},
138
    {7, 6, 5, 4},
139
    {4, 5, 1, 0},
140
    {5, 6, 2, 1},
141
    {7, 4, 0, 3}
142
  };
143
  GLfloat v[8][3];
144
  GLint i;
145
 
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;
152
 
153
  for (i = 5; i >= 0; i--) {
154
    glBegin(type);
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]);
160
    glEnd();
161
  }
162
}
163
 
164
/* CENTRY */
165
void APIENTRY
166
glutWireCube(GLdouble size)
167
{
168
  drawBox(size, GL_LINE_LOOP);
169
}
170
 
171
void APIENTRY
172
glutSolidCube(GLdouble size)
173
{
174
  drawBox(size, GL_QUADS);
175
}
176
 
177
/* ENDCENTRY */
178
 
179
static void
180
doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
181
{
182
  int i, j;
183
  GLfloat theta, phi, theta1;
184
  GLfloat cosTheta, sinTheta;
185
  GLfloat cosTheta1, sinTheta1;
186
  GLfloat ringDelta, sideDelta;
187
 
188
  ringDelta = 2.0 * M_PI / rings;
189
  sideDelta = 2.0 * M_PI / nsides;
190
 
191
  theta = 0.0;
192
  cosTheta = 1.0;
193
  sinTheta = 0.0;
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);
199
    phi = 0.0;
200
    for (j = nsides; j >= 0; j--) {
201
      GLfloat cosPhi, sinPhi, dist;
202
 
203
      phi += sideDelta;
204
      cosPhi = cos(phi);
205
      sinPhi = sin(phi);
206
      dist = R + r * cosPhi;
207
 
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);
212
    }
213
    glEnd();
214
    theta = theta1;
215
    cosTheta = cosTheta1;
216
    sinTheta = sinTheta1;
217
  }
218
}
219
 
220
/* CENTRY */
221
void APIENTRY
222
glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
223
  GLint nsides, GLint rings)
224
{
225
  glPushAttrib(GL_POLYGON_BIT);
226
  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
227
  doughnut(innerRadius, outerRadius, nsides, rings);
228
  glPopAttrib();
229
}
230
 
231
void APIENTRY
232
glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
233
  GLint nsides, GLint rings)
234
{
235
  doughnut(innerRadius, outerRadius, nsides, rings);
236
}
237
 
238
/* ENDCENTRY */
239
 
240
static GLfloat dodec[20][3];
241
 
242
static void
243
initDodecahedron(void)
244
{
245
  GLfloat alpha, beta;
246
 
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))));
250
  /* *INDENT-OFF* */
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;
271
  /* *INDENT-ON* */
272
 
273
}
274
 
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]; \
279
}
280
 
281
static void
282
crossprod(GLfloat v1[3], GLfloat v2[3], GLfloat prod[3])
283
{
284
  GLfloat p[3];         /* in case prod == v1 or v2 */
285
 
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];
289
  prod[0] = p[0];
290
  prod[1] = p[1];
291
  prod[2] = p[2];
292
}
293
 
294
static void
295
normalize(GLfloat v[3])
296
{
297
  GLfloat d;
298
 
299
  d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
300
  if (d == 0.0) {
301
//    __glutWarning("normalize: zero length vector");
302
    v[0] = d = 1.0;
303
  }
304
  d = 1 / d;
305
  v[0] *= d;
306
  v[1] *= d;
307
  v[2] *= d;
308
}
309
 
310
static void
311
pentagon(int a, int b, int c, int d, int e, GLenum shadeType)
312
{
313
  GLfloat n0[3], d1[3], d2[3];
314
 
315
  DIFF3(dodec[a], dodec[b], d1);
316
  DIFF3(dodec[b], dodec[c], d2);
317
  crossprod(d1, d2, n0);
318
  normalize(n0);
319
 
320
  glBegin(shadeType);
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]);
327
  glEnd();
328
}
329
 
330
static void
331
dodecahedron(GLenum type)
332
{
333
  static int inited = 0;
334
 
335
  if (inited == 0) {
336
    inited = 1;
337
    initDodecahedron();
338
  }
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);
351
}
352
 
353
/* CENTRY */
354
void APIENTRY
355
glutWireDodecahedron(void)
356
{
357
  dodecahedron(GL_LINE_LOOP);
358
}
359
 
360
void APIENTRY
361
glutSolidDodecahedron(void)
362
{
363
  dodecahedron(GL_TRIANGLE_FAN);
364
}
365
 
366
/* ENDCENTRY */
367
 
368
static void
369
recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
370
  GLenum shadeType)
371
{
372
  GLfloat q0[3], q1[3];
373
 
374
  DIFF3(n1, n2, q0);
375
  DIFF3(n2, n3, q1);
376
  crossprod(q0, q1, q1);
377
  normalize(q1);
378
 
379
  glBegin(shadeType);
380
  glNormal3fv(q1);
381
  glVertex3fv(n1);
382
  glVertex3fv(n2);
383
  glVertex3fv(n3);
384
  glEnd();
385
}
386
 
387
static void
388
subdivide(GLfloat * v0, GLfloat * v1, GLfloat * v2,
389
  GLenum shadeType)
390
{
391
  int depth;
392
  GLfloat w0[3], w1[3], w2[3];
393
  GLfloat l;
394
  int i, j, k, n;
395
 
396
  depth = 1;
397
  for (i = 0; i < depth; i++) {
398
    for (j = 0; i + j < depth; j++) {
399
      k = depth - i - 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])
403
          / depth;
404
        w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
405
          / depth;
406
      }
407
      l = sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
408
      w0[0] /= l;
409
      w0[1] /= l;
410
      w0[2] /= l;
411
      l = sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
412
      w1[0] /= l;
413
      w1[1] /= l;
414
      w1[2] /= l;
415
      l = sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
416
      w2[0] /= l;
417
      w2[1] /= l;
418
      w2[2] /= l;
419
      recorditem(w1, w0, w2, shadeType);
420
    }
421
  }
422
}
423
 
424
static void
425
drawtriangle(int i, GLfloat data[][3], int ndx[][3],
426
  GLenum shadeType)
427
{
428
  GLfloat *x0, *x1, *x2;
429
 
430
  x0 = data[ndx[i][0]];
431
  x1 = data[ndx[i][1]];
432
  x2 = data[ndx[i][2]];
433
  subdivide(x0, x1, x2, shadeType);
434
}
435
 
436
/* octahedron data: The octahedron produced is centered at the
437
   origin and has radius 1.0 */
438
static GLfloat odata[6][3] =
439
{
440
  {1.0, 0.0, 0.0},
441
  {-1.0, 0.0, 0.0},
442
  {0.0, 1.0, 0.0},
443
  {0.0, -1.0, 0.0},
444
  {0.0, 0.0, 1.0},
445
  {0.0, 0.0, -1.0}
446
};
447
 
448
static int ondex[8][3] =
449
{
450
  {0, 4, 2},
451
  {1, 2, 4},
452
  {0, 3, 4},
453
  {1, 4, 3},
454
  {0, 2, 5},
455
  {1, 5, 2},
456
  {0, 5, 3},
457
  {1, 3, 5}
458
};
459
 
460
static void
461
octahedron(GLenum shadeType)
462
{
463
  int i;
464
 
465
  for (i = 7; i >= 0; i--) {
466
    drawtriangle(i, odata, ondex, shadeType);
467
  }
468
}
469
 
470
/* CENTRY */
471
void APIENTRY
472
glutWireOctahedron(void)
473
{
474
  octahedron(GL_LINE_LOOP);
475
}
476
 
477
void APIENTRY
478
glutSolidOctahedron(void)
479
{
480
  octahedron(GL_TRIANGLES);
481
}
482
 
483
/* ENDCENTRY */
484
 
485
/* icosahedron data: These numbers are rigged to make an
486
   icosahedron of radius 1.0 */
487
 
488
#define X .525731112119133606
489
#define Z .850650808352039932
490
 
491
static GLfloat idata[12][3] =
492
{
493
  {-X, 0, Z},
494
  {X, 0, Z},
495
  {-X, 0, -Z},
496
  {X, 0, -Z},
497
  {0, Z, X},
498
  {0, Z, -X},
499
  {0, -Z, X},
500
  {0, -Z, -X},
501
  {Z, X, 0},
502
  {-Z, X, 0},
503
  {Z, -X, 0},
504
  {-Z, -X, 0}
505
};
506
 
507
static int index[20][3] =
508
{
509
  {0, 4, 1},
510
  {0, 9, 4},
511
  {9, 5, 4},
512
  {4, 5, 8},
513
  {4, 8, 1},
514
  {8, 10, 1},
515
  {8, 3, 10},
516
  {5, 3, 8},
517
  {5, 2, 3},
518
  {2, 7, 3},
519
  {7, 10, 3},
520
  {7, 6, 10},
521
  {7, 11, 6},
522
  {11, 0, 6},
523
  {0, 1, 6},
524
  {6, 1, 10},
525
  {9, 0, 11},
526
  {9, 11, 2},
527
  {9, 2, 5},
528
  {7, 2, 11},
529
};
530
 
531
static void
532
icosahedron(GLenum shadeType)
533
{
534
  int i;
535
 
536
  for (i = 19; i >= 0; i--) {
537
    drawtriangle(i, idata, index, shadeType);
538
  }
539
}
540
 
541
/* CENTRY */
542
void APIENTRY
543
glutWireIcosahedron(void)
544
{
545
  icosahedron(GL_LINE_LOOP);
546
}
547
 
548
void APIENTRY
549
glutSolidIcosahedron(void)
550
{
551
  icosahedron(GL_TRIANGLES);
552
}
553
 
554
/* ENDCENTRY */
555
 
556
/* tetrahedron data: */
557
 
558
#define T       1.73205080756887729
559
 
560
static GLfloat tdata[4][3] =
561
{
562
  {T, T, T},
563
  {T, -T, -T},
564
  {-T, T, -T},
565
  {-T, -T, T}
566
};
567
 
568
static int tndex[4][3] =
569
{
570
  {0, 1, 3},
571
  {2, 1, 0},
572
  {3, 2, 0},
573
  {1, 2, 3}
574
};
575
 
576
static void
577
tetrahedron(GLenum shadeType)
578
{
579
  int i;
580
 
581
  for (i = 3; i >= 0; i--)
582
    drawtriangle(i, tdata, tndex, shadeType);
583
}
584
 
585
/* CENTRY */
586
void APIENTRY
587
glutWireTetrahedron(void)
588
{
589
  tetrahedron(GL_LINE_LOOP);
590
}
591
 
592
void APIENTRY
593
glutSolidTetrahedron(void)
594
{
595
  tetrahedron(GL_TRIANGLES);
596
}
597
 
598
/* ENDCENTRY */