Clone of mesa.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

shadowtex.c 17KB

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