00001
00002
00003
00041
00042
00043
00044
00045 #include <stdio.h>
00046 #include <stdlib.h>
00047 #include <string.h>
00048 #include <math.h>
00049 #include <GL/glut.h>
00050
00051 static int useRGB = 1;
00052 static int useLighting = 1;
00053 static int useFog = 0;
00054 static int useDB = 1;
00055 static int useLogo = 0;
00056 static int useQuads = 1;
00057
00058 static int tick = -1;
00059 static int moving = 1;
00060
00061 #define GREY 0
00062 #define RED 1
00063 #define GREEN 2
00064 #define BLUE 3
00065 #define CYAN 4
00066 #define MAGENTA 5
00067 #define YELLOW 6
00068 #define BLACK 7
00069
00070 static float materialColor[8][4] =
00071 {
00072 {0.8, 0.8, 0.8, 1.0},
00073 {0.8, 0.0, 0.0, 1.0},
00074 {0.0, 0.8, 0.0, 1.0},
00075 {0.0, 0.0, 0.8, 1.0},
00076 {0.0, 0.8, 0.8, 1.0},
00077 {0.8, 0.0, 0.8, 1.0},
00078 {0.8, 0.8, 0.0, 1.0},
00079 {0.0, 0.0, 0.0, 0.6},
00080 };
00081
00082 static float lightPos[4] =
00083 {2.0, 4.0, 2.0, 1.0};
00084 #if 0
00085 static float lightDir[4] =
00086 {-2.0, -4.0, -2.0, 1.0};
00087 #endif
00088 static float lightAmb[4] =
00089 {0.2, 0.2, 0.2, 1.0};
00090 static float lightDiff[4] =
00091 {0.8, 0.8, 0.8, 1.0};
00092 static float lightSpec[4] =
00093 {0.4, 0.4, 0.4, 1.0};
00094
00095 static float groundPlane[4] =
00096 {0.0, 1.0, 0.0, 1.499};
00097 static float backPlane[4] =
00098 {0.0, 0.0, 1.0, 0.899};
00099
00100 static float fogColor[4] =
00101 {0.0, 0.0, 0.0, 0.0};
00102 static float fogIndex[1] =
00103 {0.0};
00104
00105 static unsigned char shadowPattern[128] =
00106 {
00107 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00108 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00109 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00110 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00111 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00112 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00113 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00114 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00115 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00116 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00117 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00118 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00119 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00120 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00121 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
00122 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55
00123 };
00124
00125 static unsigned char sgiPattern[128] =
00126 {
00127 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
00128 0xff, 0xbd, 0xff, 0x83, 0xff, 0x5a, 0xff, 0xef,
00129 0xfe, 0xdb, 0x7f, 0xef, 0xfd, 0xdb, 0xbf, 0xef,
00130 0xfb, 0xdb, 0xdf, 0xef, 0xf7, 0xdb, 0xef, 0xef,
00131 0xfb, 0xdb, 0xdf, 0xef, 0xfd, 0xdb, 0xbf, 0x83,
00132 0xce, 0xdb, 0x73, 0xff, 0xb7, 0x5a, 0xed, 0xff,
00133 0xbb, 0xdb, 0xdd, 0xc7, 0xbd, 0xdb, 0xbd, 0xbb,
00134 0xbe, 0xbd, 0x7d, 0xbb, 0xbf, 0x7e, 0xfd, 0xb3,
00135 0xbe, 0xe7, 0x7d, 0xbf, 0xbd, 0xdb, 0xbd, 0xbf,
00136 0xbb, 0xbd, 0xdd, 0xbb, 0xb7, 0x7e, 0xed, 0xc7,
00137 0xce, 0xdb, 0x73, 0xff, 0xfd, 0xdb, 0xbf, 0xff,
00138 0xfb, 0xdb, 0xdf, 0x87, 0xf7, 0xdb, 0xef, 0xfb,
00139 0xf7, 0xdb, 0xef, 0xfb, 0xfb, 0xdb, 0xdf, 0xfb,
00140 0xfd, 0xdb, 0xbf, 0xc7, 0xfe, 0xdb, 0x7f, 0xbf,
00141 0xff, 0x5a, 0xff, 0xbf, 0xff, 0xbd, 0xff, 0xc3,
00142 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
00143 };
00144
00145 static float cube_vertexes[6][4][4] =
00146 {
00147 {
00148 {-1.0, -1.0, -1.0, 1.0},
00149 {-1.0, -1.0, 1.0, 1.0},
00150 {-1.0, 1.0, 1.0, 1.0},
00151 {-1.0, 1.0, -1.0, 1.0}},
00152
00153 {
00154 {1.0, 1.0, 1.0, 1.0},
00155 {1.0, -1.0, 1.0, 1.0},
00156 {1.0, -1.0, -1.0, 1.0},
00157 {1.0, 1.0, -1.0, 1.0}},
00158
00159 {
00160 {-1.0, -1.0, -1.0, 1.0},
00161 {1.0, -1.0, -1.0, 1.0},
00162 {1.0, -1.0, 1.0, 1.0},
00163 {-1.0, -1.0, 1.0, 1.0}},
00164
00165 {
00166 {1.0, 1.0, 1.0, 1.0},
00167 {1.0, 1.0, -1.0, 1.0},
00168 {-1.0, 1.0, -1.0, 1.0},
00169 {-1.0, 1.0, 1.0, 1.0}},
00170
00171 {
00172 {-1.0, -1.0, -1.0, 1.0},
00173 {-1.0, 1.0, -1.0, 1.0},
00174 {1.0, 1.0, -1.0, 1.0},
00175 {1.0, -1.0, -1.0, 1.0}},
00176
00177 {
00178 {1.0, 1.0, 1.0, 1.0},
00179 {-1.0, 1.0, 1.0, 1.0},
00180 {-1.0, -1.0, 1.0, 1.0},
00181 {1.0, -1.0, 1.0, 1.0}}
00182 };
00183
00184 static float cube_normals[6][4] =
00185 {
00186 {-1.0, 0.0, 0.0, 0.0},
00187 {1.0, 0.0, 0.0, 0.0},
00188 {0.0, -1.0, 0.0, 0.0},
00189 {0.0, 1.0, 0.0, 0.0},
00190 {0.0, 0.0, -1.0, 0.0},
00191 {0.0, 0.0, 1.0, 0.0}
00192 };
00193
00194 static void
00195 usage(void)
00196 {
00197 printf("\n");
00198 printf("usage: scube [options]\n");
00199 printf("\n");
00200 printf(" display a spinning cube and its shadow\n");
00201 printf("\n");
00202 printf(" Options:\n");
00203 printf(" -geometry window size and location\n");
00204 printf(" -c toggle color index mode\n");
00205 printf(" -l toggle lighting\n");
00206 printf(" -f toggle fog\n");
00207 printf(" -db toggle double buffering\n");
00208 printf(" -logo toggle sgi logo for the shadow pattern\n");
00209 printf(" -quads toggle use of GL_QUADS to draw the checkerboard\n");
00210 printf("\n");
00211 #ifndef EXIT_FAILURE
00212
00213 #define EXIT_FAILURE 1
00214 #endif
00215 exit(EXIT_FAILURE);
00216 }
00217
00218 void
00219 buildColormap(void)
00220 {
00221 if (useRGB) {
00222 return;
00223 } else {
00224 int mapSize = 1 << glutGet(GLUT_WINDOW_BUFFER_SIZE);
00225 int rampSize = mapSize / 8;
00226 int entry;
00227 int i;
00228
00229 for (entry = 0; entry < mapSize; ++entry) {
00230 int hue = entry / rampSize;
00231 GLfloat val = (entry % rampSize) * (1.0 / (rampSize - 1));
00232 GLfloat red, green, blue;
00233
00234 red = (hue == 0 || hue == 1 || hue == 5 || hue == 6) ? val : 0;
00235 green = (hue == 0 || hue == 2 || hue == 4 || hue == 6) ? val : 0;
00236 blue = (hue == 0 || hue == 3 || hue == 4 || hue == 5) ? val : 0;
00237
00238 glutSetColor(entry, red, green, blue);
00239 }
00240
00241 for (i = 0; i < 8; ++i) {
00242 materialColor[i][0] = i * rampSize + 0.2 * (rampSize - 1);
00243 materialColor[i][1] = i * rampSize + 0.8 * (rampSize - 1);
00244 materialColor[i][2] = i * rampSize + 1.0 * (rampSize - 1);
00245 materialColor[i][3] = 0.0;
00246 }
00247
00248 fogIndex[0] = -0.2 * (rampSize - 1);
00249 }
00250 }
00251
00252 static void
00253 setColor(int c)
00254 {
00255 if (useLighting) {
00256 if (useRGB) {
00257 glMaterialfv(GL_FRONT_AND_BACK,
00258 GL_AMBIENT_AND_DIFFUSE, &materialColor[c][0]);
00259 } else {
00260 glMaterialfv(GL_FRONT_AND_BACK,
00261 GL_COLOR_INDEXES, &materialColor[c][0]);
00262 }
00263 } else {
00264 if (useRGB) {
00265 glColor4fv(&materialColor[c][0]);
00266 } else {
00267 glIndexf(materialColor[c][1]);
00268 }
00269 }
00270 }
00271
00272 static void
00273 drawCube(int color)
00274 {
00275 int i;
00276
00277 setColor(color);
00278
00279 for (i = 0; i < 6; ++i) {
00280 glNormal3fv(&cube_normals[i][0]);
00281 glBegin(GL_POLYGON);
00282 glVertex4fv(&cube_vertexes[i][0][0]);
00283 glVertex4fv(&cube_vertexes[i][1][0]);
00284 glVertex4fv(&cube_vertexes[i][2][0]);
00285 glVertex4fv(&cube_vertexes[i][3][0]);
00286 glEnd();
00287 }
00288 }
00289
00290 static void
00291 drawCheck(int w, int h, int evenColor, int oddColor)
00292 {
00293 static int initialized = 0;
00294 static int usedLighting = 0;
00295 static GLuint checklist = 0;
00296
00297 if (!initialized || (usedLighting != useLighting)) {
00298 static float square_normal[4] =
00299 {0.0, 0.0, 1.0, 0.0};
00300 static float square[4][4];
00301 int i, j;
00302
00303 if (!checklist) {
00304 checklist = glGenLists(1);
00305 }
00306 glNewList(checklist, GL_COMPILE_AND_EXECUTE);
00307
00308 if (useQuads) {
00309 glNormal3fv(square_normal);
00310 glBegin(GL_QUADS);
00311 }
00312 for (j = 0; j < h; ++j) {
00313 for (i = 0; i < w; ++i) {
00314 square[0][0] = -1.0 + 2.0 / w * i;
00315 square[0][1] = -1.0 + 2.0 / h * (j + 1);
00316 square[0][2] = 0.0;
00317 square[0][3] = 1.0;
00318
00319 square[1][0] = -1.0 + 2.0 / w * i;
00320 square[1][1] = -1.0 + 2.0 / h * j;
00321 square[1][2] = 0.0;
00322 square[1][3] = 1.0;
00323
00324 square[2][0] = -1.0 + 2.0 / w * (i + 1);
00325 square[2][1] = -1.0 + 2.0 / h * j;
00326 square[2][2] = 0.0;
00327 square[2][3] = 1.0;
00328
00329 square[3][0] = -1.0 + 2.0 / w * (i + 1);
00330 square[3][1] = -1.0 + 2.0 / h * (j + 1);
00331 square[3][2] = 0.0;
00332 square[3][3] = 1.0;
00333
00334 if (i & 1 ^ j & 1) {
00335 setColor(oddColor);
00336 } else {
00337 setColor(evenColor);
00338 }
00339
00340 if (!useQuads) {
00341 glBegin(GL_POLYGON);
00342 }
00343 glVertex4fv(&square[0][0]);
00344 glVertex4fv(&square[1][0]);
00345 glVertex4fv(&square[2][0]);
00346 glVertex4fv(&square[3][0]);
00347 if (!useQuads) {
00348 glEnd();
00349 }
00350 }
00351 }
00352
00353 if (useQuads) {
00354 glEnd();
00355 }
00356 glEndList();
00357
00358 initialized = 1;
00359 usedLighting = useLighting;
00360 } else {
00361 glCallList(checklist);
00362 }
00363 }
00364
00365 static void
00366 myShadowMatrix(float ground[4], float light[4])
00367 {
00368 float dot;
00369 float shadowMat[4][4];
00370
00371 dot = ground[0] * light[0] +
00372 ground[1] * light[1] +
00373 ground[2] * light[2] +
00374 ground[3] * light[3];
00375
00376 shadowMat[0][0] = dot - light[0] * ground[0];
00377 shadowMat[1][0] = 0.0 - light[0] * ground[1];
00378 shadowMat[2][0] = 0.0 - light[0] * ground[2];
00379 shadowMat[3][0] = 0.0 - light[0] * ground[3];
00380
00381 shadowMat[0][1] = 0.0 - light[1] * ground[0];
00382 shadowMat[1][1] = dot - light[1] * ground[1];
00383 shadowMat[2][1] = 0.0 - light[1] * ground[2];
00384 shadowMat[3][1] = 0.0 - light[1] * ground[3];
00385
00386 shadowMat[0][2] = 0.0 - light[2] * ground[0];
00387 shadowMat[1][2] = 0.0 - light[2] * ground[1];
00388 shadowMat[2][2] = dot - light[2] * ground[2];
00389 shadowMat[3][2] = 0.0 - light[2] * ground[3];
00390
00391 shadowMat[0][3] = 0.0 - light[3] * ground[0];
00392 shadowMat[1][3] = 0.0 - light[3] * ground[1];
00393 shadowMat[2][3] = 0.0 - light[3] * ground[2];
00394 shadowMat[3][3] = dot - light[3] * ground[3];
00395
00396 glMultMatrixf((const GLfloat *) shadowMat);
00397 }
00398
00399 static char *windowNameRGBDB = "shadow cube (OpenGL RGB DB)";
00400 static char *windowNameRGB = "shadow cube (OpenGL RGB)";
00401 static char *windowNameIndexDB = "shadow cube (OpenGL Index DB)";
00402 static char *windowNameIndex = "shadow cube (OpenGL Index)";
00403
00404 void
00405 idle(void)
00406 {
00407 tick++;
00408 if (tick >= 120) {
00409 tick = 0;
00410 }
00411 glutPostRedisplay();
00412 }
00413
00414
00415 void
00416 keyboard(unsigned char ch, int x, int y)
00417 {
00418 switch (ch) {
00419 case 27:
00420 exit(0);
00421 break;
00422 case 'L':
00423 case 'l':
00424 useLighting = !useLighting;
00425 useLighting ? glEnable(GL_LIGHTING) :
00426 glDisable(GL_LIGHTING);
00427 glutPostRedisplay();
00428 break;
00429 case 'F':
00430 case 'f':
00431 useFog = !useFog;
00432 useFog ? glEnable(GL_FOG) : glDisable(GL_FOG);
00433 glutPostRedisplay();
00434 break;
00435 case '1':
00436 glFogf(GL_FOG_MODE, GL_LINEAR);
00437 glutPostRedisplay();
00438 break;
00439 case '2':
00440 glFogf(GL_FOG_MODE, GL_EXP);
00441 glutPostRedisplay();
00442 break;
00443 case '3':
00444 glFogf(GL_FOG_MODE, GL_EXP2);
00445 glutPostRedisplay();
00446 break;
00447 case ' ':
00448 if (!moving) {
00449 idle();
00450 glutPostRedisplay();
00451 }
00452 }
00453 }
00454
00455 void
00456 display(void)
00457 {
00458 GLfloat cubeXform[4][4];
00459
00460 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00461
00462 glPushMatrix();
00463 glTranslatef(0.0, -1.5, 0.0);
00464 glRotatef(-90.0, 1, 0, 0);
00465 glScalef(2.0, 2.0, 2.0);
00466
00467 drawCheck(6, 6, BLUE, YELLOW);
00468 glPopMatrix();
00469
00470 glPushMatrix();
00471 glTranslatef(0.0, 0.0, -0.9);
00472 glScalef(2.0, 2.0, 2.0);
00473
00474 drawCheck(6, 6, BLUE, YELLOW);
00475 glPopMatrix();
00476
00477 glPushMatrix();
00478 glTranslatef(0.0, 0.2, 0.0);
00479 glScalef(0.3, 0.3, 0.3);
00480 glRotatef((360.0 / (30 * 1)) * tick, 1, 0, 0);
00481 glRotatef((360.0 / (30 * 2)) * tick, 0, 1, 0);
00482 glRotatef((360.0 / (30 * 4)) * tick, 0, 0, 1);
00483 glScalef(1.0, 2.0, 1.0);
00484 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) cubeXform);
00485
00486 drawCube(RED);
00487 glPopMatrix();
00488
00489 glDepthMask(GL_FALSE);
00490 if (useRGB) {
00491 glEnable(GL_BLEND);
00492 } else {
00493 glEnable(GL_POLYGON_STIPPLE);
00494 }
00495 if (useFog) {
00496 glDisable(GL_FOG);
00497 }
00498 glPushMatrix();
00499 myShadowMatrix(groundPlane, lightPos);
00500 glTranslatef(0.0, 0.0, 2.0);
00501 glMultMatrixf((const GLfloat *) cubeXform);
00502
00503 drawCube(BLACK);
00504 glPopMatrix();
00505
00506 glPushMatrix();
00507 myShadowMatrix(backPlane, lightPos);
00508 glTranslatef(0.0, 0.0, 2.0);
00509 glMultMatrixf((const GLfloat *) cubeXform);
00510
00511 drawCube(BLACK);
00512 glPopMatrix();
00513
00514 glDepthMask(GL_TRUE);
00515 if (useRGB) {
00516 glDisable(GL_BLEND);
00517 } else {
00518 glDisable(GL_POLYGON_STIPPLE);
00519 }
00520 if (useFog) {
00521 glEnable(GL_FOG);
00522 }
00523 if (useDB) {
00524 glutSwapBuffers();
00525 } else {
00526 glFlush();
00527 }
00528 }
00529
00530 void
00531 fog_select(int fog)
00532 {
00533 glFogf(GL_FOG_MODE, fog);
00534 glutPostRedisplay();
00535 }
00536
00537 void
00538 menu_select(int mode)
00539 {
00540 switch (mode) {
00541 case 1:
00542 moving = 1;
00543 glutIdleFunc(idle);
00544 break;
00545 case 2:
00546 moving = 0;
00547 glutIdleFunc(NULL);
00548 break;
00549 case 3:
00550 useFog = !useFog;
00551 useFog ? glEnable(GL_FOG) : glDisable(GL_FOG);
00552 glutPostRedisplay();
00553 break;
00554 case 4:
00555 useLighting = !useLighting;
00556 useLighting ? glEnable(GL_LIGHTING) :
00557 glDisable(GL_LIGHTING);
00558 glutPostRedisplay();
00559 break;
00560 case 5:
00561 exit(0);
00562 break;
00563 }
00564 }
00565
00566 void
00567 visible(int state)
00568 {
00569 if (state == GLUT_VISIBLE) {
00570 if (moving)
00571 glutIdleFunc(idle);
00572 } else {
00573 if (moving)
00574 glutIdleFunc(NULL);
00575 }
00576 }
00577
00578 int
00579 main(int argc, char **argv)
00580 {
00581 int width = 350, height = 350;
00582 int i;
00583 char *name;
00584 int fog_menu;
00585
00586 glutInitWindowSize(width, height);
00587 glutInit(&argc, argv);
00588
00589 for (i = 1; i < argc; ++i) {
00590 if (!strcmp("-c", argv[i])) {
00591 useRGB = !useRGB;
00592 } else if (!strcmp("-l", argv[i])) {
00593 useLighting = !useLighting;
00594 } else if (!strcmp("-f", argv[i])) {
00595 useFog = !useFog;
00596 } else if (!strcmp("-db", argv[i])) {
00597 useDB = !useDB;
00598 } else if (!strcmp("-logo", argv[i])) {
00599 useLogo = !useLogo;
00600 } else if (!strcmp("-quads", argv[i])) {
00601 useQuads = !useQuads;
00602 } else {
00603 usage();
00604 }
00605 }
00606
00607
00608 if (useRGB) {
00609 if (useDB) {
00610 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
00611 name = windowNameRGBDB;
00612 } else {
00613 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
00614 name = windowNameRGB;
00615 }
00616 } else {
00617 if (useDB) {
00618 glutInitDisplayMode(GLUT_DOUBLE | GLUT_INDEX | GLUT_DEPTH);
00619 name = windowNameIndexDB;
00620 } else {
00621 glutInitDisplayMode(GLUT_SINGLE | GLUT_INDEX | GLUT_DEPTH);
00622 name = windowNameIndex;
00623 }
00624 }
00625
00626 glutCreateWindow(name);
00627
00628 buildColormap();
00629
00630 glutKeyboardFunc(keyboard);
00631 glutDisplayFunc(display);
00632 glutVisibilityFunc(visible);
00633
00634 fog_menu = glutCreateMenu(fog_select);
00635 glutAddMenuEntry("Linear fog", GL_LINEAR);
00636 glutAddMenuEntry("Exp fog", GL_EXP);
00637 glutAddMenuEntry("Exp^2 fog", GL_EXP2);
00638
00639 glutCreateMenu(menu_select);
00640 glutAddMenuEntry("Start motion", 1);
00641 glutAddMenuEntry("Stop motion", 2);
00642 glutAddMenuEntry("Toggle fog", 3);
00643 glutAddMenuEntry("Toggle lighting", 4);
00644 glutAddSubMenu("Fog type", fog_menu);
00645 glutAddMenuEntry("Quit", 5);
00646 glutAttachMenu(GLUT_RIGHT_BUTTON);
00647
00648
00649 glMatrixMode(GL_PROJECTION);
00650 glLoadIdentity();
00651 glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 3.0);
00652
00653 glMatrixMode(GL_MODELVIEW);
00654 glLoadIdentity();
00655 glTranslatef(0.0, 0.0, -2.0);
00656
00657 glEnable(GL_DEPTH_TEST);
00658
00659 if (useLighting) {
00660 glEnable(GL_LIGHTING);
00661 }
00662 glEnable(GL_LIGHT0);
00663 glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
00664 glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
00665 glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
00666 glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
00667 #if 0
00668 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDir);
00669 glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 80);
00670 glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 25);
00671 #endif
00672
00673 glEnable(GL_NORMALIZE);
00674
00675 if (useFog) {
00676 glEnable(GL_FOG);
00677 }
00678 glFogfv(GL_FOG_COLOR, fogColor);
00679 glFogfv(GL_FOG_INDEX, fogIndex);
00680 glFogf(GL_FOG_MODE, GL_EXP);
00681 glFogf(GL_FOG_DENSITY, 0.5);
00682 glFogf(GL_FOG_START, 1.0);
00683 glFogf(GL_FOG_END, 3.0);
00684
00685 glEnable(GL_CULL_FACE);
00686 glCullFace(GL_BACK);
00687
00688 glShadeModel(GL_SMOOTH);
00689
00690 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00691 if (useLogo) {
00692 glPolygonStipple((const GLubyte *) sgiPattern);
00693 } else {
00694 glPolygonStipple((const GLubyte *) shadowPattern);
00695 }
00696
00697 glClearColor(0.0, 0.0, 0.0, 1);
00698 glClearIndex(0);
00699 glClearDepth(1);
00700
00701 glutMainLoop();
00702 return 0;
00703 }