X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fglforestfire.c;h=3697b2e4b0b7148269ac32ba6a7e1625d0f74af6;hb=6afd6db0ae9396cd7ff897ade597cd5483f49b0e;hp=dee6a56670c86a7027c41cc82d8a555110af54ea;hpb=a94197e76a5dea5cb60542840809d6c20d0abbf3;p=xscreensaver diff --git a/hacks/glx/glforestfire.c b/hacks/glx/glforestfire.c index dee6a566..3697b2e4 100644 --- a/hacks/glx/glforestfire.c +++ b/hacks/glx/glforestfire.c @@ -1,7 +1,7 @@ /* -*- Mode: C; tab-width: 4 -*- */ /* fire --- 3D fire or rain landscape */ -#if !defined( lint ) && !defined( SABER ) +#if 0 static const char sccsid[] = "@(#)fire.c 5.02 2001/09/26 xlockmore"; #endif @@ -25,7 +25,7 @@ static const char sccsid[] = "@(#)fire.c 5.02 2001/09/26 xlockmore"; * 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) + * Eric Lassauge (October-10-2000) * http://lassauge.free.fr/linux.html * * REVISION HISTORY: @@ -75,25 +75,16 @@ static const char sccsid[] = "@(#)fire.c 5.02 2001/09/26 xlockmore"; #ifdef STANDALONE /* xscreensaver mode */ -#define PROGCLASS "Fire" -#define HACK_INIT init_fire -#define HACK_DRAW draw_fire -#define HACK_RESHAPE reshape_fire -#define fire_opts xlockmore_opts #define DEFAULTS "*delay: 10000 \n" \ "*count: 800 \n" \ "*size: 0 \n" \ - "*trees: 5 \n" \ "*showFPS: False \n" \ - "*trackmouse: False \n" \ - "*wander: True \n" \ "*wireframe: False \n" \ - "*fog: False \n" \ - "*shadows: True \n" \ - "*texture: True \n" +# define refresh_fire 0 #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" @@ -103,11 +94,7 @@ static const char sccsid[] = "@(#)fire.c 5.02 2001/09/26 xlockmore"; #define MINSIZE 32 -#include -#include -#include - -#if defined( USE_XPM ) || defined( USE_XPMINC ) || defined( HAVE_XPM ) +#if defined( USE_XPM ) || defined( USE_XPMINC ) || defined(STANDALONE) /* USE_XPM & USE_XPMINC in xlock mode ; HAVE_XPM in xscreensaver mode */ #include "xpm-ximage.h" #define I_HAVE_XPM @@ -166,53 +153,47 @@ static const char sccsid[] = "@(#)fire.c 5.02 2001/09/26 xlockmore"; #define DEF_FOG "False" #define DEF_SHADOWS "True" #define DEF_FRAMERATE "False" -#define DEF_TRACKMOUSE "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_trackmouse; static Bool do_wander; static int num_trees; -static int frame = 0; static XFontStruct *mode_font = None; static XrmOptionDescRec opts[] = { - {(char *) "-texture", (char *) ".fire.texture", XrmoptionNoArg, (caddr_t) "on"}, - {(char *) "+texture", (char *) ".fire.texture", XrmoptionNoArg, (caddr_t) "off"}, - {(char *) "-fog", (char *) ".fire.fog", XrmoptionNoArg, (caddr_t) "on"}, - {(char *) "+fog", (char *) ".fire.fog", XrmoptionNoArg, (caddr_t) "off"}, - {(char *) "-shadows", (char *) ".fire.shadows", XrmoptionNoArg, (caddr_t) "on"}, - {(char *) "+shadows", (char *) ".fire.shadows", XrmoptionNoArg, (caddr_t) "off"}, - {(char *) "-trackmouse", (char *) ".fire.trackmouse", XrmoptionNoArg, (caddr_t) "on"}, - {(char *) "+trackmouse", (char *) ".fire.trackmouse", XrmoptionNoArg, (caddr_t) "off"}, - {(char *) "-wander", (char *) ".fire.wander", XrmoptionNoArg, (caddr_t) "on"}, - {(char *) "+wander", (char *) ".fire.wander", XrmoptionNoArg, (caddr_t) "off"}, - {(char *) "-trees", (char *) ".fire.trees", XrmoptionSepArg, (caddr_t) NULL}, + {"-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[] = { - {(caddr_t *) & do_texture, (char *) "texture", (char *) "Texture", (char *) DEF_TEXTURE, t_Bool}, - {(caddr_t *) & do_fog, (char *) "fog", (char *) "Fog", (char *) DEF_FOG, t_Bool}, - {(caddr_t *) & do_shadows, (char *) "shadows", (char *) "Shadows", (char *) DEF_SHADOWS, t_Bool}, - {(caddr_t *) & do_trackmouse, (char *) "trackmouse", (char *) "TrackMouse", (char *) DEF_TRACKMOUSE, t_Bool}, - {(caddr_t *) & do_wander, (char *) "wander", (char *) "Wander", (char *) DEF_WANDER, t_Bool}, - {(caddr_t *) & num_trees, (char *) "trees", (char *) "Trees", (char *) DEF_TREES, t_Int}, + {&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[] = { - {(char *) "-/+texture", (char *) "turn on/off texturing"}, - {(char *) "-/+fog", (char *) "turn on/off fog"}, - {(char *) "-/+shadows", (char *) "turn on/off shadows"}, - {(char *) "-/+trackmouse", (char *) "turn on/off the tracking of the mouse"}, - {(char *) "-/+wander", (char *) "turn on/off wandering"}, - {(char *) "-trees num", (char *) "number of trees (0 disables)"}, + {"-/+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)"}, }; -ModeSpecOpt fire_opts = +ENTRYPOINT ModeSpecOpt fire_opts = { sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc }; #ifdef USE_MODULES @@ -256,13 +237,13 @@ typedef struct { } rain; /* colors */ -static float black[3] = { 0.0, 0.0, 0.0 }; /* shadow color */ -static float partcol1[3] = { 1.0, 0.2, 0.0 }; /* initial color: red-ish */ -static float partcol2[3] = { 1.0, 1.0, 0.0 }; /* blending color: yellow-ish */ -static float fogcolor[4] = { 0.9, 0.9, 1.0, 1.0 }; +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 float q[4][3] = { +static const float q[4][3] = { {-DIMP, 0.0, -DIMP}, {DIMP, 0.0, -DIMP}, {DIMP, 0.0, DIMP}, @@ -270,7 +251,7 @@ static float q[4][3] = { }; /* ground texture */ -static float qt[4][2] = { +static const float qt[4][2] = { {-DIMTP, -DIMTP}, {DIMTP, -DIMTP}, {DIMTP, DIMTP}, @@ -320,6 +301,11 @@ typedef struct { 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 */ @@ -338,8 +324,13 @@ 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=0; + static clock_t told= (clock_t)0; clock_t tnew,ris; tnew=clock(); @@ -348,9 +339,9 @@ static float gettimerain(void) told=tnew; - return (ris/(float)CLOCKS_PER_SEC); + return (0.0125 + ris/(float)CLOCKS_PER_SEC); #else - return 0; + return 0.0150; #endif } @@ -363,7 +354,8 @@ static float vrnd(void) /* initialise new fire particle */ static void setnewpart(firestruct * fs, part * p) { - float a, vi[3], *c; + float a, vi[3]; + const float *c; p->age = 0; @@ -474,8 +466,9 @@ static void setpartrain(firestruct * fs, rain * r, float dt) } /* draw a tree */ -static void drawtree(float x, float y, float z) +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); @@ -488,6 +481,7 @@ static void drawtree(float x, float y, float z) glTexCoord2f(0.0,1.0); glVertex3f(x-1.5,y+3.0,z); + polys++; glTexCoord2f(0.0,0.0); @@ -501,9 +495,11 @@ static void drawtree(float x, float y, float z) 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 */ @@ -525,44 +521,6 @@ static void calcposobs(firestruct * fs) } } -/* track the mouse in a joystick manner : not perfect but it works */ -static void trackmouse(ModeInfo * mi) -{ - firestruct *fs = &fire[MI_SCREEN(mi)]; - /* we keep static values (not per screen) for the mouse stuff: in general you have only one mouse :-> */ - static int max[2] = { 0, 0 }; - static int min[2] = { 0x7fffffff, 0x7fffffff }, center[2]; - Window r, c; - int rx, ry, cx, cy; - unsigned int m; - - (void) XQueryPointer(MI_DISPLAY(mi), MI_WINDOW(mi), - &r, &c, &rx, &ry, &cx, &cy, &m); - - if (max[0] < cx) - max[0] = cx; - if (min[0] > cx) - min[0] = cx; - center[0] = (max[0] + min[0]) / 2; - - if (max[1] < cy) - max[1] = cy; - if (min[1] > cy) - min[1] = cy; - center[1] = (max[1] + min[1]) / 2; - - if (fabs(center[0] - (float) cx) > 0.1 * (max[0] - min[0])) - fs->alpha += 2.5 * (center[0] - (float) cx) / (max[0] - min[0]); - if (fabs(center[1] - (float) cy) > 0.1 * (max[1] - min[1])) - fs->beta += 2.5 * (center[1] - (float) cy) / (max[1] - min[1]); - - /* oops: can't get those buttons */ - if (m & Button4Mask) - fs->v += 0.01; - if (m & Button5Mask) - fs->v -= 0.01; - -} /* initialise textures */ static void inittextures(ModeInfo * mi) @@ -590,8 +548,11 @@ static void inittextures(ModeInfo * mi) 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); + fs->gtexture->width, fs->gtexture->height, 0, + GL_RGBA, + /* GL_UNSIGNED_BYTE, */ + GL_UNSIGNED_INT_8_8_8_8_REV, + fs->gtexture->data); check_gl_error("texture"); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -619,8 +580,11 @@ static void inittextures(ModeInfo * mi) 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); + fs->ttexture->width, fs->ttexture->height, 0, + GL_RGBA, + /* GL_UNSIGNED_BYTE, */ + GL_UNSIGNED_INT_8_8_8_8_REV, + fs->ttexture->data); check_gl_error("texture"); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); @@ -675,11 +639,7 @@ static Bool inittree(ModeInfo * mi) *----------------------------------------------------------------------------- */ -#ifndef STANDALONE -static void Reshape(ModeInfo * mi) -#else -void reshape_fire(ModeInfo * mi, int width, int height) -#endif +ENTRYPOINT void reshape_fire(ModeInfo * mi, int width, int height) { firestruct *fs = &fire[MI_SCREEN(mi)]; @@ -711,20 +671,19 @@ static void DrawFire(ModeInfo * mi) firestruct *fs = &fire[MI_SCREEN(mi)]; Bool wire = MI_IS_WIREFRAME(mi); - if (do_trackmouse && !MI_IS_ICONIC(mi)) - trackmouse(mi); + mi->polygon_count = 0; - if (do_wander) + if (do_wander && !fs->button_down_p) { GLfloat x, y, z; # define SINOID(SCALE,SIZE) \ - ((((1 + sin((frame * (SCALE)) / 2 * M_PI)) / 2.0) * (SIZE)) - (SIZE)/2) + ((((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); - frame++; + fs->frame++; fs->obs[0] = x + DEF_OBS[0]; fs->obs[1] = y + DEF_OBS[1]; fs->obs[2] = z + DEF_OBS[2]; @@ -744,11 +703,16 @@ static void DrawFire(ModeInfo * mi) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); + calcposobs(fs); - 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); + 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); @@ -770,6 +734,7 @@ static void DrawFire(ModeInfo * mi) glVertex3fv(q[2]); glTexCoord2fv(qt[3]); glVertex3fv(q[3]); + mi->polygon_count++; glEnd(); glAlphaFunc(GL_GEQUAL, 0.9); @@ -781,7 +746,7 @@ static void DrawFire(ModeInfo * mi) glBindTexture(GL_TEXTURE_2D,fs->treeid); #endif /* HAVE_GLBINDTEXTURE */ for(j=0;jnum_trees;j++) - drawtree(fs->treepos[j].x ,fs->treepos[j].y ,fs->treepos[j].z ); + mi->polygon_count += drawtree(fs->treepos[j].x ,fs->treepos[j].y ,fs->treepos[j].z ); glDisable(GL_ALPHA_TEST); } glDisable(GL_TEXTURE_2D); @@ -799,6 +764,7 @@ static void DrawFire(ModeInfo * mi) 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(); } @@ -814,6 +780,7 @@ static void DrawFire(ModeInfo * mi) glColor4fv(fs->p[j].c[2]); glVertex3fv(fs->p[j].p[2]); + mi->polygon_count++; setpart(fs, &fs->p[j]); } @@ -832,6 +799,7 @@ static void DrawFire(ModeInfo * mi) 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); @@ -885,23 +853,6 @@ static Bool Init(ModeInfo * mi) fs->eject_r, fs->ridtri); } - 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); - /* initialise particles and trees */ for (i = 0; i < fs->np; i++) { setnewpart(fs, &(fs->p[i])); @@ -973,7 +924,7 @@ free_fire(firestruct *fs) *----------------------------------------------------------------------------- */ -void +ENTRYPOINT void init_fire(ModeInfo * mi) { firestruct *fs; @@ -1011,8 +962,7 @@ init_fire(ModeInfo * mi) else fs->num_trees = 0; - /* check wander/trackmouse */ - if (do_trackmouse && do_wander) do_wander = 0; + fs->trackball = gltrackball_init (False); /* xlock GL stuff */ if ((fs->glx_context = init_GL(mi)) != NULL) { @@ -1037,7 +987,7 @@ init_fire(ModeInfo * mi) * Called by the mainline code periodically to update the display. *----------------------------------------------------------------------------- */ -void draw_fire(ModeInfo * mi) +ENTRYPOINT void draw_fire(ModeInfo * mi) { firestruct *fs = &fire[MI_SCREEN(mi)]; @@ -1050,7 +1000,28 @@ void draw_fire(ModeInfo * mi) 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 @@ -1070,7 +1041,7 @@ void draw_fire(ModeInfo * mi) *----------------------------------------------------------------------------- */ -void release_fire(ModeInfo * mi) +ENTRYPOINT void release_fire(ModeInfo * mi) { if (fire != NULL) { int screen; @@ -1088,7 +1059,22 @@ void release_fire(ModeInfo * mi) FreeAllGL(mi); } -void change_fire(ModeInfo * 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)]; @@ -1121,4 +1107,8 @@ void change_fire(ModeInfo * mi) fs->eject_r, fs->ridtri); } } +#endif /* !STANDALONE */ + +XSCREENSAVER_MODULE_2 ("GLForestFire", glforestfire, fire) + #endif /* MODE_fire */