X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fboxed.c;h=42f68c1c1970ffc4d86f1785063465f2c421dd94;hp=30d5f6f872b58231e524b2cab4294e8851bc3e82;hb=6b1c86cf395f59389e4ece4ea8f4bea2c332745b;hpb=cccbddbc4140cf9a06d7d95cc5c0ca36eb5d6e28 diff --git a/hacks/glx/boxed.c b/hacks/glx/boxed.c index 30d5f6f8..42f68c1c 100644 --- a/hacks/glx/boxed.c +++ b/hacks/glx/boxed.c @@ -1,8 +1,7 @@ -/* thebox --- 3D bouncing balls that explode */ +/* boxed --- 3D bouncing balls that explode */ -#if !defined( lint ) && !defined( SABER ) +#if 0 static const char sccsid[] = "@(#)boxed.c 0.9 01/09/26 xlockmore"; - #endif /*- @@ -24,9 +23,15 @@ 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 + * + * 2006: opts work. added option -decay + * + * 2008: opts work. added option -momentum + * */ -#include #include "boxed.h" /* @@ -36,44 +41,58 @@ 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 DEFAULTS "*delay: 20000 \n" \ - "*showFPS: False \n" \ - -# include "xlockmore.h" /* from the xscreensaver distribution */ +# 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 */ +# 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.07" +# define DEF_MOMENTUM "0.6" #undef countof #define countof(x) (int)(sizeof((x))/sizeof((*x))) #undef rnd -#define rnd() ( ((float)random()) / ((float)RAND_MAX * 2.0) ) +#define rnd() (frand(1.0)) -/* #define DEF_PLANETARY "False" +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 GLfloat cfg_momentum; -static int planetary; static XrmOptionDescRec opts[] = { - {"-planetary", ".gears.planetary", XrmoptionNoArg, (caddr_t) "true" }, - {"+planetary", ".gears.planetary", XrmoptionNoArg, (caddr_t) "false" }, + {"-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}, + {"-momentum", ".boxed.momentum", XrmoptionSepArg, 0}, }; static argtype vars[] = { - {(caddr_t *) &planetary, "planetary", "Planetary", DEF_PLANETARY, t_Bool}, + {&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}, + {&cfg_momentum, "momentum", "Explosion Momentum", DEF_MOMENTUM, t_Float}, }; -*/ - -/* ModeSpecOpts boxed_opts = {countof(opts), opts, countof(vars), vars, NULL}; */ -ModeSpecOpt boxed_opts = {0, NULL, 0, NULL, NULL}; +ENTRYPOINT ModeSpecOpt boxed_opts = {countof(opts), opts, countof(vars), vars, NULL}; #ifdef USE_MODULES @@ -89,11 +108,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 @@ -101,15 +115,10 @@ ModStruct boxed_description = { #define CAMDISTANCE_SPEED 1.5 /* rendering the sphere */ -#define MESH_SIZE 5 +#define MESH_SIZE 10 #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 @@ -143,6 +152,7 @@ typedef struct { vectorf loc; vectorf dir; BOOL far; + BOOL gone; } tri; typedef struct { @@ -150,6 +160,8 @@ typedef struct { int lifetime; float scalefac; float explosion; + float decay; + float momentum; vectorf color; tri *tris; GLint *indices; @@ -161,6 +173,8 @@ typedef struct { int numballs; float ballsize; float explosion; + float decay; + float momentum; BOOL textures; BOOL transparent; float camspeed; @@ -171,21 +185,22 @@ 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; triman *tman; GLXContext *glx_context; - GLint listobjects; - GLint gllists[3]; + GLuint listobjects; + GLuint gllists[3]; Window window; BOOL stop; char *tex1; } boxedstruct; -#define GLL_PATTERN 1 -#define GLL_BALL 2 -#define GLL_BOX 3 +#define GLL_PATTERN 0 +#define GLL_BALL 1 +#define GLL_BOX 2 /* **---------------------------------------------------------------------------- @@ -255,6 +270,12 @@ squaremagnitude(vectorf * v) return v->x * v->x + v->y * v->y + v->z * v->z; } +static inline GLfloat +squaremagnitudehorz(vectorf * v) +{ + return v->x * v->x + v->z * v->z; +} + /* @@ -263,7 +284,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; @@ -279,8 +300,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; @@ -343,18 +364,19 @@ 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(); newball->loc.y = 35+20*rnd(); newball->loc.z = 5-10*rnd(); - newball->dir.x = 0.5f-rnd(); + newball->dir.x = (0.5f-rnd()) * speed; newball->dir.y = 0.0; - newball->dir.z = 0.5-rnd(); + 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(); @@ -364,23 +386,26 @@ 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; GLfloat squaredist; for (b=0;bnum_balls;b++) { + GLfloat gravity = 0.30f * speed; + /* apply gravity */ - bman->balls[b].dir.y -= 0.15f; + bman->balls[b].dir.y -= gravity; /* apply movement */ 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 { @@ -391,7 +416,10 @@ void updateballs(ballman *bman) { scalevector(&bman->balls[b].dir,&bman->balls[b].dir,0.80f); if (squaremagnitude(&bman->balls[b].dir) < 0.08f) { createball(&bman->balls[b]); - } + } + if (squaremagnitudehorz(&bman->balls[b].dir) < 0.005f) { + createball(&bman->balls[b]); + } } } @@ -458,16 +486,19 @@ 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; + float momentum; float scale; register int i; - vectorf avgdir,dvect; + vectorf avgdir,dvect,mvect; tman->scalefac = b->radius; copyvector(&tman->color,&b->color); explosion = 1.0f + tman->explosion * 2.0 * rnd(); + momentum = tman->momentum; tman->num_tri = ind_num/3; @@ -479,6 +510,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]]); @@ -510,12 +542,28 @@ 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(); - dvect.y = 0.15f - 0.3f*rnd(); - dvect.z = 0.1f - 0.2f*rnd(); + dvect.x = (0.1f - 0.2f*rnd()); + dvect.y = (0.15f - 0.3f*rnd()); + dvect.z = (0.1f - 0.2f*rnd()); addvectors(&tman->tris[i].dir,&tman->tris[i].dir,&dvect); + + /* add ball's momentum to each piece of the exploded ball */ + mvect.x = b->dir.x * momentum; + mvect.y = 0; + mvect.z = b->dir.z * momentum; + addvectors(&tman->tris[i].dir,&tman->tris[i].dir,&mvect); } } @@ -524,24 +572,28 @@ 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; + t->tris[b].dir.y -= (0.1f * speed); /* apply movement */ addvectors(&t->tris[b].loc,&t->tris[b].loc,&t->tris[b].dir); /* 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.75f); /* dampening */ + scalevector(&t->tris[b].dir,&t->tris[b].dir,0.80f); /* dampening */ } else { t->tris[b].far = TRUE; @@ -549,33 +601,44 @@ void updatetris(triman *t) { } } - /* this should be replaced with code that determines - * the correct wall the tri bounces in to. this code sucks. - */ - if ((t->tris[b].loc.x > -21.0f) & + if ((t->tris[b].loc.x > -21.0f) & (t->tris[b].loc.x < 21.0f) & (t->tris[b].loc.z > -21.0f) & (t->tris[b].loc.z < 21.0f)) { /* in box? */ + + xd = zd = 999.0f; /* big */ if ((t->tris[b].loc.x > -21.0f) & (t->tris[b].loc.x < 0)) { - t->tris[b].loc.x = -21.0f; - t->tris[b].dir.x = -t->tris[b].dir.x; + xd = t->tris[b].loc.x + 21.0f; } if ((t->tris[b].loc.x < 21.0f) & (t->tris[b].loc.x > 0)) { - t->tris[b].loc.x = 21.0f; - t->tris[b].dir.x = -t->tris[b].dir.x; + xd = 21.0f - t->tris[b].loc.x; } if ((t->tris[b].loc.z > -21.0f) & (t->tris[b].loc.z < 0)) { - t->tris[b].loc.z = -21.0f; - t->tris[b].dir.z = -t->tris[b].dir.z; + zd = t->tris[b].loc.z + 21.0f; } if ((t->tris[b].loc.z < 21.0f) & (t->tris[b].loc.z > 0)) { - t->tris[b].loc.z = 21.0f; - t->tris[b].dir.z = -t->tris[b].dir.z; + zd = 21.0f - t->tris[b].loc.z; } + if (xd < zd) { + /* bounce x */ + if (t->tris[b].dir.x < 0) + t->tris[b].loc.x += (21.0f - t->tris[b].loc.x); + else + t->tris[b].loc.x += (-21.0f - t->tris[b].loc.x); + t->tris[b].dir.x = -t->tris[b].dir.x; + } else { + /* bounce z */ + if (t->tris[b].dir.z < 0) + t->tris[b].loc.z += (21.0f - t->tris[b].loc.z); + else + t->tris[b].loc.z += (-21.0f - t->tris[b].loc.z); + t->tris[b].dir.z = -t->tris[b].dir.z; + } + } } /* end for b */ } @@ -584,7 +647,8 @@ 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); if (t->vertices) free(t->vertices); @@ -600,12 +664,21 @@ void freetris(triman *t) { /* *load defaults in config structure */ -void setdefaultconfig(boxed_config *config) { - config->numballs = NUMBALLS; +static void setdefaultconfig(boxed_config *config) +{ + 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)); + cfg_momentum = MAX(0.0f,MIN(1.0f,cfg_momentum)); + + 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->momentum = cfg_momentum; + config->ballsize = cfg_ballsize; config->camspeed = 35.0f; } @@ -613,7 +686,7 @@ void setdefaultconfig(boxed_config *config) { /* * draw bottom */ -static void drawfilledbox(boxedstruct *boxed) +static void drawfilledbox(boxedstruct *boxed, int wire) { /* draws texture filled box, top is drawn using the entire texture, @@ -621,7 +694,7 @@ static void drawfilledbox(boxedstruct *boxed) */ /* front */ - glBegin(GL_QUADS); + glBegin(wire ? GL_LINE_LOOP : GL_QUADS); glTexCoord2f(0,1); glVertex3f(-1.0,1.0,1.0); glTexCoord2f(1,1); @@ -718,7 +791,7 @@ static void drawbox(boxedstruct *boxed) /* * Draw ball */ -static void drawball(boxedstruct *gp, ball *b) +static void drawball(boxedstruct *gp, ball *b, int wire) { int i,pos,cnt; GLint *spherei = gp->spherei; @@ -740,11 +813,11 @@ static void drawball(boxedstruct *gp, ball *b) glMaterialfv(GL_FRONT, GL_EMISSION,col); if (!gp->gllists[GLL_BALL]) { - glNewList(gp->listobjects + GLL_BALL,GL_COMPILE_AND_EXECUTE); + glNewList(gp->listobjects + GLL_BALL,GL_COMPILE); cnt = SPHERE_INDICES/3; for (i=0; ivertices; @@ -784,10 +857,11 @@ static void drawtriman(triman *t) 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); - glBegin(GL_TRIANGLES); + glBegin(wire ? GL_LINE_LOOP : GL_TRIANGLES); glNormal3f(t->normals[i].x,t->normals[i].y,t->normals[i].z); glVertex3f(spherev[pos+0].x,spherev[pos+0].y,spherev[pos+0].z); glVertex3f(spherev[pos+1].x,spherev[pos+1].y,spherev[pos+1].z); @@ -801,11 +875,11 @@ static void drawtriman(triman *t) /* * 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_AND_EXECUTE); - + if (!gp->gllists[GLL_PATTERN]) { + glNewList(gp->listobjects + GLL_PATTERN, GL_COMPILE); + glBegin(GL_LINE_STRIP); glVertex3f(-25.0f, 0.0f, 35.0f); glVertex3f(-15.0f, 0.0f, 35.0f); @@ -845,11 +919,13 @@ static void drawpattern(boxedstruct *boxed) glVertex3f(-15.0f, 0.0f, 5.0f); glVertex3f(-5.0f, 0.0f, 15.0f); glEnd(); + glEndList(); - boxed->gllists[GLL_PATTERN] = 1; + gp->gllists[GLL_PATTERN] = 1; } else { - glCallList(boxed->listobjects + GLL_PATTERN); + glCallList(gp->listobjects + GLL_PATTERN); } + } @@ -859,6 +935,7 @@ static void drawpattern(boxedstruct *boxed) static void draw(ModeInfo * mi) { boxedstruct *gp = &boxed[MI_SCREEN(mi)]; + int wire = MI_IS_WIREFRAME (mi); vectorf v1; GLfloat dcam; int dx, dz; @@ -881,31 +958,34 @@ 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); - v1.x = dcam * sin(gp->tic/gp->cam_x_speed); - v1.z = dcam * cos(gp->tic/gp->cam_z_speed); - v1.y = CAM_HEIGHT * sin(gp->tic/gp->cam_y_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); - glLightfv(GL_LIGHT0, GL_AMBIENT, l0_ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, l0_diffuse); - glLightfv(GL_LIGHT0, GL_SPECULAR, l0_specular); - glLightfv(GL_LIGHT0, GL_POSITION, l0_position); - glLightfv(GL_LIGHT1, GL_AMBIENT, l1_ambient); - glLightfv(GL_LIGHT1, GL_DIFFUSE, l1_diffuse); - glLightfv(GL_LIGHT1, GL_SPECULAR, l1_specular); - glLightfv(GL_LIGHT1, GL_POSITION, l1_position); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); + if (!wire) { + glLightfv(GL_LIGHT0, GL_AMBIENT, l0_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, l0_diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, l0_specular); + glLightfv(GL_LIGHT0, GL_POSITION, l0_position); + glLightfv(GL_LIGHT1, GL_AMBIENT, l1_ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, l1_diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, l1_specular); + glLightfv(GL_LIGHT1, GL_POSITION, l1_position); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); - glFrontFace(GL_CW); + glFrontFace(GL_CW); - glMaterialfv(GL_FRONT, GL_SPECULAR, black); - glMaterialfv(GL_FRONT, GL_EMISSION, lblue); - glMaterialfv(GL_FRONT,GL_AMBIENT,black); - glMaterialf(GL_FRONT, GL_SHININESS, 5.0); + glMaterialfv(GL_FRONT, GL_SPECULAR, black); + glMaterialfv(GL_FRONT, GL_EMISSION, lblue); + glMaterialfv(GL_FRONT,GL_AMBIENT,black); + glMaterialf(GL_FRONT, GL_SHININESS, 5.0); + } /* draw ground grid */ @@ -924,12 +1004,12 @@ static void draw(ModeInfo * mi) /* Set drawing mode for the boxes */ glEnable(GL_DEPTH_TEST); - glEnable(GL_TEXTURE_2D); + if (!wire) glEnable(GL_TEXTURE_2D); glPushMatrix(); glColor3f(1.0,1.0,1.0); glScalef(20.0,0.25,20.0); glTranslatef(0.0,2.0,0.0); - drawfilledbox(gp); + drawfilledbox(gp, wire); glPopMatrix(); glDisable(GL_TEXTURE_2D); @@ -961,10 +1041,12 @@ static void draw(ModeInfo * mi) drawbox(gp); glPopMatrix(); - glEnable(GL_LIGHTING); + if (!wire) { + glEnable(GL_LIGHTING); - glMaterialfv(GL_FRONT, GL_DIFFUSE, dgray); - glMaterialfv(GL_FRONT, GL_EMISSION, black); /* turn it off before painting the balls */ + glMaterialfv(GL_FRONT, GL_DIFFUSE, dgray); + glMaterialfv(GL_FRONT, GL_EMISSION, black); /* turn it off before painting the balls */ + } /* move the balls and shrapnel */ updateballs(&gp->bman); @@ -975,16 +1057,17 @@ static void draw(ModeInfo * mi) gp->bman.balls[i].justcreated = FALSE; freetris(&gp->tman[i]); } - if ((gp->bman.balls[i].bounced) & (gp->tman[i].vertices == NULL)) { - createtrisfromball(&gp->tman[i],gp->spherev,gp->spherei,SPHERE_INDICES,&gp->bman.balls[i]); - } - if (gp->bman.balls[i].bounced) { - updatetris(&gp->tman[i]); + if (gp->bman.balls[i].bounced) { + if (gp->tman[i].vertices == NULL) { + createtrisfromball(&gp->tman[i],gp->spherev,gp->spherei,SPHERE_INDICES,&gp->bman.balls[i]); + } else { + updatetris(&gp->tman[i]); + } glDisable(GL_CULL_FACE); - drawtriman(&gp->tman[i]); - glEnable(GL_CULL_FACE); + drawtriman(&gp->tman[i], wire); + if (!wire) glEnable(GL_CULL_FACE); } else { - drawball(gp, &gp->bman.balls[i]); + drawball(gp, &gp->bman.balls[i], wire); } } @@ -996,7 +1079,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; @@ -1015,6 +1098,7 @@ static void pinit(ModeInfo * mi) { boxedstruct *gp = &boxed[MI_SCREEN(mi)]; + int wire = MI_IS_WIREFRAME (mi); ballman *bman; int i,texpixels; char *texpixeldata; @@ -1027,6 +1111,10 @@ pinit(ModeInfo * mi) /* Load configuration */ setdefaultconfig(&gp->config); + + /* give the decay parameter a better curve */ + if (gp->config.decay <= 0.8182) { gp->config.decay = gp->config.decay / 3; } + else { gp->config.decay = (gp->config.decay - 0.75) * 4; } bman = &gp->bman; @@ -1040,6 +1128,8 @@ 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].momentum = gp->config.momentum; gp->tman[i].vertices = NULL; gp->tman[i].normals = NULL; gp->tman[i].tris = NULL; @@ -1047,10 +1137,12 @@ pinit(ModeInfo * mi) bman->balls[i].loc.y *= rnd(); } - generatesphere(); + generatesphere(gp); - glEnable(GL_CULL_FACE); - glEnable(GL_LIGHTING); + if (!wire) { + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + } /* define cam path */ gp->cam_x_speed = 1.0f/((float)gp->config.camspeed/50.0 + rnd()*((float)gp->config.camspeed/50.0)); @@ -1058,8 +1150,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; @@ -1077,7 +1172,7 @@ pinit(ModeInfo * mi) GL_RGB, GL_UNSIGNED_BYTE, gp->tex1); if (i) { - const char *s = gluErrorString (i); + const char *s = (char *) gluErrorString (i); fprintf (stderr, "%s: error mipmapping texture: %s\n", progname, (s ? s : "(unknown)")); exit (1); @@ -1094,7 +1189,7 @@ pinit(ModeInfo * mi) -void +ENTRYPOINT void init_boxed(ModeInfo * mi) { int screen = MI_SCREEN(mi); @@ -1125,7 +1220,7 @@ init_boxed(ModeInfo * mi) } -void +ENTRYPOINT void draw_boxed(ModeInfo * mi) { boxedstruct *gp = &boxed[MI_SCREEN(mi)]; @@ -1145,9 +1240,11 @@ draw_boxed(ModeInfo * mi) glXSwapBuffers(display, window); } -void +ENTRYPOINT void release_boxed(ModeInfo * mi) { + int i; + if (boxed != NULL) { int screen; @@ -1158,23 +1255,16 @@ release_boxed(ModeInfo * mi) /* Display lists MUST be freed while their glXContext is current. */ glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context)); - /*if (glIsList(gp->gear1)) - glDeleteLists(gp->gear1, 1); - if (glIsList(gp->gear2)) - glDeleteLists(gp->gear2, 1); - if (glIsList(gp->gear3)) - glDeleteLists(gp->gear3, 1); - if (glIsList(gp->gear_inner)) - glDeleteLists(gp->gear_inner, 1); - if (glIsList(gp->gear_outer)) - glDeleteLists(gp->gear_outer, 1); - */ + if (glIsList(gp->listobjects)) + glDeleteLists(gp->listobjects, 3); - /* TODO - * free all trimans - * free all balls - * free all sphere indices & vertices - */ + for (i=0;ibman.num_balls;i++) { + if (gp->bman.balls[i].bounced) freetris(&gp->tman[i]); + } + free (gp->bman.balls); + free (gp->tman); + free (gp->tex1); + } } @@ -1185,6 +1275,8 @@ release_boxed(ModeInfo * mi) } +XSCREENSAVER_MODULE ("Boxed", boxed) + /*********************************************************/ #endif