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.

tunnel2.c 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. /*
  2. * This program is under the GNU GPL.
  3. * Use at your own risk.
  4. *
  5. * You need TWO Voodoo Graphics boards in order to run
  6. * this demo !
  7. *
  8. * written by David Bucciarelli (tech.hmw@plus.it)
  9. * Humanware s.r.l.
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <math.h>
  14. #include <time.h>
  15. #ifdef WIN32
  16. #include <windows.h>
  17. #endif
  18. #include <GL/glut.h>
  19. #include "../util/readtex.c"
  20. #include "tunneldat.c"
  21. #ifdef FX
  22. #endif
  23. #ifdef XMESA
  24. #include "GL/xmesa.h"
  25. static int fullscreen = 1;
  26. #endif
  27. #ifdef FX
  28. GLboolean fxMesaSelectCurrentBoard(int);
  29. #endif
  30. static int WIDTHC0 = 640;
  31. static int HEIGHTC0 = 480;
  32. static int WIDTHC1 = 640;
  33. static int HEIGHTC1 = 480;
  34. #define FRAME 50
  35. #define NUMBLOC 5
  36. #ifndef M_PI
  37. #define M_PI 3.1415926535
  38. #endif
  39. extern int striplength_skin_13[];
  40. extern float stripdata_skin_13[];
  41. extern int striplength_skin_12[];
  42. extern float stripdata_skin_12[];
  43. extern int striplength_skin_11[];
  44. extern float stripdata_skin_11[];
  45. extern int striplength_skin_9[];
  46. extern float stripdata_skin_9[];
  47. static float obs[3] = { 1000.0, 0.0, 2.0 };
  48. static float dir[3];
  49. static float v = 0.5;
  50. static float alpha = 90.0;
  51. static float beta = 90.0;
  52. static int fog = 0;
  53. static int bfcull = 1;
  54. static int usetex = 1;
  55. static int cstrip = 0;
  56. static int help = 1;
  57. static int joyavailable = 0;
  58. static int joyactive = 0;
  59. static int channel[2];
  60. static GLuint t1id, t2id;
  61. static void
  62. inittextures(void)
  63. {
  64. glGenTextures(1, &t1id);
  65. glBindTexture(GL_TEXTURE_2D, t1id);
  66. if (!LoadRGBMipmaps("../images/tile.rgb", GL_RGB)) {
  67. fprintf(stderr, "Error reading a texture.\n");
  68. exit(-1);
  69. }
  70. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  71. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  72. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  73. GL_LINEAR_MIPMAP_NEAREST);
  74. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  75. glGenTextures(1, &t2id);
  76. glBindTexture(GL_TEXTURE_2D, t2id);
  77. if (!LoadRGBMipmaps("../images/bw.rgb", GL_RGB)) {
  78. fprintf(stderr, "Error reading a texture.\n");
  79. exit(-1);
  80. }
  81. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  82. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  83. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  84. GL_LINEAR_MIPMAP_NEAREST);
  85. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  86. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  87. }
  88. static void
  89. drawobjs(int *l, float *f)
  90. {
  91. int mend, j;
  92. if (cstrip) {
  93. float r = 0.33, g = 0.33, b = 0.33;
  94. for (; (*l) != 0;) {
  95. mend = *l++;
  96. r += 0.33;
  97. if (r > 1.0) {
  98. r = 0.33;
  99. g += 0.33;
  100. if (g > 1.0) {
  101. g = 0.33;
  102. b += 0.33;
  103. if (b > 1.0)
  104. b = 0.33;
  105. }
  106. }
  107. glColor3f(r, g, b);
  108. glBegin(GL_TRIANGLE_STRIP);
  109. for (j = 0; j < mend; j++) {
  110. f += 4;
  111. glTexCoord2fv(f);
  112. f += 2;
  113. glVertex3fv(f);
  114. f += 3;
  115. }
  116. glEnd();
  117. }
  118. }
  119. else
  120. for (; (*l) != 0;) {
  121. mend = *l++;
  122. glBegin(GL_TRIANGLE_STRIP);
  123. for (j = 0; j < mend; j++) {
  124. glColor4fv(f);
  125. f += 4;
  126. glTexCoord2fv(f);
  127. f += 2;
  128. glVertex3fv(f);
  129. f += 3;
  130. }
  131. glEnd();
  132. }
  133. }
  134. static float
  135. gettime(void)
  136. {
  137. static clock_t told = 0;
  138. clock_t tnew, ris;
  139. tnew = clock();
  140. ris = tnew - told;
  141. told = tnew;
  142. return (ris / (float) CLOCKS_PER_SEC);
  143. }
  144. static void
  145. calcposobs(void)
  146. {
  147. dir[0] = sin(alpha * M_PI / 180.0);
  148. dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0);
  149. dir[2] = cos(beta * M_PI / 180.0);
  150. obs[0] += v * dir[0];
  151. obs[1] += v * dir[1];
  152. obs[2] += v * dir[2];
  153. }
  154. static void
  155. special(int k, int x, int y)
  156. {
  157. switch (k) {
  158. case GLUT_KEY_LEFT:
  159. alpha -= 2.0;
  160. break;
  161. case GLUT_KEY_RIGHT:
  162. alpha += 2.0;
  163. break;
  164. case GLUT_KEY_DOWN:
  165. beta -= 2.0;
  166. break;
  167. case GLUT_KEY_UP:
  168. beta += 2.0;
  169. break;
  170. }
  171. }
  172. static void
  173. key(unsigned char k, int x, int y)
  174. {
  175. switch (k) {
  176. case 27:
  177. exit(0);
  178. break;
  179. case 'a':
  180. v += 0.01;
  181. break;
  182. case 'z':
  183. v -= 0.01;
  184. break;
  185. #ifdef XMESA
  186. case ' ':
  187. fullscreen = (!fullscreen);
  188. glutSetWindow(channel[0]);
  189. XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
  190. glutSetWindow(channel[1]);
  191. XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
  192. break;
  193. #endif
  194. case 'j':
  195. joyactive = (!joyactive);
  196. break;
  197. case 'h':
  198. help = (!help);
  199. break;
  200. case 'f':
  201. fog = (!fog);
  202. break;
  203. case 't':
  204. usetex = (!usetex);
  205. break;
  206. case 'b':
  207. if (bfcull) {
  208. glDisable(GL_CULL_FACE);
  209. bfcull = 0;
  210. }
  211. else {
  212. glEnable(GL_CULL_FACE);
  213. bfcull = 1;
  214. }
  215. break;
  216. case 'm':
  217. cstrip = (!cstrip);
  218. break;
  219. case 'd':
  220. fprintf(stderr, "Deleting textures...\n");
  221. glDeleteTextures(1, &t1id);
  222. glDeleteTextures(1, &t2id);
  223. fprintf(stderr, "Loading textures...\n");
  224. inittextures();
  225. fprintf(stderr, "Done.\n");
  226. break;
  227. }
  228. }
  229. static void
  230. reshapechannel0(int w, int h)
  231. {
  232. float ratio;
  233. WIDTHC0 = w;
  234. HEIGHTC0 = h;
  235. glMatrixMode(GL_PROJECTION);
  236. glLoadIdentity();
  237. ratio = 0.5f * w / (float) h;
  238. glFrustum(-2.0, 0.0, -1.0 * ratio, 1.0 * ratio, 1.0, 60.0);
  239. glMatrixMode(GL_MODELVIEW);
  240. glLoadIdentity();
  241. glViewport(0, 0, w, h);
  242. }
  243. static void
  244. reshapechannel1(int w, int h)
  245. {
  246. float ratio;
  247. WIDTHC1 = w;
  248. HEIGHTC1 = h;
  249. glMatrixMode(GL_PROJECTION);
  250. glLoadIdentity();
  251. ratio = 0.5f * w / (float) h;
  252. glFrustum(0.0, 2.0, -1.0 * ratio, 1.0 * ratio, 1.0, 60.0);
  253. glMatrixMode(GL_MODELVIEW);
  254. glLoadIdentity();
  255. glViewport(0, 0, w, h);
  256. }
  257. static void
  258. printstring(void *font, char *string)
  259. {
  260. int len, i;
  261. len = (int) strlen(string);
  262. for (i = 0; i < len; i++)
  263. glutBitmapCharacter(font, string[i]);
  264. }
  265. static void
  266. printhelp(void)
  267. {
  268. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  269. glColor4f(0.0, 0.0, 0.0, 0.5);
  270. glRecti(40, 40, 600, 440);
  271. glColor3f(1.0, 0.0, 0.0);
  272. glRasterPos2i(300, 420);
  273. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help");
  274. glRasterPos2i(60, 390);
  275. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Togle Help");
  276. glRasterPos2i(60, 360);
  277. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Togle Textures");
  278. glRasterPos2i(60, 330);
  279. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Togle Fog");
  280. glRasterPos2i(60, 300);
  281. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "m - Togle strips");
  282. glRasterPos2i(60, 270);
  283. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "b - Togle Back face culling");
  284. glRasterPos2i(60, 240);
  285. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate");
  286. glRasterPos2i(60, 210);
  287. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity");
  288. glRasterPos2i(60, 180);
  289. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity");
  290. glRasterPos2i(60, 150);
  291. if (joyavailable)
  292. printstring(GLUT_BITMAP_TIMES_ROMAN_24,
  293. "j - Togle jostick control (Joystick control available)");
  294. else
  295. printstring(GLUT_BITMAP_TIMES_ROMAN_24,
  296. "(No Joystick control available)");
  297. }
  298. static void
  299. dojoy(void)
  300. {
  301. #ifdef WIN32
  302. static UINT max[2] = { 0, 0 };
  303. static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2];
  304. MMRESULT res;
  305. JOYINFO joy;
  306. res = joyGetPos(JOYSTICKID1, &joy);
  307. if (res == JOYERR_NOERROR) {
  308. joyavailable = 1;
  309. if (max[0] < joy.wXpos)
  310. max[0] = joy.wXpos;
  311. if (min[0] > joy.wXpos)
  312. min[0] = joy.wXpos;
  313. center[0] = (max[0] + min[0]) / 2;
  314. if (max[1] < joy.wYpos)
  315. max[1] = joy.wYpos;
  316. if (min[1] > joy.wYpos)
  317. min[1] = joy.wYpos;
  318. center[1] = (max[1] + min[1]) / 2;
  319. if (joyactive) {
  320. if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0]))
  321. alpha -=
  322. 2.0 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]);
  323. if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1]))
  324. beta += 2.0 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]);
  325. if (joy.wButtons & JOY_BUTTON1)
  326. v += 0.01;
  327. if (joy.wButtons & JOY_BUTTON2)
  328. v -= 0.01;
  329. }
  330. }
  331. else
  332. joyavailable = 0;
  333. #endif
  334. }
  335. static void
  336. draw(void)
  337. {
  338. static int count = 0;
  339. static char frbuf[80];
  340. int i;
  341. float fr, base, offset;
  342. dojoy();
  343. glClear(GL_COLOR_BUFFER_BIT);
  344. glClear(GL_COLOR_BUFFER_BIT);
  345. if (usetex)
  346. glEnable(GL_TEXTURE_2D);
  347. else
  348. glDisable(GL_TEXTURE_2D);
  349. if (fog)
  350. glEnable(GL_FOG);
  351. else
  352. glDisable(GL_FOG);
  353. glShadeModel(GL_SMOOTH);
  354. glPushMatrix();
  355. calcposobs();
  356. gluLookAt(obs[0], obs[1], obs[2],
  357. obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2],
  358. 0.0, 0.0, 1.0);
  359. if (dir[0] > 0) {
  360. offset = 8.0;
  361. base = obs[0] - fmod(obs[0], 8.0);
  362. }
  363. else {
  364. offset = -8.0;
  365. base = obs[0] + (8.0 - fmod(obs[0], 8.0));
  366. }
  367. glPushMatrix();
  368. glTranslatef(base - offset / 2.0, 0.0, 0.0);
  369. for (i = 0; i < NUMBLOC; i++) {
  370. glTranslatef(offset, 0.0, 0.0);
  371. glBindTexture(GL_TEXTURE_2D, t1id);
  372. drawobjs(striplength_skin_11, stripdata_skin_11);
  373. glBindTexture(GL_TEXTURE_2D, t2id);
  374. drawobjs(striplength_skin_12, stripdata_skin_12);
  375. drawobjs(striplength_skin_9, stripdata_skin_9);
  376. drawobjs(striplength_skin_13, stripdata_skin_13);
  377. }
  378. glPopMatrix();
  379. glPopMatrix();
  380. if ((count % FRAME) == 0) {
  381. fr = gettime();
  382. sprintf(frbuf, "Frame rate: %f", FRAME / fr);
  383. }
  384. glDisable(GL_TEXTURE_2D);
  385. glDisable(GL_FOG);
  386. glShadeModel(GL_FLAT);
  387. glMatrixMode(GL_PROJECTION);
  388. glPushMatrix();
  389. glLoadIdentity();
  390. glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
  391. glMatrixMode(GL_MODELVIEW);
  392. glLoadIdentity();
  393. glColor3f(1.0, 0.0, 0.0);
  394. glRasterPos2i(10, 10);
  395. printstring(GLUT_BITMAP_HELVETICA_18, frbuf);
  396. glRasterPos2i(350, 470);
  397. printstring(GLUT_BITMAP_HELVETICA_10,
  398. "Tunnel2 V1.0 Written by David Bucciarelli (tech.hmw@plus.it)");
  399. if (help)
  400. printhelp();
  401. glMatrixMode(GL_PROJECTION);
  402. glPopMatrix();
  403. glMatrixMode(GL_MODELVIEW);
  404. count++;
  405. }
  406. static void
  407. drawchannel0(void)
  408. {
  409. glutSetWindow(channel[0]);
  410. draw();
  411. glutSwapBuffers();
  412. }
  413. static void
  414. drawchannel1(void)
  415. {
  416. glutSetWindow(channel[1]);
  417. draw();
  418. glutSwapBuffers();
  419. }
  420. static void
  421. drawall(void)
  422. {
  423. glutSetWindow(channel[0]);
  424. draw();
  425. glutSetWindow(channel[1]);
  426. draw();
  427. glutSetWindow(channel[0]);
  428. glutSwapBuffers();
  429. glutSetWindow(channel[1]);
  430. glutSwapBuffers();
  431. }
  432. static void
  433. init(void)
  434. {
  435. float fogcolor[4] = { 0.7, 0.7, 0.7, 1.0 };
  436. glShadeModel(GL_SMOOTH);
  437. glDisable(GL_DEPTH_TEST);
  438. glEnable(GL_CULL_FACE);
  439. glEnable(GL_TEXTURE_2D);
  440. glEnable(GL_FOG);
  441. glFogi(GL_FOG_MODE, GL_EXP2);
  442. glFogfv(GL_FOG_COLOR, fogcolor);
  443. glFogf(GL_FOG_DENSITY, 0.06);
  444. glHint(GL_FOG_HINT, GL_NICEST);
  445. glEnable(GL_BLEND);
  446. /*
  447. glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
  448. glEnable(GL_POLYGON_SMOOTH);
  449. */
  450. glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]);
  451. glClear(GL_COLOR_BUFFER_BIT);
  452. }
  453. int
  454. main(int ac, char **av)
  455. {
  456. fprintf(stderr,
  457. "Tunnel2 V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
  458. fprintf(stderr,
  459. "You need TWO Voodoo Graphics boards in order to run this demo !\n");
  460. glutInitWindowPosition(0, 0);
  461. glutInitWindowSize(WIDTHC0, HEIGHTC0);
  462. glutInit(&ac, av);
  463. glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_ALPHA);
  464. #ifdef FX
  465. if (!fxMesaSelectCurrentBoard(0)) {
  466. fprintf(stderr, "The first Voodoo Graphics board is missing !?!?\n");
  467. return -1;
  468. }
  469. #endif
  470. if (!(channel[0] = glutCreateWindow("Channel 0"))) {
  471. fprintf(stderr, "Error, couldn't open window\n");
  472. return -1;
  473. }
  474. reshapechannel0(WIDTHC0, HEIGHTC0);
  475. init();
  476. inittextures();
  477. glutDisplayFunc(drawchannel0);
  478. glutReshapeFunc(reshapechannel0);
  479. glutKeyboardFunc(key);
  480. glutSpecialFunc(special);
  481. #ifdef FX
  482. if (!fxMesaSelectCurrentBoard(1)) {
  483. fprintf(stderr, "The second Voodoo Graphics board is missing !\n");
  484. exit(-1);
  485. }
  486. #endif
  487. glutInitWindowPosition(WIDTHC0, 0);
  488. glutInitWindowSize(WIDTHC1, HEIGHTC1);
  489. if (!(channel[1] = glutCreateWindow("Channel 1"))) {
  490. fprintf(stderr, "Error, couldn't open window\n");
  491. exit(-1);
  492. }
  493. reshapechannel1(WIDTHC1, HEIGHTC1);
  494. init();
  495. inittextures();
  496. glutDisplayFunc(drawchannel1);
  497. glutReshapeFunc(reshapechannel1);
  498. glutKeyboardFunc(key);
  499. glutSpecialFunc(special);
  500. glutIdleFunc(drawall);
  501. calcposobs();
  502. glutMainLoop();
  503. return 0;
  504. }