diff options
| author | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2024-09-06 14:42:37 +0200 |
| commit | badef32037f52f79abc1f1440b786cd71afdf270 (patch) | |
| tree | 412b792d4cab4a7a110db82fcf74fe8a1ac55ec1 /hacks/glx/glforestfire.c | |
| parent | Delete pre-6.00 files (diff) | |
| download | xscreensaver-master.tar.gz xscreensaver-master.tar.xz xscreensaver-master.zip | |
Diffstat (limited to 'hacks/glx/glforestfire.c')
| -rw-r--r-- | hacks/glx/glforestfire.c | 1088 |
1 files changed, 0 insertions, 1088 deletions
diff --git a/hacks/glx/glforestfire.c b/hacks/glx/glforestfire.c deleted file mode 100644 index 304324a..0000000 --- a/hacks/glx/glforestfire.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* -*- Mode: C; tab-width: 4 -*- */ -/* fire --- 3D fire or rain landscape */ - -#if 0 -static const char sccsid[] = "@(#)fire.c 5.02 2001/09/26 xlockmore"; -#endif - -/* Copyright (c) E. Lassauge, 2001. */ - -/* - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * This file is provided AS IS with no warranties of any kind. The author - * shall have no liability with respect to the infringement of copyrights, - * trade secrets or any patents by this file or any part thereof. In no - * event will the author be liable for any lost revenue or profits or - * other special, indirect and consequential damages. - * - * The original code for this mode was written by David Bucciarelli - * (tech.hmw@plus.it) and could be found in the demo package - * of Mesa (Mesa-3.2/3Dfx/demos/). This mode is the result of the merge of - * two of the David's demos (fire and rain). - * - * Eric Lassauge (October-10-2000) <lassauge@users.sourceforge.net> - * http://lassauge.free.fr/linux.html - * - * REVISION HISTORY: - * - * E.Lassauge - 26-Sep-2001: - * - add wander option and code - * - cleanups for xscreensaver - * - * E.Lassauge - 09-Mar-2001: - * - get rid of my framerate options to use showfps - * - * E.Lassauge - 12-Jan-2001: - * - add rain particules, selected if count=0 (no fire means rain !) - * - * E.Lassauge - 28-Nov-2000: - * - modified release part to add freeing of GL objects - * - * E.Lassauge - 14-Nov-2000: - * - use new common xpm_to_ximage function - * - * E.Lassauge - 25-Oct-2000: - * - add the trees (with a new resource '-trees') - * - corrected handling of color (textured vs untextured) - * - corrected handling of endiannes for the xpm files - * - inverted ground pixmap file - * - use malloc-ed tree array - * - * TSchmidt - 23-Oct-2000: - * - added size option like used in sproingies mode - * - * E.Lassauge - 13-Oct-2000: - * - when trackmouse and window is iconified (login screen): stop tracking - * - add pure GLX handling of framerate display (erased GLUT stuff) - * - made count a per screen variable and update it only if framemode - * - changes for no_texture an wireframe modes - * - change no_texture color for the ground - * - add freeing of texture image - * - misc comments and little tweakings - * - * TODO: - * - perhaps use a user supplied xpm for ground image (or a whatever image - * file using ImageMagick ?) - * - random number of trees ? change trees at change_fire ? - * - fix wireframe mode: it's too CPU intensive. - * - look how we can get the Wheel events (Button4&5). - */ - - -#ifdef STANDALONE /* xscreensaver mode */ -#define DEFAULTS "*delay: 10000 \n" \ - "*count: 800 \n" \ - "*size: 0 \n" \ - "*showFPS: False \n" \ - "*wireframe: False \n" \ - -#define MODE_fire -#include "xlockmore.h" /* from the xscreensaver distribution */ -#include "gltrackball.h" -#else /* !STANDALONE */ -#include "xlock.h" /* from the xlockmore distribution */ -#include "visgl.h" -#endif /* !STANDALONE */ - -#ifdef MODE_fire - -#define MINSIZE 32 - -#if defined( USE_XPM ) || defined( USE_XPMINC ) || defined(STANDALONE) -/* USE_XPM & USE_XPMINC in xlock mode ; HAVE_XPM in xscreensaver mode */ -#include "ximage-loader.h" -#define I_HAVE_XPM - -#include "images/gen/ground_png.h" -#include "images/gen/tree_png.h" -#endif /* HAVE_XPM */ - -/* vector utility macros */ -#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]);\ -} - -/* Manage option vars */ -#define DEF_TEXTURE "True" -#define DEF_FOG "False" -#define DEF_SHADOWS "True" -#define DEF_FRAMERATE "False" -#define DEF_WANDER "True" -#define DEF_TREES "5" -#define MAX_TREES 20 -static Bool do_texture; -static Bool do_fog; -static Bool do_shadows; -static Bool do_wander; -static int num_trees; - -static XrmOptionDescRec opts[] = { - {"-texture", ".fire.texture", XrmoptionNoArg, "on"}, - {"+texture", ".fire.texture", XrmoptionNoArg, "off"}, - {"-fog", ".fire.fog", XrmoptionNoArg, "on"}, - {"+fog", ".fire.fog", XrmoptionNoArg, "off"}, - {"-shadows", ".fire.shadows", XrmoptionNoArg, "on"}, - {"+shadows", ".fire.shadows", XrmoptionNoArg, "off"}, - {"-wander", ".fire.wander", XrmoptionNoArg, "on"}, - {"+wander", ".fire.wander", XrmoptionNoArg, "off"}, - {"-trees", ".fire.trees", XrmoptionSepArg, 0}, - {"-rain", ".fire.count", XrmoptionNoArg, "0"}, - -}; - -static argtype vars[] = { - {&do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool}, - {&do_fog, "fog", "Fog", DEF_FOG, t_Bool}, - {&do_shadows, "shadows", "Shadows", DEF_SHADOWS, t_Bool}, - {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool}, - {&num_trees, "trees", "Trees", DEF_TREES, t_Int}, -}; - -static OptionStruct desc[] = { - {"-/+texture", "turn on/off texturing"}, - {"-/+fog", "turn on/off fog"}, - {"-/+shadows", "turn on/off shadows"}, - {"-/+wander", "turn on/off wandering"}, - {"-trees num", "number of trees (0 disables)"}, -}; - -ENTRYPOINT ModeSpecOpt fire_opts = - { sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc }; - -#ifdef USE_MODULES -ModStruct fire_description = - { "fire", "init_fire", "draw_fire", "release_fire", - "draw_fire", "change_fire", (char *) NULL, &fire_opts, - 10000, 800, 1, 400, 64, 1.0, "", - "Shows a 3D fire-like image", 0, NULL -}; -#endif /* USE_MODULES */ - -/* misc defines */ -#define TREEINR 2.5 /* tree min distance */ -#define TREEOUTR 8.0 /* tree max distance */ -#define FRAME 50 /* frame count interval */ -#define DIMP 20.0 /* dimension of ground */ -#define DIMTP 16.0 /* dimension of ground texture */ - -#define RIDCOL 0.4 /* factor for color blending */ - -#define AGRAV -9.8 /* gravity */ - -#define NUMPART 7500 /* rain particles */ - -/* fire particle struct */ -typedef struct { - int age; - float p[3][3]; - float v[3]; - float c[3][4]; -} part; - -/* rain particle struct */ -typedef struct { - float age; - float acc[3]; - float vel[3]; - float pos[3]; - float partLength; - float oldpos[3]; -} rain; - -/* colors */ -static const GLfloat black[3] = { 0.0, 0.0, 0.0 }; /* shadow color */ -static const GLfloat partcol1[3] = { 1.0, 0.2, 0.0 }; /* initial color: red-ish */ -static const GLfloat partcol2[3] = { 1.0, 1.0, 0.0 }; /* blending color: yellow-ish */ -static const GLfloat fogcolor[4] = { 0.9, 0.9, 1.0, 1.0 }; - -/* ground */ -static const float q[4][3] = { - {-DIMP, 0.0, -DIMP}, - {DIMP, 0.0, -DIMP}, - {DIMP, 0.0, DIMP}, - {-DIMP, 0.0, DIMP} -}; - -/* ground texture */ -static const float qt[4][2] = { - {-DIMTP, -DIMTP}, - {DIMTP, -DIMTP}, - {DIMTP, DIMTP}, - {-DIMTP, DIMTP} -}; - -/* default values for observer */ -static const float DEF_OBS[3] = { 2.0f, 1.0f, 0.0f }; -#define DEV_V 0.0 -#define DEF_ALPHA -90.0 -#define DEF_BETA 90.0 - -/* tree struct */ -typedef struct { - float x,y,z; -} treestruct; - -/* the mode struct, contains all per screen variables */ -typedef struct { - GLint WIDTH, HEIGHT; /* display dimensions */ - GLXContext *glx_context; - - int np; /* number of fire particles : set it through 'count' resource */ - float eject_r; /* emission radius */ - float dt, maxage, eject_vy, eject_vl; - float ridtri; /* fire particle size */ - Bool shadows; /* misc booleans: set them through specific resources */ - Bool fog; - - part *p; /* fire particles array */ - rain *r; /* rain particles array */ - - XImage *gtexture; /* ground texture image bits */ - XImage *ttexture; /* tree texture image bits */ - GLuint groundid; /* ground texture id: GL world */ - GLuint treeid; /* tree texture id: GL world */ - - int num_trees; /* number of trees: set it through 'trees' resource */ - treestruct *treepos; /* trees positions: float treepos[num_trees][3] */ - - float min[3]; /* raining area */ - float max[3]; - - float obs[3]; /* observer coordinates */ - float dir[3]; /* view direction */ - float v; /* observer velocity */ - float alpha; /* observer angles */ - float beta; - - trackball_state *trackball; - Bool button_down_p; - int frame; - -} firestruct; - -/* array of firestruct indexed by screen number */ -static firestruct *fire = (firestruct *) NULL; - -/* - *----------------------------------------------------------------------------- - *----------------------------------------------------------------------------- - * Misc funcs. - *----------------------------------------------------------------------------- - *----------------------------------------------------------------------------- - */ - -/* utility function for the rain particles */ -static float gettimerain(void) -{ -#if 0 - /* Oh yeah, *that's* portable! WTF. */ - /* - * I really thought clock() was standard ... EL - * I found this on the net: - * The clock() function conforms to ISO/IEC 9899:1990 (``ISO C89'') - * */ - - static clock_t told= (clock_t)0; - clock_t tnew,ris; - - tnew=clock(); - - ris=tnew-told; - - told=tnew; - - return (0.0125 + ris/(float)CLOCKS_PER_SEC); -#else - return 0.0150; -#endif -} - -/* my RAND */ -static float vrnd(void) -{ - return ((float) LRAND() / (float) MAXRAND); -} - -/* initialise new fire particle */ -static void setnewpart(firestruct * fs, part * p) -{ - float a, vi[3]; - const float *c; - - p->age = 0; - - a = vrnd() * M_PI * 2.0; - - vinit(vi, sin(a) * fs->eject_r * vrnd(), 0.15, cos(a) * fs->eject_r * vrnd()); - vinit(p->p[0], vi[0] + vrnd() * fs->ridtri, vi[1] + vrnd() * fs->ridtri, vi[2] + vrnd() * fs->ridtri); - vinit(p->p[1], vi[0] + vrnd() * fs->ridtri, vi[1] + vrnd() * fs->ridtri, vi[2] + vrnd() * fs->ridtri); - vinit(p->p[2], vi[0] + vrnd() * fs->ridtri, vi[1] + vrnd() * fs->ridtri, vi[2] + vrnd() * fs->ridtri); - - vinit(p->v, vi[0] * fs->eject_vl / (fs->eject_r / 2), - vrnd() * fs->eject_vy + fs->eject_vy / 2, - vi[2] * fs->eject_vl / (fs->eject_r / 2)); - - c = partcol1; - - 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); -} - -/* initialise new rain particle */ -static void setnewrain(firestruct * fs, rain * r) -{ - r->age=0.0f; - - vinit(r->acc,0.0f,-0.98f,0.0f); - vinit(r->vel,0.0f,0.0f,0.0f); - - r->partLength=0.2f; - - vinit(r->oldpos,fs->min[0]+(fs->max[0]-fs->min[0])*vrnd(), - fs->max[1]+0.2f*fs->max[1]*vrnd(), - fs->min[2]+(fs->max[2]-fs->min[2])*vrnd()); - vequ(r->pos,r->oldpos); - vadds(r->oldpos,-(r->partLength),r->vel); - - r->pos[1]=(fs->max[1]-fs->min[1])*vrnd()+fs->min[1]; - r->oldpos[1]=r->pos[1]-r->partLength*r->vel[1]; -} - -/* set fire particle values */ -static void setpart(firestruct * fs, part * p) -{ - float fact; - - if (p->p[0][1] < 0.1) { - setnewpart(fs, p); - return; - } - - p->v[1] += AGRAV * fs->dt; - - vadds(p->p[0], fs->dt, p->v); - vadds(p->p[1], fs->dt, p->v); - vadds(p->p[2], fs->dt, p->v); - - p->age++; - - if ((p->age) > fs->maxage) { - vequ(p->c[0], partcol2); - vequ(p->c[1], partcol2); - vequ(p->c[2], partcol2); - } else { - fact = 1.0 / fs->maxage; - vadds(p->c[0], fact, partcol2); - vclamp(p->c[0]); - p->c[0][3] = fact * (fs->maxage - p->age); - - vadds(p->c[1], fact, partcol2); - vclamp(p->c[1]); - p->c[1][3] = fact * (fs->maxage - p->age); - - vadds(p->c[2], fact, partcol2); - vclamp(p->c[2]); - p->c[2][3] = fact * (fs->maxage - p->age); - } -} - -/* set rain particle values */ -static void setpartrain(firestruct * fs, rain * r, float dt) -{ - r->age += dt; - - vadds(r->vel,dt,r->acc); - vadds(r->pos,dt,r->vel); - - if(r->pos[0]<fs->min[0]) - r->pos[0]=fs->max[0]-(fs->min[0]-r->pos[0]); - if(r->pos[2]<fs->min[2]) - r->pos[2]=fs->max[2]-(fs->min[2]-r->pos[2]); - - if(r->pos[0]>fs->max[0]) - r->pos[0]=fs->min[0]+(r->pos[0]-fs->max[0]); - if(r->pos[2]>fs->max[2]) - r->pos[2]=fs->min[2]+(r->pos[2]-fs->max[2]); - - vequ(r->oldpos,r->pos); - vadds(r->oldpos,-(r->partLength),r->vel); - if(r->pos[1]<fs->min[1]) - setnewrain(fs, r); -} - -/* draw a tree */ -static int drawtree(float x, float y, float z) -{ - int polys = 0; - 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); - polys++; - - - 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); - polys++; - - glEnd(); - - return polys; -} - -/* calculate observer position : modified only if trackmouse is used */ -static void calcposobs(firestruct * fs) -{ - fs->dir[0] = sin(fs->alpha * M_PI / 180.0); - fs->dir[2] = - cos(fs->alpha * M_PI / 180.0) * sin(fs->beta * M_PI / 180.0); - fs->dir[1] = cos(fs->beta * M_PI / 180.0); - - fs->obs[0] += fs->v * fs->dir[0]; - fs->obs[1] += fs->v * fs->dir[1]; - fs->obs[2] += fs->v * fs->dir[2]; - - if (!fs->np) - { - vinit(fs->min,fs->obs[0]-7.0f,-0.2f,fs->obs[2]-7.0f); - vinit(fs->max,fs->obs[0]+7.0f,8.0f,fs->obs[2]+7.0f); - } -} - - -/* initialise textures */ -static void inittextures(ModeInfo * mi) -{ - firestruct *fs = &fire[MI_SCREEN(mi)]; - -#if defined( I_HAVE_XPM ) - if (do_texture) { - - glGenTextures(1, &fs->groundid); -#ifdef HAVE_GLBINDTEXTURE - glBindTexture(GL_TEXTURE_2D, fs->groundid); -#endif /* HAVE_GLBINDTEXTURE */ - - if ((fs->gtexture = image_data_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi), - ground_png, - sizeof(ground_png))) - == None) { - (void) fprintf(stderr, "Error reading the ground texture.\n"); - glDeleteTextures(1, &fs->groundid); - do_texture = False; - fs->groundid = 0; - fs->treeid = 0; - return; - } - - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - clear_gl_error(); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - fs->gtexture->width, fs->gtexture->height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, fs->gtexture->data); - check_gl_error("texture"); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); - - if (fs->num_trees) - { - glGenTextures(1, &fs->treeid); -#ifdef HAVE_GLBINDTEXTURE - glBindTexture(GL_TEXTURE_2D,fs->treeid); -#endif /* HAVE_GLBINDTEXTURE */ - if ((fs->ttexture = image_data_to_ximage(MI_DISPLAY(mi), - MI_VISUAL(mi), - tree_png, - sizeof(tree_png))) - == None) { - (void)fprintf(stderr,"Error reading tree texture.\n"); - glDeleteTextures(1, &fs->treeid); - fs->treeid = 0; - fs->num_trees = 0; - return; - } - - clear_gl_error(); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - fs->ttexture->width, fs->ttexture->height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, fs->ttexture->data); - check_gl_error("texture"); - - 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_NEAREST); - glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); - - glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); - } - } - else - { - fs->groundid = 0; /* default textures */ - fs->treeid = 0; - } -#else /* !I_HAVE_XPM */ - do_texture = False; - fs->groundid = 0; /* default textures */ - fs->treeid = 0; -#endif /* !I_HAVE_XPM */ -} - -/* init tree array and positions */ -static Bool inittree(ModeInfo * mi) -{ - firestruct *fs = &fire[MI_SCREEN(mi)]; - int i; - float dist; - - /* allocate treepos array */ - if ((fs->treepos = (treestruct *) malloc(fs->num_trees * - sizeof(treestruct))) == NULL) { - return False; - } - /* initialise positions */ - for(i=0;i<fs->num_trees;i++) { - do { - fs->treepos[i].x =vrnd()*TREEOUTR*2.0-TREEOUTR; - fs->treepos[i].y =0.0; - fs->treepos[i].z =vrnd()*TREEOUTR*2.0-TREEOUTR; - dist = sqrt(fs->treepos[i].x * fs->treepos[i].x + - fs->treepos[i].z * fs->treepos[i].z); - } while((dist<TREEINR) || (dist>TREEOUTR)); - } - return True; -} - -/* - *----------------------------------------------------------------------------- - *----------------------------------------------------------------------------- - * GL funcs. - *----------------------------------------------------------------------------- - *----------------------------------------------------------------------------- - */ - -ENTRYPOINT void reshape_fire(ModeInfo * mi, int width, int height) -{ - - firestruct *fs = &fire[MI_SCREEN(mi)]; - int size = MI_SIZE(mi); - - /* Viewport is specified size if size >= MINSIZE && size < screensize */ - if (size <= 1) { - fs->WIDTH = MI_WIDTH(mi); - fs->HEIGHT = MI_HEIGHT(mi); - } else if (size < MINSIZE) { - fs->WIDTH = MINSIZE; - fs->HEIGHT = MINSIZE; - } else { - fs->WIDTH = (size > MI_WIDTH(mi)) ? MI_WIDTH(mi) : size; - fs->HEIGHT = (size > MI_HEIGHT(mi)) ? MI_HEIGHT(mi) : size; - } - glViewport((MI_WIDTH(mi) - fs->WIDTH) / 2, (MI_HEIGHT(mi) - fs->HEIGHT) / 2, fs->WIDTH, fs->HEIGHT); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(70.0, fs->WIDTH / (float) fs->HEIGHT, 0.1, 30.0); - - glMatrixMode(GL_MODELVIEW); - -} - -static void DrawFire(ModeInfo * mi) -{ - int j; - firestruct *fs = &fire[MI_SCREEN(mi)]; - Bool wire = MI_IS_WIREFRAME(mi); - - mi->polygon_count = 0; - - if (do_wander && !fs->button_down_p) - { - GLfloat x, y, z; - -# define SINOID(SCALE,SIZE) \ - ((((1 + sin((fs->frame * (SCALE)) / 2 * M_PI)) / 2.0) * (SIZE)) - (SIZE)/2) - - x = SINOID(0.031, 0.85); - y = SINOID(0.017, 0.25); - z = SINOID(0.023, 0.85); - fs->frame++; - fs->obs[0] = x + DEF_OBS[0]; - fs->obs[1] = y + DEF_OBS[1]; - fs->obs[2] = z + DEF_OBS[2]; - fs->dir[1] = y; - fs->dir[2] = z; - } - - glEnable(GL_DEPTH_TEST); - - if (fs->fog) - glEnable(GL_FOG); - else - glDisable(GL_FOG); - - glDepthMask(GL_TRUE); - glClearColor(0.5, 0.5, 0.8, 1.0); /* sky in the distance */ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glPushMatrix(); - - calcposobs(fs); - - gltrackball_rotate (fs->trackball); - - gluLookAt(fs->obs[0], fs->obs[1], fs->obs[2], - fs->obs[0] + fs->dir[0], - fs->obs[1] + fs->dir[1], - fs->obs[2] + fs->dir[2], - 0.0, 1.0, 0.0); - - glEnable(GL_TEXTURE_2D); - - /* draw ground using the computed texture */ - if (do_texture) { - glColor4f(1.0,1.0,1.0,1.0); /* white to get texture in it's true color */ -#ifdef HAVE_GLBINDTEXTURE - glBindTexture(GL_TEXTURE_2D, fs->groundid); -#endif /* HAVE_GLBINDTEXTURE */ - } - else - glColor4f(0.54, 0.27, 0.07, 1.0); /* untextured ground color */ - 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]); - mi->polygon_count++; - glEnd(); - - glAlphaFunc(GL_GEQUAL, 0.9); - if (fs->num_trees) - { - /* here do_texture IS True - and color used is white */ - glEnable(GL_ALPHA_TEST); -#ifdef HAVE_GLBINDTEXTURE - glBindTexture(GL_TEXTURE_2D,fs->treeid); -#endif /* HAVE_GLBINDTEXTURE */ - for(j=0;j<fs->num_trees;j++) - mi->polygon_count += drawtree(fs->treepos[j].x ,fs->treepos[j].y ,fs->treepos[j].z ); - glDisable(GL_ALPHA_TEST); - } - glDisable(GL_TEXTURE_2D); - glDepthMask(GL_FALSE); - - if (fs->shadows) { - /* draw shadows with black color */ - glBegin(wire ? GL_LINE_STRIP : GL_TRIANGLES); - for (j = 0; j < fs->np; j++) { - glColor4f(black[0], black[1], black[2], fs->p[j].c[0][3]); - glVertex3f(fs->p[j].p[0][0], 0.1, fs->p[j].p[0][2]); - - glColor4f(black[0], black[1], black[2], fs->p[j].c[1][3]); - glVertex3f(fs->p[j].p[1][0], 0.1, fs->p[j].p[1][2]); - - glColor4f(black[0], black[1], black[2], fs->p[j].c[2][3]); - glVertex3f(fs->p[j].p[2][0], 0.1, fs->p[j].p[2][2]); - mi->polygon_count++; - } - glEnd(); - } - - glBegin(wire ? GL_LINE_STRIP : GL_TRIANGLES); - for (j = 0; j < fs->np; j++) { - /* draw particles: colors are computed in setpart */ - glColor4fv(fs->p[j].c[0]); - glVertex3fv(fs->p[j].p[0]); - - glColor4fv(fs->p[j].c[1]); - glVertex3fv(fs->p[j].p[1]); - - glColor4fv(fs->p[j].c[2]); - glVertex3fv(fs->p[j].p[2]); - mi->polygon_count++; - - setpart(fs, &fs->p[j]); - } - glEnd(); - - /* draw rain particles if no fire particles */ - if (!fs->np) - { - float timeused = gettimerain(); - glDisable(GL_TEXTURE_2D); - glShadeModel(GL_SMOOTH); - glBegin(GL_LINES); - for (j = 0; j < NUMPART; j++) { - glColor4f(0.7f,0.95f,1.0f,0.0f); - glVertex3fv(fs->r[j].oldpos); - glColor4f(0.3f,0.7f,1.0f,1.0f); - glVertex3fv(fs->r[j].pos); - setpartrain(fs, &fs->r[j],timeused); - mi->polygon_count++; - } - glEnd(); - glShadeModel(GL_FLAT); - } - - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_FOG); - - /* manage framerate display */ - if (MI_IS_FPS(mi)) do_fps (mi); - glPopMatrix(); -} - - -static Bool Init(ModeInfo * mi) -{ - int i; - firestruct *fs = &fire[MI_SCREEN(mi)]; - - /* default settings */ - fs->eject_r = 0.1 + NRAND(10) * 0.03; - fs->dt = 0.015; - fs->eject_vy = 4; - fs->eject_vl = 1; - fs->ridtri = 0.1 + NRAND(10) * 0.005; - fs->maxage = 1.0 / fs->dt; - vinit(fs->obs, DEF_OBS[0], DEF_OBS[1], DEF_OBS[2]); - fs->v = 0.0; - fs->alpha = DEF_ALPHA; - fs->beta = DEF_BETA; - - /* initialise texture stuff */ - if (do_texture) - inittextures(mi); - else - { - fs->ttexture = (XImage*) NULL; - fs->gtexture = (XImage*) NULL; - } - - if (MI_IS_DEBUG(mi)) { - (void) fprintf(stderr, - "%s:\n\tnum_part=%d\n\ttrees=%d\n\tfog=%s\n\tshadows=%s\n\teject_r=%.3f\n\tridtri=%.3f\n", - MI_NAME(mi), - fs->np, - fs->num_trees, - fs->fog ? "on" : "off", - fs->shadows ? "on" : "off", - fs->eject_r, fs->ridtri); - } - - /* initialise particles and trees */ - for (i = 0; i < fs->np; i++) { - setnewpart(fs, &(fs->p[i])); - } - - if (fs->num_trees) - if (!inittree(mi)) { - return False; - } - - /* if no fire particles then initialise rain particles */ - if (!fs->np) - { - vinit(fs->min,-7.0f,-0.2f,-7.0f); - vinit(fs->max,7.0f,8.0f,7.0f); - for (i = 0; i < NUMPART; i++) { - setnewrain(fs, &(fs->r[i])); - } - } - - return True; -} - -/* - *----------------------------------------------------------------------------- - *----------------------------------------------------------------------------- - * Xlock hooks. - *----------------------------------------------------------------------------- - *----------------------------------------------------------------------------- - */ - - -ENTRYPOINT void -free_fire(ModeInfo * mi) -{ - firestruct *fs = &fire[MI_SCREEN(mi)]; - - if (!fs->glx_context) return; - glXMakeCurrent (MI_DISPLAY(mi), MI_WINDOW(mi), *fs->glx_context); - - if (fs->p != NULL) { - free(fs->p); - fs->p = (part *) NULL; - } - if (fs->r != NULL) { - free(fs->r); - fs->r = (rain *) NULL; - } - if (fs->treepos != NULL) { - free(fs->treepos); - fs->treepos = (treestruct *) NULL; - } - if (fs->ttexture != None) { - glDeleteTextures(1, &fs->treeid); - XDestroyImage(fs->ttexture); - fs->ttexture = None; - } - if (fs->gtexture != None) { - glDeleteTextures(1, &fs->groundid); - XDestroyImage(fs->gtexture); - fs->gtexture = None; - } - - if (fs->trackball) gltrackball_free (fs->trackball); -} - -/* - *----------------------------------------------------------------------------- - * Initialize fire. Called each time the window changes. - *----------------------------------------------------------------------------- - */ - -ENTRYPOINT void -init_fire(ModeInfo * mi) -{ - firestruct *fs; - - MI_INIT (mi, fire); - fs = &fire[MI_SCREEN(mi)]; - fs->np = MI_COUNT(mi); - fs->fog = do_fog; - fs->shadows = do_shadows; - /* initialise fire particles if any */ - if ((fs->np)&&(fs->p == NULL)) { - if ((fs->p = (part *) calloc(fs->np, sizeof(part))) == NULL) { - free_fire(mi); - return; - } - } - else if (fs->r == NULL) { - /* initialise rain particles if no fire particles */ - if ((fs->r = (rain *) calloc(NUMPART, sizeof(part))) == NULL) { - free_fire(mi); - return; - } - } - - /* check tree number */ - if (do_texture) - fs->num_trees = (num_trees<MAX_TREES)?num_trees:MAX_TREES; - else - fs->num_trees = 0; - - fs->trackball = gltrackball_init (False); - - /* xlock GL stuff */ - if ((fs->glx_context = init_GL(mi)) != NULL) { - -#ifndef STANDALONE - Reshape(mi); /* xlock mode */ -#else - reshape_fire(mi,MI_WIDTH(mi),MI_HEIGHT(mi)); /* xscreensaver mode */ -#endif - glDrawBuffer(GL_BACK); - if (!Init(mi)) { - free_fire(mi); - return; - } - } else { - MI_CLEARWINDOW(mi); - } -} - -/* - *----------------------------------------------------------------------------- - * Called by the mainline code periodically to update the display. - *----------------------------------------------------------------------------- - */ -ENTRYPOINT void draw_fire(ModeInfo * mi) -{ - firestruct *fs = &fire[MI_SCREEN(mi)]; - - Display *display = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - - MI_IS_DRAWN(mi) = True; - - if (!fs->glx_context) - return; - - glXMakeCurrent(display, window, *fs->glx_context); - - glShadeModel(GL_FLAT); - glEnable(GL_DEPTH_TEST); - - /* makes particles blend with background */ - if (!MI_IS_WIREFRAME(mi)||(!fs->np)) - { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - - /* fog stuff */ - glEnable(GL_FOG); - glFogi(GL_FOG_MODE, GL_EXP); - glFogfv(GL_FOG_COLOR, fogcolor); - glFogf(GL_FOG_DENSITY, 0.03); - glHint(GL_FOG_HINT, GL_NICEST); - - glPushMatrix(); - glRotatef(current_device_rotation(), 0, 0, 1); - DrawFire(mi); - glPopMatrix(); -#ifndef STANDALONE - Reshape(mi); /* xlock mode */ -#else - reshape_fire(mi,MI_WIDTH(mi),MI_HEIGHT(mi)); /* xscreensaver mode */ -#endif - - glFinish(); - glXSwapBuffers(display, window); -} - - -/* - *----------------------------------------------------------------------------- - * The display is being taken away from us. Free up malloc'ed - * memory and X resources that we've alloc'ed. Only called - * once, we must zap everything for every screen. - *----------------------------------------------------------------------------- - */ - -ENTRYPOINT void release_fire(ModeInfo * mi) -{ - FreeAllGL(mi); -} - -ENTRYPOINT Bool -fire_handle_event (ModeInfo *mi, XEvent *event) -{ - firestruct *fs = &fire[MI_SCREEN(mi)]; - - if (gltrackball_event_handler (event, fs->trackball, - MI_WIDTH (mi), MI_HEIGHT (mi), - &fs->button_down_p)) - return True; - - return False; -} - - -#ifndef STANDALONE -ENTRYPOINT void change_fire(ModeInfo * mi) -{ - firestruct *fs = &fire[MI_SCREEN(mi)]; - - if (!fs->glx_context) - return; - - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *fs->glx_context); - - /* if available, randomly change some values */ - if (do_fog) - fs->fog = LRAND() & 1; - if (do_shadows) - fs->shadows = LRAND() & 1; - /* reset observer position */ - frame = 0; - vinit(fs->obs, DEF_OBS[0], DEF_OBS[1], DEF_OBS[2]); - fs->v = 0.0; - /* particle randomisation */ - fs->eject_r = 0.1 + NRAND(10) * 0.03; - fs->ridtri = 0.1 + NRAND(10) * 0.005; - - if (MI_IS_DEBUG(mi)) { - (void) fprintf(stderr, - "%s:\n\tnum_part=%d\n\ttrees=%d\n\tfog=%s\n\tshadows=%s\n\teject_r=%.3f\n\tridtri=%.3f\n", - MI_NAME(mi), - fs->np, - fs->num_trees, - fs->fog ? "on" : "off", - fs->shadows ? "on" : "off", - fs->eject_r, fs->ridtri); - } -} -#endif /* !STANDALONE */ - -XSCREENSAVER_MODULE_2 ("GLForestFire", glforestfire, fire) - -#endif /* MODE_fire */ |
