Clone of mesa.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

shadowtex.c 17KB

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