~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to progs/demos/fire.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

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