X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fboxed.c;h=1791052602042a21944acddc82b25f538883aaa4;hp=6a2d79a68c37939c9880c562b98eab77ec465c84;hb=4361b69d3178d7fc98d0388f9a223af6c2651aba;hpb=f8cf5ac7b2f53510f80a0eaf286a25298be17bfe diff --git a/hacks/glx/boxed.c b/hacks/glx/boxed.c index 6a2d79a6..17910526 100644 --- a/hacks/glx/boxed.c +++ b/hacks/glx/boxed.c @@ -41,11 +41,12 @@ static const char sccsid[] = "@(#)boxed.c 0.9 01/09/26 xlockmore"; */ #ifdef STANDALONE -# 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 */ @@ -55,8 +56,8 @@ static const char sccsid[] = "@(#)boxed.c 0.9 01/09/26 xlockmore"; #ifdef USE_GL # define DEF_SPEED "0.5" -# define DEF_BALLS "25" -# define DEF_BALLSIZE "2.0" +# define DEF_BALLS "20" +# define DEF_BALLSIZE "3.0" # define DEF_EXPLOSION "15.0" # define DEF_DECAY "0.07" # define DEF_MOMENTUM "0.6" @@ -97,7 +98,7 @@ ENTRYPOINT ModeSpecOpt boxed_opts = {countof(opts), opts, countof(vars), vars, N #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}; @@ -109,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 @@ -152,7 +154,7 @@ typedef struct { vectorf loc; vectorf dir; BOOL far; - BOOL gone; + int gone; } tri; typedef struct { @@ -407,7 +409,7 @@ static 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); @@ -511,7 +513,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; + 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]]); @@ -580,7 +582,10 @@ static void updatetris(triman *t) for (b=0;bnum_tri;b++) { /* the exploded triangles disappear over time */ - if (rnd() < t->decay) { t->tris[b].gone = TRUE; } + 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 */ @@ -670,7 +675,7 @@ 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_decay = MAX(0.02f,MIN(0.90f,cfg_decay)); cfg_momentum = MAX(0.0f,MIN(1.0f,cfg_momentum)); config->numballs = cfg_balls; @@ -693,7 +698,7 @@ static int drawfilledbox(boxedstruct *boxed, int wire) top is drawn using the entire texture, the sides are drawn using the edge of the texture */ - int polys = 0; + int polys = 0; /* front */ glBegin(wire ? GL_LINE_LOOP : GL_QUADS); @@ -827,20 +832,22 @@ static int 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); gp->list_polys[GLL_BALL]++; - glEnd(); } + glEnd(); glEndList(); gp->gllists[GLL_BALL] = 1; } else { @@ -852,6 +859,27 @@ static int drawball(boxedstruct *gp, ball *b, int wire) 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 @@ -859,8 +887,7 @@ static int drawball(boxedstruct *gp, ball *b, int wire) static int drawtriman(triman *t, int wire) { int polys = 0; - int i,pos; - vectorf *spherev = t->vertices; + int i; GLfloat col[3]; glPushMatrix(); @@ -873,22 +900,43 @@ static int 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++) { - 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(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); + 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(); - } - glPopMatrix(); + } + glEnd(); + glPopMatrix(); return polys; } @@ -959,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; @@ -982,17 +1030,30 @@ static void draw(ModeInfo * mi) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); - glRotatef(current_device_rotation(), 0, 0, 1); +# 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); @@ -1222,6 +1283,8 @@ pinit(ModeInfo * mi) +static void free_boxed(ModeInfo * mi); + ENTRYPOINT void init_boxed(ModeInfo * mi) { @@ -1231,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); @@ -1274,37 +1335,27 @@ draw_boxed(ModeInfo * mi) } ENTRYPOINT void -release_boxed(ModeInfo * mi) +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); }