diff options
Diffstat (limited to 'progs/demos/fire.c')
-rw-r--r-- | progs/demos/fire.c | 784 |
1 files changed, 0 insertions, 784 deletions
diff --git a/progs/demos/fire.c b/progs/demos/fire.c deleted file mode 100644 index bb912fb4473..00000000000 --- a/progs/demos/fire.c +++ /dev/null @@ -1,784 +0,0 @@ -/* - * This program is under the GNU GPL. - * Use at your own risk. - * - * written by David Bucciarelli ([email protected]) - * Humanware s.r.l. - */ - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> -#include <time.h> -#include <string.h> - -#ifdef WIN32 -#include <windows.h> -#include <mmsystem.h> -#endif - -#include <GL/glut.h> -#include "readtex.h" - -#ifdef XMESA -#include "GL/xmesa.h" -static int fullscreen = 1; -#endif - -#ifndef M_PI -#define M_PI 3.1415926535 -#endif - -#define vinit(a,i,j,k) {\ - (a)[0]=i;\ - (a)[1]=j;\ - (a)[2]=k;\ -} - -#define vinit4(a,i,j,k,w) {\ - (a)[0]=i;\ - (a)[1]=j;\ - (a)[2]=k;\ - (a)[3]=w;\ -} - - -#define vadds(a,dt,b) {\ - (a)[0]+=(dt)*(b)[0];\ - (a)[1]+=(dt)*(b)[1];\ - (a)[2]+=(dt)*(b)[2];\ -} - -#define vequ(a,b) {\ - (a)[0]=(b)[0];\ - (a)[1]=(b)[1];\ - (a)[2]=(b)[2];\ -} - -#define vinter(a,dt,b,c) {\ - (a)[0]=(dt)*(b)[0]+(1.0-dt)*(c)[0];\ - (a)[1]=(dt)*(b)[1]+(1.0-dt)*(c)[1];\ - (a)[2]=(dt)*(b)[2]+(1.0-dt)*(c)[2];\ -} - -#define clamp(a) ((a) < 0.0 ? 0.0 : ((a) < 1.0 ? (a) : 1.0)) - -#define vclamp(v) {\ - (v)[0]=clamp((v)[0]);\ - (v)[1]=clamp((v)[1]);\ - (v)[2]=clamp((v)[2]);\ -} - -static int WIDTH = 640; -static int HEIGHT = 480; - -static GLint T0 = 0; -static GLint Frames = 0; -static GLint NiceFog = 1; - -#define DIMP 20.0 -#define DIMTP 16.0 - -#define RIDCOL 0.4 - -#define NUMTREE 50 -#define TREEINR 2.5 -#define TREEOUTR 8.0 - -#define AGRAV -9.8 - -typedef struct -{ - int age; - float p[3][3]; - float v[3]; - float c[3][4]; -} -part; - -static float treepos[NUMTREE][3]; - -static float black[3] = { 0.0, 0.0, 0.0 }; -static float blu[3] = { 1.0, 0.2, 0.0 }; -static float blu2[3] = { 1.0, 1.0, 0.0 }; - -static float fogcolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - -static float q[4][3] = { - {-DIMP, 0.0, -DIMP}, - {DIMP, 0.0, -DIMP}, - {DIMP, 0.0, DIMP}, - {-DIMP, 0.0, DIMP} -}; - -static float qt[4][2] = { - {-DIMTP, -DIMTP}, - {DIMTP, -DIMTP}, - {DIMTP, DIMTP}, - {-DIMTP, DIMTP} -}; - -static int win = 0; - -static int np; -static float eject_r, dt, maxage, eject_vy, eject_vl; -static short shadows; -static float ridtri; -static int fog = 1; -static int help = 1; -static int joyavailable = 0; -static int joyactive = 0; - -static part *p; - -static GLuint groundid; -static GLuint treeid; - -static float obs[3] = { 2.0, 1.0, 0.0 }; -static float dir[3]; -static float v = 0.0; -static float alpha = -84.0; -static float beta = 90.0; - -static float -vrnd(void) -{ - return (((float) rand()) / RAND_MAX); -} - -static void -setnewpart(part * p) -{ - float a, v[3], *c; - - p->age = 0; - - a = vrnd() * 3.14159265359 * 2.0; - - vinit(v, sin(a) * eject_r * vrnd(), 0.15, cos(a) * eject_r * vrnd()); - vinit(p->p[0], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, - v[2] + vrnd() * ridtri); - vinit(p->p[1], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, - v[2] + vrnd() * ridtri); - vinit(p->p[2], v[0] + vrnd() * ridtri, v[1] + vrnd() * ridtri, - v[2] + vrnd() * ridtri); - - vinit(p->v, v[0] * eject_vl / (eject_r / 2), - vrnd() * eject_vy + eject_vy / 2, v[2] * eject_vl / (eject_r / 2)); - - c = blu; - - vinit4(p->c[0], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), - c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), - c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); - vinit4(p->c[1], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), - c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), - c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); - vinit4(p->c[2], c[0] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), - c[1] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), - c[2] * ((1.0 - RIDCOL) + vrnd() * RIDCOL), 1.0); -} - -static void -setpart(part * p) -{ - float fact; - - if (p->p[0][1] < 0.1) { - setnewpart(p); - return; - } - - p->v[1] += AGRAV * dt; - - vadds(p->p[0], dt, p->v); - vadds(p->p[1], dt, p->v); - vadds(p->p[2], dt, p->v); - - p->age++; - - if ((p->age) > maxage) { - vequ(p->c[0], blu2); - vequ(p->c[1], blu2); - vequ(p->c[2], blu2); - } - else { - fact = 1.0 / maxage; - vadds(p->c[0], fact, blu2); - vclamp(p->c[0]); - p->c[0][3] = fact * (maxage - p->age); - - vadds(p->c[1], fact, blu2); - vclamp(p->c[1]); - p->c[1][3] = fact * (maxage - p->age); - - vadds(p->c[2], fact, blu2); - vclamp(p->c[2]); - p->c[2][3] = fact * (maxage - p->age); - } -} - -static void -drawtree(float x, float y, float z) -{ - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); - glVertex3f(x - 1.5, y + 0.0, z); - - glTexCoord2f(1.0, 0.0); - glVertex3f(x + 1.5, y + 0.0, z); - - glTexCoord2f(1.0, 1.0); - glVertex3f(x + 1.5, y + 3.0, z); - - glTexCoord2f(0.0, 1.0); - glVertex3f(x - 1.5, y + 3.0, z); - - - glTexCoord2f(0.0, 0.0); - glVertex3f(x, y + 0.0, z - 1.5); - - glTexCoord2f(1.0, 0.0); - glVertex3f(x, y + 0.0, z + 1.5); - - glTexCoord2f(1.0, 1.0); - glVertex3f(x, y + 3.0, z + 1.5); - - glTexCoord2f(0.0, 1.0); - glVertex3f(x, y + 3.0, z - 1.5); - - glEnd(); - -} - -static void -calcposobs(void) -{ - dir[0] = sin(alpha * M_PI / 180.0); - dir[2] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0); - dir[1] = cos(beta * M_PI / 180.0); - - if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5) - dir[0] = 0; - if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5) - dir[1] = 0; - if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5) - dir[2] = 0; - - obs[0] += v * dir[0]; - obs[1] += v * dir[1]; - obs[2] += v * dir[2]; -} - -static void -printstring(void *font, char *string) -{ - int len, i; - - len = (int) strlen(string); - for (i = 0; i < len; i++) - glutBitmapCharacter(font, string[i]); -} - -static void -reshape(int width, int height) -{ - WIDTH = width; - HEIGHT = height; - glViewport(0, 0, (GLint) width, (GLint) height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(70.0, width / (float) height, 0.1, 30.0); - - glMatrixMode(GL_MODELVIEW); -} - -static void -printhelp(void) -{ - glColor4f(0.0, 0.0, 0.0, 0.5); - glRecti(40, 40, 600, 440); - - glColor3f(1.0, 0.0, 0.0); - glRasterPos2i(300, 420); - printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help"); - - glRasterPos2i(60, 390); - printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Toggle Help"); - - glRasterPos2i(60, 360); - printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Increase particle size"); - glRasterPos2i(60, 330); - printstring(GLUT_BITMAP_TIMES_ROMAN_24, "T - Decrease particle size"); - - glRasterPos2i(60, 300); - printstring(GLUT_BITMAP_TIMES_ROMAN_24, "r - Increase emission radius"); - glRasterPos2i(60, 270); - printstring(GLUT_BITMAP_TIMES_ROMAN_24, "R - Decrease emission radius"); - - glRasterPos2i(60, 240); - printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Toggle Fog"); - glRasterPos2i(60, 210); - printstring(GLUT_BITMAP_TIMES_ROMAN_24, "s - Toggle shadows"); - glRasterPos2i(60, 180); - printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate"); - glRasterPos2i(60, 150); - printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity"); - glRasterPos2i(60, 120); - printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity"); - - glRasterPos2i(60, 90); - if (joyavailable) - printstring(GLUT_BITMAP_TIMES_ROMAN_24, - "j - Toggle jostick control (Joystick control available)"); - else - printstring(GLUT_BITMAP_TIMES_ROMAN_24, - "(No Joystick control available)"); -} - -static void -dojoy(void) -{ -#ifdef WIN32 - static UINT max[2] = { 0, 0 }; - static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2]; - MMRESULT res; - JOYINFO joy; - - res = joyGetPos(JOYSTICKID1, &joy); - - if (res == JOYERR_NOERROR) { - joyavailable = 1; - - if (max[0] < joy.wXpos) - max[0] = joy.wXpos; - if (min[0] > joy.wXpos) - min[0] = joy.wXpos; - center[0] = (max[0] + min[0]) / 2; - - if (max[1] < joy.wYpos) - max[1] = joy.wYpos; - if (min[1] > joy.wYpos) - min[1] = joy.wYpos; - center[1] = (max[1] + min[1]) / 2; - - if (joyactive) { - if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0])) - alpha += - 2.5 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]); - if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1])) - beta += 2.5 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]); - - if (joy.wButtons & JOY_BUTTON1) - v += 0.01; - if (joy.wButtons & JOY_BUTTON2) - v -= 0.01; - } - } - else - joyavailable = 0; -#endif -} - -static void -drawfire(void) -{ - static char frbuf[80] = ""; - int j; - static double t0 = -1.; - double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; - if (t0 < 0.0) - t0 = t; - dt = (t - t0) * 1.0; - t0 = t; - - dojoy(); - - if (NiceFog) - glHint(GL_FOG_HINT, GL_NICEST); - else - glHint(GL_FOG_HINT, GL_DONT_CARE); - - glEnable(GL_DEPTH_TEST); - - if (fog) - glEnable(GL_FOG); - else - glDisable(GL_FOG); - - glDepthMask(GL_TRUE); - glClearColor(1.0, 1.0, 1.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glPushMatrix(); - calcposobs(); - gluLookAt(obs[0], obs[1], obs[2], - obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2], - 0.0, 1.0, 0.0); - - glColor4f(1.0, 1.0, 1.0, 1.0); - - glEnable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, groundid); -#if 1 - glBegin(GL_QUADS); - glTexCoord2fv(qt[0]); - glVertex3fv(q[0]); - glTexCoord2fv(qt[1]); - glVertex3fv(q[1]); - glTexCoord2fv(qt[2]); - glVertex3fv(q[2]); - glTexCoord2fv(qt[3]); - glVertex3fv(q[3]); - glEnd(); -#else - /* Subdivide the ground into a bunch of quads. This improves fog - * if GL_FOG_HINT != GL_NICEST - */ - { - float x, y; - float dx = 1.0, dy = 1.0; - glBegin(GL_QUADS); - for (y = -DIMP; y < DIMP; y += 1.0) { - for (x = -DIMP; x < DIMP; x += 1.0) { - glTexCoord2f(0, 0); glVertex3f(x, 0, y); - glTexCoord2f(1, 0); glVertex3f(x+dx, 0, y); - glTexCoord2f(1, 1); glVertex3f(x+dx, 0, y+dy); - glTexCoord2f(0, 1); glVertex3f(x, 0, y+dy); - } - } - glEnd(); - } -#endif - - - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GEQUAL, 0.9); - - glBindTexture(GL_TEXTURE_2D, treeid); - for (j = 0; j < NUMTREE; j++) - drawtree(treepos[j][0], treepos[j][1], treepos[j][2]); - - glDisable(GL_TEXTURE_2D); - glDepthMask(GL_FALSE); - glDisable(GL_ALPHA_TEST); - - if (shadows) { - glBegin(GL_TRIANGLES); - for (j = 0; j < np; j++) { - glColor4f(black[0], black[1], black[2], p[j].c[0][3]); - glVertex3f(p[j].p[0][0], 0.1, p[j].p[0][2]); - - glColor4f(black[0], black[1], black[2], p[j].c[1][3]); - glVertex3f(p[j].p[1][0], 0.1, p[j].p[1][2]); - - glColor4f(black[0], black[1], black[2], p[j].c[2][3]); - glVertex3f(p[j].p[2][0], 0.1, p[j].p[2][2]); - } - glEnd(); - } - - glBegin(GL_TRIANGLES); - for (j = 0; j < np; j++) { - glColor4fv(p[j].c[0]); - glVertex3fv(p[j].p[0]); - - glColor4fv(p[j].c[1]); - glVertex3fv(p[j].p[1]); - - glColor4fv(p[j].c[2]); - glVertex3fv(p[j].p[2]); - - setpart(&p[j]); - } - glEnd(); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_FOG); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glColor3f(1.0, 0.0, 0.0); - glRasterPos2i(10, 10); - printstring(GLUT_BITMAP_HELVETICA_18, frbuf); - glRasterPos2i(370, 470); - printstring(GLUT_BITMAP_HELVETICA_10, - "Fire V1.5 Written by David Bucciarelli ([email protected])"); - - if (help) - printhelp(); - - reshape(WIDTH, HEIGHT); - glPopMatrix(); - - glutSwapBuffers(); - - Frames++; - { - GLint t = glutGet(GLUT_ELAPSED_TIME); - if (t - T0 >= 2000) { - GLfloat seconds = (t - T0) / 1000.0; - GLfloat fps = Frames / seconds; - sprintf(frbuf, "Frame rate: %f", fps); - T0 = t; - Frames = 0; - } - } -} - - -static void -idle(void) -{ - glutPostRedisplay(); -} - - -static void -special(int key, int x, int y) -{ - switch (key) { - case GLUT_KEY_LEFT: - alpha += 2.0; - break; - case GLUT_KEY_RIGHT: - alpha -= 2.0; - break; - case GLUT_KEY_DOWN: - beta -= 2.0; - break; - case GLUT_KEY_UP: - beta += 2.0; - break; - } - glutPostRedisplay(); -} - -static void -key(unsigned char key, int x, int y) -{ - switch (key) { - case 27: - exit(0); - break; - - case 'a': - v += 0.0005; - break; - case 'z': - v -= 0.0005; - break; - - case 'j': - joyactive = (!joyactive); - break; - case 'h': - help = (!help); - break; - case 'f': - fog = (!fog); - break; - case 's': - shadows = !shadows; - break; - case 'R': - eject_r -= 0.03; - break; - case 'r': - eject_r += 0.03; - break; - case 't': - ridtri += 0.005; - break; - case 'T': - ridtri -= 0.005; - break; -#ifdef XMESA - case ' ': - XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW); - fullscreen = (!fullscreen); - break; -#endif - case 'n': - NiceFog = !NiceFog; - printf("NiceFog %d\n", NiceFog); - break; - } - glutPostRedisplay(); -} - -static void -inittextures(void) -{ - GLenum gluerr; - GLubyte tex[128][128][4]; - - glGenTextures(1, &groundid); - glBindTexture(GL_TEXTURE_2D, groundid); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - if (!LoadRGBMipmaps("../images/s128.rgb", GL_RGB)) { - fprintf(stderr, "Error reading a texture.\n"); - exit(-1); - } - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - - glGenTextures(1, &treeid); - glBindTexture(GL_TEXTURE_2D, treeid); - - if (1) - { - int w, h; - GLenum format; - int x, y; - GLubyte *image = LoadRGBImage("../images/tree3.rgb", &w, &h, &format); - - if (!image) { - fprintf(stderr, "Error reading a texture.\n"); - exit(-1); - } - - for (y = 0; y < 128; y++) - for (x = 0; x < 128; x++) { - tex[x][y][0] = image[(y + x * 128) * 3]; - tex[x][y][1] = image[(y + x * 128) * 3 + 1]; - tex[x][y][2] = image[(y + x * 128) * 3 + 2]; - if ((tex[x][y][0] == tex[x][y][1]) && - (tex[x][y][1] == tex[x][y][2]) && (tex[x][y][2] == 255)) - tex[x][y][3] = 0; - else - tex[x][y][3] = 255; - } - - if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, 128, 128, GL_RGBA, - GL_UNSIGNED_BYTE, (GLvoid *) (tex)))) { - fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr)); - exit(-1); - } - } - else { - if (!LoadRGBMipmaps("../images/tree2.rgba", GL_RGBA)) { - fprintf(stderr, "Error reading a texture.\n"); - exit(-1); - } - } - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -} - -static void -inittree(void) -{ - int i; - float dist; - - for (i = 0; i < NUMTREE; i++) - do { - treepos[i][0] = vrnd() * TREEOUTR * 2.0 - TREEOUTR; - treepos[i][1] = 0.0; - treepos[i][2] = vrnd() * TREEOUTR * 2.0 - TREEOUTR; - dist = - sqrt(treepos[i][0] * treepos[i][0] + - treepos[i][2] * treepos[i][2]); - } while ((dist < TREEINR) || (dist > TREEOUTR)); -} - -int -main(int ac, char **av) -{ - int i; - - fprintf(stderr, - "Fire V1.5\nWritten by David Bucciarelli ([email protected])\n"); - - /* Default settings */ - - np = 800; - eject_r = -0.65; - dt = 0.015; - eject_vy = 4; - eject_vl = 1; - shadows = 1; - ridtri = 0.25; - - maxage = 1.0 / dt; - - if (ac == 2) { - np = atoi(av[1]); - if (np <= 0 || np > 1000000) { - fprintf(stderr, "Invalid input.\n"); - exit(-1); - } - } - - if (ac == 4) { - WIDTH = atoi(av[2]); - HEIGHT = atoi(av[3]); - } - - glutInitWindowSize(WIDTH, HEIGHT); - glutInit(&ac, av); - - glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); - - if (!(win = glutCreateWindow("Fire"))) { - fprintf(stderr, "Error opening a window.\n"); - exit(-1); - } - - reshape(WIDTH, HEIGHT); - - inittextures(); - - glShadeModel(GL_FLAT); - glEnable(GL_DEPTH_TEST); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glEnable(GL_FOG); - glFogi(GL_FOG_MODE, GL_EXP); - glFogfv(GL_FOG_COLOR, fogcolor); - glFogf(GL_FOG_DENSITY, 0.1); - - assert(np > 0); - p = (part *) malloc(sizeof(part) * np); - assert(p); - - for (i = 0; i < np; i++) - setnewpart(&p[i]); - - inittree(); - - glutKeyboardFunc(key); - glutSpecialFunc(special); - glutDisplayFunc(drawfire); - glutIdleFunc(idle); - glutReshapeFunc(reshape); - glutMainLoop(); - - return (0); -} |