use 'p' key to toggle use of GL_EXT_packed_depth_stencil
[mesa.git] / progs / demos / shadowtex.c
1 /*
2 * Shadow demo using the GL_ARB_depth_texture, GL_ARB_shadow and
3 * GL_ARB_shadow_ambient extensions (or the old SGIX extensions).
4 *
5 * Brian Paul
6 * 19 Feb 2001
7 *
8 * Added GL_EXT_shadow_funcs support on 23 March 2002
9 *
10 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 */
29
30
31 #include <assert.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <math.h>
35 #include <GL/glut.h>
36 #include "showbuffer.h"
37
38 #if 0 /* change to 1 if you want to use the old SGIX extensions */
39 #undef GL_ARB_depth_texture
40 #undef GL_ARB_shadow
41 #undef GL_ARB_shadow_ambient
42 #endif
43
44 #define DEG_TO_RAD (3.14159 / 180.0)
45
46 static GLint WindowWidth = 450, WindowHeight = 300;
47 static GLfloat Xrot = 15, Yrot = 0, Zrot = 0;
48
49 static GLfloat Red[4] = {1, 0, 0, 1};
50 static GLfloat Green[4] = {0, 1, 0, 1};
51 static GLfloat Blue[4] = {0, 0, 1, 1};
52 static GLfloat Yellow[4] = {1, 1, 0, 1};
53
54 static GLfloat LightDist = 10;
55 static GLfloat LightLatitude = 45.0;
56 static GLfloat LightLongitude = 45.0;
57 static GLfloat LightPos[4];
58 static GLfloat SpotDir[3];
59 static GLfloat SpotAngle = 40.0 * DEG_TO_RAD;
60 static GLfloat ShadowNear = 4.0, ShadowFar = 24.0;
61 static GLint ShadowTexWidth = 256, ShadowTexHeight = 256;
62
63 static GLboolean LinearFilter = GL_FALSE;
64
65 static GLfloat Bias = -0.06;
66
67 static GLboolean Anim = GL_TRUE;
68
69 static GLboolean UsePackedDepthStencil = GL_FALSE;
70 static GLboolean HaveEXTshadowFuncs = GL_FALSE;
71 static GLint Operator = 0;
72 static const GLenum OperatorFunc[8] = {
73 GL_LEQUAL, GL_LESS, GL_GEQUAL, GL_GREATER,
74 GL_EQUAL, GL_NOTEQUAL, GL_ALWAYS, GL_NEVER };
75 static const char *OperatorName[8] = {
76 "GL_LEQUAL", "GL_LESS", "GL_GEQUAL", "GL_GREATER",
77 "GL_EQUAL", "GL_NOTEQUAL", "GL_ALWAYS", "GL_NEVER" };
78
79
80 static GLuint DisplayMode;
81 #define SHOW_NORMAL 0
82 #define SHOW_DEPTH_IMAGE 1
83 #define SHOW_DEPTH_MAPPING 2
84 #define SHOW_DISTANCE 3
85
86
87
88 static void
89 DrawScene(void)
90 {
91 GLfloat k = 6;
92 /* sphere */
93 glPushMatrix();
94 glTranslatef(1.6, 2.2, 2.7);
95 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Green);
96 glColor4fv(Green);
97 glutSolidSphere(1.5, 15, 15);
98 glPopMatrix();
99 /* dodecahedron */
100 glPushMatrix();
101 glTranslatef(-2.0, 1.2, 2.1);
102 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Red);
103 glColor4fv(Red);
104 glutSolidDodecahedron();
105 glPopMatrix();
106 /* icosahedron */
107 glPushMatrix();
108 glTranslatef(-0.6, 1.3, -0.5);
109 glScalef(1.5, 1.5, 1.5);
110 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Yellow);
111 glColor4fv(Red);
112 glutSolidIcosahedron();
113 glPopMatrix();
114 /* a plane */
115 glPushMatrix();
116 glTranslatef(0, -1.1, 0);
117 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Blue);
118 glColor4fv(Blue);
119 glNormal3f(0, 1, 0);
120 glBegin(GL_POLYGON);
121 glVertex3f(-k, 0, -k);
122 glVertex3f( k, 0, -k);
123 glVertex3f( k, 0, k);
124 glVertex3f(-k, 0, k);
125 glEnd();
126 glPopMatrix();
127 }
128
129
130 /*
131 * Load the GL_TEXTURE matrix with the projection from the light
132 * source's point of view.
133 */
134 static void
135 MakeShadowMatrix(const GLfloat lightPos[4], const GLfloat spotDir[3],
136 GLfloat spotAngle, GLfloat shadowNear, GLfloat shadowFar)
137 {
138 GLfloat d;
139
140 glMatrixMode(GL_TEXTURE);
141 glLoadIdentity();
142 glTranslatef(0.5, 0.5, 0.5 + Bias);
143 glScalef(0.5, 0.5, 0.5);
144 d = shadowNear * tan(spotAngle);
145 glFrustum(-d, d, -d, d, shadowNear, shadowFar);
146 gluLookAt(lightPos[0], lightPos[1], lightPos[2],
147 lightPos[0] + spotDir[0],
148 lightPos[1] + spotDir[1],
149 lightPos[2] + spotDir[2],
150 0, 1, 0);
151 glMatrixMode(GL_MODELVIEW);
152 }
153
154
155 static void
156 EnableIdentityTexgen(void)
157 {
158 /* texgen so that texcoord = vertex coord */
159 static GLfloat sPlane[4] = { 1, 0, 0, 0 };
160 static GLfloat tPlane[4] = { 0, 1, 0, 0 };
161 static GLfloat rPlane[4] = { 0, 0, 1, 0 };
162 static GLfloat qPlane[4] = { 0, 0, 0, 1 };
163
164 glTexGenfv(GL_S, GL_EYE_PLANE, sPlane);
165 glTexGenfv(GL_T, GL_EYE_PLANE, tPlane);
166 glTexGenfv(GL_R, GL_EYE_PLANE, rPlane);
167 glTexGenfv(GL_Q, GL_EYE_PLANE, qPlane);
168 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
169 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
170 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
171 glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
172
173 glEnable(GL_TEXTURE_GEN_S);
174 glEnable(GL_TEXTURE_GEN_T);
175 glEnable(GL_TEXTURE_GEN_R);
176 glEnable(GL_TEXTURE_GEN_Q);
177 }
178
179
180 /*
181 * Setup 1-D texgen so that the distance from the light source, between
182 * the near and far planes maps to s=0 and s=1. When we draw the scene,
183 * the grayness will indicate the fragment's distance from the light
184 * source.
185 */
186 static void
187 EnableDistanceTexgen(const GLfloat lightPos[4], const GLfloat lightDir[3],
188 GLfloat lightNear, GLfloat lightFar)
189 {
190 GLfloat m, d;
191 GLfloat sPlane[4];
192 GLfloat nearPoint[3];
193
194 m = sqrt(lightDir[0] * lightDir[0] +
195 lightDir[1] * lightDir[1] +
196 lightDir[2] * lightDir[2]);
197
198 d = lightFar - lightNear;
199
200 /* nearPoint = point on light direction vector which intersects the
201 * near plane of the light frustum.
202 */
203 nearPoint[0] = LightPos[0] + lightDir[0] / m * lightNear;
204 nearPoint[1] = LightPos[1] + lightDir[1] / m * lightNear;
205 nearPoint[2] = LightPos[2] + lightDir[2] / m * lightNear;
206
207 sPlane[0] = lightDir[0] / d / m;
208 sPlane[1] = lightDir[1] / d / m;
209 sPlane[2] = lightDir[2] / d / m;
210 sPlane[3] = -(sPlane[0] * nearPoint[0]
211 + sPlane[1] * nearPoint[1]
212 + sPlane[2] * nearPoint[2]);
213
214 glTexGenfv(GL_S, GL_EYE_PLANE, sPlane);
215 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
216 glEnable(GL_TEXTURE_GEN_S);
217 }
218
219
220 static void
221 DisableTexgen(void)
222 {
223 glDisable(GL_TEXTURE_GEN_S);
224 glDisable(GL_TEXTURE_GEN_T);
225 glDisable(GL_TEXTURE_GEN_R);
226 glDisable(GL_TEXTURE_GEN_Q);
227 }
228
229
230 static void
231 ComputeLightPos(GLfloat dist, GLfloat latitude, GLfloat longitude,
232 GLfloat pos[4], GLfloat dir[3])
233 {
234
235 pos[0] = dist * sin(longitude * DEG_TO_RAD);
236 pos[1] = dist * sin(latitude * DEG_TO_RAD);
237 pos[2] = dist * cos(latitude * DEG_TO_RAD) * cos(longitude * DEG_TO_RAD);
238 pos[3] = 1;
239 dir[0] = -pos[0];
240 dir[1] = -pos[1];
241 dir[2] = -pos[2];
242 }
243
244
245 static void
246 Display(void)
247 {
248 GLfloat ar = (GLfloat) WindowWidth / (GLfloat) WindowHeight;
249 GLfloat d;
250 GLenum error;
251
252 ComputeLightPos(LightDist, LightLatitude, LightLongitude,
253 LightPos, SpotDir);
254 /*
255 * Step 1: render scene from point of view of the light source
256 */
257 /* compute frustum to enclose spot light cone */
258 d = ShadowNear * tan(SpotAngle);
259 glMatrixMode(GL_PROJECTION);
260 glLoadIdentity();
261 glFrustum(-d, d, -d, d, ShadowNear, ShadowFar);
262 glMatrixMode(GL_MODELVIEW);
263 glLoadIdentity();
264 gluLookAt(LightPos[0], LightPos[1], LightPos[2], /* from */
265 0, 0, 0, /* target */
266 0, 1, 0); /* up */
267
268 glViewport(0, 0, ShadowTexWidth, ShadowTexHeight);
269 glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
270 DrawScene();
271
272 /*
273 * Step 2: copy depth buffer into texture map
274 */
275 if (DisplayMode == SHOW_DEPTH_MAPPING) {
276 /* load depth image as gray-scale luminance texture */
277 if (UsePackedDepthStencil) {
278 GLuint *depth = (GLuint *) malloc(ShadowTexWidth * ShadowTexHeight
279 * sizeof(GLuint));
280 assert(depth);
281 glReadPixels(0, 0, ShadowTexWidth, ShadowTexHeight,
282 GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, depth);
283 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
284 ShadowTexWidth, ShadowTexHeight, 0,
285 GL_LUMINANCE, GL_UNSIGNED_INT, depth);
286 free(depth);
287 }
288 else {
289 GLfloat *depth = (GLfloat *) malloc(ShadowTexWidth * ShadowTexHeight
290 * sizeof(GLfloat));
291 assert(depth);
292 glReadPixels(0, 0, ShadowTexWidth, ShadowTexHeight,
293 GL_DEPTH_COMPONENT, GL_FLOAT, depth);
294 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
295 ShadowTexWidth, ShadowTexHeight, 0,
296 GL_LUMINANCE, GL_FLOAT, depth);
297 free(depth);
298 }
299 }
300 else {
301 /* The normal shadow case */
302 if (UsePackedDepthStencil) {
303 GLint intFormat;
304 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL_EXT,
305 0, 0, ShadowTexWidth, ShadowTexHeight, 0);
306 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
307 GL_TEXTURE_INTERNAL_FORMAT, &intFormat);
308 assert(intFormat == GL_DEPTH_STENCIL_EXT);
309 }
310 else {
311 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
312 0, 0, ShadowTexWidth, ShadowTexHeight, 0);
313 }
314 }
315
316 /*
317 * Step 3: render scene from point of view of the camera
318 */
319 glViewport(0, 0, WindowWidth, WindowHeight);
320 if (DisplayMode == SHOW_DEPTH_IMAGE) {
321 ShowDepthBuffer(WindowWidth, WindowHeight, 0, 1);
322 }
323 else {
324 glMatrixMode(GL_PROJECTION);
325 glLoadIdentity();
326 glFrustum(-ar, ar, -1.0, 1.0, 4.0, 50.0);
327 glMatrixMode(GL_MODELVIEW);
328 glLoadIdentity();
329 glTranslatef(0.0, 0.0, -22.0);
330 glRotatef(Xrot, 1, 0, 0);
331 glRotatef(Yrot, 0, 1, 0);
332 glRotatef(Zrot, 0, 0, 1);
333 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
334 glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
335 if (LinearFilter) {
336 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
337 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
338 }
339 else {
340 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
341 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
342 }
343 if (DisplayMode == SHOW_DEPTH_MAPPING) {
344 #if defined(GL_ARB_shadow)
345 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
346 #elif defined(GL_SGIX_shadow)
347 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_SGIX, GL_FALSE);
348 #endif
349 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
350 glEnable(GL_TEXTURE_2D);
351 MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
352 EnableIdentityTexgen();
353 }
354 else if (DisplayMode == SHOW_DISTANCE) {
355 glMatrixMode(GL_TEXTURE);
356 glLoadIdentity();
357 glMatrixMode(GL_MODELVIEW);
358 EnableDistanceTexgen(LightPos, SpotDir, ShadowNear+Bias, ShadowFar);
359 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
360 glEnable(GL_TEXTURE_1D);
361 }
362 else {
363 assert(DisplayMode == SHOW_NORMAL);
364 #if defined(GL_ARB_shadow)
365 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
366 GL_COMPARE_R_TO_TEXTURE_ARB);
367 #elif defined(GL_SGIX_shadow)
368 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_SGIX, GL_TRUE);
369 #endif
370 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
371 glEnable(GL_TEXTURE_2D);
372 MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
373 EnableIdentityTexgen();
374 }
375 DrawScene();
376 DisableTexgen();
377 glDisable(GL_TEXTURE_1D);
378 glDisable(GL_TEXTURE_2D);
379 }
380
381 glutSwapBuffers();
382
383 error = glGetError();
384 if (error) {
385 printf("GL Error: %s\n", (char *) gluErrorString(error));
386 }
387 }
388
389
390 static void
391 Reshape(int width, int height)
392 {
393 WindowWidth = width;
394 WindowHeight = height;
395 if (width >= 512 && height >= 512) {
396 ShadowTexWidth = ShadowTexHeight = 512;
397 }
398 else if (width >= 256 && height >= 256) {
399 ShadowTexWidth = ShadowTexHeight = 256;
400 }
401 else {
402 ShadowTexWidth = ShadowTexHeight = 128;
403 }
404 printf("Using %d x %d depth texture\n", ShadowTexWidth, ShadowTexHeight);
405 }
406
407
408 static void
409 Idle(void)
410 {
411 static double t0 = -1.;
412 double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
413 if (t0 < 0.0)
414 t0 = t;
415 dt = t - t0;
416 t0 = t;
417 Yrot += 75.0 * dt;
418 /*LightLongitude -= 5.0;*/
419 glutPostRedisplay();
420 }
421
422
423 static void
424 Key(unsigned char key, int x, int y)
425 {
426 const GLfloat step = 3.0;
427 (void) x;
428 (void) y;
429 switch (key) {
430 case 'a':
431 Anim = !Anim;
432 if (Anim)
433 glutIdleFunc(Idle);
434 else
435 glutIdleFunc(NULL);
436 break;
437 case 'b':
438 Bias -= 0.01;
439 printf("Bias %g\n", Bias);
440 break;
441 case 'B':
442 Bias += 0.01;
443 printf("Bias %g\n", Bias);
444 break;
445 case 'd':
446 DisplayMode = SHOW_DISTANCE;
447 break;
448 case 'f':
449 LinearFilter = !LinearFilter;
450 printf("%s filtering\n", LinearFilter ? "Bilinear" : "Nearest");
451 break;
452 case 'i':
453 DisplayMode = SHOW_DEPTH_IMAGE;
454 break;
455 case 'm':
456 DisplayMode = SHOW_DEPTH_MAPPING;
457 break;
458 case 'n':
459 case ' ':
460 DisplayMode = SHOW_NORMAL;
461 break;
462 case 'o':
463 if (HaveEXTshadowFuncs) {
464 Operator++;
465 if (Operator >= 8)
466 Operator = 0;
467 printf("Operator: %s\n", OperatorName[Operator]);
468 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB,
469 OperatorFunc[Operator]);
470 }
471 break;
472 case 'p':
473 UsePackedDepthStencil = !UsePackedDepthStencil;
474 if (UsePackedDepthStencil
475 && !glutExtensionSupported("GL_EXT_packed_depth_stencil")) {
476 printf("Sorry, GL_EXT_packed_depth_stencil not supported\n");
477 UsePackedDepthStencil = GL_FALSE;
478 }
479 else {
480 printf("Use GL_DEPTH_STENCIL_EXT: %d\n", UsePackedDepthStencil);
481 }
482 break;
483 case 'z':
484 Zrot -= step;
485 break;
486 case 'Z':
487 Zrot += step;
488 break;
489 case 27:
490 exit(0);
491 break;
492 }
493 glutPostRedisplay();
494 }
495
496
497 static void
498 SpecialKey(int key, int x, int y)
499 {
500 const GLfloat step = 3.0;
501 const int mod = glutGetModifiers();
502 (void) x;
503 (void) y;
504 switch (key) {
505 case GLUT_KEY_UP:
506 if (mod)
507 LightLatitude += step;
508 else
509 Xrot += step;
510 break;
511 case GLUT_KEY_DOWN:
512 if (mod)
513 LightLatitude -= step;
514 else
515 Xrot -= step;
516 break;
517 case GLUT_KEY_LEFT:
518 if (mod)
519 LightLongitude += step;
520 else
521 Yrot += step;
522 break;
523 case GLUT_KEY_RIGHT:
524 if (mod)
525 LightLongitude -= step;
526 else
527 Yrot -= step;
528 break;
529 }
530 glutPostRedisplay();
531 }
532
533
534 static void
535 Init(void)
536 {
537 #if defined(GL_ARB_depth_texture) && defined(GL_ARB_shadow)
538 if (!glutExtensionSupported("GL_ARB_depth_texture") ||
539 !glutExtensionSupported("GL_ARB_shadow")) {
540 printf("Sorry, this demo requires the GL_ARB_depth_texture and GL_ARB_shadow extensions\n");
541 exit(1);
542 }
543 printf("Using GL_ARB_depth_texture and GL_ARB_shadow\n");
544 #elif defined(GL_SGIX_depth_texture) && defined(GL_SGIX_shadow)
545 if (!glutExtensionSupported("GL_SGIX_depth_texture") ||
546 !glutExtensionSupported("GL_SGIX_shadow")) {
547 printf("Sorry, this demo requires the GL_SGIX_depth_texture and GL_SGIX_shadow extensions\n");
548 exit(1);
549 }
550 printf("Using GL_SGIX_depth_texture and GL_SGIX_shadow\n");
551 #endif
552 HaveEXTshadowFuncs = glutExtensionSupported("GL_EXT_shadow_funcs");
553
554 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
555 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
556 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
557 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP);
558 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
559 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
560 #if defined(GL_ARB_shadow)
561 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
562 GL_COMPARE_R_TO_TEXTURE_ARB);
563 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
564 #elif defined(GL_SGIX_shadow)
565 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_OPERATOR_SGIX,
566 GL_TEXTURE_LEQUAL_R_SGIX);
567 #endif
568
569 #if defined(GL_ARB_shadow_ambient)
570 if (glutExtensionSupported("GL_ARB_shadow_ambient")) {
571 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.3);
572 printf("and GL_ARB_shadow_ambient\n");
573 }
574 #elif defined(GL_SGIX_shadow_ambient)
575 if (glutExtensionSupported("GL_SGIX_shadow_ambient")) {
576 glTexParameterf(GL_TEXTURE_2D, GL_SHADOW_AMBIENT_SGIX, 0.3);
577 printf("and GL_SGIX_shadow_ambient\n");
578 }
579 #endif
580
581 /* setup 1-D grayscale texture image for SHOW_DISTANCE mode */
582 {
583 GLuint i;
584 GLubyte image[256];
585 for (i = 0; i < 256; i++)
586 image[i] = i;
587 glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE,
588 256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image);
589 }
590
591 glEnable(GL_DEPTH_TEST);
592 glEnable(GL_LIGHTING);
593 glEnable(GL_LIGHT0);
594 }
595
596
597 static void
598 PrintHelp(void)
599 {
600 printf("Keys:\n");
601 printf(" a = toggle animation\n");
602 printf(" i = show depth texture image\n");
603 printf(" m = show depth texture mapping\n");
604 printf(" d = show fragment distance from light source\n");
605 printf(" n = show normal, shadowed image\n");
606 printf(" f = toggle nearest/bilinear texture filtering\n");
607 printf(" b/B = decrease/increase shadow map Z bias\n");
608 printf(" p = toggle use of packed depth/stencil\n");
609 printf(" cursor keys = rotate scene\n");
610 printf(" <shift> + cursor keys = rotate light source\n");
611 if (HaveEXTshadowFuncs)
612 printf(" o = cycle through comparison modes\n");
613 }
614
615
616 int
617 main(int argc, char *argv[])
618 {
619 glutInit(&argc, argv);
620 glutInitWindowPosition(0, 0);
621 glutInitWindowSize(WindowWidth, WindowHeight);
622 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
623 glutCreateWindow(argv[0]);
624 glutReshapeFunc(Reshape);
625 glutKeyboardFunc(Key);
626 glutSpecialFunc(SpecialKey);
627 glutDisplayFunc(Display);
628 if (Anim)
629 glutIdleFunc(Idle);
630 Init();
631 PrintHelp();
632 glutMainLoop();
633 return 0;
634 }