00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include <math.h>
00048 #include <GL/gl.h>
00049 #include <GL/glu.h>
00050 #include <GL/glut.h>
00051 #include "glutint.h"
00052
00053 static GLUquadricObj *quadObj;
00054
00055 #define QUAD_OBJ_INIT() { if(!quadObj) initQuadObj(); }
00056
00057 static void
00058 initQuadObj(void)
00059 {
00060 quadObj = gluNewQuadric();
00061 if (!quadObj)
00062 __glutFatalError("out of memory.");
00063 }
00064
00065 void
00066 glutWireSphere(GLdouble radius, GLint slices, GLint stacks)
00067 {
00068 QUAD_OBJ_INIT();
00069 gluQuadricDrawStyle(quadObj, GLU_LINE);
00070 gluQuadricNormals(quadObj, GLU_SMOOTH);
00071
00072
00073
00074 gluSphere(quadObj, radius, slices, stacks);
00075 }
00076
00077 void
00078 glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
00079 {
00080 QUAD_OBJ_INIT();
00081 gluQuadricDrawStyle(quadObj, GLU_FILL);
00082 gluQuadricNormals(quadObj, GLU_SMOOTH);
00083
00084
00085
00086 gluSphere(quadObj, radius, slices, stacks);
00087 }
00088
00089 void
00090 glutWireCone(GLdouble base, GLdouble height,
00091 GLint slices, GLint stacks)
00092 {
00093 QUAD_OBJ_INIT();
00094 gluQuadricDrawStyle(quadObj, GLU_LINE);
00095 gluQuadricNormals(quadObj, GLU_SMOOTH);
00096
00097
00098
00099 gluCylinder(quadObj, base, 0.0, height, slices, stacks);
00100 }
00101
00102 void
00103 glutSolidCone(GLdouble base, GLdouble height,
00104 GLint slices, GLint stacks)
00105 {
00106 QUAD_OBJ_INIT();
00107 gluQuadricDrawStyle(quadObj, GLU_FILL);
00108 gluQuadricNormals(quadObj, GLU_SMOOTH);
00109
00110
00111
00112 gluCylinder(quadObj, base, 0.0, height, slices, stacks);
00113 }
00114
00115 static void
00116 drawBox(GLfloat x0, GLfloat x1, GLfloat y0, GLfloat y1,
00117 GLfloat z0, GLfloat z1, GLenum type)
00118 {
00119 static GLfloat n[6][3] =
00120 {
00121 {-1.0, 0.0, 0.0},
00122 {0.0, 1.0, 0.0},
00123 {1.0, 0.0, 0.0},
00124 {0.0, -1.0, 0.0},
00125 {0.0, 0.0, 1.0},
00126 {0.0, 0.0, -1.0}
00127 };
00128 static GLint faces[6][4] =
00129 {
00130 {0, 1, 2, 3},
00131 {3, 2, 6, 7},
00132 {7, 6, 5, 4},
00133 {4, 5, 1, 0},
00134 {5, 6, 2, 1},
00135 {7, 4, 0, 3}
00136 };
00137 GLfloat v[8][3], tmp;
00138 GLint i;
00139
00140 if (x0 > x1) {
00141 tmp = x0;
00142 x0 = x1;
00143 x1 = tmp;
00144 }
00145 if (y0 > y1) {
00146 tmp = y0;
00147 y0 = y1;
00148 y1 = tmp;
00149 }
00150 if (z0 > z1) {
00151 tmp = z0;
00152 z0 = z1;
00153 z1 = tmp;
00154 }
00155 v[0][0] = v[1][0] = v[2][0] = v[3][0] = x0;
00156 v[4][0] = v[5][0] = v[6][0] = v[7][0] = x1;
00157 v[0][1] = v[1][1] = v[4][1] = v[5][1] = y0;
00158 v[2][1] = v[3][1] = v[6][1] = v[7][1] = y1;
00159 v[0][2] = v[3][2] = v[4][2] = v[7][2] = z0;
00160 v[1][2] = v[2][2] = v[5][2] = v[6][2] = z1;
00161
00162 for (i = 0; i < 6; i++) {
00163 glBegin(type);
00164 glNormal3fv(&n[i][0]);
00165 glVertex3fv(&v[faces[i][0]][0]);
00166 glVertex3fv(&v[faces[i][1]][0]);
00167 glVertex3fv(&v[faces[i][2]][0]);
00168 glVertex3fv(&v[faces[i][3]][0]);
00169 glEnd();
00170 }
00171 }
00172
00173 void
00174 glutWireCube(GLdouble size)
00175 {
00176 drawBox(-size / 2., size / 2.,
00177 -size / 2., size / 2.,
00178 -size / 2., size / 2.,
00179 GL_LINE_LOOP);
00180 }
00181
00182 void
00183 glutSolidCube(GLdouble size)
00184 {
00185 drawBox(-size / 2., size / 2.,
00186 -size / 2., size / 2.,
00187 -size / 2., size / 2.,
00188 GL_QUADS);
00189 }
00190
00191 static void
00192 doughnut(GLfloat r, GLfloat R, GLint nsides,
00193 GLint rings, GLenum type)
00194 {
00195 int i, j;
00196 GLfloat theta, phi, theta1, phi1;
00197 GLfloat p0[03], p1[3], p2[3], p3[3];
00198 GLfloat n0[3], n1[3], n2[3], n3[3];
00199
00200 for (i = 0; i < rings; i++) {
00201 theta = (GLfloat) i *2.0 * M_PI / rings;
00202 theta1 = (GLfloat) (i + 1) * 2.0 * M_PI / rings;
00203 for (j = 0; j < nsides; j++) {
00204 phi = (GLfloat) j *2.0 * M_PI / nsides;
00205 phi1 = (GLfloat) (j + 1) * 2.0 * M_PI / nsides;
00206
00207 p0[0] = cos(theta) * (R + r * cos(phi));
00208 p0[1] = -sin(theta) * (R + r * cos(phi));
00209 p0[2] = r * sin(phi);
00210
00211 p1[0] = cos(theta1) * (R + r * cos(phi));
00212 p1[1] = -sin(theta1) * (R + r * cos(phi));
00213 p1[2] = r * sin(phi);
00214
00215 p2[0] = cos(theta1) * (R + r * cos(phi1));
00216 p2[1] = -sin(theta1) * (R + r * cos(phi1));
00217 p2[2] = r * sin(phi1);
00218
00219 p3[0] = cos(theta) * (R + r * cos(phi1));
00220 p3[1] = -sin(theta) * (R + r * cos(phi1));
00221 p3[2] = r * sin(phi1);
00222
00223 n0[0] = cos(theta) * (cos(phi));
00224 n0[1] = -sin(theta) * (cos(phi));
00225 n0[2] = sin(phi);
00226
00227 n1[0] = cos(theta1) * (cos(phi));
00228 n1[1] = -sin(theta1) * (cos(phi));
00229 n1[2] = sin(phi);
00230
00231 n2[0] = cos(theta1) * (cos(phi1));
00232 n2[1] = -sin(theta1) * (cos(phi1));
00233 n2[2] = sin(phi1);
00234
00235 n3[0] = cos(theta) * (cos(phi1));
00236 n3[1] = -sin(theta) * (cos(phi1));
00237 n3[2] = sin(phi1);
00238
00239 glBegin(type);
00240 glNormal3fv(n3);
00241 glVertex3fv(p3);
00242 glNormal3fv(n2);
00243 glVertex3fv(p2);
00244 glNormal3fv(n1);
00245 glVertex3fv(p1);
00246 glNormal3fv(n0);
00247 glVertex3fv(p0);
00248 glEnd();
00249 }
00250 }
00251 }
00252
00253 void
00254 glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
00255 GLint nsides, GLint rings)
00256 {
00257 doughnut(innerRadius, outerRadius,
00258 nsides, rings, GL_LINE_LOOP);
00259 }
00260
00261 void
00262 glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
00263 GLint nsides, GLint rings)
00264 {
00265 doughnut(innerRadius, outerRadius, nsides, rings, GL_QUADS);
00266 }
00267
00268 static GLfloat dodec[20][3];
00269
00270 static void
00271 initDodecahedron(void)
00272 {
00273 GLfloat alpha, beta;
00274
00275 alpha = sqrt(2.0 / (3.0 + sqrt(5.0)));
00276 beta = 1.0 + sqrt(6.0 / (3.0 + sqrt(5.0)) -
00277 2.0 + 2.0 * sqrt(2.0 / (3.0 + sqrt(5.0))));
00278 dodec[0][0] = -alpha; dodec[0][1] = 0; dodec[0][2] = beta;
00279 dodec[1][0] = alpha; dodec[1][1] = 0; dodec[1][2] = beta;
00280 dodec[2][0] = -1; dodec[2][1] = -1; dodec[2][2] = -1;
00281 dodec[3][0] = -1; dodec[3][1] = -1; dodec[3][2] = 1;
00282 dodec[4][0] = -1; dodec[4][1] = 1; dodec[4][2] = -1;
00283 dodec[5][0] = -1; dodec[5][1] = 1; dodec[5][2] = 1;
00284 dodec[6][0] = 1; dodec[6][1] = -1; dodec[6][2] = -1;
00285 dodec[7][0] = 1; dodec[7][1] = -1; dodec[7][2] = 1;
00286 dodec[8][0] = 1; dodec[8][1] = 1; dodec[8][2] = -1;
00287 dodec[9][0] = 1; dodec[9][1] = 1; dodec[9][2] = 1;
00288 dodec[10][0] = beta; dodec[10][1] = alpha; dodec[10][2] = 0;
00289 dodec[11][0] = beta; dodec[11][1] = -alpha; dodec[11][2] = 0;
00290 dodec[12][0] = -beta; dodec[12][1] = alpha; dodec[12][2] = 0;
00291 dodec[13][0] = -beta; dodec[13][1] = -alpha; dodec[13][2] = 0;
00292 dodec[14][0] = -alpha; dodec[14][1] = 0; dodec[14][2] = -beta;
00293 dodec[15][0] = alpha; dodec[15][1] = 0; dodec[15][2] = -beta;
00294 dodec[16][0] = 0; dodec[16][1] = beta; dodec[16][2] = alpha;
00295 dodec[17][0] = 0; dodec[17][1] = beta; dodec[17][2] = -alpha;
00296 dodec[18][0] = 0; dodec[18][1] = -beta; dodec[18][2] = alpha;
00297 dodec[19][0] = 0; dodec[19][1] = -beta; dodec[19][2] = -alpha;
00298 }
00299
00300 #define DIFF3(_a,_b,_c) { \
00301 (_c)[0] = (_a)[0] - (_b)[0]; \
00302 (_c)[1] = (_a)[1] - (_b)[1]; \
00303 (_c)[2] = (_a)[2] - (_b)[2]; \
00304 }
00305
00306 static void
00307 crossprod(GLfloat v1[3], GLfloat v2[3], GLfloat prod[3])
00308 {
00309 GLfloat p[3];
00310
00311 p[0] = v1[1] * v2[2] - v2[1] * v1[2];
00312 p[1] = v1[2] * v2[0] - v2[2] * v1[0];
00313 p[2] = v1[0] * v2[1] - v2[0] * v1[1];
00314 prod[0] = p[0];
00315 prod[1] = p[1];
00316 prod[2] = p[2];
00317 }
00318
00319 static void
00320 normalize(GLfloat v[3])
00321 {
00322 GLfloat d;
00323
00324 d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
00325 if (d == 0.0) {
00326 __glutWarning("normalize: zero length vector");
00327 v[0] = d = 1.0;
00328 }
00329 d = 1 / d;
00330 v[0] *= d;
00331 v[1] *= d;
00332 v[2] *= d;
00333 }
00334
00335 static void
00336 pentagon(int a, int b, int c, int d, int e, GLenum shadeType)
00337 {
00338 GLfloat n0[3], d1[3], d2[3];
00339
00340 DIFF3(dodec[a], dodec[b], d1);
00341 DIFF3(dodec[b], dodec[c], d2);
00342 crossprod(d1, d2, n0);
00343 normalize(n0);
00344
00345 glBegin(shadeType);
00346 glNormal3fv(n0);
00347 glVertex3fv(&dodec[a][0]);
00348 glVertex3fv(&dodec[b][0]);
00349 glVertex3fv(&dodec[c][0]);
00350 glVertex3fv(&dodec[d][0]);
00351 glVertex3fv(&dodec[e][0]);
00352 glEnd();
00353 }
00354
00355 static void
00356 dodecahedron(GLenum type)
00357 {
00358 static int inited = 0;
00359
00360 if (inited == 0) {
00361 inited = 1;
00362 initDodecahedron();
00363 }
00364 pentagon(0, 1, 9, 16, 5, type);
00365 pentagon(1, 0, 3, 18, 7, type);
00366 pentagon(1, 7, 11, 10, 9, type);
00367 pentagon(11, 7, 18, 19, 6, type);
00368 pentagon(8, 17, 16, 9, 10, type);
00369 pentagon(2, 14, 15, 6, 19, type);
00370 pentagon(2, 13, 12, 4, 14, type);
00371 pentagon(2, 19, 18, 3, 13, type);
00372 pentagon(3, 0, 5, 12, 13, type);
00373 pentagon(6, 15, 8, 10, 11, type);
00374 pentagon(4, 17, 8, 15, 14, type);
00375 pentagon(4, 12, 5, 16, 17, type);
00376 }
00377
00378 void
00379 glutWireDodecahedron(void)
00380 {
00381 dodecahedron(GL_LINE_LOOP);
00382 }
00383
00384 void
00385 glutSolidDodecahedron(void)
00386 {
00387 dodecahedron(GL_TRIANGLE_FAN);
00388 }
00389
00390 static void
00391 recorditem(GLfloat * n1, GLfloat * n2, GLfloat * n3,
00392 GLenum shadeType)
00393 {
00394 GLfloat q0[3], q1[3];
00395
00396 DIFF3(n1, n2, q0);
00397 DIFF3(n2, n3, q1);
00398 crossprod(q0, q1, q1);
00399 normalize(q1);
00400
00401 glBegin(shadeType);
00402 glNormal3fv(q1);
00403 glVertex3fv(n1);
00404 glVertex3fv(n2);
00405 glVertex3fv(n3);
00406 glEnd();
00407 }
00408
00409 static void
00410 subdivide(GLfloat * v0, GLfloat * v1, GLfloat * v2,
00411 GLenum shadeType)
00412 {
00413 int depth;
00414 GLfloat w0[3], w1[3], w2[3];
00415 GLfloat l;
00416 int i, j, k, n;
00417
00418 depth = 1;
00419 for (i = 0; i < depth; i++) {
00420 for (j = 0; i + j < depth; j++) {
00421 k = depth - i - j;
00422 for (n = 0; n < 3; n++) {
00423 w0[n] = (i * v0[n] + j * v1[n] + k * v2[n]) / depth;
00424 w1[n] = ((i + 1) * v0[n] + j * v1[n] + (k - 1) * v2[n])
00425 / depth;
00426 w2[n] = (i * v0[n] + (j + 1) * v1[n] + (k - 1) * v2[n])
00427 / depth;
00428 }
00429 l = sqrt(w0[0] * w0[0] + w0[1] * w0[1] + w0[2] * w0[2]);
00430 w0[0] /= l;
00431 w0[1] /= l;
00432 w0[2] /= l;
00433 l = sqrt(w1[0] * w1[0] + w1[1] * w1[1] + w1[2] * w1[2]);
00434 w1[0] /= l;
00435 w1[1] /= l;
00436 w1[2] /= l;
00437 l = sqrt(w2[0] * w2[0] + w2[1] * w2[1] + w2[2] * w2[2]);
00438 w2[0] /= l;
00439 w2[1] /= l;
00440 w2[2] /= l;
00441 recorditem(w1, w0, w2, shadeType);
00442 }
00443 }
00444 }
00445
00446 static void
00447 drawtriangle(int i, GLfloat data[][3], int ndx[][3],
00448 GLenum shadeType)
00449 {
00450 GLfloat *x0, *x1, *x2;
00451
00452 x0 = data[ndx[i][0]];
00453 x1 = data[ndx[i][1]];
00454 x2 = data[ndx[i][2]];
00455 subdivide(x0, x1, x2, shadeType);
00456 }
00457
00458
00459
00460 static GLfloat odata[6][3] =
00461 {
00462 {1.0, 0.0, 0.0},
00463 {-1.0, 0.0, 0.0},
00464 {0.0, 1.0, 0.0},
00465 {0.0, -1.0, 0.0},
00466 {0.0, 0.0, 1.0},
00467 {0.0, 0.0, -1.0}
00468 };
00469
00470 static int ondex[8][3] =
00471 {
00472 {0, 4, 2},
00473 {1, 2, 4},
00474 {0, 3, 4},
00475 {1, 4, 3},
00476 {0, 2, 5},
00477 {1, 5, 2},
00478 {0, 5, 3},
00479 {1, 3, 5}
00480 };
00481
00482 static void
00483 octahedron(GLenum shadeType)
00484 {
00485 int i;
00486
00487 for (i = 0; i < 8; i++) {
00488 drawtriangle(i, odata, ondex, shadeType);
00489 }
00490 }
00491
00492 void
00493 glutWireOctahedron(void)
00494 {
00495 octahedron(GL_LINE_LOOP);
00496 }
00497
00498 void
00499 glutSolidOctahedron(void)
00500 {
00501 octahedron(GL_TRIANGLES);
00502 }
00503
00504
00505
00506
00507 #define X .525731112119133606
00508 #define Z .850650808352039932
00509
00510 static GLfloat idata[12][3] =
00511 {
00512 {-X, 0, Z},
00513 {X, 0, Z},
00514 {-X, 0, -Z},
00515 {X, 0, -Z},
00516 {0, Z, X},
00517 {0, Z, -X},
00518 {0, -Z, X},
00519 {0, -Z, -X},
00520 {Z, X, 0},
00521 {-Z, X, 0},
00522 {Z, -X, 0},
00523 {-Z, -X, 0}
00524 };
00525
00526 static int index[20][3] =
00527 {
00528 {0, 4, 1},
00529 {0, 9, 4},
00530 {9, 5, 4},
00531 {4, 5, 8},
00532 {4, 8, 1},
00533 {8, 10, 1},
00534 {8, 3, 10},
00535 {5, 3, 8},
00536 {5, 2, 3},
00537 {2, 7, 3},
00538 {7, 10, 3},
00539 {7, 6, 10},
00540 {7, 11, 6},
00541 {11, 0, 6},
00542 {0, 1, 6},
00543 {6, 1, 10},
00544 {9, 0, 11},
00545 {9, 11, 2},
00546 {9, 2, 5},
00547 {7, 2, 11},
00548 };
00549
00550 static void
00551 icosahedron(GLenum shadeType)
00552 {
00553 int i;
00554
00555 for (i = 0; i < 20; i++) {
00556 drawtriangle(i, idata, index, shadeType);
00557 }
00558 }
00559
00560 void
00561 glutWireIcosahedron(void)
00562 {
00563 icosahedron(GL_LINE_LOOP);
00564 }
00565
00566 void
00567 glutSolidIcosahedron(void)
00568 {
00569 icosahedron(GL_TRIANGLES);
00570 }
00571
00572
00573
00574 #define T 1.73205080756887729
00575
00576 static GLfloat tdata[4][3] =
00577 {
00578 {T, T, T},
00579 {T, -T, -T},
00580 {-T, T, -T},
00581 {-T, -T, T}
00582 };
00583
00584 static int tndex[4][3] =
00585 {
00586 {0, 1, 3},
00587 {2, 1, 0},
00588 {3, 2, 0},
00589 {1, 2, 3}
00590 };
00591
00592 static void
00593 tetrahedron(GLenum shadeType)
00594 {
00595 int i;
00596
00597 for (i = 0; i < 4; i++)
00598 drawtriangle(i, tdata, tndex, shadeType);
00599 }
00600
00601 void
00602 glutWireTetrahedron(void)
00603 {
00604 tetrahedron(GL_LINE_LOOP);
00605 }
00606
00607 void
00608 glutSolidTetrahedron(void)
00609 {
00610 tetrahedron(GL_TRIANGLES);
00611 }
00612