Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

617 lines
16 KiB

  1. /*
  2. * 1992 David G Yu -- Silicon Graphics Computer Systems
  3. */
  4. #include <windows.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <math.h>
  9. #include <limits.h>
  10. #include <GL/gl.h>
  11. #include "glaux.h"
  12. #include "miscutil.h"
  13. #include "miscflt.h"
  14. #define WINDOW_WIDTH 300
  15. #define WINDOW_HEIGHT 300
  16. #define WINDOW_TOP 30
  17. #define WINDOW_LEFT 10
  18. static int useRGB = 1;
  19. static int useLighting = 1;
  20. static int useFog = 0;
  21. static int useDB = 1;
  22. static int useLogo = 0;
  23. static int useQuads = 1;
  24. #define GREY 0
  25. #define RED 1
  26. #define GREEN 2
  27. #define BLUE 3
  28. #define CYAN 4
  29. #define MAGENTA 5
  30. #define YELLOW 6
  31. #define BLACK 7
  32. static float materialColor[8][4] = {
  33. { 0.8f, 0.8f, 0.8f, ONE },
  34. { 0.8f, ZERO, ZERO, ONE },
  35. { ZERO, 0.8f, ZERO, ONE },
  36. { ZERO, ZERO, 0.8f, ONE },
  37. { ZERO, 0.8f, 0.8f, ONE },
  38. { 0.8f, ZERO, 0.8f, ONE },
  39. { 0.8f, 0.8f, ZERO, ONE },
  40. { ZERO, ZERO, ZERO, 0.4f },
  41. };
  42. static float lightPos[4] = { TWO , 4.0f, TWO , ONE };
  43. static float lightDir[4] = { -TWO , -4.0f, -TWO , ONE };
  44. static float lightAmb[4] = { 0.2f, 0.2f, 0.2f, ONE };
  45. static float lightDiff[4] = { 0.8f, 0.8f, 0.8f, ONE };
  46. static float lightSpec[4] = { 0.4f, 0.4f, 0.4f, ONE };
  47. static float groundPlane[4] = { ZERO, ONE , ZERO, 1.499f };
  48. static float backPlane[4] = { ZERO, ZERO, ONE , 0.899f };
  49. static float fogColor[4] = { ZERO, ZERO, ZERO, ZERO };
  50. static float fogIndex[1] = { ZERO };
  51. static int ColorMapSize = 0; /* This also tells us if the colormap */
  52. /* has been initialized */
  53. static unsigned char shadowPattern[128] = {
  54. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, /* 50% Grey */
  55. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  56. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  57. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  58. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  59. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  60. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  61. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  62. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  63. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  64. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  65. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  66. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  67. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  68. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
  69. 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55
  70. };
  71. static unsigned char sgiPattern[128] = {
  72. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* SGI Logo */
  73. 0xff, 0xbd, 0xff, 0x83, 0xff, 0x5a, 0xff, 0xef,
  74. 0xfe, 0xdb, 0x7f, 0xef, 0xfd, 0xdb, 0xbf, 0xef,
  75. 0xfb, 0xdb, 0xdf, 0xef, 0xf7, 0xdb, 0xef, 0xef,
  76. 0xfb, 0xdb, 0xdf, 0xef, 0xfd, 0xdb, 0xbf, 0x83,
  77. 0xce, 0xdb, 0x73, 0xff, 0xb7, 0x5a, 0xed, 0xff,
  78. 0xbb, 0xdb, 0xdd, 0xc7, 0xbd, 0xdb, 0xbd, 0xbb,
  79. 0xbe, 0xbd, 0x7d, 0xbb, 0xbf, 0x7e, 0xfd, 0xb3,
  80. 0xbe, 0xe7, 0x7d, 0xbf, 0xbd, 0xdb, 0xbd, 0xbf,
  81. 0xbb, 0xbd, 0xdd, 0xbb, 0xb7, 0x7e, 0xed, 0xc7,
  82. 0xce, 0xdb, 0x73, 0xff, 0xfd, 0xdb, 0xbf, 0xff,
  83. 0xfb, 0xdb, 0xdf, 0x87, 0xf7, 0xdb, 0xef, 0xfb,
  84. 0xf7, 0xdb, 0xef, 0xfb, 0xfb, 0xdb, 0xdf, 0xfb,
  85. 0xfd, 0xdb, 0xbf, 0xc7, 0xfe, 0xdb, 0x7f, 0xbf,
  86. 0xff, 0x5a, 0xff, 0xbf, 0xff, 0xbd, 0xff, 0xc3,
  87. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  88. };
  89. static float cube_vertexes[6][4][4] = {
  90. { { -ONE , -ONE , -ONE , ONE },
  91. { -ONE , -ONE , ONE , ONE },
  92. { -ONE , ONE , ONE , ONE },
  93. { -ONE , ONE , -ONE , ONE } },
  94. { { ONE , ONE , ONE , ONE },
  95. { ONE , -ONE , ONE , ONE },
  96. { ONE , -ONE , -ONE , ONE },
  97. { ONE , ONE , -ONE , ONE } },
  98. { { -ONE , -ONE , -ONE , ONE },
  99. { ONE , -ONE , -ONE , ONE },
  100. { ONE , -ONE , ONE , ONE },
  101. { -ONE , -ONE , ONE , ONE } },
  102. { { ONE , ONE , ONE , ONE },
  103. { ONE , ONE , -ONE , ONE },
  104. { -ONE , ONE , -ONE , ONE },
  105. { -ONE , ONE , ONE , ONE } },
  106. { { -ONE , -ONE , -ONE , ONE },
  107. { -ONE , ONE , -ONE , ONE },
  108. { ONE , ONE , -ONE , ONE },
  109. { ONE , -ONE , -ONE , ONE } },
  110. { { ONE , ONE , ONE , ONE },
  111. { -ONE , ONE , ONE , ONE },
  112. { -ONE , -ONE , ONE , ONE },
  113. { ONE , -ONE , ONE , ONE } }
  114. };
  115. static float cube_normals[6][4] = {
  116. { -ONE , ZERO, ZERO, ZERO },
  117. { ONE , ZERO, ZERO, ZERO },
  118. { ZERO, -ONE , ZERO, ZERO },
  119. { ZERO, ONE , ZERO, ZERO },
  120. { ZERO, ZERO, -ONE , ZERO },
  121. { ZERO, ZERO, ONE , ZERO }
  122. };
  123. void MyInit( void );
  124. void MyReshape( GLsizei Width, GLsizei Height );
  125. void Display( void );
  126. void EnableLighting( void );
  127. void EnableFog( void );
  128. void FogModeLinear( void );
  129. void FogModeExp( void );
  130. void FogModeExp2( void );
  131. void MakeColorMap( void );
  132. static void
  133. usage(int argc, char **argv)
  134. {
  135. printf("\n");
  136. printf("usage: %s [options]\n", argv[0]);
  137. printf("\n");
  138. printf(" display a spinning cube and its shadow\n");
  139. printf("\n");
  140. printf(" Options:\n");
  141. printf(" -geometry window size and location\n");
  142. printf(" -c toggle color index mode\n");
  143. printf(" -l toggle lighting\n");
  144. printf(" -f toggle fog\n");
  145. printf(" -db toggle double buffering\n");
  146. printf(" -logo toggle sgi logo for the shadow pattern\n");
  147. printf(" -quads toggle use of GL_QUADS to draw the checkerboard\n");
  148. printf("\n");
  149. exit(EXIT_FAILURE);
  150. }
  151. static void
  152. setColor(int c)
  153. {
  154. if (useLighting) {
  155. if (useRGB) {
  156. glMaterialfv(GL_FRONT_AND_BACK,
  157. GL_AMBIENT_AND_DIFFUSE, &materialColor[c][0]);
  158. } else {
  159. glMaterialfv(GL_FRONT_AND_BACK,
  160. GL_COLOR_INDEXES, &materialColor[c][0]);
  161. }
  162. } else {
  163. if (useRGB) {
  164. glColor4fv(&materialColor[c][0]);
  165. } else {
  166. glIndexf(materialColor[c][1]);
  167. }
  168. }
  169. }
  170. static void
  171. drawCube(int color)
  172. {
  173. int i;
  174. setColor(color);
  175. for (i = 0; i < 6; ++i)
  176. {
  177. glNormal3fv(&cube_normals[i][0]);
  178. glBegin(GL_POLYGON);
  179. glVertex4fv(&cube_vertexes[i][0][0]);
  180. glVertex4fv(&cube_vertexes[i][1][0]);
  181. glVertex4fv(&cube_vertexes[i][2][0]);
  182. glVertex4fv(&cube_vertexes[i][3][0]);
  183. glEnd();
  184. }
  185. }
  186. static void
  187. drawCheck(int w, int h, int evenColor, int oddColor)
  188. {
  189. static int initialized = 0;
  190. static int usedLighting = 0;
  191. static GLuint checklist = 0;
  192. if (!initialized || (usedLighting != useLighting))
  193. {
  194. static float square_normal[4] = { ZERO, ZERO, ONE , ZERO };
  195. static float square[4][4];
  196. int i, j;
  197. if (!checklist)
  198. {
  199. checklist = glGenLists(1);
  200. }
  201. glNewList(checklist, GL_COMPILE_AND_EXECUTE);
  202. if (useQuads) {
  203. glNormal3fv(square_normal);
  204. glBegin(GL_QUADS);
  205. }
  206. for (j = 0; j < h; ++j)
  207. {
  208. for (i = 0; i < w; ++i)
  209. {
  210. square[0][0] = (float)( -1.0 + 2.0/w * i );
  211. square[0][1] = (float)( -1.0 + 2.0/h * (j+1) );
  212. square[0][2] = (float)( 0.0 );
  213. square[0][3] = (float)( 1.0 );
  214. square[1][0] = (float)( -1.0 + 2.0/w * i );
  215. square[1][1] = (float)( -1.0 + 2.0/h * j );
  216. square[1][2] = (float)( 0.0 );
  217. square[1][3] = (float)( 1.0 );
  218. square[2][0] = (float)( -1.0 + 2.0/w * (i+1) );
  219. square[2][1] = (float)( -1.0 + 2.0/h * j );
  220. square[2][2] = (float)( 0.0 );
  221. square[2][3] = (float)( 1.0 );
  222. square[3][0] = (float)( -1.0 + 2.0/w * (i+1) );
  223. square[3][1] = (float)( -1.0 + 2.0/h * (j+1) );
  224. square[3][2] = (float)( 0.0 );
  225. square[3][3] = (float)( 1.0 );
  226. if (i & 1 ^ j & 1) {
  227. setColor(oddColor);
  228. } else {
  229. setColor(evenColor);
  230. }
  231. if (!useQuads) {
  232. glBegin(GL_POLYGON);
  233. }
  234. glVertex4fv(&square[0][0]);
  235. glVertex4fv(&square[1][0]);
  236. glVertex4fv(&square[2][0]);
  237. glVertex4fv(&square[3][0]);
  238. if (!useQuads) {
  239. glEnd();
  240. }
  241. }
  242. }
  243. if (useQuads) {
  244. glEnd();
  245. }
  246. glEndList();
  247. initialized = 1;
  248. usedLighting = useLighting;
  249. }
  250. else
  251. {
  252. glCallList(checklist);
  253. }
  254. }
  255. static void
  256. myShadowMatrix(float ground[4], float light[4])
  257. {
  258. float dot;
  259. float shadowMat[4][4];
  260. dot = ground[0] * light[0] +
  261. ground[1] * light[1] +
  262. ground[2] * light[2] +
  263. ground[3] * light[3];
  264. shadowMat[0][0] = dot - light[0] * ground[0];
  265. shadowMat[1][0] = ZERO - light[0] * ground[1];
  266. shadowMat[2][0] = ZERO - light[0] * ground[2];
  267. shadowMat[3][0] = ZERO - light[0] * ground[3];
  268. shadowMat[0][1] = ZERO - light[1] * ground[0];
  269. shadowMat[1][1] = dot - light[1] * ground[1];
  270. shadowMat[2][1] = ZERO - light[1] * ground[2];
  271. shadowMat[3][1] = ZERO - light[1] * ground[3];
  272. shadowMat[0][2] = ZERO - light[2] * ground[0];
  273. shadowMat[1][2] = ZERO - light[2] * ground[1];
  274. shadowMat[2][2] = dot - light[2] * ground[2];
  275. shadowMat[3][2] = ZERO - light[2] * ground[3];
  276. shadowMat[0][3] = ZERO - light[3] * ground[0];
  277. shadowMat[1][3] = ZERO - light[3] * ground[1];
  278. shadowMat[2][3] = ZERO - light[3] * ground[2];
  279. shadowMat[3][3] = dot - light[3] * ground[3];
  280. glMultMatrixf((const GLfloat*)shadowMat);
  281. }
  282. int
  283. main(int argc, char **argv)
  284. {
  285. int width = WINDOW_WIDTH;
  286. int height = WINDOW_HEIGHT;
  287. int top = WINDOW_TOP;
  288. int left = WINDOW_LEFT;
  289. int i;
  290. int DisplayMode;
  291. /* process commmand line args */
  292. for (i = 1; i < argc; ++i)
  293. {
  294. if (!strcmp("-geometry", argv[i]))
  295. {
  296. i++;
  297. if ( !miscParseGeometry(argv[i],
  298. &left,
  299. &top,
  300. &width,
  301. &height )
  302. )
  303. {
  304. usage(argc, argv);
  305. }
  306. }
  307. else if (!strcmp("-c", argv[i]))
  308. {
  309. useRGB = !useRGB;
  310. }
  311. else if (!strcmp("-l", argv[i]))
  312. {
  313. useLighting = !useLighting;
  314. }
  315. else if (!strcmp("-f", argv[i]))
  316. {
  317. useFog = !useFog;
  318. }
  319. else if (!strcmp("-db", argv[i]))
  320. {
  321. useDB = !useDB;
  322. }
  323. else if (!strcmp("-logo", argv[i]))
  324. {
  325. useLogo = !useLogo;
  326. }
  327. else if (!strcmp("-quads", argv[i]))
  328. {
  329. useQuads = !useQuads;
  330. }
  331. else
  332. {
  333. usage(argc, argv);
  334. }
  335. }
  336. auxInitPosition( left, top, width, height );
  337. DisplayMode = AUX_DEPTH16;
  338. DisplayMode |= useRGB ? AUX_RGB : AUX_INDEX;
  339. DisplayMode |= useDB ? AUX_DOUBLE : AUX_SINGLE;
  340. auxInitDisplayMode( DisplayMode );
  341. auxInitWindow( *argv );
  342. auxIdleFunc( Display );
  343. auxReshapeFunc( MyReshape );
  344. auxKeyFunc( AUX_L, EnableLighting );
  345. auxKeyFunc( AUX_l, EnableLighting );
  346. auxKeyFunc( AUX_F, EnableFog );
  347. auxKeyFunc( AUX_f, EnableFog );
  348. auxKeyFunc( AUX_1, FogModeLinear );
  349. auxKeyFunc( AUX_2, FogModeExp );
  350. auxKeyFunc( AUX_3, FogModeExp2 );
  351. MakeColorMap();
  352. MyInit();
  353. auxMainLoop( Display );
  354. return(0);
  355. }
  356. void
  357. MyInit( void )
  358. {
  359. glMatrixMode(GL_PROJECTION);
  360. glLoadIdentity();
  361. glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 3.0);
  362. glMatrixMode(GL_MODELVIEW);
  363. glLoadIdentity();
  364. glTranslatef(ZERO, ZERO, -TWO );
  365. glEnable(GL_DEPTH_TEST);
  366. if (useLighting) {
  367. glEnable(GL_LIGHTING);
  368. }
  369. glEnable(GL_LIGHT0);
  370. glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
  371. glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
  372. glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
  373. glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);
  374. /*
  375. glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDir);
  376. glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 80);
  377. glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 25);
  378. */
  379. glEnable(GL_NORMALIZE);
  380. if (useFog) {
  381. glEnable(GL_FOG);
  382. }
  383. glFogfv(GL_FOG_COLOR, fogColor);
  384. glFogfv(GL_FOG_INDEX, fogIndex);
  385. glFogf(GL_FOG_MODE, (GLfloat)GL_EXP);
  386. glFogf(GL_FOG_DENSITY, HALF);
  387. glFogf(GL_FOG_START, ONE );
  388. glFogf(GL_FOG_END, THREE);
  389. glEnable(GL_CULL_FACE);
  390. glCullFace(GL_BACK);
  391. glShadeModel(GL_SMOOTH);
  392. glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA);
  393. if (useLogo) {
  394. glPolygonStipple((const GLubyte *)sgiPattern);
  395. } else {
  396. glPolygonStipple((const GLubyte *)shadowPattern);
  397. }
  398. glClearColor(ZERO, ZERO, ZERO, ONE );
  399. glClearIndex(ZERO);
  400. glClearDepth(1);
  401. }
  402. void
  403. MyReshape( GLsizei Width, GLsizei Height )
  404. {
  405. glViewport(0, 0, Width, Height);
  406. }
  407. void
  408. Display( void )
  409. {
  410. static int i = 0;
  411. GLfloat cubeXform[4][4];
  412. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  413. glPushMatrix();
  414. glTranslatef(ZERO, -1.5f, ZERO);
  415. glRotatef(-NINETY, ONE , ZERO, ZERO);
  416. glScalef(TWO , TWO , TWO );
  417. drawCheck(6, 6, BLUE, YELLOW); /* draw ground */
  418. glPopMatrix();
  419. glPushMatrix();
  420. glTranslatef(ZERO, ZERO, -0.9f);
  421. glScalef(TWO , TWO , TWO );
  422. drawCheck(6, 6, BLUE, YELLOW); /* draw back */
  423. glPopMatrix();
  424. glPushMatrix();
  425. glTranslatef(ZERO, 0.2f, ZERO);
  426. glScalef(0.3f, 0.3f, 0.3f);
  427. glRotatef((float)((360.0 / (30.0 * 1.0)) * (double)i), ONE , ZERO, ZERO);
  428. glRotatef((float)((360.0 / (30.0 * 2.0)) * (double)i), ZERO, ONE , ZERO);
  429. glRotatef((float)((360.0 / (30.0 * 4.0)) * (double)i), ZERO, ZERO, ONE );
  430. glScalef(ONE , TWO , ONE );
  431. glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)cubeXform);
  432. drawCube(RED); /* draw cube */
  433. glPopMatrix();
  434. glDepthMask(GL_FALSE);
  435. if (useRGB) {
  436. glEnable(GL_BLEND);
  437. } else {
  438. glEnable(GL_POLYGON_STIPPLE);
  439. }
  440. if (useFog) {
  441. glDisable(GL_FOG);
  442. }
  443. glPushMatrix();
  444. myShadowMatrix(groundPlane, lightPos);
  445. glTranslatef(ZERO, ZERO, TWO );
  446. glMultMatrixf((const GLfloat *) cubeXform);
  447. drawCube(BLACK); /* draw ground shadow */
  448. glPopMatrix();
  449. glPushMatrix();
  450. myShadowMatrix(backPlane, lightPos);
  451. glTranslatef(ZERO, ZERO, TWO);
  452. glMultMatrixf((const GLfloat *) cubeXform);
  453. drawCube(BLACK); /* draw back shadow */
  454. glPopMatrix();
  455. glDepthMask(GL_TRUE);
  456. if (useRGB) {
  457. glDisable(GL_BLEND);
  458. } else {
  459. glDisable(GL_POLYGON_STIPPLE);
  460. }
  461. if (useFog) {
  462. glEnable(GL_FOG);
  463. }
  464. auxSwapBuffers();
  465. if ( i++ == 120 )
  466. i = 0;
  467. }
  468. void
  469. EnableLighting( void )
  470. {
  471. useLighting = !useLighting;
  472. useLighting ? glEnable(GL_LIGHTING) : glDisable(GL_LIGHTING);
  473. }
  474. void
  475. EnableFog( void )
  476. {
  477. useFog = !useFog;
  478. useFog ? glEnable(GL_FOG) : glDisable(GL_FOG);
  479. }
  480. void
  481. FogModeLinear( void )
  482. {
  483. glFogf(GL_FOG_MODE, (GLfloat)GL_LINEAR);
  484. }
  485. void
  486. FogModeExp( void )
  487. {
  488. glFogf(GL_FOG_MODE, (GLfloat)GL_EXP);
  489. }
  490. void
  491. FogModeExp2( void )
  492. {
  493. glFogf(GL_FOG_MODE, (GLfloat)GL_EXP2);
  494. }
  495. void
  496. MakeColorMap( void )
  497. {
  498. if (!useRGB)
  499. {
  500. int mapSize;
  501. int rampSize;
  502. int entry;
  503. int i;
  504. mapSize = auxGetColorMapSize();
  505. rampSize = mapSize / 8;
  506. for (entry = 0; entry < mapSize; ++entry)
  507. {
  508. int hue = entry / rampSize;
  509. float red, green, blue, val;
  510. val = ((float)(entry % rampSize)) / (float)(rampSize-1);
  511. red = (hue==0 || hue==1 || hue==5 || hue==6) ? val : 0;
  512. green = (hue==0 || hue==2 || hue==4 || hue==6) ? val : 0;
  513. blue = (hue==0 || hue==3 || hue==4 || hue==5) ? val : 0;
  514. auxSetOneColor( entry, (float)red, (float)green, (float)blue );
  515. }
  516. for (i = 0; i < 8; ++i)
  517. {
  518. materialColor[i][0] = (float)(i*rampSize + 0.2 * (rampSize-1));
  519. materialColor[i][1] = (float)(i*rampSize + 0.8 * (rampSize-1));
  520. materialColor[i][2] = (float)(i*rampSize + 1.0 * (rampSize-1));
  521. materialColor[i][3] = ZERO;
  522. }
  523. fogIndex[0] = (float)(-0.2 * (rampSize-1));
  524. }
  525. }