X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fboxed.c;h=f1a409a1f775dfb4c66a4766ecec57105994bf0f;hb=5f9c47ca98dd43d8f59b7c27d3fde6edfde4fe21;hp=2bff1ec01219afb893d79f38cccdfb0ba3129a74;hpb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;p=xscreensaver diff --git a/hacks/glx/boxed.c b/hacks/glx/boxed.c index 2bff1ec0..f1a409a1 100644 --- a/hacks/glx/boxed.c +++ b/hacks/glx/boxed.c @@ -26,6 +26,10 @@ static const char sccsid[] = "@(#)boxed.c 0.9 01/09/26 xlockmore"; * * 2005: opts work. added options -balls, -ballsize, -explosion * + * 2006: opts work. added option -decay + * + * 2008: opts work. added option -momentum + * */ #include "boxed.h" @@ -53,7 +57,9 @@ static const char sccsid[] = "@(#)boxed.c 0.9 01/09/26 xlockmore"; # define DEF_SPEED "0.5" # define DEF_BALLS "25" # define DEF_BALLSIZE "2.0" -# define DEF_EXPLOSION "25.0f" +# 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))) @@ -64,6 +70,8 @@ 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 XrmOptionDescRec opts[] = { @@ -71,13 +79,17 @@ static XrmOptionDescRec opts[] = { {"-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[] = { {&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", "Exlosion", 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}, }; ENTRYPOINT ModeSpecOpt boxed_opts = {countof(opts), opts, countof(vars), vars, NULL}; @@ -140,6 +152,7 @@ typedef struct { vectorf loc; vectorf dir; BOOL far; + BOOL gone; } tri; typedef struct { @@ -147,6 +160,8 @@ typedef struct { int lifetime; float scalefac; float explosion; + float decay; + float momentum; vectorf color; tri *tris; GLint *indices; @@ -158,6 +173,8 @@ typedef struct { int numballs; float ballsize; float explosion; + float decay; + float momentum; BOOL textures; BOOL transparent; float camspeed; @@ -176,6 +193,7 @@ typedef struct { GLXContext *glx_context; GLuint listobjects; GLuint gllists[3]; + int list_polys[3]; Window window; BOOL stop; char *tex1; @@ -253,6 +271,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; +} + /* @@ -393,7 +417,10 @@ static 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]); + } } } @@ -464,13 +491,15 @@ static void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, i { 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; @@ -482,6 +511,7 @@ static void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, i 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]]); @@ -529,6 +559,12 @@ static void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, i 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); } } @@ -543,6 +579,8 @@ static void updatetris(triman *t) 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 */ @@ -632,10 +670,15 @@ 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 = cfg_explosion; + config->decay = cfg_decay; + config->momentum = cfg_momentum; config->ballsize = cfg_ballsize; config->camspeed = 35.0f; } @@ -644,12 +687,13 @@ static void setdefaultconfig(boxed_config *config) /* * draw bottom */ -static void drawfilledbox(boxedstruct *boxed, int wire) +static int drawfilledbox(boxedstruct *boxed, int wire) { /* draws texture filled box, top is drawn using the entire texture, the sides are drawn using the edge of the texture */ + int polys = 0; /* front */ glBegin(wire ? GL_LINE_LOOP : GL_QUADS); @@ -661,6 +705,7 @@ static void drawfilledbox(boxedstruct *boxed, int wire) glVertex3f(1.0,-1.0,1.0); glTexCoord2f(0,1); glVertex3f(-1.0,-1.0,1.0); + polys++; /* rear */ glTexCoord2f(0,1); glVertex3f(1.0,1.0,-1.0); @@ -670,6 +715,7 @@ static void drawfilledbox(boxedstruct *boxed, int wire) glVertex3f(-1.0,-1.0,-1.0); glTexCoord2f(0,1); glVertex3f(1.0,-1.0,-1.0); + polys++; /* left */ glTexCoord2f(1,1); glVertex3f(-1.0,1.0,1.0); @@ -679,6 +725,7 @@ static void drawfilledbox(boxedstruct *boxed, int wire) glVertex3f(-1.0,-1.0,-1.0); glTexCoord2f(0,1); glVertex3f(-1.0,1.0,-1.0); + polys++; /* right */ glTexCoord2f(0,1); glVertex3f(1.0,1.0,1.0); @@ -688,6 +735,7 @@ static void drawfilledbox(boxedstruct *boxed, int wire) glVertex3f(1.0,-1.0,-1.0); glTexCoord2f(0,1); glVertex3f(1.0,-1.0,1.0); + polys++; /* top */ glTexCoord2f(0.0,0.0); glVertex3f(-1.0,1.0,1.0); @@ -697,6 +745,7 @@ static void drawfilledbox(boxedstruct *boxed, int wire) glVertex3f(1.0,1.0,-1.0); glTexCoord2f(1.0,0.0); glVertex3f(1.0,1.0,1.0); + polys++; /* bottom */ glTexCoord2f(0,0); glVertex3f(-1.0,-1.0,1.0); @@ -706,42 +755,47 @@ static void drawfilledbox(boxedstruct *boxed, int wire) glVertex3f(1.0,-1.0,-1.0); glTexCoord2f(1,0); glVertex3f(1.0,-1.0,1.0); + polys++; glEnd(); + + return polys; } /* * Draw a box made of lines */ -static void drawbox(boxedstruct *boxed) +static int drawbox(boxedstruct *boxed) { + int polys = 0; /* top */ glBegin(GL_LINE_STRIP); glVertex3f(-1.0,1.0,1.0); - glVertex3f(-1.0,1.0,-1.0); - glVertex3f(1.0,1.0,-1.0); - glVertex3f(1.0,1.0,1.0); - glVertex3f(-1.0,1.0,1.0); + glVertex3f(-1.0,1.0,-1.0); polys++; + glVertex3f(1.0,1.0,-1.0); polys++; + glVertex3f(1.0,1.0,1.0); polys++; + glVertex3f(-1.0,1.0,1.0); polys++; glEnd(); /* bottom */ glBegin(GL_LINE_STRIP); glVertex3f(-1.0,-1.0,1.0); - glVertex3f(1.0,-1.0,1.0); - glVertex3f(1.0,-1.0,-1.0); - glVertex3f(-1.0,-1.0,-1.0); - glVertex3f(-1.0,-1.0,1.0); + glVertex3f(1.0,-1.0,1.0); polys++; + glVertex3f(1.0,-1.0,-1.0); polys++; + glVertex3f(-1.0,-1.0,-1.0); polys++; + glVertex3f(-1.0,-1.0,1.0); polys++; glEnd(); /* connect top & bottom */ glBegin(GL_LINES); glVertex3f(-1.0,1.0,1.0); - glVertex3f(-1.0,-1.0,1.0); + glVertex3f(-1.0,-1.0,1.0); polys++; glVertex3f(1.0,1.0,1.0); - glVertex3f(1.0,-1.0,1.0); + glVertex3f(1.0,-1.0,1.0); polys++; glVertex3f(1.0,1.0,-1.0); - glVertex3f(1.0,-1.0,-1.0); + glVertex3f(1.0,-1.0,-1.0); polys++; glVertex3f(-1.0,1.0,-1.0); - glVertex3f(-1.0,-1.0,-1.0); + glVertex3f(-1.0,-1.0,-1.0); polys++; glEnd(); + return polys; } @@ -749,8 +803,9 @@ static void drawbox(boxedstruct *boxed) /* * Draw ball */ -static void drawball(boxedstruct *gp, ball *b, int wire) +static int drawball(boxedstruct *gp, ball *b, int wire) { + int polys = 0; int i,pos,cnt; GLint *spherei = gp->spherei; vectorf *spherev = gp->spherev; @@ -779,26 +834,31 @@ static void drawball(boxedstruct *gp, ball *b, int wire) glNormal3f(spherev[spherei[pos+0]].x,spherev[spherei[pos+0]].y,spherev[spherei[pos+0]].z); glVertex3f(spherev[spherei[pos+0]].x,spherev[spherei[pos+0]].y,spherev[spherei[pos+0]].z); glNormal3f(spherev[spherei[pos+1]].x,spherev[spherei[pos+1]].y,spherev[spherei[pos+1]].z); + gp->list_polys[GLL_BALL]++; glVertex3f(spherev[spherei[pos+1]].x,spherev[spherei[pos+1]].y,spherev[spherei[pos+1]].z); glNormal3f(spherev[spherei[pos+2]].x,spherev[spherei[pos+2]].y,spherev[spherei[pos+2]].z); glVertex3f(spherev[spherei[pos+2]].x,spherev[spherei[pos+2]].y,spherev[spherei[pos+2]].z); + gp->list_polys[GLL_BALL]++; glEnd(); } glEndList(); gp->gllists[GLL_BALL] = 1; } else { glCallList(gp->listobjects + GLL_BALL); + polys += gp->list_polys[GLL_BALL]; } glPopMatrix(); + return polys; } /* * Draw all triangles in triman */ -static void drawtriman(triman *t, int wire) +static int drawtriman(triman *t, int wire) { + int polys = 0; int i,pos; vectorf *spherev = t->vertices; GLfloat col[3]; @@ -815,6 +875,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); @@ -823,66 +884,71 @@ static void drawtriman(triman *t, int wire) 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); glVertex3f(spherev[pos+2].x,spherev[pos+2].y,spherev[pos+2].z); + polys++; glEnd(); glPopMatrix(); } glPopMatrix(); + return polys; } /* * draw floor pattern */ -static void drawpattern(boxedstruct *gp) +static int drawpattern(boxedstruct *gp) { + int polys = 0; 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); - glVertex3f(-5.0f, 0.0f, 25.0f); - glVertex3f(5.0f, 0.0f, 25.0f); - glVertex3f(15.0f, 0.0f, 35.0f); - glVertex3f(25.0f, 0.0f, 35.0f); - glVertex3f(35.0f, 0.0f, 25.0f); - glVertex3f(35.0f, 0.0f, 15.0f); - glVertex3f(25.0f, 0.0f, 5.0f); - glVertex3f(25.0f, 0.0f, -5.0f); - glVertex3f(35.0f, 0.0f, -15.0f); - glVertex3f(35.0f, 0.0f, -25.0f); - glVertex3f(25.0f, 0.0f, -35.0f); - glVertex3f(15.0f, 0.0f,-35.0f); - glVertex3f(5.0f, 0.0f, -25.0f); - glVertex3f(-5.0f, 0.0f, -25.0f); - glVertex3f(-15.0f, 0.0f,-35.0f); - glVertex3f(-25.0f, 0.0f,-35.0f); - glVertex3f(-35.0f, 0.0f, -25.0f); - glVertex3f(-35.0f, 0.0f, -15.0f); - glVertex3f(-25.0f, 0.0f, -5.0f); - glVertex3f(-25.0f, 0.0f, 5.0f); - glVertex3f(-35.0f, 0.0f, 15.0f); - glVertex3f(-35.0f, 0.0f, 25.0f); - glVertex3f(-25.0f, 0.0f, 35.0f); + glVertex3f(-15.0f, 0.0f, 35.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-5.0f, 0.0f, 25.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(5.0f, 0.0f, 25.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(15.0f, 0.0f, 35.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(25.0f, 0.0f, 35.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(35.0f, 0.0f, 25.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(35.0f, 0.0f, 15.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(25.0f, 0.0f, 5.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(25.0f, 0.0f, -5.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(35.0f, 0.0f, -15.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(35.0f, 0.0f, -25.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(25.0f, 0.0f, -35.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(15.0f, 0.0f,-35.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(5.0f, 0.0f, -25.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-5.0f, 0.0f, -25.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-15.0f, 0.0f,-35.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-25.0f, 0.0f,-35.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-35.0f, 0.0f, -25.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-35.0f, 0.0f, -15.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-25.0f, 0.0f, -5.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-25.0f, 0.0f, 5.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-35.0f, 0.0f, 15.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-35.0f, 0.0f, 25.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-25.0f, 0.0f, 35.0f); gp->list_polys[GLL_PATTERN]++; glEnd(); glBegin(GL_LINE_STRIP); glVertex3f(-5.0f, 0.0f, 15.0f); - glVertex3f(5.0f, 0.0f, 15.0f); - glVertex3f(15.0f, 0.0f, 5.0f); - glVertex3f(15.0f, 0.0f, -5.0f); - glVertex3f(5.0f, 0.0f, -15.0f); - glVertex3f(-5.0f, 0.0f, -15.0f); - glVertex3f(-15.0f, 0.0f, -5.0f); - glVertex3f(-15.0f, 0.0f, 5.0f); - glVertex3f(-5.0f, 0.0f, 15.0f); + glVertex3f(5.0f, 0.0f, 15.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(15.0f, 0.0f, 5.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(15.0f, 0.0f, -5.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(5.0f, 0.0f, -15.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-5.0f, 0.0f, -15.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-15.0f, 0.0f, -5.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-15.0f, 0.0f, 5.0f); gp->list_polys[GLL_PATTERN]++; + glVertex3f(-5.0f, 0.0f, 15.0f); gp->list_polys[GLL_PATTERN]++; glEnd(); glEndList(); gp->gllists[GLL_PATTERN] = 1; } else { glCallList(gp->listobjects + GLL_PATTERN); - } + polys += gp->list_polys[GLL_PATTERN]; + } + return polys; } @@ -911,6 +977,8 @@ static void draw(ModeInfo * mi) GLfloat l1_diffuse[] = {0.5, 0.5, 0.5, 1.0}; GLfloat l1_position[] = {0.0, 1.0, 0.0, 0.0}; /* w = 0 -> directional light */ + mi->polygon_count = 0; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); @@ -966,7 +1034,7 @@ static void draw(ModeInfo * mi) glColor3f(1.0,1.0,1.0); glScalef(20.0,0.25,20.0); glTranslatef(0.0,2.0,0.0); - drawfilledbox(gp, wire); + mi->polygon_count += drawfilledbox(gp, wire); glPopMatrix(); glDisable(GL_TEXTURE_2D); @@ -974,28 +1042,28 @@ static void draw(ModeInfo * mi) glColor3f(0.2,0.5,0.2); glScalef(20.0,20.0,0.25); glTranslatef(0.0,1.0,81.0); - drawbox(gp); + mi->polygon_count += drawbox(gp); glPopMatrix(); glPushMatrix(); glColor3f(0.2,0.5,0.2); glScalef(20.0,20.0,0.25); glTranslatef(0.0,1.0,-81.0); - drawbox(gp); + mi->polygon_count += drawbox(gp); glPopMatrix(); glPushMatrix(); glColor3f(0.2,0.5,0.2); glScalef(.25,20.0,20.0); glTranslatef(-81.0,1.0,0.0); - drawbox(gp); + mi->polygon_count += drawbox(gp); glPopMatrix(); glPushMatrix(); glColor3f(0.2,0.5,0.2); glScalef(.25,20.0,20.0); glTranslatef(81.0,1.0,0.0); - drawbox(gp); + mi->polygon_count += drawbox(gp); glPopMatrix(); if (!wire) { @@ -1021,10 +1089,10 @@ static void draw(ModeInfo * mi) updatetris(&gp->tman[i]); } glDisable(GL_CULL_FACE); - drawtriman(&gp->tman[i], wire); + mi->polygon_count += drawtriman(&gp->tman[i], wire); if (!wire) glEnable(GL_CULL_FACE); } else { - drawball(gp, &gp->bman.balls[i], wire); + mi->polygon_count += drawball(gp, &gp->bman.balls[i], wire); } } @@ -1063,11 +1131,14 @@ pinit(ModeInfo * mi) glShadeModel(GL_SMOOTH); glClearDepth(1.0); - glClearColor(0.0,0.05,0.1,0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* 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; @@ -1081,6 +1152,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;