blob: 5c467acfaca525eb9ddfb8b9d8310ecba58c5ac4 [file] [log] [blame]
Brian Paul5b0a7f32000-06-27 16:52:38 +00001/*
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>
pescod1ff1f62000-12-24 22:53:54 +000020#include "readtex.c"
Brian Paul5b0a7f32000-06-27 16:52:38 +000021
22#ifdef XMESA
23#include "GL/xmesa.h"
24static 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
71static int WIDTH = 640;
72static int HEIGHT = 480;
73
Brian Pauld49b34a2000-09-12 18:44:45 +000074static GLint T0 = 0;
75static GLint Frames = 0;
Brian Paul8a42f6b2001-02-16 21:48:16 +000076static GLint NiceFog = 1;
Brian Pauld49b34a2000-09-12 18:44:45 +000077
Brian Paul5b0a7f32000-06-27 16:52:38 +000078#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
89typedef struct
90{
91 int age;
92 float p[3][3];
93 float v[3];
94 float c[3][4];
95}
96part;
97
98static float treepos[NUMTREE][3];
99
100static float black[3] = { 0.0, 0.0, 0.0 };
101static float blu[3] = { 0.0, 0.2, 1.0 };
102static float blu2[3] = { 0.0, 1.0, 1.0 };
103
104static float fogcolor[4] = { 1.0, 1.0, 1.0, 1.0 };
105
106static 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
113static float qt[4][2] = {
114 {-DIMTP, -DIMTP},
115 {DIMTP, -DIMTP},
116 {DIMTP, DIMTP},
117 {-DIMTP, DIMTP}
118};
119
120static int win = 0;
121
122static int np;
123static float eject_r, dt, maxage, eject_vy, eject_vl;
124static short shadows;
125static float ridtri;
126static int fog = 1;
127static int help = 1;
128static int joyavailable = 0;
129static int joyactive = 0;
130
131static part *p;
132
133static GLuint groundid;
134static GLuint treeid;
135
136static float obs[3] = { 2.0, 1.0, 0.0 };
137static float dir[3];
138static float v = 0.0;
139static float alpha = -90.0;
140static float beta = 90.0;
141
142static float
Brian Paul5b0a7f32000-06-27 16:52:38 +0000143vrnd(void)
144{
145 return (((float) rand()) / RAND_MAX);
146}
147
148static void
149setnewpart(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
181static void
182setpart(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
220static void
221drawtree(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
253static void
254calcposobs(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
Brian Paula41edc32001-05-09 20:02:28 +0000260 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
Brian Paul5b0a7f32000-06-27 16:52:38 +0000267 obs[0] += v * dir[0];
268 obs[1] += v * dir[1];
269 obs[2] += v * dir[2];
270}
271
272static void
273printstring(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
282static void
283reshape(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
295static void
296printhelp(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
338static void
339dojoy(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
382static void
383drawfire(void)
384{
Brian Pauld49b34a2000-09-12 18:44:45 +0000385 static char frbuf[80] = "";
Brian Paul5b0a7f32000-06-27 16:52:38 +0000386 int j;
Brian Paul5b0a7f32000-06-27 16:52:38 +0000387
388 dojoy();
389
Brian Paul8a42f6b2001-02-16 21:48:16 +0000390 if (NiceFog)
391 glHint(GL_FOG_HINT, GL_NICEST);
392 else
393 glHint(GL_FOG_HINT, GL_DONT_CARE);
394
Brian Paul5b0a7f32000-06-27 16:52:38 +0000395 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);
Brian Paul8a42f6b2001-02-16 21:48:16 +0000417#if 1
Brian Paul5b0a7f32000-06-27 16:52:38 +0000418 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();
Brian Paul8a42f6b2001-02-16 21:48:16 +0000428#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
Brian Paul5b0a7f32000-06-27 16:52:38 +0000448
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
Brian Paul5b0a7f32000-06-27 16:52:38 +0000490 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
Brian Pauld49b34a2000-09-12 18:44:45 +0000516 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 }
Brian Paul5b0a7f32000-06-27 16:52:38 +0000527}
528
529
530static void
Brian Paule188b6e2000-10-21 04:29:02 +0000531idle(void)
532{
533 glutPostRedisplay();
534}
535
536
537static void
Brian Paul5b0a7f32000-06-27 16:52:38 +0000538special(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 }
Brian Paul8a42f6b2001-02-16 21:48:16 +0000554 glutPostRedisplay();
Brian Paul5b0a7f32000-06-27 16:52:38 +0000555}
556
557static void
558key(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
Brian Paul8a42f6b2001-02-16 21:48:16 +0000602 case 'n':
603 NiceFog = !NiceFog;
604 printf("NiceFog %d\n", NiceFog);
605 break;
Brian Paul5b0a7f32000-06-27 16:52:38 +0000606 }
Brian Paul8a42f6b2001-02-16 21:48:16 +0000607 glutPostRedisplay();
Brian Paul5b0a7f32000-06-27 16:52:38 +0000608}
609
610static void
611inittextures(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
Brian Paulf7688172000-06-27 17:12:10 +0000637 if (1)
Brian Paul5b0a7f32000-06-27 16:52:38 +0000638 {
639 int w, h;
640 GLenum format;
641 int x, y;
Brian Paulf7688172000-06-27 17:12:10 +0000642 GLubyte *image = LoadRGBImage("../images/tree3.rgb", &w, &h, &format);
Brian Paul5b0a7f32000-06-27 16:52:38 +0000643
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)))) {
Brian Paul1972ac62002-08-08 17:12:38 +0000663 fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr));
Brian Paul5b0a7f32000-06-27 16:52:38 +0000664 exit(-1);
665 }
666 }
Brian Paulf7688172000-06-27 17:12:10 +0000667 else {
668 if (!LoadRGBMipmaps("../images/tree2.rgba", GL_RGBA)) {
669 fprintf(stderr, "Error reading a texture.\n");
670 exit(-1);
671 }
672 }
Brian Paul5b0a7f32000-06-27 16:52:38 +0000673
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
684static void
685inittree(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
701int
702main(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
Brian Paul5b0a7f32000-06-27 16:52:38 +0000711 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);
Brian Paul5b0a7f32000-06-27 16:52:38 +0000754
Brian Paulf02a5f62002-07-12 15:54:01 +0000755 p = (part *) malloc(sizeof(part) * np);
Brian Paul5b0a7f32000-06-27 16:52:38 +0000756
757 for (i = 0; i < np; i++)
758 setnewpart(&p[i]);
759
760 inittree();
761
762 glutKeyboardFunc(key);
763 glutSpecialFunc(special);
764 glutDisplayFunc(drawfire);
Brian Paule188b6e2000-10-21 04:29:02 +0000765 glutIdleFunc(idle);
Brian Paul5b0a7f32000-06-27 16:52:38 +0000766 glutReshapeFunc(reshape);
767 glutMainLoop();
768
769 return (0);
770}