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