X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fboxed.c;h=ef7e051f792cf7224281aa4ffa6fb6dba14f3e07;hp=e875f0fa2a3a43d07e29956ae1efa5137e2e3ba7;hb=07faf451b99879183ed7e909e43a0e065be1ee7f;hpb=3f438031d610c7e15fd33876a879b97e290e05fb diff --git a/hacks/glx/boxed.c b/hacks/glx/boxed.c index e875f0fa..ef7e051f 100644 --- a/hacks/glx/boxed.c +++ b/hacks/glx/boxed.c @@ -1,4 +1,4 @@ -/* thebox --- 3D bouncing balls that explode */ +/* boxed --- 3D bouncing balls that explode */ #if 0 static const char sccsid[] = "@(#)boxed.c 0.9 01/09/26 xlockmore"; @@ -23,9 +23,11 @@ static const char sccsid[] = "@(#)boxed.c 0.9 01/09/26 xlockmore"; * as an OpenGL screensaver for the xscreensaver package. * Lots of hardcoded values still in place. Also, there are some * copy/paste leftovers from the gears hack. opts don't work. + * + * 2005: opts work. added options -balls, -ballsize, -explosion + * */ -#include #include "boxed.h" /* @@ -35,42 +37,54 @@ static const char sccsid[] = "@(#)boxed.c 0.9 01/09/26 xlockmore"; */ #ifdef STANDALONE -# define PROGCLASS "boxed" -# define HACK_INIT init_boxed -# define HACK_DRAW draw_boxed -# define HACK_RESHAPE reshape_boxed -# define boxed_opts xlockmore_opts - -# define DEF_SPEED "0.5" # define DEFAULTS "*delay: 20000 \n" \ "*showFPS: False \n" \ "*wireframe: False \n" +# define refresh_boxed 0 +# define boxed_handle_event 0 # include "xlockmore.h" /* from the xscreensaver distribution */ #else /* !STANDALONE */ # include "xlock.h" /* from the xlockmore distribution */ #endif /* !STANDALONE */ #ifdef USE_GL -#include + +# define DEF_SPEED "0.5" +# define DEF_BALLS "25" +# define DEF_BALLSIZE "2.0" +# define DEF_EXPLOSION "15.0" +# define DEF_DECAY "0.1" #undef countof #define countof(x) (int)(sizeof((x))/sizeof((*x))) #undef rnd #define rnd() (frand(1.0)) -GLfloat speed; /* jwz -- overall speed factor applied to all motion */ +static GLfloat speed; /* jwz -- overall speed factor applied to all motion */ +static int cfg_balls; +static GLfloat cfg_ballsize; +static GLfloat cfg_explosion; +static GLfloat cfg_decay; static XrmOptionDescRec opts[] = { {"-speed", ".boxed.speed", XrmoptionSepArg, 0}, + {"-balls", ".boxed.balls", XrmoptionSepArg, 0}, + {"-ballsize", ".boxed.ballsize", XrmoptionSepArg, 0}, + {"-explosion", ".boxed.explosion", XrmoptionSepArg, 0}, + {"-decay", ".boxed.decay", XrmoptionSepArg, 0}, }; static argtype vars[] = { {&speed, "speed", "Speed", DEF_SPEED, t_Float}, + {&cfg_balls, "balls", "Balls", DEF_BALLS, t_Int}, + {&cfg_ballsize, "ballsize", "Ball Size", DEF_BALLSIZE, t_Float}, + {&cfg_explosion, "explosion", "Explosion", DEF_EXPLOSION, t_Float}, + {&cfg_decay, "decay", "Explosion Decay", DEF_DECAY, t_Float}, }; -ModeSpecOpt boxed_opts = {countof(opts), opts, countof(vars), vars, NULL}; +ENTRYPOINT ModeSpecOpt boxed_opts = {countof(opts), opts, countof(vars), vars, NULL}; #ifdef USE_MODULES @@ -86,12 +100,6 @@ ModStruct boxed_description = { #define TRUE 1 #define FALSE 0 -/* rendering defines */ - - -/* box size */ -#define BOX_SIZE 20.0f - /* camera */ #define CAM_HEIGHT 100.0f #define CAMDISTANCE_MIN 20.0 @@ -103,11 +111,6 @@ ModStruct boxed_description = { #define SPHERE_VERTICES (2+MESH_SIZE*MESH_SIZE*2) #define SPHERE_INDICES ((MESH_SIZE*4 + MESH_SIZE*4*(MESH_SIZE-1))*3) -#define EXPLOSION 10.0f -#define MAXBALLS 50; -#define NUMBALLS 12; -#define BALLSIZE 3.0f; - /* **----------------------------------------------------------------------------- ** Typedefs @@ -141,6 +144,7 @@ typedef struct { vectorf loc; vectorf dir; BOOL far; + BOOL gone; } tri; typedef struct { @@ -148,6 +152,7 @@ typedef struct { int lifetime; float scalefac; float explosion; + float decay; vectorf color; tri *tris; GLint *indices; @@ -159,6 +164,7 @@ typedef struct { int numballs; float ballsize; float explosion; + float decay; BOOL textures; BOOL transparent; float camspeed; @@ -169,6 +175,7 @@ typedef struct { float cam_x_speed, cam_z_speed, cam_y_speed; boxed_config config; float tic; + float camtic; vectorf spherev[SPHERE_VERTICES]; GLint spherei[SPHERE_INDICES]; ballman bman; @@ -261,7 +268,7 @@ squaremagnitude(vectorf * v) * Input: */ -static void generatesphere(void) +static void generatesphere(boxedstruct *gp) { float dj = M_PI/(MESH_SIZE+1.0f); float di = M_PI/MESH_SIZE; @@ -277,8 +284,8 @@ static void generatesphere(void) * vertices 0 and 1 are the north and south poles */ - spherei = boxed->spherei; - spherev = boxed->spherev; + spherei = gp->spherei; + spherev = gp->spherev; spherev[0].x = 0.0f; spherev[0].y =1.0f; spherev[0].z = 0.0f; spherev[1].x = 0.0f; spherev[1].y =-1.0f; spherev[1].z = 0.0f; @@ -341,7 +348,7 @@ static void generatesphere(void) * create fresh ball */ -void createball(ball *newball) +static void createball(ball *newball) { float r=0.0f,g=0.0f,b=0.0f; newball->loc.x = 5-10*rnd(); @@ -352,8 +359,8 @@ void createball(ball *newball) newball->dir.z = (0.5-rnd()) * speed; newball->offside = 0; newball->bounced = FALSE; - newball->radius = BALLSIZE; - while (r+g+b < 1.7f ) { + newball->radius = cfg_ballsize; + while (r+g+b < 1.8f ) { newball->color.x = r=rnd(); newball->color.y = g=rnd(); newball->color.z = b=rnd(); @@ -363,7 +370,7 @@ void createball(ball *newball) /* Update position of each ball */ -void updateballs(ballman *bman) +static void updateballs(ballman *bman) { register int b,j; vectorf dvect,richting,relspeed,influence; @@ -371,7 +378,7 @@ void updateballs(ballman *bman) for (b=0;bnum_balls;b++) { - GLfloat gravity = 0.15f * speed; + GLfloat gravity = 0.30f * speed; /* apply gravity */ bman->balls[b].dir.y -= gravity; @@ -379,10 +386,10 @@ void updateballs(ballman *bman) addvectors(&bman->balls[b].loc,&bman->balls[b].loc,&bman->balls[b].dir); /* boundary check */ if (bman->balls[b].loc.y < bman->balls[b].radius) { /* ball onder bodem? (bodem @ y=0) */ - if ((bman->balls[b].loc.x < -100.0) || - (bman->balls[b].loc.x > 100.0) || - (bman->balls[b].loc.z < -100.0) || - (bman->balls[b].loc.z > 100.0)) { + if ((bman->balls[b].loc.x < -95.0) || + (bman->balls[b].loc.x > 95.0) || + (bman->balls[b].loc.z < -95.0) || + (bman->balls[b].loc.z > 95.0)) { if (bman->balls[b].loc.y < -1000.0) createball(&bman->balls[b]); } else { @@ -460,7 +467,7 @@ void updateballs(ballman *bman) * explode ball into triangles */ -void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, int ind_num, ball *b) +static void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, int ind_num, ball *b) { int pos; float explosion; @@ -482,6 +489,7 @@ void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, int ind_ for (i=0; i<(tman->num_tri); i++) { tman->tris[i].far = FALSE; + tman->tris[i].gone = FALSE; pos = i * 3; /* kopieer elke poly apart naar een tri structure */ copyvector(&tman->vertices[pos+0],&spherev[spherei[pos+0]]); @@ -513,6 +521,16 @@ void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, int ind_ scalevector(&tman->vertices[pos+1],&tman->vertices[pos+1],scale); scalevector(&tman->vertices[pos+2],&tman->vertices[pos+2],scale); + tman->vertices[pos+0].x += avgdir.x; + tman->vertices[pos+0].y += avgdir.y; + tman->vertices[pos+0].z += avgdir.z; + tman->vertices[pos+1].x += avgdir.x; + tman->vertices[pos+1].y += avgdir.y; + tman->vertices[pos+1].z += avgdir.z; + tman->vertices[pos+2].x += avgdir.x; + tman->vertices[pos+2].y += avgdir.y; + tman->vertices[pos+2].z += avgdir.z; + /* bereken nieuwe richting */ scalevector(&tman->tris[i].dir,&avgdir,explosion); dvect.x = (0.1f - 0.2f*rnd()); @@ -527,12 +545,14 @@ void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, int ind_ * update position of each tri */ -void updatetris(triman *t) +static void updatetris(triman *t) { int b; GLfloat xd,zd; for (b=0;bnum_tri;b++) { + /* the exploded triangles disappear over time */ + if (rnd() < t->decay) { t->tris[b].gone = TRUE; } /* apply gravity */ t->tris[b].dir.y -= (0.1f * speed); /* apply movement */ @@ -540,10 +560,10 @@ void updatetris(triman *t) /* boundary check */ if (t->tris[b].far) continue; if (t->tris[b].loc.y < 0) { /* onder bodem ? */ - if ((t->tris[b].loc.x > -100.0f) & - (t->tris[b].loc.x < 100.0f) & - (t->tris[b].loc.z > -100.0f) & - (t->tris[b].loc.z < 100.0f)) { /* in veld */ + if ((t->tris[b].loc.x > -95.0f) & + (t->tris[b].loc.x < 95.0f) & + (t->tris[b].loc.z > -95.0f) & + (t->tris[b].loc.z < 95.0f)) { /* in veld */ t->tris[b].dir.y = -(t->tris[b].dir.y); t->tris[b].loc.y = -t->tris[b].loc.y; scalevector(&t->tris[b].dir,&t->tris[b].dir,0.80f); /* dampening */ @@ -600,7 +620,7 @@ void updatetris(triman *t) /* * free memory allocated by a tri manager */ -void freetris(triman *t) +static void freetris(triman *t) { if (!t) return; if (t->tris) free(t->tris); @@ -617,13 +637,19 @@ void freetris(triman *t) /* *load defaults in config structure */ -void setdefaultconfig(boxed_config *config) +static void setdefaultconfig(boxed_config *config) { - config->numballs = NUMBALLS; + cfg_balls = MAX(3,MIN(40,cfg_balls)); + cfg_ballsize = MAX(1.0f,MIN(5.0f,cfg_ballsize)); + cfg_explosion = MAX(0.0f,MIN(50.0f,cfg_explosion)); + cfg_decay = MAX(0.0f,MIN(1.0f,cfg_decay)); + + config->numballs = cfg_balls; config->textures = TRUE; config->transparent = FALSE; - config->explosion = 25.0f; - config->ballsize = BALLSIZE; + config->explosion = cfg_explosion; + config->decay = cfg_decay; + config->ballsize = cfg_ballsize; config->camspeed = 35.0f; } @@ -802,6 +828,7 @@ static void drawtriman(triman *t, int wire) glMaterialfv(GL_FRONT, GL_EMISSION,col); for (i=0; inum_tri; i++) { + if (t->tris[i].gone == TRUE) { continue; } pos = i*3; glPushMatrix(); glTranslatef(t->tris[i].loc.x,t->tris[i].loc.y,t->tris[i].loc.z); @@ -819,10 +846,10 @@ static void drawtriman(triman *t, int wire) /* * draw floor pattern */ -static void drawpattern(boxedstruct *boxed) +static void drawpattern(boxedstruct *gp) { - if (!boxed->gllists[GLL_PATTERN]) { - glNewList(boxed->listobjects + GLL_PATTERN, GL_COMPILE); + if (!gp->gllists[GLL_PATTERN]) { + glNewList(gp->listobjects + GLL_PATTERN, GL_COMPILE); glBegin(GL_LINE_STRIP); glVertex3f(-25.0f, 0.0f, 35.0f); @@ -865,9 +892,9 @@ static void drawpattern(boxedstruct *boxed) glEnd(); glEndList(); - boxed->gllists[GLL_PATTERN] = 1; + gp->gllists[GLL_PATTERN] = 1; } else { - glCallList(boxed->listobjects + GLL_PATTERN); + glCallList(gp->listobjects + GLL_PATTERN); } } @@ -902,12 +929,13 @@ static void draw(ModeInfo * mi) glLoadIdentity(); gp->tic += 0.01f; - + gp->camtic += 0.01f + 0.01f * sin(gp->tic * speed); + /* rotate camera around (0,0,0), looking at (0,0,0), up is (0,1,0) */ - dcam = CAMDISTANCE_MIN + (CAMDISTANCE_MAX - CAMDISTANCE_MIN) + (CAMDISTANCE_MAX - CAMDISTANCE_MIN)*cos((gp->tic/CAMDISTANCE_SPEED) * speed); - v1.x = dcam * sin((gp->tic/gp->cam_x_speed) * speed); - v1.z = dcam * cos((gp->tic/gp->cam_z_speed) * speed); - v1.y = CAM_HEIGHT * sin((gp->tic/gp->cam_y_speed) * speed) + 1.02 * CAM_HEIGHT; + dcam = CAMDISTANCE_MIN + (CAMDISTANCE_MAX - CAMDISTANCE_MIN) + (CAMDISTANCE_MAX - CAMDISTANCE_MIN)*cos((gp->camtic/CAMDISTANCE_SPEED) * speed); + v1.x = dcam * sin((gp->camtic/gp->cam_x_speed) * speed); + v1.z = dcam * cos((gp->camtic/gp->cam_z_speed) * speed); + v1.y = CAM_HEIGHT * sin((gp->camtic/gp->cam_y_speed) * speed) + 1.02 * CAM_HEIGHT; gluLookAt(v1.x,v1.y,v1.z,0.0,0.0,0.0,0.0,1.0,0.0); if (!wire) { @@ -1022,7 +1050,7 @@ static void draw(ModeInfo * mi) /* * new window size or exposure */ -void reshape_boxed(ModeInfo *mi, int width, int height) +ENTRYPOINT void reshape_boxed(ModeInfo *mi, int width, int height) { GLfloat h = (GLfloat) height / (GLfloat) width; @@ -1067,6 +1095,7 @@ pinit(ModeInfo * mi) for(i=0;inum_balls;i++) { gp->tman[i].explosion = (float) (((int)gp->config.explosion) / 15.0f ); + gp->tman[i].decay = gp->config.decay; gp->tman[i].vertices = NULL; gp->tman[i].normals = NULL; gp->tman[i].tris = NULL; @@ -1074,7 +1103,7 @@ pinit(ModeInfo * mi) bman->balls[i].loc.y *= rnd(); } - generatesphere(); + generatesphere(gp); if (!wire) { glEnable(GL_CULL_FACE); @@ -1087,8 +1116,11 @@ pinit(ModeInfo * mi) gp->cam_y_speed = 1.0f/((float)gp->config.camspeed/250.0 + rnd()*((float)gp->config.camspeed/250.0)); if (rnd() < 0.5f) gp->cam_x_speed = -gp->cam_x_speed; if (rnd() < 0.5f) gp->cam_z_speed = -gp->cam_z_speed; + + /* define initial cam position */ + gp->tic = gp->camtic = rnd() * 100.0f; - + /* define tex1 (bottom plate) */ gp->tex1 = (char *)malloc(3*width*height*sizeof(GLuint)); texpixels = 256*256; /*width*height;*/ texpixeldata = header_data; @@ -1123,7 +1155,7 @@ pinit(ModeInfo * mi) -void +ENTRYPOINT void init_boxed(ModeInfo * mi) { int screen = MI_SCREEN(mi); @@ -1154,7 +1186,7 @@ init_boxed(ModeInfo * mi) } -void +ENTRYPOINT void draw_boxed(ModeInfo * mi) { boxedstruct *gp = &boxed[MI_SCREEN(mi)]; @@ -1174,7 +1206,7 @@ draw_boxed(ModeInfo * mi) glXSwapBuffers(display, window); } -void +ENTRYPOINT void release_boxed(ModeInfo * mi) { int i; @@ -1209,6 +1241,8 @@ release_boxed(ModeInfo * mi) } +XSCREENSAVER_MODULE ("Boxed", boxed) + /*********************************************************/ #endif