X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fboxed.c;h=1791052602042a21944acddc82b25f538883aaa4;hp=9f7706c6c9b03f86fa5b0061262fc94db7c877f7;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hpb=0d6b320def9180cf907ceaed56b23a972a11b757 diff --git a/hacks/glx/boxed.c b/hacks/glx/boxed.c index 9f7706c6..17910526 100644 --- a/hacks/glx/boxed.c +++ b/hacks/glx/boxed.c @@ -26,9 +26,12 @@ 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 #include "boxed.h" /* @@ -38,37 +41,38 @@ 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 DEF_BALLS "25" -# define DEF_BALLSIZE "2.0" -# define DEF_EXPLOSION "25.0f" -# define DEFAULTS "*delay: 20000 \n" \ +# define DEFAULTS "*delay: 15000 \n" \ "*showFPS: False \n" \ "*wireframe: False \n" +# define refresh_boxed 0 +# define release_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 "20" +# define DEF_BALLSIZE "3.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() (frand(1.0)) -GLfloat speed; /* jwz -- overall speed factor applied to all motion */ -int cfg_balls; -GLfloat cfg_ballsize; -GLfloat cfg_explosion; +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[] = { @@ -76,21 +80,25 @@ 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}, }; -ModeSpecOpt boxed_opts = {countof(opts), opts, countof(vars), vars, NULL}; +ENTRYPOINT ModeSpecOpt boxed_opts = {countof(opts), opts, countof(vars), vars, NULL}; #ifdef USE_MODULES ModStruct boxed_description = { - "boxed", "init_boxed", "draw_boxed", "release_boxed", + "boxed", "init_boxed", "draw_boxed", NULL, "draw_boxed", "init_boxed", NULL, &boxed_opts, 1000, 1, 2, 1, 4, 1.0, "", "Shows GL's boxed balls", 0, NULL}; @@ -102,10 +110,11 @@ ModStruct boxed_description = { #define FALSE 0 /* camera */ -#define CAM_HEIGHT 100.0f -#define CAMDISTANCE_MIN 20.0 +#define CAM_HEIGHT 80.0f +#define CAMDISTANCE_MIN 35.0 #define CAMDISTANCE_MAX 150.0 #define CAMDISTANCE_SPEED 1.5 +#define LOOKAT_R 30.0 /* rendering the sphere */ #define MESH_SIZE 10 @@ -145,6 +154,7 @@ typedef struct { vectorf loc; vectorf dir; BOOL far; + int gone; } tri; typedef struct { @@ -152,6 +162,8 @@ typedef struct { int lifetime; float scalefac; float explosion; + float decay; + float momentum; vectorf color; tri *tris; GLint *indices; @@ -163,6 +175,8 @@ typedef struct { int numballs; float ballsize; float explosion; + float decay; + float momentum; BOOL textures; BOOL transparent; float camspeed; @@ -181,6 +195,7 @@ typedef struct { GLXContext *glx_context; GLuint listobjects; GLuint gllists[3]; + int list_polys[3]; Window window; BOOL stop; char *tex1; @@ -258,6 +273,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; +} + /* @@ -266,7 +287,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; @@ -282,8 +303,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; @@ -346,7 +367,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(); @@ -368,7 +389,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; @@ -388,7 +409,7 @@ void updateballs(ballman *bman) (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) + if (bman->balls[b].loc.y < -2000.0) createball(&bman->balls[b]); } else { bman->balls[b].loc.y = bman->balls[b].radius + (bman->balls[b].radius - bman->balls[b].loc.y); @@ -398,7 +419,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]); + } } } @@ -465,17 +489,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; @@ -487,6 +513,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 = 0; pos = i * 3; /* kopieer elke poly apart naar een tri structure */ copyvector(&tman->vertices[pos+0],&spherev[spherei[pos+0]]); @@ -534,6 +561,12 @@ void createtrisfromball(triman* tman, vectorf *spherev, GLint *spherei, int ind_ 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); } } @@ -542,12 +575,17 @@ 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) { + if (t->tris[b].gone == 0) + t->tris[b].gone = 1; + } /* apply gravity */ t->tris[b].dir.y -= (0.1f * speed); /* apply movement */ @@ -615,7 +653,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); @@ -632,15 +670,20 @@ void freetris(triman *t) /* *load defaults in config structure */ -void setdefaultconfig(boxed_config *config) +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.02f,MIN(0.90f,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; } @@ -649,12 +692,13 @@ 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); @@ -666,6 +710,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); @@ -675,6 +720,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); @@ -684,6 +730,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); @@ -693,6 +740,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); @@ -702,6 +750,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); @@ -711,42 +760,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; } @@ -754,8 +808,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; @@ -777,35 +832,62 @@ static void drawball(boxedstruct *gp, ball *b, int wire) if (!gp->gllists[GLL_BALL]) { glNewList(gp->listobjects + GLL_BALL,GL_COMPILE); + glBegin(wire ? GL_LINES : GL_TRIANGLES); cnt = SPHERE_INDICES/3; for (i=0; ilist_polys[GLL_BALL]++; glVertex3f(spherev[spherei[pos+1]].x,spherev[spherei[pos+1]].y,spherev[spherei[pos+1]].z); + if (wire) + 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); - glEnd(); + 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 a single triangle + */ +static void drawtri(triman *t, int wire, int i) +{ + const vectorf *spherev = t->vertices + i*3; + const vectorf *loc = &t->tris[i].loc; + + glNormal3f(t->normals[i].x,t->normals[i].y,t->normals[i].z); + glVertex3f(spherev[0].x+loc->x,spherev[0].y+loc->y,spherev[0].z+loc->z); + glVertex3f(spherev[1].x+loc->x,spherev[1].y+loc->y,spherev[1].z+loc->z); + if (wire) + glVertex3f(spherev[1].x+loc->x,spherev[1].y+loc->y,spherev[1].z+loc->z); + glVertex3f(spherev[2].x+loc->x,spherev[2].y+loc->y,spherev[2].z+loc->z); + if (wire) { + glVertex3f(spherev[2].x+loc->x,spherev[2].y+loc->y,spherev[2].z+loc->z); + glVertex3f(spherev[0].x+loc->x,spherev[0].y+loc->y,spherev[0].z+loc->z); + } } /* * Draw all triangles in triman */ -static void drawtriman(triman *t, int wire) +static int drawtriman(triman *t, int wire) { - int i,pos; - vectorf *spherev = t->vertices; + int polys = 0; + int i; GLfloat col[3]; glPushMatrix(); @@ -818,76 +900,103 @@ static void drawtriman(triman *t, int wire) col[1] *= 0.3; col[2] *= 0.3; glMaterialfv(GL_FRONT, GL_EMISSION,col); + glBegin(wire ? GL_LINES : GL_TRIANGLES); for (i=0; inum_tri; i++) { - pos = i*3; - glPushMatrix(); - glTranslatef(t->tris[i].loc.x,t->tris[i].loc.y,t->tris[i].loc.z); - 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); - glVertex3f(spherev[pos+2].x,spherev[pos+2].y,spherev[pos+2].z); - glEnd(); - glPopMatrix(); - } - glPopMatrix(); + if (t->tris[i].gone > 3) { continue; } + if (t->tris[i].gone > 0) { + glColor3f(t->color.x,t->color.y,t->color.z); + col[0] = 1.0f; + col[1] = 1.0f; + col[2] = 1.0f; + glMaterialfv(GL_FRONT, GL_DIFFUSE, col); + col[0] *= 0.8; + col[1] *= 0.8; + col[2] *= 0.8; + glMaterialfv(GL_FRONT, GL_EMISSION,col); + + drawtri(t, wire, i); + polys++; + + glColor3f(t->color.x,t->color.y,t->color.z); + col[0] = t->color.x; + col[1] = t->color.y; + col[2] = t->color.z; + glMaterialfv(GL_FRONT, GL_DIFFUSE, col); + col[0] *= 0.3; + col[1] *= 0.3; + col[2] *= 0.3; + glMaterialfv(GL_FRONT, GL_EMISSION,col); + + t->tris[i].gone++; + continue; + } + + drawtri(t, wire, i); + polys++; + } + glEnd(); + glPopMatrix(); + return polys; } /* * draw floor pattern */ -static void drawpattern(boxedstruct *boxed) +static int drawpattern(boxedstruct *gp) { - if (!boxed->gllists[GLL_PATTERN]) { - glNewList(boxed->listobjects + GLL_PATTERN, GL_COMPILE); + 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(); - boxed->gllists[GLL_PATTERN] = 1; + gp->gllists[GLL_PATTERN] = 1; } else { - glCallList(boxed->listobjects + GLL_PATTERN); - } + glCallList(gp->listobjects + GLL_PATTERN); + polys += gp->list_polys[GLL_PATTERN]; + } + return polys; } @@ -898,8 +1007,8 @@ static void draw(ModeInfo * mi) { boxedstruct *gp = &boxed[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME (mi); - vectorf v1; - GLfloat dcam; + vectorf v1,v2; + GLfloat r; int dx, dz; int i; @@ -916,18 +1025,35 @@ 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(); +# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */ + { + GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi); + int o = (int) current_device_rotation(); + if (o != 0 && o != 180 && o != -180) + glScalef (1/h, 1/h, 1/h); + glRotatef(o, 0, 0, 1); + } +# endif + 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->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); + r = CAMDISTANCE_MIN + (CAMDISTANCE_MAX - CAMDISTANCE_MIN) + (CAMDISTANCE_MAX - CAMDISTANCE_MIN)*cos((gp->camtic/CAMDISTANCE_SPEED) * speed); + v1.x = r * sin((gp->camtic/gp->cam_x_speed) * speed); + v1.z = r * cos((gp->camtic/gp->cam_x_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); + + v2.x = LOOKAT_R * sin((gp->camtic/(gp->cam_x_speed * 5.0f)) * speed); + v2.z = LOOKAT_R * cos((gp->camtic/(gp->cam_x_speed * 5.0f)) * speed); + v2.y = (CAM_HEIGHT * sin((gp->camtic/gp->cam_y_speed) * speed) + 1.02 * CAM_HEIGHT)/10.0; + + gluLookAt(v1.x,v1.y,v1.z,v2.x,v2.y,v2.x,0.0,1.0,0.0); if (!wire) { glLightfv(GL_LIGHT0, GL_AMBIENT, l0_ambient); @@ -971,7 +1097,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); @@ -979,28 +1105,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) { @@ -1026,10 +1152,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); } } @@ -1041,7 +1167,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; @@ -1068,11 +1194,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; @@ -1086,6 +1215,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; @@ -1093,7 +1224,7 @@ pinit(ModeInfo * mi) bman->balls[i].loc.y *= rnd(); } - generatesphere(); + generatesphere(gp); if (!wire) { glEnable(GL_CULL_FACE); @@ -1124,6 +1255,7 @@ pinit(ModeInfo * mi) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); clear_gl_error(); +#if 0 i = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, gp->tex1); if (i) @@ -1134,6 +1266,12 @@ pinit(ModeInfo * mi) exit (1); } check_gl_error("mipmapping"); +#else + glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, + GL_RGB, GL_UNSIGNED_BYTE, + gp->tex1); + check_gl_error("texture"); +#endif glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -1145,7 +1283,9 @@ pinit(ModeInfo * mi) -void +static void free_boxed(ModeInfo * mi); + +ENTRYPOINT void init_boxed(ModeInfo * mi) { int screen = MI_SCREEN(mi); @@ -1154,9 +1294,7 @@ init_boxed(ModeInfo * mi) /* Boolean rgba, doublebuffer, cmap_installed; */ boxedstruct *gp; - if (boxed == NULL) { - if ((boxed = (boxedstruct *) calloc(MI_NUM_SCREENS(mi),sizeof (boxedstruct))) == NULL) return; - } + MI_INIT(mi, boxed, free_boxed); gp = &boxed[screen]; gp->window = MI_WINDOW(mi); @@ -1176,7 +1314,7 @@ init_boxed(ModeInfo * mi) } -void +ENTRYPOINT void draw_boxed(ModeInfo * mi) { boxedstruct *gp = &boxed[MI_SCREEN(mi)]; @@ -1196,41 +1334,33 @@ draw_boxed(ModeInfo * mi) glXSwapBuffers(display, window); } -void -release_boxed(ModeInfo * mi) +ENTRYPOINT void +free_boxed(ModeInfo * mi) { + boxedstruct *gp = &boxed[MI_SCREEN(mi)]; int i; + + if (gp->glx_context) { + /* Display lists MUST be freed while their glXContext is current. */ + glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context)); - if (boxed != NULL) { - int screen; - - for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { - boxedstruct *gp = &boxed[screen]; - - if (gp->glx_context) { - /* Display lists MUST be freed while their glXContext is current. */ - glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context)); - - if (glIsList(gp->listobjects)) - glDeleteLists(gp->listobjects, 3); - - 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); - - - } + if (glIsList(gp->listobjects)) + glDeleteLists(gp->listobjects, 3); + + for (i=0;ibman.num_balls;i++) { + if (gp->bman.balls[i].bounced) freetris(&gp->tman[i]); } - (void) free((void *) boxed); - boxed = NULL; + free (gp->bman.balls); + free (gp->tman); + free (gp->tex1); + + } - FreeAllGL(mi); } +XSCREENSAVER_MODULE ("Boxed", boxed) + /*********************************************************/ #endif