fire.c revision 7ec3b29a
132001f49Smrg/* 232001f49Smrg * This program is under the GNU GPL. 332001f49Smrg * Use at your own risk. 432001f49Smrg * 532001f49Smrg * written by David Bucciarelli (tech.hmw@plus.it) 632001f49Smrg * Humanware s.r.l. 732001f49Smrg */ 832001f49Smrg 932001f49Smrg#include <assert.h> 1032001f49Smrg#include <stdio.h> 1132001f49Smrg#include <stdlib.h> 1232001f49Smrg#include <math.h> 1332001f49Smrg#include <time.h> 1432001f49Smrg#include <string.h> 1532001f49Smrg 1632001f49Smrg#ifdef WIN32 1732001f49Smrg#include <windows.h> 1832001f49Smrg#include <mmsystem.h> 1932001f49Smrg#endif 2032001f49Smrg 2132001f49Smrg#include "glut_wrap.h" 2232001f49Smrg#include "readtex.h" 2332001f49Smrg 2432001f49Smrg#ifdef XMESA 2532001f49Smrg#include "GL/xmesa.h" 2632001f49Smrgstatic int fullscreen = 1; 2732001f49Smrg#endif 2832001f49Smrg 2932001f49Smrg#ifndef M_PI 3032001f49Smrg#define M_PI 3.1415926535 3132001f49Smrg#endif 3232001f49Smrg 3332001f49Smrg#define vinit(a,i,j,k) {\ 3432001f49Smrg (a)[0]=i;\ 3532001f49Smrg (a)[1]=j;\ 3632001f49Smrg (a)[2]=k;\ 3732001f49Smrg} 3832001f49Smrg 3932001f49Smrg#define vinit4(a,i,j,k,w) {\ 4032001f49Smrg (a)[0]=i;\ 4132001f49Smrg (a)[1]=j;\ 4232001f49Smrg (a)[2]=k;\ 4332001f49Smrg (a)[3]=w;\ 4432001f49Smrg} 4532001f49Smrg 4632001f49Smrg 4732001f49Smrg#define vadds(a,dt,b) {\ 4832001f49Smrg (a)[0]+=(dt)*(b)[0];\ 4932001f49Smrg (a)[1]+=(dt)*(b)[1];\ 5032001f49Smrg (a)[2]+=(dt)*(b)[2];\ 5132001f49Smrg} 5232001f49Smrg 5332001f49Smrg#define vequ(a,b) {\ 5432001f49Smrg (a)[0]=(b)[0];\ 5532001f49Smrg (a)[1]=(b)[1];\ 5632001f49Smrg (a)[2]=(b)[2];\ 5732001f49Smrg} 5832001f49Smrg 5932001f49Smrg#define vinter(a,dt,b,c) {\ 6032001f49Smrg (a)[0]=(dt)*(b)[0]+(1.0-dt)*(c)[0];\ 6132001f49Smrg (a)[1]=(dt)*(b)[1]+(1.0-dt)*(c)[1];\ 6232001f49Smrg (a)[2]=(dt)*(b)[2]+(1.0-dt)*(c)[2];\ 6332001f49Smrg} 6432001f49Smrg 6532001f49Smrg#define clamp(a) ((a) < 0.0 ? 0.0 : ((a) < 1.0 ? (a) : 1.0)) 6632001f49Smrg 6732001f49Smrg#define vclamp(v) {\ 6832001f49Smrg (v)[0]=clamp((v)[0]);\ 6932001f49Smrg (v)[1]=clamp((v)[1]);\ 7032001f49Smrg (v)[2]=clamp((v)[2]);\ 7132001f49Smrg} 7232001f49Smrg 7332001f49Smrgstatic int WIDTH = 640; 7432001f49Smrgstatic int HEIGHT = 480; 7532001f49Smrg 7632001f49Smrgstatic GLint T0 = 0; 7732001f49Smrgstatic GLint Frames = 0; 7832001f49Smrgstatic GLint NiceFog = 1; 7932001f49Smrg 8032001f49Smrg#define DIMP 20.0 8132001f49Smrg#define DIMTP 16.0 8232001f49Smrg 8332001f49Smrg#define RIDCOL 0.4 8432001f49Smrg 8532001f49Smrg#define NUMTREE 50 8632001f49Smrg#define TREEINR 2.5 8732001f49Smrg#define TREEOUTR 8.0 8832001f49Smrg 8932001f49Smrg#define AGRAV -9.8 9032001f49Smrg 9132001f49Smrgtypedef struct 9232001f49Smrg{ 9332001f49Smrg int age; 9432001f49Smrg float p[3][3]; 9532001f49Smrg float v[3]; 9632001f49Smrg float c[3][4]; 9732001f49Smrg} 9832001f49Smrgpart; 9932001f49Smrg 10032001f49Smrgstatic float treepos[NUMTREE][3]; 10132001f49Smrg 10232001f49Smrgstatic float black[3] = { 0.0, 0.0, 0.0 }; 10332001f49Smrgstatic float blu[3] = { 1.0, 0.2, 0.0 }; 10432001f49Smrgstatic float blu2[3] = { 1.0, 1.0, 0.0 }; 10532001f49Smrg 10632001f49Smrgstatic float fogcolor[4] = { 1.0, 1.0, 1.0, 1.0 }; 10732001f49Smrg 10832001f49Smrgstatic float q[4][3] = { 10932001f49Smrg {-DIMP, 0.0, -DIMP}, 11032001f49Smrg {DIMP, 0.0, -DIMP}, 11132001f49Smrg {DIMP, 0.0, DIMP}, 11232001f49Smrg {-DIMP, 0.0, DIMP} 11332001f49Smrg}; 11432001f49Smrg 11532001f49Smrgstatic float qt[4][2] = { 11632001f49Smrg {-DIMTP, -DIMTP}, 11732001f49Smrg {DIMTP, -DIMTP}, 11832001f49Smrg {DIMTP, DIMTP}, 11932001f49Smrg {-DIMTP, DIMTP} 12032001f49Smrg}; 12132001f49Smrg 12232001f49Smrgstatic int win = 0; 12332001f49Smrg 12432001f49Smrgstatic int np; 12532001f49Smrgstatic float eject_r, dt, maxage, eject_vy, eject_vl; 12632001f49Smrgstatic short shadows; 12732001f49Smrgstatic float ridtri; 12832001f49Smrgstatic int fog = 1; 12932001f49Smrgstatic int help = 1; 13032001f49Smrgstatic int joyavailable = 0; 13132001f49Smrgstatic int joyactive = 0; 13232001f49Smrg 13332001f49Smrgstatic part *p; 13432001f49Smrg 13532001f49Smrgstatic GLuint groundid; 13632001f49Smrgstatic GLuint treeid; 13732001f49Smrg 13832001f49Smrgstatic float obs[3] = { 2.0, 1.0, 0.0 }; 13932001f49Smrgstatic float dir[3]; 14032001f49Smrgstatic float v = 0.0; 14132001f49Smrgstatic float alpha = -84.0; 14232001f49Smrgstatic float beta = 90.0; 14332001f49Smrg 14432001f49Smrgstatic float 14532001f49Smrgvrnd(void) 14632001f49Smrg{ 14732001f49Smrg return (((float) rand()) / RAND_MAX); 14832001f49Smrg} 14932001f49Smrg 15032001f49Smrgstatic void 15132001f49Smrgsetnewpart(part * p) 15232001f49Smrg{ 15332001f49Smrg float a, v[3], *c; 15432001f49Smrg 15532001f49Smrg p->age = 0; 15632001f49Smrg 15732001f49Smrg a = vrnd() * 3.14159265359 * 2.0; 15832001f49Smrg 15932001f49Smrg vinit(v, sin(a) * eject_r * vrnd(), 0.15, cos(a) * eject_r * vrnd()); 16032001f49Smrg vinit(p->p[0], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, 16132001f49Smrg v[2] + vrnd() * ridtri); 16232001f49Smrg vinit(p->p[1], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, 16332001f49Smrg v[2] + vrnd() * ridtri); 16432001f49Smrg vinit(p->p[2], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, 16532001f49Smrg v[2] + vrnd() * ridtri); 16632001f49Smrg 16732001f49Smrg vinit(p->v, v[0] * eject_vl / (eject_r / 2), 16832001f49Smrg vrnd() * eject_vy + eject_vy / 2, v[2] * eject_vl / (eject_r / 2)); 16932001f49Smrg 17032001f49Smrg c = blu; 17132001f49Smrg 17232001f49Smrg vinit4(p->c[0], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 17332001f49Smrg c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 17432001f49Smrg c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); 17532001f49Smrg vinit4(p->c[1], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 17632001f49Smrg c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 17732001f49Smrg c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); 17832001f49Smrg vinit4(p->c[2], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 17932001f49Smrg c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 18032001f49Smrg c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); 18132001f49Smrg} 18232001f49Smrg 18332001f49Smrgstatic void 18432001f49Smrgsetpart(part * p) 18532001f49Smrg{ 18632001f49Smrg float fact; 18732001f49Smrg 18832001f49Smrg if (p->p[0][1] < 0.1) { 18932001f49Smrg setnewpart(p); 19032001f49Smrg return; 19132001f49Smrg } 19232001f49Smrg 19332001f49Smrg p->v[1] += AGRAV * dt; 19432001f49Smrg 19532001f49Smrg vadds(p->p[0], dt, p->v); 19632001f49Smrg vadds(p->p[1], dt, p->v); 19732001f49Smrg vadds(p->p[2], dt, p->v); 19832001f49Smrg 19932001f49Smrg p->age++; 20032001f49Smrg 20132001f49Smrg if ((p->age) > maxage) { 20232001f49Smrg vequ(p->c[0], blu2); 20332001f49Smrg vequ(p->c[1], blu2); 20432001f49Smrg vequ(p->c[2], blu2); 20532001f49Smrg } 20632001f49Smrg else { 20732001f49Smrg fact = 1.0 / maxage; 20832001f49Smrg vadds(p->c[0], fact, blu2); 20932001f49Smrg vclamp(p->c[0]); 21032001f49Smrg p->c[0][3] = fact * (maxage - p->age); 21132001f49Smrg 21232001f49Smrg vadds(p->c[1], fact, blu2); 21332001f49Smrg vclamp(p->c[1]); 21432001f49Smrg p->c[1][3] = fact * (maxage - p->age); 21532001f49Smrg 21632001f49Smrg vadds(p->c[2], fact, blu2); 21732001f49Smrg vclamp(p->c[2]); 21832001f49Smrg p->c[2][3] = fact * (maxage - p->age); 21932001f49Smrg } 22032001f49Smrg} 22132001f49Smrg 22232001f49Smrgstatic void 22332001f49Smrgdrawtree(float x, float y, float z) 22432001f49Smrg{ 22532001f49Smrg glBegin(GL_QUADS); 22632001f49Smrg glTexCoord2f(0.0, 0.0); 22732001f49Smrg glVertex3f(x - 1.5, y + 0.0, z); 22832001f49Smrg 22932001f49Smrg glTexCoord2f(1.0, 0.0); 23032001f49Smrg glVertex3f(x + 1.5, y + 0.0, z); 23132001f49Smrg 23232001f49Smrg glTexCoord2f(1.0, 1.0); 23332001f49Smrg glVertex3f(x + 1.5, y + 3.0, z); 23432001f49Smrg 23532001f49Smrg glTexCoord2f(0.0, 1.0); 23632001f49Smrg glVertex3f(x - 1.5, y + 3.0, z); 23732001f49Smrg 23832001f49Smrg 23932001f49Smrg glTexCoord2f(0.0, 0.0); 24032001f49Smrg glVertex3f(x, y + 0.0, z - 1.5); 24132001f49Smrg 24232001f49Smrg glTexCoord2f(1.0, 0.0); 24332001f49Smrg glVertex3f(x, y + 0.0, z + 1.5); 24432001f49Smrg 24532001f49Smrg glTexCoord2f(1.0, 1.0); 24632001f49Smrg glVertex3f(x, y + 3.0, z + 1.5); 24732001f49Smrg 24832001f49Smrg glTexCoord2f(0.0, 1.0); 24932001f49Smrg glVertex3f(x, y + 3.0, z - 1.5); 25032001f49Smrg 25132001f49Smrg glEnd(); 25232001f49Smrg 25332001f49Smrg} 25432001f49Smrg 25532001f49Smrgstatic void 25632001f49Smrgcalcposobs(void) 25732001f49Smrg{ 25832001f49Smrg dir[0] = sin(alpha * M_PI / 180.0); 25932001f49Smrg dir[2] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0); 26032001f49Smrg dir[1] = cos(beta * M_PI / 180.0); 26132001f49Smrg 26232001f49Smrg if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5) 26332001f49Smrg dir[0] = 0; 26432001f49Smrg if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5) 26532001f49Smrg dir[1] = 0; 26632001f49Smrg if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5) 26732001f49Smrg dir[2] = 0; 26832001f49Smrg 26932001f49Smrg obs[0] += v * dir[0]; 27032001f49Smrg obs[1] += v * dir[1]; 27132001f49Smrg obs[2] += v * dir[2]; 27232001f49Smrg} 27332001f49Smrg 27432001f49Smrgstatic void 27532001f49Smrgprintstring(void *font, char *string) 27632001f49Smrg{ 27732001f49Smrg int len, i; 27832001f49Smrg 27932001f49Smrg len = (int) strlen(string); 28032001f49Smrg for (i = 0; i < len; i++) 28132001f49Smrg glutBitmapCharacter(font, string[i]); 28232001f49Smrg} 28332001f49Smrg 28432001f49Smrgstatic void 28532001f49Smrgreshape(int width, int height) 28632001f49Smrg{ 28732001f49Smrg WIDTH = width; 28832001f49Smrg HEIGHT = height; 28932001f49Smrg glViewport(0, 0, (GLint) width, (GLint) height); 29032001f49Smrg glMatrixMode(GL_PROJECTION); 29132001f49Smrg glLoadIdentity(); 29232001f49Smrg gluPerspective(70.0, width / (float) height, 0.1, 30.0); 29332001f49Smrg 29432001f49Smrg glMatrixMode(GL_MODELVIEW); 29532001f49Smrg} 29632001f49Smrg 29732001f49Smrgstatic void 29832001f49Smrgprinthelp(void) 29932001f49Smrg{ 30032001f49Smrg glColor4f(0.0, 0.0, 0.0, 0.5); 30132001f49Smrg glRecti(40, 40, 600, 440); 30232001f49Smrg 30332001f49Smrg glColor3f(1.0, 0.0, 0.0); 30432001f49Smrg glRasterPos2i(300, 420); 30532001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help"); 30632001f49Smrg 30732001f49Smrg glRasterPos2i(60, 390); 30832001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Toggle Help"); 30932001f49Smrg 31032001f49Smrg glRasterPos2i(60, 360); 31132001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Increase particle size"); 31232001f49Smrg glRasterPos2i(60, 330); 31332001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "T - Decrease particle size"); 31432001f49Smrg 31532001f49Smrg glRasterPos2i(60, 300); 31632001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "r - Increase emission radius"); 31732001f49Smrg glRasterPos2i(60, 270); 31832001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "R - Decrease emission radius"); 31932001f49Smrg 32032001f49Smrg glRasterPos2i(60, 240); 32132001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Toggle Fog"); 32232001f49Smrg glRasterPos2i(60, 210); 32332001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "s - Toggle shadows"); 32432001f49Smrg glRasterPos2i(60, 180); 32532001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate"); 32632001f49Smrg glRasterPos2i(60, 150); 32732001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity"); 32832001f49Smrg glRasterPos2i(60, 120); 32932001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity"); 33032001f49Smrg 33132001f49Smrg glRasterPos2i(60, 90); 33232001f49Smrg if (joyavailable) 33332001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, 33432001f49Smrg "j - Toggle jostick control (Joystick control available)"); 33532001f49Smrg else 33632001f49Smrg printstring(GLUT_BITMAP_TIMES_ROMAN_24, 33732001f49Smrg "(No Joystick control available)"); 33832001f49Smrg} 33932001f49Smrg 34032001f49Smrgstatic void 34132001f49Smrgdojoy(void) 34232001f49Smrg{ 34332001f49Smrg#ifdef WIN32 34432001f49Smrg static UINT max[2] = { 0, 0 }; 34532001f49Smrg static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2]; 34632001f49Smrg MMRESULT res; 34732001f49Smrg JOYINFO joy; 34832001f49Smrg 34932001f49Smrg res = joyGetPos(JOYSTICKID1, &joy); 35032001f49Smrg 35132001f49Smrg if (res == JOYERR_NOERROR) { 35232001f49Smrg joyavailable = 1; 35332001f49Smrg 35432001f49Smrg if (max[0] < joy.wXpos) 35532001f49Smrg max[0] = joy.wXpos; 35632001f49Smrg if (min[0] > joy.wXpos) 35732001f49Smrg min[0] = joy.wXpos; 35832001f49Smrg center[0] = (max[0] + min[0]) / 2; 35932001f49Smrg 36032001f49Smrg if (max[1] < joy.wYpos) 36132001f49Smrg max[1] = joy.wYpos; 36232001f49Smrg if (min[1] > joy.wYpos) 36332001f49Smrg min[1] = joy.wYpos; 36432001f49Smrg center[1] = (max[1] + min[1]) / 2; 36532001f49Smrg 36632001f49Smrg if (joyactive) { 36732001f49Smrg if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0])) 36832001f49Smrg alpha += 36932001f49Smrg 2.5 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]); 37032001f49Smrg if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1])) 37132001f49Smrg beta += 2.5 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]); 37232001f49Smrg 37332001f49Smrg if (joy.wButtons & JOY_BUTTON1) 37432001f49Smrg v += 0.01; 37532001f49Smrg if (joy.wButtons & JOY_BUTTON2) 37632001f49Smrg v -= 0.01; 37732001f49Smrg } 37832001f49Smrg } 37932001f49Smrg else 38032001f49Smrg joyavailable = 0; 38132001f49Smrg#endif 38232001f49Smrg} 38332001f49Smrg 38432001f49Smrgstatic void 38532001f49Smrgdrawfire(void) 38632001f49Smrg{ 38732001f49Smrg static char frbuf[80] = ""; 38832001f49Smrg int j; 38932001f49Smrg static double t0 = -1.; 39032001f49Smrg double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; 39132001f49Smrg if (t0 < 0.0) 39232001f49Smrg t0 = t; 39332001f49Smrg dt = (t - t0) * 1.0; 39432001f49Smrg t0 = t; 39532001f49Smrg 39632001f49Smrg dojoy(); 39732001f49Smrg 39832001f49Smrg if (NiceFog) 39932001f49Smrg glHint(GL_FOG_HINT, GL_NICEST); 40032001f49Smrg else 40132001f49Smrg glHint(GL_FOG_HINT, GL_DONT_CARE); 40232001f49Smrg 40332001f49Smrg glEnable(GL_DEPTH_TEST); 40432001f49Smrg 40532001f49Smrg if (fog) 40632001f49Smrg glEnable(GL_FOG); 40732001f49Smrg else 40832001f49Smrg glDisable(GL_FOG); 40932001f49Smrg 41032001f49Smrg glDepthMask(GL_TRUE); 41132001f49Smrg glClearColor(1.0, 1.0, 1.0, 1.0); 41232001f49Smrg glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 41332001f49Smrg 41432001f49Smrg glPushMatrix(); 41532001f49Smrg calcposobs(); 41632001f49Smrg gluLookAt(obs[0], obs[1], obs[2], 41732001f49Smrg obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2], 41832001f49Smrg 0.0, 1.0, 0.0); 41932001f49Smrg 42032001f49Smrg glColor4f(1.0, 1.0, 1.0, 1.0); 42132001f49Smrg 42232001f49Smrg glEnable(GL_TEXTURE_2D); 42332001f49Smrg 42432001f49Smrg glBindTexture(GL_TEXTURE_2D, groundid); 42532001f49Smrg#if 1 42632001f49Smrg glBegin(GL_QUADS); 42732001f49Smrg glTexCoord2fv(qt[0]); 42832001f49Smrg glVertex3fv(q[0]); 42932001f49Smrg glTexCoord2fv(qt[1]); 43032001f49Smrg glVertex3fv(q[1]); 43132001f49Smrg glTexCoord2fv(qt[2]); 43232001f49Smrg glVertex3fv(q[2]); 43332001f49Smrg glTexCoord2fv(qt[3]); 43432001f49Smrg glVertex3fv(q[3]); 43532001f49Smrg glEnd(); 43632001f49Smrg#else 43732001f49Smrg /* Subdivide the ground into a bunch of quads. This improves fog 43832001f49Smrg * if GL_FOG_HINT != GL_NICEST 43932001f49Smrg */ 44032001f49Smrg { 44132001f49Smrg float x, y; 44232001f49Smrg float dx = 1.0, dy = 1.0; 44332001f49Smrg glBegin(GL_QUADS); 44432001f49Smrg for (y = -DIMP; y < DIMP; y += 1.0) { 44532001f49Smrg for (x = -DIMP; x < DIMP; x += 1.0) { 44632001f49Smrg glTexCoord2f(0, 0); glVertex3f(x, 0, y); 44732001f49Smrg glTexCoord2f(1, 0); glVertex3f(x+dx, 0, y); 44832001f49Smrg glTexCoord2f(1, 1); glVertex3f(x+dx, 0, y+dy); 44932001f49Smrg glTexCoord2f(0, 1); glVertex3f(x, 0, y+dy); 45032001f49Smrg } 45132001f49Smrg } 45232001f49Smrg glEnd(); 45332001f49Smrg } 45432001f49Smrg#endif 45532001f49Smrg 45632001f49Smrg 45732001f49Smrg glEnable(GL_ALPHA_TEST); 45832001f49Smrg glAlphaFunc(GL_GEQUAL, 0.9); 45932001f49Smrg 46032001f49Smrg glBindTexture(GL_TEXTURE_2D, treeid); 46132001f49Smrg for (j = 0; j < NUMTREE; j++) 46232001f49Smrg drawtree(treepos[j][0], treepos[j][1], treepos[j][2]); 46332001f49Smrg 46432001f49Smrg glDisable(GL_TEXTURE_2D); 46532001f49Smrg glDepthMask(GL_FALSE); 46632001f49Smrg glDisable(GL_ALPHA_TEST); 46732001f49Smrg 46832001f49Smrg if (shadows) { 46932001f49Smrg glBegin(GL_TRIANGLES); 47032001f49Smrg for (j = 0; j < np; j++) { 47132001f49Smrg glColor4f(black[0], black[1], black[2], p[j].c[0][3]); 47232001f49Smrg glVertex3f(p[j].p[0][0], 0.1, p[j].p[0][2]); 47332001f49Smrg 47432001f49Smrg glColor4f(black[0], black[1], black[2], p[j].c[1][3]); 47532001f49Smrg glVertex3f(p[j].p[1][0], 0.1, p[j].p[1][2]); 47632001f49Smrg 47732001f49Smrg glColor4f(black[0], black[1], black[2], p[j].c[2][3]); 47832001f49Smrg glVertex3f(p[j].p[2][0], 0.1, p[j].p[2][2]); 47932001f49Smrg } 48032001f49Smrg glEnd(); 48132001f49Smrg } 48232001f49Smrg 48332001f49Smrg glBegin(GL_TRIANGLES); 48432001f49Smrg for (j = 0; j < np; j++) { 48532001f49Smrg glColor4fv(p[j].c[0]); 48632001f49Smrg glVertex3fv(p[j].p[0]); 48732001f49Smrg 48832001f49Smrg glColor4fv(p[j].c[1]); 48932001f49Smrg glVertex3fv(p[j].p[1]); 49032001f49Smrg 49132001f49Smrg glColor4fv(p[j].c[2]); 49232001f49Smrg glVertex3fv(p[j].p[2]); 49332001f49Smrg 49432001f49Smrg setpart(&p[j]); 49532001f49Smrg } 49632001f49Smrg glEnd(); 49732001f49Smrg 49832001f49Smrg glDisable(GL_TEXTURE_2D); 49932001f49Smrg glDisable(GL_ALPHA_TEST); 50032001f49Smrg glDisable(GL_DEPTH_TEST); 50132001f49Smrg glDisable(GL_FOG); 50232001f49Smrg 50332001f49Smrg glMatrixMode(GL_PROJECTION); 50432001f49Smrg glLoadIdentity(); 50532001f49Smrg glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0); 50632001f49Smrg glMatrixMode(GL_MODELVIEW); 50732001f49Smrg glLoadIdentity(); 50832001f49Smrg 50932001f49Smrg glColor3f(1.0, 0.0, 0.0); 51032001f49Smrg glRasterPos2i(10, 10); 51132001f49Smrg printstring(GLUT_BITMAP_HELVETICA_18, frbuf); 51232001f49Smrg glRasterPos2i(370, 470); 51332001f49Smrg printstring(GLUT_BITMAP_HELVETICA_10, 51432001f49Smrg "Fire V1.5 Written by David Bucciarelli (tech.hmw@plus.it)"); 51532001f49Smrg 51632001f49Smrg if (help) 51732001f49Smrg printhelp(); 51832001f49Smrg 51932001f49Smrg reshape(WIDTH, HEIGHT); 52032001f49Smrg glPopMatrix(); 52132001f49Smrg 52232001f49Smrg glutSwapBuffers(); 52332001f49Smrg 52432001f49Smrg Frames++; 52532001f49Smrg { 52632001f49Smrg GLint t = glutGet(GLUT_ELAPSED_TIME); 52732001f49Smrg if (t - T0 >= 2000) { 52832001f49Smrg GLfloat seconds = (t - T0) / 1000.0; 52932001f49Smrg GLfloat fps = Frames / seconds; 53032001f49Smrg sprintf(frbuf, "Frame rate: %f", fps); 53132001f49Smrg printf("%s\n", frbuf); 5327ec3b29aSmrg fflush(stdout); 53332001f49Smrg T0 = t; 53432001f49Smrg Frames = 0; 53532001f49Smrg } 53632001f49Smrg } 53732001f49Smrg} 53832001f49Smrg 53932001f49Smrg 54032001f49Smrgstatic void 54132001f49Smrgidle(void) 54232001f49Smrg{ 54332001f49Smrg glutPostRedisplay(); 54432001f49Smrg} 54532001f49Smrg 54632001f49Smrg 54732001f49Smrgstatic void 54832001f49Smrgspecial(int key, int x, int y) 54932001f49Smrg{ 55032001f49Smrg switch (key) { 55132001f49Smrg case GLUT_KEY_LEFT: 55232001f49Smrg alpha += 2.0; 55332001f49Smrg break; 55432001f49Smrg case GLUT_KEY_RIGHT: 55532001f49Smrg alpha -= 2.0; 55632001f49Smrg break; 55732001f49Smrg case GLUT_KEY_DOWN: 55832001f49Smrg beta -= 2.0; 55932001f49Smrg break; 56032001f49Smrg case GLUT_KEY_UP: 56132001f49Smrg beta += 2.0; 56232001f49Smrg break; 56332001f49Smrg } 56432001f49Smrg glutPostRedisplay(); 56532001f49Smrg} 56632001f49Smrg 56732001f49Smrgstatic void 56832001f49Smrgkey(unsigned char key, int x, int y) 56932001f49Smrg{ 57032001f49Smrg switch (key) { 57132001f49Smrg case 27: 57232001f49Smrg glutDestroyWindow(win); 57332001f49Smrg exit(0); 57432001f49Smrg break; 57532001f49Smrg 57632001f49Smrg case 'a': 57732001f49Smrg v += 0.0005; 57832001f49Smrg break; 57932001f49Smrg case 'z': 58032001f49Smrg v -= 0.0005; 58132001f49Smrg break; 58232001f49Smrg 58332001f49Smrg case 'j': 58432001f49Smrg joyactive = (!joyactive); 58532001f49Smrg break; 58632001f49Smrg case 'h': 58732001f49Smrg help = (!help); 58832001f49Smrg break; 58932001f49Smrg case 'f': 59032001f49Smrg fog = (!fog); 59132001f49Smrg break; 59232001f49Smrg case 's': 59332001f49Smrg shadows = !shadows; 59432001f49Smrg break; 59532001f49Smrg case 'R': 59632001f49Smrg eject_r -= 0.03; 59732001f49Smrg break; 59832001f49Smrg case 'r': 59932001f49Smrg eject_r += 0.03; 60032001f49Smrg break; 60132001f49Smrg case 't': 60232001f49Smrg ridtri += 0.005; 60332001f49Smrg break; 60432001f49Smrg case 'T': 60532001f49Smrg ridtri -= 0.005; 60632001f49Smrg break; 60732001f49Smrg#ifdef XMESA 60832001f49Smrg case ' ': 60932001f49Smrg XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); 61032001f49Smrg fullscreen = (!fullscreen); 61132001f49Smrg break; 61232001f49Smrg#endif 61332001f49Smrg case 'n': 61432001f49Smrg NiceFog = !NiceFog; 61532001f49Smrg printf("NiceFog %d\n", NiceFog); 61632001f49Smrg break; 61732001f49Smrg } 61832001f49Smrg glutPostRedisplay(); 61932001f49Smrg} 62032001f49Smrg 62132001f49Smrgstatic void 62232001f49Smrginittextures(void) 62332001f49Smrg{ 62432001f49Smrg GLenum gluerr; 62532001f49Smrg GLubyte tex[128][128][4]; 62632001f49Smrg 62732001f49Smrg glGenTextures(1, &groundid); 62832001f49Smrg glBindTexture(GL_TEXTURE_2D, groundid); 62932001f49Smrg 63032001f49Smrg glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 63132001f49Smrg if (!LoadRGBMipmaps(DEMOS_DATA_DIR "s128.rgb", GL_RGB)) { 63232001f49Smrg fprintf(stderr, "Error reading a texture.\n"); 63332001f49Smrg exit(-1); 63432001f49Smrg } 63532001f49Smrg 63632001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 63732001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 63832001f49Smrg 63932001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 64032001f49Smrg GL_LINEAR_MIPMAP_LINEAR); 64132001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 64232001f49Smrg 64332001f49Smrg glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 64432001f49Smrg 64532001f49Smrg glGenTextures(1, &treeid); 64632001f49Smrg glBindTexture(GL_TEXTURE_2D, treeid); 64732001f49Smrg 64832001f49Smrg if (1) 64932001f49Smrg { 65032001f49Smrg int w, h; 65132001f49Smrg GLenum format; 65232001f49Smrg int x, y; 65332001f49Smrg GLubyte *image = LoadRGBImage(DEMOS_DATA_DIR "tree3.rgb", 65432001f49Smrg &w, &h, &format); 65532001f49Smrg 65632001f49Smrg if (!image) { 65732001f49Smrg fprintf(stderr, "Error reading a texture.\n"); 65832001f49Smrg exit(-1); 65932001f49Smrg } 66032001f49Smrg 66132001f49Smrg for (y = 0; y < 128; y++) 66232001f49Smrg for (x = 0; x < 128; x++) { 66332001f49Smrg tex[x][y][0] = image[(y + x * 128) * 3]; 66432001f49Smrg tex[x][y][1] = image[(y + x * 128) * 3 + 1]; 66532001f49Smrg tex[x][y][2] = image[(y + x * 128) * 3 + 2]; 66632001f49Smrg if ((tex[x][y][0] == tex[x][y][1]) && 66732001f49Smrg (tex[x][y][1] == tex[x][y][2]) && (tex[x][y][2] == 255)) 66832001f49Smrg tex[x][y][3] = 0; 66932001f49Smrg else 67032001f49Smrg tex[x][y][3] = 255; 67132001f49Smrg } 67232001f49Smrg 67332001f49Smrg if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, 128, 128, GL_RGBA, 67432001f49Smrg GL_UNSIGNED_BYTE, (GLvoid *) (tex)))) { 67532001f49Smrg fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr)); 67632001f49Smrg exit(-1); 67732001f49Smrg } 67832001f49Smrg } 67932001f49Smrg else { 68032001f49Smrg if (!LoadRGBMipmaps(DEMOS_DATA_DIR "tree2.rgba", GL_RGBA)) { 68132001f49Smrg fprintf(stderr, "Error reading a texture.\n"); 68232001f49Smrg exit(-1); 68332001f49Smrg } 68432001f49Smrg } 68532001f49Smrg 68632001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 68732001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 68832001f49Smrg 68932001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 69032001f49Smrg GL_LINEAR_MIPMAP_LINEAR); 69132001f49Smrg glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 69232001f49Smrg 69332001f49Smrg glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 69432001f49Smrg} 69532001f49Smrg 69632001f49Smrgstatic void 69732001f49Smrginittree(void) 69832001f49Smrg{ 69932001f49Smrg int i; 70032001f49Smrg float dist; 70132001f49Smrg 70232001f49Smrg for (i = 0; i < NUMTREE; i++) 70332001f49Smrg do { 70432001f49Smrg treepos[i][0] = vrnd() * TREEOUTR * 2.0 - TREEOUTR; 70532001f49Smrg treepos[i][1] = 0.0; 70632001f49Smrg treepos[i][2] = vrnd() * TREEOUTR * 2.0 - TREEOUTR; 70732001f49Smrg dist = 70832001f49Smrg sqrt(treepos[i][0] * treepos[i][0] + 70932001f49Smrg treepos[i][2] * treepos[i][2]); 71032001f49Smrg } while ((dist < TREEINR) || (dist > TREEOUTR)); 71132001f49Smrg} 71232001f49Smrg 71332001f49Smrgint 71432001f49Smrgmain(int ac, char **av) 71532001f49Smrg{ 71632001f49Smrg int i; 71732001f49Smrg 71832001f49Smrg fprintf(stderr, 71932001f49Smrg "Fire V1.5\nWritten by David Bucciarelli (tech.hmw@plus.it)\n"); 72032001f49Smrg 72132001f49Smrg /* Default settings */ 72232001f49Smrg 72332001f49Smrg np = 800; 72432001f49Smrg eject_r = -0.65; 72532001f49Smrg dt = 0.015; 72632001f49Smrg eject_vy = 4; 72732001f49Smrg eject_vl = 1; 72832001f49Smrg shadows = 1; 72932001f49Smrg ridtri = 0.25; 73032001f49Smrg 73132001f49Smrg maxage = 1.0 / dt; 73232001f49Smrg 73332001f49Smrg if (ac == 2) { 73432001f49Smrg np = atoi(av[1]); 73532001f49Smrg if (np <= 0 || np > 1000000) { 73632001f49Smrg fprintf(stderr, "Invalid input.\n"); 73732001f49Smrg exit(-1); 73832001f49Smrg } 73932001f49Smrg } 74032001f49Smrg 74132001f49Smrg if (ac == 4) { 74232001f49Smrg WIDTH = atoi(av[2]); 74332001f49Smrg HEIGHT = atoi(av[3]); 74432001f49Smrg } 74532001f49Smrg 74632001f49Smrg glutInitWindowSize(WIDTH, HEIGHT); 74732001f49Smrg glutInit(&ac, av); 74832001f49Smrg 74932001f49Smrg glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); 75032001f49Smrg 75132001f49Smrg if (!(win = glutCreateWindow("Fire"))) { 75232001f49Smrg fprintf(stderr, "Error opening a window.\n"); 75332001f49Smrg exit(-1); 75432001f49Smrg } 75532001f49Smrg 75632001f49Smrg reshape(WIDTH, HEIGHT); 75732001f49Smrg 75832001f49Smrg inittextures(); 75932001f49Smrg 76032001f49Smrg glShadeModel(GL_FLAT); 76132001f49Smrg glEnable(GL_DEPTH_TEST); 76232001f49Smrg 76332001f49Smrg glEnable(GL_BLEND); 76432001f49Smrg glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 76532001f49Smrg 76632001f49Smrg glEnable(GL_FOG); 76732001f49Smrg glFogi(GL_FOG_MODE, GL_EXP); 76832001f49Smrg glFogfv(GL_FOG_COLOR, fogcolor); 76932001f49Smrg glFogf(GL_FOG_DENSITY, 0.1); 77032001f49Smrg 77132001f49Smrg assert(np > 0); 77232001f49Smrg p = (part *) malloc(sizeof(part) * np); 77332001f49Smrg assert(p); 77432001f49Smrg 77532001f49Smrg for (i = 0; i < np; i++) 77632001f49Smrg setnewpart(&p[i]); 77732001f49Smrg 77832001f49Smrg inittree(); 77932001f49Smrg 78032001f49Smrg glutKeyboardFunc(key); 78132001f49Smrg glutSpecialFunc(special); 78232001f49Smrg glutDisplayFunc(drawfire); 78332001f49Smrg glutIdleFunc(idle); 78432001f49Smrg glutReshapeFunc(reshape); 78532001f49Smrg glutMainLoop(); 78632001f49Smrg 78732001f49Smrg return (0); 78832001f49Smrg} 789