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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  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. #ifndef M_PI
  23. #define M_PI 3.1415926535
  24. #endif
  25. #define vinit(a,i,j,k) {\
  26. (a)[0]=i;\
  27. (a)[1]=j;\
  28. (a)[2]=k;\
  29. }
  30. #define vinit4(a,i,j,k,w) {\
  31. (a)[0]=i;\
  32. (a)[1]=j;\
  33. (a)[2]=k;\
  34. (a)[3]=w;\
  35. }
  36. #define vadds(a,dt,b) {\
  37. (a)[0]+=(dt)*(b)[0];\
  38. (a)[1]+=(dt)*(b)[1];\
  39. (a)[2]+=(dt)*(b)[2];\
  40. }
  41. #define vequ(a,b) {\
  42. (a)[0]=(b)[0];\
  43. (a)[1]=(b)[1];\
  44. (a)[2]=(b)[2];\
  45. }
  46. #define vinter(a,dt,b,c) {\
  47. (a)[0]=(dt)*(b)[0]+(1.0-dt)*(c)[0];\
  48. (a)[1]=(dt)*(b)[1]+(1.0-dt)*(c)[1];\
  49. (a)[2]=(dt)*(b)[2]+(1.0-dt)*(c)[2];\
  50. }
  51. #define clamp(a) ((a) < 0.0 ? 0.0 : ((a) < 1.0 ? (a) : 1.0))
  52. #define vclamp(v) {\
  53. (v)[0]=clamp((v)[0]);\
  54. (v)[1]=clamp((v)[1]);\
  55. (v)[2]=clamp((v)[2]);\
  56. }
  57. static int WIDTH = 640;
  58. static int HEIGHT = 480;
  59. static GLint T0 = 0;
  60. static GLint Frames = 0;
  61. #define DIMP 20.0
  62. #define DIMTP 16.0
  63. #define RIDCOL 0.4
  64. #define NUMTREE 50
  65. #define TREEINR 2.5
  66. #define TREEOUTR 8.0
  67. #define AGRAV -9.8
  68. typedef struct
  69. {
  70. int age;
  71. float p[3][3];
  72. float v[3];
  73. float c[3][4];
  74. }
  75. part;
  76. static float treepos[NUMTREE][3];
  77. static float black[3] = { 0.0, 0.0, 0.0 };
  78. static float blu[3] = { 0.0, 0.2, 1.0 };
  79. static float blu2[3] = { 0.0, 1.0, 1.0 };
  80. static float fogcolor[4] = { 1.0, 1.0, 1.0, 1.0 };
  81. static float q[4][3] = {
  82. {-DIMP, 0.0, -DIMP},
  83. {DIMP, 0.0, -DIMP},
  84. {DIMP, 0.0, DIMP},
  85. {-DIMP, 0.0, DIMP}
  86. };
  87. static float qt[4][2] = {
  88. {-DIMTP, -DIMTP},
  89. {DIMTP, -DIMTP},
  90. {DIMTP, DIMTP},
  91. {-DIMTP, DIMTP}
  92. };
  93. static int win = 0;
  94. static int np;
  95. static float eject_r, dt, maxage, eject_vy, eject_vl;
  96. static short shadows;
  97. static float ridtri;
  98. static int fog = 1;
  99. static int help = 1;
  100. static int joyavailable = 0;
  101. static int joyactive = 0;
  102. static part *p;
  103. static GLuint groundid;
  104. static GLuint treeid;
  105. static float obs[3] = { 2.0, 1.0, 0.0 };
  106. static float dir[3];
  107. static float v = 0.0;
  108. static float alpha = -90.0;
  109. static float beta = 90.0;
  110. static float
  111. vrnd(void)
  112. {
  113. return (((float) rand()) / RAND_MAX);
  114. }
  115. static void
  116. setnewpart(part * p)
  117. {
  118. float a, v[3], *c;
  119. p->age = 0;
  120. a = vrnd() * 3.14159265359 * 2.0;
  121. vinit(v, sin(a) * eject_r * vrnd(), 0.15, cos(a) * eject_r * vrnd());
  122. vinit(p->p[0], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri,
  123. v[2] + vrnd() * ridtri);
  124. vinit(p->p[1], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri,
  125. v[2] + vrnd() * ridtri);
  126. vinit(p->p[2], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri,
  127. v[2] + vrnd() * ridtri);
  128. vinit(p->v, v[0] * eject_vl / (eject_r / 2),
  129. vrnd() * eject_vy + eject_vy / 2, v[2] * eject_vl / (eject_r / 2));
  130. c = blu;
  131. vinit4(p->c[0], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL),
  132. c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL),
  133. c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0);
  134. vinit4(p->c[1], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL),
  135. c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL),
  136. c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0);
  137. vinit4(p->c[2], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL),
  138. c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL),
  139. c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0);
  140. }
  141. static void
  142. setpart(part * p)
  143. {
  144. float fact;
  145. if (p->p[0][1] < 0.1) {
  146. setnewpart(p);
  147. return;
  148. }
  149. p->v[1] += AGRAV * dt;
  150. vadds(p->p[0], dt, p->v);
  151. vadds(p->p[1], dt, p->v);
  152. vadds(p->p[2], dt, p->v);
  153. p->age++;
  154. if ((p->age) > maxage) {
  155. vequ(p->c[0], blu2);
  156. vequ(p->c[1], blu2);
  157. vequ(p->c[2], blu2);
  158. }
  159. else {
  160. fact = 1.0 / maxage;
  161. vadds(p->c[0], fact, blu2);
  162. vclamp(p->c[0]);
  163. p->c[0][3] = fact * (maxage - p->age);
  164. vadds(p->c[1], fact, blu2);
  165. vclamp(p->c[1]);
  166. p->c[1][3] = fact * (maxage - p->age);
  167. vadds(p->c[2], fact, blu2);
  168. vclamp(p->c[2]);
  169. p->c[2][3] = fact * (maxage - p->age);
  170. }
  171. }
  172. static void
  173. drawtree(float x, float y, float z)
  174. {
  175. glBegin(GL_QUADS);
  176. glTexCoord2f(0.0, 0.0);
  177. glVertex3f(x - 1.5, y + 0.0, z);
  178. glTexCoord2f(1.0, 0.0);
  179. glVertex3f(x + 1.5, y + 0.0, z);
  180. glTexCoord2f(1.0, 1.0);
  181. glVertex3f(x + 1.5, y + 3.0, z);
  182. glTexCoord2f(0.0, 1.0);
  183. glVertex3f(x - 1.5, y + 3.0, z);
  184. glTexCoord2f(0.0, 0.0);
  185. glVertex3f(x, y + 0.0, z - 1.5);
  186. glTexCoord2f(1.0, 0.0);
  187. glVertex3f(x, y + 0.0, z + 1.5);
  188. glTexCoord2f(1.0, 1.0);
  189. glVertex3f(x, y + 3.0, z + 1.5);
  190. glTexCoord2f(0.0, 1.0);
  191. glVertex3f(x, y + 3.0, z - 1.5);
  192. glEnd();
  193. }
  194. static void
  195. calcposobs(void)
  196. {
  197. dir[0] = sin(alpha * M_PI / 180.0);
  198. dir[2] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0);
  199. dir[1] = cos(beta * M_PI / 180.0);
  200. obs[0] += v * dir[0];
  201. obs[1] += v * dir[1];
  202. obs[2] += v * dir[2];
  203. }
  204. static void
  205. printstring(void *font, char *string)
  206. {
  207. int len, i;
  208. len = (int) strlen(string);
  209. for (i = 0; i < len; i++)
  210. glutBitmapCharacter(font, string[i]);
  211. }
  212. static void
  213. reshape(int width, int height)
  214. {
  215. WIDTH = width;
  216. HEIGHT = height;
  217. glViewport(0, 0, (GLint) width, (GLint) height);
  218. glMatrixMode(GL_PROJECTION);
  219. glLoadIdentity();
  220. gluPerspective(70.0, width / (float) height, 0.1, 30.0);
  221. glMatrixMode(GL_MODELVIEW);
  222. }
  223. static void
  224. printhelp(void)
  225. {
  226. glColor4f(0.0, 0.0, 0.0, 0.5);
  227. glRecti(40, 40, 600, 440);
  228. glColor3f(1.0, 0.0, 0.0);
  229. glRasterPos2i(300, 420);
  230. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help");
  231. glRasterPos2i(60, 390);
  232. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Togle Help");
  233. glRasterPos2i(60, 360);
  234. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Increase particle size");
  235. glRasterPos2i(60, 330);
  236. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "T - Decrease particle size");
  237. glRasterPos2i(60, 300);
  238. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "r - Increase emission radius");
  239. glRasterPos2i(60, 270);
  240. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "R - Decrease emission radius");
  241. glRasterPos2i(60, 240);
  242. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Togle Fog");
  243. glRasterPos2i(60, 210);
  244. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "s - Togle shadows");
  245. glRasterPos2i(60, 180);
  246. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate");
  247. glRasterPos2i(60, 150);
  248. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity");
  249. glRasterPos2i(60, 120);
  250. printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity");
  251. glRasterPos2i(60, 90);
  252. if (joyavailable)
  253. printstring(GLUT_BITMAP_TIMES_ROMAN_24,
  254. "j - Togle jostick control (Joystick control available)");
  255. else
  256. printstring(GLUT_BITMAP_TIMES_ROMAN_24,
  257. "(No Joystick control available)");
  258. }
  259. static void
  260. dojoy(void)
  261. {
  262. #ifdef WIN32
  263. static UINT max[2] = { 0, 0 };
  264. static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2];
  265. MMRESULT res;
  266. JOYINFO joy;
  267. res = joyGetPos(JOYSTICKID1, &joy);
  268. if (res == JOYERR_NOERROR) {
  269. joyavailable = 1;
  270. if (max[0] < joy.wXpos)
  271. max[0] = joy.wXpos;
  272. if (min[0] > joy.wXpos)
  273. min[0] = joy.wXpos;
  274. center[0] = (max[0] + min[0]) / 2;
  275. if (max[1] < joy.wYpos)
  276. max[1] = joy.wYpos;
  277. if (min[1] > joy.wYpos)
  278. min[1] = joy.wYpos;
  279. center[1] = (max[1] + min[1]) / 2;
  280. if (joyactive) {
  281. if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0]))
  282. alpha +=
  283. 2.5 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]);
  284. if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1]))
  285. beta += 2.5 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]);
  286. if (joy.wButtons & JOY_BUTTON1)
  287. v += 0.01;
  288. if (joy.wButtons & JOY_BUTTON2)
  289. v -= 0.01;
  290. }
  291. }
  292. else
  293. joyavailable = 0;
  294. #endif
  295. }
  296. static void
  297. drawfire(void)
  298. {
  299. static char frbuf[80] = "";
  300. int j;
  301. dojoy();
  302. glEnable(GL_DEPTH_TEST);
  303. if (fog)
  304. glEnable(GL_FOG);
  305. else
  306. glDisable(GL_FOG);
  307. glDepthMask(GL_TRUE);
  308. glClearColor(1.0, 1.0, 1.0, 1.0);
  309. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  310. glPushMatrix();
  311. calcposobs();
  312. gluLookAt(obs[0], obs[1], obs[2],
  313. obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2],
  314. 0.0, 1.0, 0.0);
  315. glColor4f(1.0, 1.0, 1.0, 1.0);
  316. glEnable(GL_TEXTURE_2D);
  317. glBindTexture(GL_TEXTURE_2D, groundid);
  318. glBegin(GL_QUADS);
  319. glTexCoord2fv(qt[0]);
  320. glVertex3fv(q[0]);
  321. glTexCoord2fv(qt[1]);
  322. glVertex3fv(q[1]);
  323. glTexCoord2fv(qt[2]);
  324. glVertex3fv(q[2]);
  325. glTexCoord2fv(qt[3]);
  326. glVertex3fv(q[3]);
  327. glEnd();
  328. glEnable(GL_ALPHA_TEST);
  329. glAlphaFunc(GL_GEQUAL, 0.9);
  330. glBindTexture(GL_TEXTURE_2D, treeid);
  331. for (j = 0; j < NUMTREE; j++)
  332. drawtree(treepos[j][0], treepos[j][1], treepos[j][2]);
  333. glDisable(GL_TEXTURE_2D);
  334. glDepthMask(GL_FALSE);
  335. glDisable(GL_ALPHA_TEST);
  336. if (shadows) {
  337. glBegin(GL_TRIANGLES);
  338. for (j = 0; j < np; j++) {
  339. glColor4f(black[0], black[1], black[2], p[j].c[0][3]);
  340. glVertex3f(p[j].p[0][0], 0.1, p[j].p[0][2]);
  341. glColor4f(black[0], black[1], black[2], p[j].c[1][3]);
  342. glVertex3f(p[j].p[1][0], 0.1, p[j].p[1][2]);
  343. glColor4f(black[0], black[1], black[2], p[j].c[2][3]);
  344. glVertex3f(p[j].p[2][0], 0.1, p[j].p[2][2]);
  345. }
  346. glEnd();
  347. }
  348. glBegin(GL_TRIANGLES);
  349. for (j = 0; j < np; j++) {
  350. glColor4fv(p[j].c[0]);
  351. glVertex3fv(p[j].p[0]);
  352. glColor4fv(p[j].c[1]);
  353. glVertex3fv(p[j].p[1]);
  354. glColor4fv(p[j].c[2]);
  355. glVertex3fv(p[j].p[2]);
  356. setpart(&p[j]);
  357. }
  358. glEnd();
  359. glDisable(GL_TEXTURE_2D);
  360. glDisable(GL_ALPHA_TEST);
  361. glDisable(GL_DEPTH_TEST);
  362. glDisable(GL_FOG);
  363. glMatrixMode(GL_PROJECTION);
  364. glLoadIdentity();
  365. glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
  366. glMatrixMode(GL_MODELVIEW);
  367. glLoadIdentity();
  368. glColor3f(1.0, 0.0, 0.0);
  369. glRasterPos2i(10, 10);
  370. printstring(GLUT_BITMAP_HELVETICA_18, frbuf);
  371. glRasterPos2i(370, 470);
  372. printstring(GLUT_BITMAP_HELVETICA_10,
  373. "Fire V1.5 Written by David Bucciarelli (tech.hmw@plus.it)");
  374. if (help)
  375. printhelp();
  376. reshape(WIDTH, HEIGHT);
  377. glPopMatrix();
  378. glutSwapBuffers();
  379. Frames++;
  380. {
  381. GLint t = glutGet(GLUT_ELAPSED_TIME);
  382. if (t - T0 >= 2000) {
  383. GLfloat seconds = (t - T0) / 1000.0;
  384. GLfloat fps = Frames / seconds;
  385. sprintf(frbuf, "Frame rate: %f", fps);
  386. T0 = t;
  387. Frames = 0;
  388. }
  389. }
  390. }
  391. static void
  392. idle(void)
  393. {
  394. glutPostRedisplay();
  395. }
  396. static void
  397. special(int key, int x, int y)
  398. {
  399. switch (key) {
  400. case GLUT_KEY_LEFT:
  401. alpha += 2.0;
  402. break;
  403. case GLUT_KEY_RIGHT:
  404. alpha -= 2.0;
  405. break;
  406. case GLUT_KEY_DOWN:
  407. beta -= 2.0;
  408. break;
  409. case GLUT_KEY_UP:
  410. beta += 2.0;
  411. break;
  412. }
  413. }
  414. static void
  415. key(unsigned char key, int x, int y)
  416. {
  417. switch (key) {
  418. case 27:
  419. exit(0);
  420. break;
  421. case 'a':
  422. v += 0.01;
  423. break;
  424. case 'z':
  425. v -= 0.01;
  426. break;
  427. case 'j':
  428. joyactive = (!joyactive);
  429. break;
  430. case 'h':
  431. help = (!help);
  432. break;
  433. case 'f':
  434. fog = (!fog);
  435. break;
  436. case 's':
  437. shadows = !shadows;
  438. break;
  439. case 'R':
  440. eject_r -= 0.03;
  441. break;
  442. case 'r':
  443. eject_r += 0.03;
  444. break;
  445. case 't':
  446. ridtri += 0.005;
  447. break;
  448. case 'T':
  449. ridtri -= 0.005;
  450. break;
  451. #ifdef XMESA
  452. case ' ':
  453. XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
  454. fullscreen = (!fullscreen);
  455. break;
  456. #endif
  457. }
  458. }
  459. static void
  460. inittextures(void)
  461. {
  462. GLenum gluerr;
  463. GLubyte tex[128][128][4];
  464. glGenTextures(1, &groundid);
  465. glBindTexture(GL_TEXTURE_2D, groundid);
  466. glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
  467. if (!LoadRGBMipmaps("../images/s128.rgb", GL_RGB)) {
  468. fprintf(stderr, "Error reading a texture.\n");
  469. exit(-1);
  470. }
  471. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  472. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  473. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  474. GL_LINEAR_MIPMAP_LINEAR);
  475. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  476. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  477. glGenTextures(1, &treeid);
  478. glBindTexture(GL_TEXTURE_2D, treeid);
  479. if (1)
  480. {
  481. int w, h;
  482. GLenum format;
  483. int x, y;
  484. GLubyte *image = LoadRGBImage("../images/tree3.rgb", &w, &h, &format);
  485. if (!image) {
  486. fprintf(stderr, "Error reading a texture.\n");
  487. exit(-1);
  488. }
  489. for (y = 0; y < 128; y++)
  490. for (x = 0; x < 128; x++) {
  491. tex[x][y][0] = image[(y + x * 128) * 3];
  492. tex[x][y][1] = image[(y + x * 128) * 3 + 1];
  493. tex[x][y][2] = image[(y + x * 128) * 3 + 2];
  494. if ((tex[x][y][0] == tex[x][y][1]) &&
  495. (tex[x][y][1] == tex[x][y][2]) && (tex[x][y][2] == 255))
  496. tex[x][y][3] = 0;
  497. else
  498. tex[x][y][3] = 255;
  499. }
  500. if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, 128, 128, GL_RGBA,
  501. GL_UNSIGNED_BYTE, (GLvoid *) (tex)))) {
  502. fprintf(stderr, "GLULib%s\n", gluErrorString(gluerr));
  503. exit(-1);
  504. }
  505. }
  506. else {
  507. if (!LoadRGBMipmaps("../images/tree2.rgba", GL_RGBA)) {
  508. fprintf(stderr, "Error reading a texture.\n");
  509. exit(-1);
  510. }
  511. }
  512. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  513. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  514. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
  515. GL_LINEAR_MIPMAP_LINEAR);
  516. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  517. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  518. }
  519. static void
  520. inittree(void)
  521. {
  522. int i;
  523. float dist;
  524. for (i = 0; i < NUMTREE; i++)
  525. do {
  526. treepos[i][0] = vrnd() * TREEOUTR * 2.0 - TREEOUTR;
  527. treepos[i][1] = 0.0;
  528. treepos[i][2] = vrnd() * TREEOUTR * 2.0 - TREEOUTR;
  529. dist =
  530. sqrt(treepos[i][0] * treepos[i][0] +
  531. treepos[i][2] * treepos[i][2]);
  532. } while ((dist < TREEINR) || (dist > TREEOUTR));
  533. }
  534. int
  535. main(int ac, char **av)
  536. {
  537. int i;
  538. fprintf(stderr,
  539. "Fire V1.5\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
  540. /* Default settings */
  541. WIDTH = 640;
  542. HEIGHT = 480;
  543. np = 800;
  544. eject_r = 0.1;
  545. dt = 0.015;
  546. eject_vy = 4;
  547. eject_vl = 1;
  548. shadows = 1;
  549. ridtri = 0.1;
  550. maxage = 1.0 / dt;
  551. if (ac == 2)
  552. np = atoi(av[1]);
  553. if (ac == 4) {
  554. WIDTH = atoi(av[2]);
  555. HEIGHT = atoi(av[3]);
  556. }
  557. glutInitWindowPosition(0, 0);
  558. glutInitWindowSize(WIDTH, HEIGHT);
  559. glutInit(&ac, av);
  560. glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
  561. if (!(win = glutCreateWindow("Fire"))) {
  562. fprintf(stderr, "Error opening a window.\n");
  563. exit(-1);
  564. }
  565. reshape(WIDTH, HEIGHT);
  566. inittextures();
  567. glShadeModel(GL_FLAT);
  568. glEnable(GL_DEPTH_TEST);
  569. glEnable(GL_BLEND);
  570. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  571. glEnable(GL_FOG);
  572. glFogi(GL_FOG_MODE, GL_EXP);
  573. glFogfv(GL_FOG_COLOR, fogcolor);
  574. glFogf(GL_FOG_DENSITY, 0.1);
  575. #ifdef FX
  576. glHint(GL_FOG_HINT, GL_NICEST);
  577. #endif
  578. p = malloc(sizeof(part) * np);
  579. for (i = 0; i < np; i++)
  580. setnewpart(&p[i]);
  581. inittree();
  582. glutKeyboardFunc(key);
  583. glutSpecialFunc(special);
  584. glutDisplayFunc(drawfire);
  585. glutIdleFunc(idle);
  586. glutReshapeFunc(reshape);
  587. glutMainLoop();
  588. return (0);
  589. }