2 * Shadow demo using the GL_ARB_depth_texture, GL_ARB_shadow and
3 * GL_ARB_shadow_ambient extensions.
8 * Added GL_EXT_shadow_funcs support on 23 March 2002
9 * Added GL_EXT_packed_depth_stencil support on 15 March 2006.
10 * Added GL_EXT_framebuffer_object support on 27 March 2006.
11 * Removed old SGIX extension support on 5 April 2006.
13 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
15 * Permission is hereby granted, free of charge, to any person obtaining a
16 * copy of this software and associated documentation files (the "Software"),
17 * to deal in the Software without restriction, including without limitation
18 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
19 * and/or sell copies of the Software, and to permit persons to whom the
20 * Software is furnished to do so, subject to the following conditions:
22 * The above copyright notice and this permission notice shall be included
23 * in all copies or substantial portions of the Software.
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
26 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
29 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 #define GL_GLEXT_PROTOTYPES
39 #include "showbuffer.h"
41 #define DEG_TO_RAD (3.14159 / 180.0)
43 static GLint WindowWidth
= 450, WindowHeight
= 300;
44 static GLfloat Xrot
= 15, Yrot
= 0, Zrot
= 0;
46 static GLfloat Red
[4] = {1, 0, 0, 1};
47 static GLfloat Green
[4] = {0, 1, 0, 1};
48 static GLfloat Blue
[4] = {0, 0, 1, 1};
49 static GLfloat Yellow
[4] = {1, 1, 0, 1};
51 static GLfloat LightDist
= 10;
52 static GLfloat LightLatitude
= 45.0;
53 static GLfloat LightLongitude
= 45.0;
54 static GLfloat LightPos
[4];
55 static GLfloat SpotDir
[3];
56 static GLfloat SpotAngle
= 40.0 * DEG_TO_RAD
;
57 static GLfloat ShadowNear
= 4.0, ShadowFar
= 24.0;
58 static GLint ShadowTexWidth
= 256, ShadowTexHeight
= 256;
60 static GLboolean LinearFilter
= GL_FALSE
;
62 static GLfloat Bias
= -0.06;
64 static GLboolean Anim
= GL_TRUE
;
66 static GLboolean NeedNewShadowMap
= GL_FALSE
;
67 static GLuint ShadowTexture
, GrayTexture
;
68 static GLuint ShadowFBO
;
70 static GLboolean HaveFBO
= GL_FALSE
;
71 static GLboolean UseFBO
= GL_FALSE
;
72 static GLboolean HavePackedDepthStencil
= GL_FALSE
;
73 static GLboolean UsePackedDepthStencil
= GL_FALSE
;
74 static GLboolean HaveEXTshadowFuncs
= GL_FALSE
;
75 static GLboolean HaveShadowAmbient
= GL_FALSE
;
77 static GLint Operator
= 0;
78 static const GLenum OperatorFunc
[8] = {
79 GL_LEQUAL
, GL_LESS
, GL_GEQUAL
, GL_GREATER
,
80 GL_EQUAL
, GL_NOTEQUAL
, GL_ALWAYS
, GL_NEVER
};
81 static const char *OperatorName
[8] = {
82 "GL_LEQUAL", "GL_LESS", "GL_GEQUAL", "GL_GREATER",
83 "GL_EQUAL", "GL_NOTEQUAL", "GL_ALWAYS", "GL_NEVER" };
86 static GLuint DisplayMode
;
87 #define SHOW_SHADOWS 0
88 #define SHOW_DEPTH_IMAGE 1
89 #define SHOW_DEPTH_MAPPING 2
90 #define SHOW_DISTANCE 3
101 glTranslatef(1.6, 2.2, 2.7);
102 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, Green
);
104 glutSolidSphere(1.5, 15, 15);
108 glTranslatef(-2.0, 1.2, 2.1);
109 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, Red
);
111 glutSolidDodecahedron();
115 glTranslatef(-0.6, 1.3, -0.5);
116 glScalef(1.5, 1.5, 1.5);
117 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, Yellow
);
119 glutSolidIcosahedron();
123 glTranslatef(0, -1.1, 0);
124 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, Blue
);
128 glVertex3f(-k
, 0, -k
);
129 glVertex3f( k
, 0, -k
);
130 glVertex3f( k
, 0, k
);
131 glVertex3f(-k
, 0, k
);
138 * Load the GL_TEXTURE matrix with the projection from the light
139 * source's point of view.
142 MakeShadowMatrix(const GLfloat lightPos
[4], const GLfloat spotDir
[3],
143 GLfloat spotAngle
, GLfloat shadowNear
, GLfloat shadowFar
)
147 glMatrixMode(GL_TEXTURE
);
149 glTranslatef(0.5, 0.5, 0.5 + Bias
);
150 glScalef(0.5, 0.5, 0.5);
151 d
= shadowNear
* tan(spotAngle
);
152 glFrustum(-d
, d
, -d
, d
, shadowNear
, shadowFar
);
153 gluLookAt(lightPos
[0], lightPos
[1], lightPos
[2],
154 lightPos
[0] + spotDir
[0],
155 lightPos
[1] + spotDir
[1],
156 lightPos
[2] + spotDir
[2],
158 glMatrixMode(GL_MODELVIEW
);
163 EnableIdentityTexgen(void)
165 /* texgen so that texcoord = vertex coord */
166 static GLfloat sPlane
[4] = { 1, 0, 0, 0 };
167 static GLfloat tPlane
[4] = { 0, 1, 0, 0 };
168 static GLfloat rPlane
[4] = { 0, 0, 1, 0 };
169 static GLfloat qPlane
[4] = { 0, 0, 0, 1 };
171 glTexGenfv(GL_S
, GL_EYE_PLANE
, sPlane
);
172 glTexGenfv(GL_T
, GL_EYE_PLANE
, tPlane
);
173 glTexGenfv(GL_R
, GL_EYE_PLANE
, rPlane
);
174 glTexGenfv(GL_Q
, GL_EYE_PLANE
, qPlane
);
175 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
176 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
177 glTexGeni(GL_R
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
178 glTexGeni(GL_Q
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
180 glEnable(GL_TEXTURE_GEN_S
);
181 glEnable(GL_TEXTURE_GEN_T
);
182 glEnable(GL_TEXTURE_GEN_R
);
183 glEnable(GL_TEXTURE_GEN_Q
);
188 * Setup 1-D texgen so that the distance from the light source, between
189 * the near and far planes maps to s=0 and s=1. When we draw the scene,
190 * the grayness will indicate the fragment's distance from the light
194 EnableDistanceTexgen(const GLfloat lightPos
[4], const GLfloat lightDir
[3],
195 GLfloat lightNear
, GLfloat lightFar
)
199 GLfloat nearPoint
[3];
201 m
= sqrt(lightDir
[0] * lightDir
[0] +
202 lightDir
[1] * lightDir
[1] +
203 lightDir
[2] * lightDir
[2]);
205 d
= lightFar
- lightNear
;
207 /* nearPoint = point on light direction vector which intersects the
208 * near plane of the light frustum.
210 nearPoint
[0] = lightPos
[0] + lightDir
[0] / m
* lightNear
;
211 nearPoint
[1] = lightPos
[1] + lightDir
[1] / m
* lightNear
;
212 nearPoint
[2] = lightPos
[2] + lightDir
[2] / m
* lightNear
;
214 sPlane
[0] = lightDir
[0] / d
/ m
;
215 sPlane
[1] = lightDir
[1] / d
/ m
;
216 sPlane
[2] = lightDir
[2] / d
/ m
;
217 sPlane
[3] = -(sPlane
[0] * nearPoint
[0]
218 + sPlane
[1] * nearPoint
[1]
219 + sPlane
[2] * nearPoint
[2]);
221 glTexGenfv(GL_S
, GL_EYE_PLANE
, sPlane
);
222 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
223 glEnable(GL_TEXTURE_GEN_S
);
230 glDisable(GL_TEXTURE_GEN_S
);
231 glDisable(GL_TEXTURE_GEN_T
);
232 glDisable(GL_TEXTURE_GEN_R
);
233 glDisable(GL_TEXTURE_GEN_Q
);
238 ComputeLightPos(GLfloat dist
, GLfloat latitude
, GLfloat longitude
,
239 GLfloat pos
[4], GLfloat dir
[3])
242 pos
[0] = dist
* sin(longitude
* DEG_TO_RAD
);
243 pos
[1] = dist
* sin(latitude
* DEG_TO_RAD
);
244 pos
[2] = dist
* cos(latitude
* DEG_TO_RAD
) * cos(longitude
* DEG_TO_RAD
);
253 * Render the shadow map / depth texture.
254 * The result will be in the texture object named ShadowTexture.
257 RenderShadowMap(void)
259 GLenum depthFormat
; /* GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT */
260 GLenum depthType
; /* GL_UNSIGNED_INT_24_8_EXT or GL_UNSIGNED_INT */
263 if (WindowWidth
>= 1024 && WindowHeight
>= 1024) {
264 ShadowTexWidth
= ShadowTexHeight
= 1024;
266 else if (WindowWidth
>= 512 && WindowHeight
>= 512) {
267 ShadowTexWidth
= ShadowTexHeight
= 512;
269 else if (WindowWidth
>= 256 && WindowHeight
>= 256) {
270 ShadowTexWidth
= ShadowTexHeight
= 256;
273 ShadowTexWidth
= ShadowTexHeight
= 128;
275 printf("Rendering %d x %d depth texture\n", ShadowTexWidth
, ShadowTexHeight
);
277 if (UsePackedDepthStencil
) {
278 depthFormat
= GL_DEPTH_STENCIL_EXT
;
279 depthType
= GL_UNSIGNED_INT_24_8_EXT
;
282 depthFormat
= GL_DEPTH_COMPONENT
;
283 depthType
= GL_UNSIGNED_INT
;
286 /* compute frustum to enclose spot light cone */
287 d
= ShadowNear
* tan(SpotAngle
);
289 glMatrixMode(GL_PROJECTION
);
291 glFrustum(-d
, d
, -d
, d
, ShadowNear
, ShadowFar
);
292 glMatrixMode(GL_MODELVIEW
);
294 gluLookAt(LightPos
[0], LightPos
[1], LightPos
[2], /* from */
295 0, 0, 0, /* target */
299 glTexImage2D(GL_TEXTURE_2D
, 0, depthFormat
,
300 ShadowTexWidth
, ShadowTexHeight
, 0,
301 depthFormat
, depthType
, NULL
);
302 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, ShadowFBO
);
303 glDrawBuffer(GL_NONE
);
304 glReadBuffer(GL_NONE
);
305 assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT
)
306 == GL_FRAMEBUFFER_COMPLETE_EXT
);
309 assert(!glIsEnabled(GL_TEXTURE_1D
));
310 assert(!glIsEnabled(GL_TEXTURE_2D
));
312 glViewport(0, 0, ShadowTexWidth
, ShadowTexHeight
);
313 glClear(GL_DEPTH_BUFFER_BIT
);
314 glEnable(GL_DEPTH_TEST
);
319 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, 0);
323 * copy depth buffer into the texture map
325 if (DisplayMode
== SHOW_DEPTH_MAPPING
) {
326 /* load depth image as gray-scale luminance texture */
327 GLuint
*depth
= (GLuint
*)
328 malloc(ShadowTexWidth
* ShadowTexHeight
* sizeof(GLuint
));
330 glReadPixels(0, 0, ShadowTexWidth
, ShadowTexHeight
,
331 depthFormat
, depthType
, depth
);
332 glTexImage2D(GL_TEXTURE_2D
, 0, GL_LUMINANCE
,
333 ShadowTexWidth
, ShadowTexHeight
, 0,
334 GL_LUMINANCE
, GL_UNSIGNED_INT
, depth
);
338 /* The normal shadow case - a real depth texture */
339 glCopyTexImage2D(GL_TEXTURE_2D
, 0, depthFormat
,
340 0, 0, ShadowTexWidth
, ShadowTexHeight
, 0);
341 if (UsePackedDepthStencil
) {
344 glGetTexLevelParameteriv(GL_TEXTURE_2D
, 0,
345 GL_TEXTURE_INTERNAL_FORMAT
, &intFormat
);
346 assert(intFormat
== GL_DEPTH_STENCIL_EXT
);
354 * Show the shadow map as a grayscale image.
359 glClear(GL_COLOR_BUFFER_BIT
);
361 glMatrixMode(GL_TEXTURE
);
364 glMatrixMode(GL_PROJECTION
);
366 glOrtho(0, WindowWidth
, 0, WindowHeight
, -1, 1);
368 glMatrixMode(GL_MODELVIEW
);
371 glDisable(GL_DEPTH_TEST
);
372 glDisable(GL_LIGHTING
);
374 glEnable(GL_TEXTURE_2D
);
378 /* interpret texture's depth values as luminance values */
379 #if defined(GL_ARB_shadow)
380 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_COMPARE_MODE_ARB
, GL_NONE
);
381 glTexParameteri(GL_TEXTURE_2D
, GL_DEPTH_TEXTURE_MODE_ARB
, GL_LUMINANCE
);
383 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
386 glTexCoord2f(0, 0); glVertex2f(0, 0);
387 glTexCoord2f(1, 0); glVertex2f(ShadowTexWidth
, 0);
388 glTexCoord2f(1, 1); glVertex2f(ShadowTexWidth
, ShadowTexHeight
);
389 glTexCoord2f(0, 1); glVertex2f(0, ShadowTexHeight
);
392 glDisable(GL_TEXTURE_2D
);
393 glEnable(GL_DEPTH_TEST
);
394 glEnable(GL_LIGHTING
);
399 * Redraw window image
406 ComputeLightPos(LightDist
, LightLatitude
, LightLongitude
,
409 if (NeedNewShadowMap
) {
411 NeedNewShadowMap
= GL_FALSE
;
414 glViewport(0, 0, WindowWidth
, WindowHeight
);
415 if (DisplayMode
== SHOW_DEPTH_IMAGE
) {
419 /* prepare to draw scene from camera's view */
420 const GLfloat ar
= (GLfloat
) WindowWidth
/ (GLfloat
) WindowHeight
;
422 glMatrixMode(GL_PROJECTION
);
424 glFrustum(-ar
, ar
, -1.0, 1.0, 4.0, 50.0);
426 glMatrixMode(GL_MODELVIEW
);
428 glTranslatef(0.0, 0.0, -22.0);
429 glRotatef(Xrot
, 1, 0, 0);
430 glRotatef(Yrot
, 0, 1, 0);
431 glRotatef(Zrot
, 0, 0, 1);
433 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
435 glLightfv(GL_LIGHT0
, GL_POSITION
, LightPos
);
438 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
439 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
442 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
443 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
446 if (DisplayMode
== SHOW_DEPTH_MAPPING
) {
447 #if defined(GL_ARB_shadow)
448 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_COMPARE_MODE_ARB
, GL_NONE
);
450 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
451 glEnable(GL_TEXTURE_2D
);
452 MakeShadowMatrix(LightPos
, SpotDir
, SpotAngle
, ShadowNear
, ShadowFar
);
453 EnableIdentityTexgen();
455 else if (DisplayMode
== SHOW_DISTANCE
) {
456 glMatrixMode(GL_TEXTURE
);
458 glMatrixMode(GL_MODELVIEW
);
459 EnableDistanceTexgen(LightPos
, SpotDir
, ShadowNear
+Bias
, ShadowFar
);
460 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
461 glEnable(GL_TEXTURE_1D
);
462 assert(!glIsEnabled(GL_TEXTURE_2D
));
465 assert(DisplayMode
== SHOW_SHADOWS
);
466 #if defined(GL_ARB_shadow)
467 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_COMPARE_MODE_ARB
,
468 GL_COMPARE_R_TO_TEXTURE_ARB
);
470 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
471 glEnable(GL_TEXTURE_2D
);
472 MakeShadowMatrix(LightPos
, SpotDir
, SpotAngle
, ShadowNear
, ShadowFar
);
473 EnableIdentityTexgen();
479 glDisable(GL_TEXTURE_1D
);
480 glDisable(GL_TEXTURE_2D
);
485 error
= glGetError();
487 printf("GL Error: %s\n", (char *) gluErrorString(error
));
493 Reshape(int width
, int height
)
496 WindowHeight
= height
;
497 NeedNewShadowMap
= GL_TRUE
;
504 static double t0
= -1.;
505 double dt
, t
= glutGet(GLUT_ELAPSED_TIME
) / 1000.0;
511 /*LightLongitude -= 5.0;*/
517 Key(unsigned char key
, int x
, int y
)
519 const GLfloat step
= 3.0;
532 printf("Bias %g\n", Bias
);
536 printf("Bias %g\n", Bias
);
539 DisplayMode
= SHOW_DISTANCE
;
542 LinearFilter
= !LinearFilter
;
543 printf("%s filtering\n", LinearFilter
? "Bilinear" : "Nearest");
546 DisplayMode
= SHOW_DEPTH_IMAGE
;
549 DisplayMode
= SHOW_DEPTH_MAPPING
;
554 DisplayMode
= SHOW_SHADOWS
;
557 if (HaveEXTshadowFuncs
) {
561 printf("Operator: %s\n", OperatorName
[Operator
]);
562 #if defined(GL_ARB_shadow)
563 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_COMPARE_FUNC_ARB
,
564 OperatorFunc
[Operator
]);
569 UsePackedDepthStencil
= !UsePackedDepthStencil
;
570 if (UsePackedDepthStencil
&& !HavePackedDepthStencil
) {
571 printf("Sorry, GL_EXT_packed_depth_stencil not supported\n");
572 UsePackedDepthStencil
= GL_FALSE
;
575 printf("Use GL_DEPTH_STENCIL_EXT: %d\n", UsePackedDepthStencil
);
576 /* Don't really need to regenerate shadow map texture, but do so
577 * to exercise more code more often.
579 NeedNewShadowMap
= GL_TRUE
;
597 SpecialKey(int key
, int x
, int y
)
599 const GLfloat step
= 3.0;
600 const int mod
= glutGetModifiers();
606 LightLatitude
+= step
;
612 LightLatitude
-= step
;
618 LightLongitude
+= step
;
624 LightLongitude
-= step
;
630 NeedNewShadowMap
= GL_TRUE
;
639 static const GLfloat borderColor
[4] = {1.0, 0.0, 0.0, 0.0};
641 #if defined(GL_ARB_depth_texture) && defined(GL_ARB_shadow)
642 if (!glutExtensionSupported("GL_ARB_depth_texture") ||
643 !glutExtensionSupported("GL_ARB_shadow")) {
647 printf("Sorry, this demo requires the GL_ARB_depth_texture and GL_ARB_shadow extensions\n");
650 printf("Using GL_ARB_depth_texture and GL_ARB_shadow\n");
652 #if defined(GL_ARB_shadow_ambient)
653 HaveShadowAmbient
= glutExtensionSupported("GL_ARB_shadow_ambient");
654 if (HaveShadowAmbient
) {
655 printf("and GL_ARB_shadow_ambient\n");
659 HaveEXTshadowFuncs
= glutExtensionSupported("GL_EXT_shadow_funcs");
661 HavePackedDepthStencil
= glutExtensionSupported("GL_EXT_packed_depth_stencil");
662 UsePackedDepthStencil
= HavePackedDepthStencil
;
664 #if defined(GL_EXT_framebuffer_object)
665 HaveFBO
= glutExtensionSupported("GL_EXT_framebuffer_object");
668 printf("Using GL_EXT_framebuffer_object\n");
673 * Set up the 2D shadow map texture
675 glGenTextures(1, &ShadowTexture
);
676 glBindTexture(GL_TEXTURE_2D
, ShadowTexture
);
677 glTexParameterfv(GL_TEXTURE_2D
, GL_TEXTURE_BORDER_COLOR
, borderColor
);
678 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP
);
679 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP
);
680 #if defined(GL_ARB_shadow)
681 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_COMPARE_MODE_ARB
,
682 GL_COMPARE_R_TO_TEXTURE_ARB
);
683 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_COMPARE_FUNC_ARB
, GL_LEQUAL
);
685 if (HaveShadowAmbient
) {
686 #if defined(GL_ARB_shadow_ambient)
687 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB
, 0.3);
691 #if defined(GL_EXT_framebuffer_object)
693 glGenFramebuffersEXT(1, &ShadowFBO
);
694 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, ShadowFBO
);
695 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
,
696 GL_COLOR_ATTACHMENT0_EXT
,
697 GL_RENDERBUFFER_EXT
, 0);
698 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT
, GL_DEPTH_ATTACHMENT_EXT
,
699 GL_TEXTURE_2D
, ShadowTexture
, 0);
701 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, 0);
706 * Setup 1-D grayscale texture image for SHOW_DISTANCE mode
708 glGenTextures(1, &GrayTexture
);
709 glBindTexture(GL_TEXTURE_1D
, GrayTexture
);
710 glTexParameteri(GL_TEXTURE_1D
, GL_TEXTURE_WRAP_S
, GL_CLAMP
);
711 glTexParameteri(GL_TEXTURE_1D
, GL_TEXTURE_WRAP_T
, GL_CLAMP
);
712 glTexParameteri(GL_TEXTURE_1D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
713 glTexParameteri(GL_TEXTURE_1D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
717 for (i
= 0; i
< 256; i
++)
719 glTexImage1D(GL_TEXTURE_1D
, 0, GL_LUMINANCE
,
720 256, 0, GL_LUMINANCE
, GL_UNSIGNED_BYTE
, image
);
723 glEnable(GL_DEPTH_TEST
);
724 glEnable(GL_LIGHTING
);
733 printf(" a = toggle animation\n");
734 printf(" i = show depth texture image\n");
735 printf(" m = show depth texture mapping\n");
736 printf(" d = show fragment distance from light source\n");
737 printf(" n = show normal, shadowed image\n");
738 printf(" f = toggle nearest/bilinear texture filtering\n");
739 printf(" b/B = decrease/increase shadow map Z bias\n");
740 printf(" p = toggle use of packed depth/stencil\n");
741 printf(" cursor keys = rotate scene\n");
742 printf(" <shift> + cursor keys = rotate light source\n");
743 if (HaveEXTshadowFuncs
)
744 printf(" o = cycle through comparison modes\n");
749 main(int argc
, char *argv
[])
751 glutInit(&argc
, argv
);
752 glutInitWindowPosition(0, 0);
753 glutInitWindowSize(WindowWidth
, WindowHeight
);
754 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
| GLUT_STENCIL
);
755 glutCreateWindow(argv
[0]);
756 glutReshapeFunc(Reshape
);
757 glutKeyboardFunc(Key
);
758 glutSpecialFunc(SpecialKey
);
759 glutDisplayFunc(Display
);