Clone of mesa.
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.

ipers.c 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. /*
  2. * This program is under the GNU GPL.
  3. * Use at your own risk.
  4. *
  5. * written by David Bucciarelli (tech.hmw@plus.it)
  6. * Humanware s.r.l.
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <math.h>
  11. #include <time.h>
  12. #ifdef WIN32
  13. #include <windows.h>
  14. #include <mmsystem.h>
  15. #endif
  16. #include <GL/glut.h>
  17. #include "readtex.c"
  18. #ifdef XMESA
  19. #include "GL/xmesa.h"
  20. static int fullscreen = 1;
  21. #endif
  22. static int WIDTH = 640;
  23. static int HEIGHT = 480;
  24. static GLint T0;
  25. static GLint Frames;
  26. #define MAX_LOD 9
  27. #define TEX_SKY_WIDTH 256
  28. #define TEX_SKY_HEIGHT TEX_SKY_WIDTH
  29. #ifndef M_PI
  30. #define M_PI 3.1415926535
  31. #endif
  32. #define FROM_NONE 0
  33. #define FROM_DOWN 1
  34. #define FROM_UP 2
  35. #define FROM_LEFT 3
  36. #define FROM_RIGHT 4
  37. #define FROM_FRONT 5
  38. #define FROM_BACK 6
  39. static int win = 0;
  40. static float obs[3] = { 3.8, 0.0, 0.0 };
  41. static float dir[3];
  42. static float v = 0.0;
  43. static float alpha = -90.0;
  44. static float beta = 90.0;
  45. static int fog = 1;
  46. static int bfcull = 1;
  47. static int usetex = 1;
  48. static int help = 1;
  49. static int poutline = 0;
  50. static int normext = 1;
  51. static int joyavailable = 0;
  52. static int joyactive = 0;
  53. static int LODbias = 3;
  54. static int maxdepth = MAX_LOD;
  55. static unsigned int totpoly = 0;
  56. static GLuint t1id, t2id;
  57. static GLuint skydlist, LODdlist[MAX_LOD], LODnumpoly[MAX_LOD];
  58. static void
  59. initlight(void)
  60. {
  61. GLfloat lspec[4] = { 1.0, 1.0, 1.0, 1.0 };
  62. static GLfloat lightpos[4] = { 30, 15.0, 30.0, 1.0 };
  63. glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  64. glLightfv(GL_LIGHT0, GL_SPECULAR, lspec);
  65. glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 32.0);
  66. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, lspec);
  67. }
  68. static void
  69. initdlists(void)
  70. {
  71. static int slicetable[MAX_LOD][2] = {
  72. {21, 10},
  73. {18, 9},
  74. {15, 8},
  75. {12, 7},
  76. {9, 6},
  77. {7, 5},
  78. {5, 4},
  79. {4, 3},
  80. {3, 2}
  81. };
  82. GLUquadricObj *obj;
  83. int i, xslices, yslices;
  84. obj = gluNewQuadric();
  85. skydlist = glGenLists(1);
  86. glNewList(skydlist, GL_COMPILE);
  87. glBindTexture(GL_TEXTURE_2D, t2id);
  88. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  89. glColor3f(1.0f, 1.0f, 1.0f);
  90. gluQuadricDrawStyle(obj, GLU_FILL);
  91. gluQuadricNormals(obj, GLU_NONE);
  92. gluQuadricTexture(obj, GL_TRUE);
  93. gluQuadricOrientation(obj, GLU_INSIDE);
  94. gluSphere(obj, 40.0f, 18, 9);
  95. glEndList();
  96. for (i = 0; i < MAX_LOD; i++) {
  97. LODdlist[i] = glGenLists(1);
  98. glNewList(LODdlist[i], GL_COMPILE);
  99. gluQuadricDrawStyle(obj, GLU_FILL);
  100. gluQuadricNormals(obj, GLU_SMOOTH);
  101. gluQuadricTexture(obj, GL_TRUE);
  102. gluQuadricOrientation(obj, GLU_OUTSIDE);
  103. xslices = slicetable[i][0];
  104. yslices = slicetable[i][1];
  105. gluSphere(obj, 1.0f, xslices, yslices);
  106. LODnumpoly[i] = xslices * (yslices - 2) + 2 * (xslices - 1);
  107. glEndList();
  108. }
  109. }
  110. static void
  111. inittextures(void)
  112. {
  113. GLubyte tsky[TEX_SKY_HEIGHT][TEX_SKY_WIDTH][3];
  114. GLuint x, y;
  115. GLfloat fact;
  116. GLenum gluerr;
  117. /* Brick */
  118. glGenTextures(1, &t1id);
  119. glBindTexture(GL_TEXTURE_2D, t1id);
  120. if (!LoadRGBMipmaps("../images/bw.rgb", 3)) {
  121. fprintf(stderr, "Error reading a texture.\n");
  122. exit(-1);
  123. }
  124. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  125. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  126. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  127. GL_LINEAR_MIPMAP_LINEAR);
  128. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  129. /* Sky */
  130. glGenTextures(1, &t2id);
  131. glBindTexture(GL_TEXTURE_2D, t2id);
  132. for (y = 0; y < TEX_SKY_HEIGHT; y++)
  133. for (x = 0; x < TEX_SKY_WIDTH; x++)
  134. if (y < TEX_SKY_HEIGHT / 2) {
  135. fact = y / (GLfloat) (TEX_SKY_HEIGHT / 2);
  136. tsky[y][x][0] =
  137. (GLubyte) (255.0f * (0.1f * fact + 0.3f * (1.0f - fact)));
  138. tsky[y][x][1] =
  139. (GLubyte) (255.0f * (0.2f * fact + 1.0f * (1.0f - fact)));
  140. tsky[y][x][2] = 255;
  141. }
  142. else {
  143. tsky[y][x][0] = tsky[TEX_SKY_HEIGHT - y - 1][x][0];
  144. tsky[y][x][1] = tsky[TEX_SKY_HEIGHT - y - 1][x][1];
  145. tsky[y][x][2] = 255;
  146. }
  147. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  148. if (
  149. (gluerr =
  150. gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TEX_SKY_WIDTH, TEX_SKY_HEIGHT,
  151. GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *) (tsky)))) {
  152. fprintf(stderr, "GLULib%s\n", gluErrorString(gluerr));
  153. exit(-1);
  154. }
  155. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  156. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  157. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  158. GL_LINEAR_MIPMAP_LINEAR);
  159. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  160. }
  161. static void
  162. calcposobs(void)
  163. {
  164. dir[0] = sin(alpha * M_PI / 180.0);
  165. dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0);
  166. dir[2] = cos(beta * M_PI / 180.0);
  167. if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5)
  168. dir[0] = 0;
  169. if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5)
  170. dir[1] = 0;
  171. if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5)
  172. dir[2] = 0;
  173. obs[0] += v * dir[0];
  174. obs[1] += v * dir[1];
  175. obs[2] += v * dir[2];
  176. }
  177. static void
  178. special(int k, int x, int y)
  179. {
  180. switch (k) {
  181. case GLUT_KEY_LEFT:
  182. alpha -= 2.0;
  183. break;
  184. case GLUT_KEY_RIGHT:
  185. alpha += 2.0;
  186. break;
  187. case GLUT_KEY_DOWN:
  188. beta -= 2.0;
  189. break;
  190. case GLUT_KEY_UP:
  191. beta += 2.0;
  192. break;
  193. }
  194. }
  195. static void
  196. key(unsigned char k, int x, int y)
  197. {
  198. switch (k) {
  199. case 27:
  200. exit(0);
  201. break;
  202. case 'a':
  203. v += 0.01;
  204. break;
  205. case 'z':
  206. v -= 0.01;
  207. break;
  208. #ifdef XMESA
  209. case ' ':
  210. fullscreen = (!fullscreen);
  211. XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
  212. break;
  213. #endif
  214. case '+':
  215. LODbias--;
  216. break;
  217. case '-':
  218. LODbias++;
  219. break;
  220. case 'j':
  221. joyactive = (!joyactive);
  222. break;
  223. case 'h':
  224. help = (!help);
  225. break;
  226. case 'f':
  227. fog = (!fog);
  228. break;
  229. case 't':
  230. usetex = (!usetex);
  231. break;
  232. case 'n':
  233. normext = (!normext);
  234. break;
  235. case 'b':
  236. if (bfcull) {
  237. glDisable(GL_CULL_FACE);
  238. bfcull = 0;
  239. }
  240. else {
  241. glEnable(GL_CULL_FACE);
  242. bfcull = 1;
  243. }
  244. break;
  245. case 'p':
  246. if (poutline) {
  247. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  248. poutline = 0;
  249. usetex = 1;
  250. }
  251. else {
  252. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  253. poutline = 1;
  254. usetex = 0;
  255. }
  256. break;
  257. }
  258. }
  259. static void
  260. reshape(int w, int h)
  261. {
  262. WIDTH = w;
  263. HEIGHT = h;
  264. glMatrixMode(GL_PROJECTION);
  265. glLoadIdentity();
  266. gluPerspective(90.0, w / (float) h, 0.8, 100.0);
  267. glMatrixMode(GL_MODELVIEW);
  268. glLoadIdentity();
  269. glViewport(0, 0, w, h);
  270. }
  271. static void
  272. printstring(void *font, char *string)
  273. {
  274. int len, i;
  275. len = (int) strlen(string);
  276. for (i = 0; i < len; i++)
  277. glutBitmapCharacter(font, string[i]);
  278. }
  279. static void
  280. printhelp(void)
  281. {
  282. glEnable(GL_BLEND);
  283. glColor4f(0.5, 0.5, 0.5, 0.5);
  284. glRecti(40, 40, 600, 440);
  285. glDisable(GL_BLEND);
  286. glColor3f(1.0, 0.0, 0.0);
  287. glRasterPos2i(300, 420);
  288. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help");
  289. glRasterPos2i(60, 390);
  290. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Toggle Help");
  291. glRasterPos2i(60, 360);
  292. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Toggle Textures");
  293. glRasterPos2i(60, 330);
  294. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Toggle Fog");
  295. glRasterPos2i(60, 300);
  296. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "b - Toggle Back face culling");
  297. glRasterPos2i(60, 270);
  298. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate");
  299. glRasterPos2i(60, 240);
  300. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity");
  301. glRasterPos2i(60, 210);
  302. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity");
  303. glRasterPos2i(60, 180);
  304. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "p - Toggle Wire frame");
  305. glRasterPos2i(60, 150);
  306. printstring(GLUT_BITMAP_TIMES_ROMAN_24,
  307. "b - Toggle GL_EXT_rescale_normal extension");
  308. glRasterPos2i(60, 120);
  309. printstring(GLUT_BITMAP_TIMES_ROMAN_24,
  310. "+/- - Increase/decrease the Object maximum LOD");
  311. glRasterPos2i(60, 90);
  312. if (joyavailable)
  313. printstring(GLUT_BITMAP_TIMES_ROMAN_24,
  314. "j - Toggle jostick control (Joystick control available)");
  315. else
  316. printstring(GLUT_BITMAP_TIMES_ROMAN_24,
  317. "(No Joystick control available)");
  318. }
  319. static void
  320. dojoy(void)
  321. {
  322. #ifdef _WIN32
  323. static UINT max[2] = { 0, 0 };
  324. static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2];
  325. MMRESULT res;
  326. JOYINFO joy;
  327. res = joyGetPos(JOYSTICKID1, &joy);
  328. if (res == JOYERR_NOERROR) {
  329. joyavailable = 1;
  330. if (max[0] < joy.wXpos)
  331. max[0] = joy.wXpos;
  332. if (min[0] > joy.wXpos)
  333. min[0] = joy.wXpos;
  334. center[0] = (max[0] + min[0]) / 2;
  335. if (max[1] < joy.wYpos)
  336. max[1] = joy.wYpos;
  337. if (min[1] > joy.wYpos)
  338. min[1] = joy.wYpos;
  339. center[1] = (max[1] + min[1]) / 2;
  340. if (joyactive) {
  341. if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0]))
  342. alpha -=
  343. 2.0 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]);
  344. if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1]))
  345. beta += 2.0 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]);
  346. if (joy.wButtons & JOY_BUTTON1)
  347. v += 0.01;
  348. if (joy.wButtons & JOY_BUTTON2)
  349. v -= 0.01;
  350. }
  351. }
  352. else
  353. joyavailable = 0;
  354. #endif
  355. }
  356. static void
  357. drawipers(int depth, int from)
  358. {
  359. int lod;
  360. if (depth == maxdepth)
  361. return;
  362. lod = depth + LODbias;
  363. if (lod < 0)
  364. lod = 0;
  365. if (lod >= MAX_LOD)
  366. return;
  367. switch (from) {
  368. case FROM_NONE:
  369. glCallList(LODdlist[lod]);
  370. depth++;
  371. drawipers(depth, FROM_DOWN);
  372. drawipers(depth, FROM_UP);
  373. drawipers(depth, FROM_FRONT);
  374. drawipers(depth, FROM_BACK);
  375. drawipers(depth, FROM_LEFT);
  376. drawipers(depth, FROM_RIGHT);
  377. break;
  378. case FROM_FRONT:
  379. glPushMatrix();
  380. glTranslatef(0.0f, -1.5f, 0.0f);
  381. glScalef(0.5f, 0.5f, 0.5f);
  382. glCallList(LODdlist[lod]);
  383. depth++;
  384. drawipers(depth, FROM_DOWN);
  385. drawipers(depth, FROM_UP);
  386. drawipers(depth, FROM_FRONT);
  387. drawipers(depth, FROM_LEFT);
  388. drawipers(depth, FROM_RIGHT);
  389. glPopMatrix();
  390. break;
  391. case FROM_BACK:
  392. glPushMatrix();
  393. glTranslatef(0.0f, 1.5f, 0.0f);
  394. glScalef(0.5f, 0.5f, 0.5f);
  395. glCallList(LODdlist[lod]);
  396. depth++;
  397. drawipers(depth, FROM_DOWN);
  398. drawipers(depth, FROM_UP);
  399. drawipers(depth, FROM_BACK);
  400. drawipers(depth, FROM_LEFT);
  401. drawipers(depth, FROM_RIGHT);
  402. glPopMatrix();
  403. break;
  404. case FROM_LEFT:
  405. glPushMatrix();
  406. glTranslatef(-1.5f, 0.0f, 0.0f);
  407. glScalef(0.5f, 0.5f, 0.5f);
  408. glCallList(LODdlist[lod]);
  409. depth++;
  410. drawipers(depth, FROM_DOWN);
  411. drawipers(depth, FROM_UP);
  412. drawipers(depth, FROM_FRONT);
  413. drawipers(depth, FROM_BACK);
  414. drawipers(depth, FROM_LEFT);
  415. glPopMatrix();
  416. break;
  417. case FROM_RIGHT:
  418. glPushMatrix();
  419. glTranslatef(1.5f, 0.0f, 0.0f);
  420. glScalef(0.5f, 0.5f, 0.5f);
  421. glCallList(LODdlist[lod]);
  422. depth++;
  423. drawipers(depth, FROM_DOWN);
  424. drawipers(depth, FROM_UP);
  425. drawipers(depth, FROM_FRONT);
  426. drawipers(depth, FROM_BACK);
  427. drawipers(depth, FROM_RIGHT);
  428. glPopMatrix();
  429. break;
  430. case FROM_DOWN:
  431. glPushMatrix();
  432. glTranslatef(0.0f, 0.0f, 1.5f);
  433. glScalef(0.5f, 0.5f, 0.5f);
  434. glCallList(LODdlist[lod]);
  435. depth++;
  436. drawipers(depth, FROM_DOWN);
  437. drawipers(depth, FROM_FRONT);
  438. drawipers(depth, FROM_BACK);
  439. drawipers(depth, FROM_LEFT);
  440. drawipers(depth, FROM_RIGHT);
  441. glPopMatrix();
  442. break;
  443. case FROM_UP:
  444. glPushMatrix();
  445. glTranslatef(0.0f, 0.0f, -1.5f);
  446. glScalef(0.5f, 0.5f, 0.5f);
  447. glCallList(LODdlist[lod]);
  448. depth++;
  449. drawipers(depth, FROM_UP);
  450. drawipers(depth, FROM_FRONT);
  451. drawipers(depth, FROM_BACK);
  452. drawipers(depth, FROM_LEFT);
  453. drawipers(depth, FROM_RIGHT);
  454. glPopMatrix();
  455. break;
  456. }
  457. totpoly += LODnumpoly[lod];
  458. }
  459. static void
  460. draw(void)
  461. {
  462. static char frbuf[80] = "";
  463. static GLfloat alpha = 0.0f;
  464. static GLfloat beta = 0.0f;
  465. static float fr = 0.0;
  466. dojoy();
  467. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  468. if (usetex)
  469. glEnable(GL_TEXTURE_2D);
  470. else
  471. glDisable(GL_TEXTURE_2D);
  472. if (fog)
  473. glEnable(GL_FOG);
  474. else
  475. glDisable(GL_FOG);
  476. glPushMatrix();
  477. calcposobs();
  478. gluLookAt(obs[0], obs[1], obs[2],
  479. obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2],
  480. 0.0, 0.0, 1.0);
  481. /* Scene */
  482. glEnable(GL_DEPTH_TEST);
  483. glShadeModel(GL_SMOOTH);
  484. glBindTexture(GL_TEXTURE_2D, t1id);
  485. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  486. glColor3f(1.0f, 1.0f, 1.0f);
  487. glEnable(GL_LIGHT0);
  488. glEnable(GL_LIGHTING);
  489. if (normext)
  490. glEnable(GL_RESCALE_NORMAL_EXT);
  491. else
  492. glEnable(GL_NORMALIZE);
  493. glPushMatrix();
  494. glRotatef(alpha, 0.0f, 0.0f, 1.0f);
  495. glRotatef(beta, 1.0f, 0.0f, 0.0f);
  496. totpoly = 0;
  497. drawipers(0, FROM_NONE);
  498. glPopMatrix();
  499. alpha += 0.5f;
  500. beta += 0.3f;
  501. glDisable(GL_LIGHTING);
  502. glDisable(GL_LIGHT0);
  503. glShadeModel(GL_FLAT);
  504. if (normext)
  505. glDisable(GL_RESCALE_NORMAL_EXT);
  506. else
  507. glDisable(GL_NORMALIZE);
  508. glCallList(skydlist);
  509. glPopMatrix();
  510. /* Help Screen */
  511. sprintf(frbuf,
  512. "Frame rate: %0.2f LOD: %d Tot. poly.: %d Poly/sec: %.1f",
  513. fr, LODbias, totpoly, totpoly * fr);
  514. glDisable(GL_TEXTURE_2D);
  515. glDisable(GL_FOG);
  516. glShadeModel(GL_FLAT);
  517. glDisable(GL_DEPTH_TEST);
  518. glMatrixMode(GL_PROJECTION);
  519. glPushMatrix();
  520. glLoadIdentity();
  521. glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
  522. glMatrixMode(GL_MODELVIEW);
  523. glLoadIdentity();
  524. glColor3f(1.0, 0.0, 0.0);
  525. glRasterPos2i(10, 10);
  526. printstring(GLUT_BITMAP_HELVETICA_18, frbuf);
  527. glRasterPos2i(350, 470);
  528. printstring(GLUT_BITMAP_HELVETICA_10,
  529. "IperS V1.0 Written by David Bucciarelli (tech.hmw@plus.it)");
  530. if (help)
  531. printhelp();
  532. glMatrixMode(GL_PROJECTION);
  533. glPopMatrix();
  534. glMatrixMode(GL_MODELVIEW);
  535. glutSwapBuffers();
  536. Frames++;
  537. {
  538. GLint t = glutGet(GLUT_ELAPSED_TIME);
  539. if (t - T0 >= 2000) {
  540. GLfloat seconds = (t - T0) / 1000.0;
  541. fr = Frames / seconds;
  542. T0 = t;
  543. Frames = 0;
  544. }
  545. }
  546. }
  547. int
  548. main(int ac, char **av)
  549. {
  550. float fogcolor[4] = { 0.7, 0.7, 0.7, 1.0 };
  551. fprintf(stderr,
  552. "IperS V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
  553. glutInitWindowPosition(0, 0);
  554. glutInitWindowSize(WIDTH, HEIGHT);
  555. glutInit(&ac, av);
  556. glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  557. if (!(win = glutCreateWindow("IperS"))) {
  558. fprintf(stderr, "Error, couldn't open window\n");
  559. exit(-1);
  560. }
  561. reshape(WIDTH, HEIGHT);
  562. glShadeModel(GL_SMOOTH);
  563. glEnable(GL_DEPTH_TEST);
  564. glEnable(GL_CULL_FACE);
  565. glEnable(GL_TEXTURE_2D);
  566. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  567. glEnable(GL_FOG);
  568. glFogi(GL_FOG_MODE, GL_EXP2);
  569. glFogfv(GL_FOG_COLOR, fogcolor);
  570. glFogf(GL_FOG_DENSITY, 0.006);
  571. glHint(GL_FOG_HINT, GL_NICEST);
  572. inittextures();
  573. initdlists();
  574. initlight();
  575. glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]);
  576. glClear(GL_COLOR_BUFFER_BIT);
  577. calcposobs();
  578. glutReshapeFunc(reshape);
  579. glutDisplayFunc(draw);
  580. glutKeyboardFunc(key);
  581. glutSpecialFunc(special);
  582. glutIdleFunc(draw);
  583. glutMainLoop();
  584. return 0;
  585. }