-/* 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
/*-
* 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 <X11/Intrinsic.h>
#include "boxed.h"
/*
*/
#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: 15000 \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 <GL/glu.h>
+
+# 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))
-/* #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
#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
+#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 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
vectorf loc;
vectorf dir;
BOOL far;
+ int gone;
} tri;
typedef struct {
int lifetime;
float scalefac;
float explosion;
+ float decay;
+ float momentum;
vectorf color;
tri *tris;
GLint *indices;
int numballs;
float ballsize;
float explosion;
+ float decay;
+ float momentum;
BOOL textures;
BOOL transparent;
float camspeed;
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;
GLXContext *glx_context;
GLuint listobjects;
GLuint gllists[3];
+ int list_polys[3];
Window window;
BOOL stop;
char *tex1;
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;
+}
+
/*
* Input:
*/
-static void generatesphere(void)
+static void generatesphere(boxedstruct *gp)
{
float dj = M_PI/(MESH_SIZE+1.0f);
float di = M_PI/MESH_SIZE;
* 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;
* 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();
/* 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;b<bman->num_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.y < -1000.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 < -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);
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]);
+ }
}
}
* 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;
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]]);
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);
}
}
* update position of each tri
*/
-void updatetris(triman *t) {
+static void updatetris(triman *t)
+{
int b;
GLfloat xd,zd;
for (b=0;b<t->num_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;
+ 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.80f); /* dampening */
/*
* 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);
/*
*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.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 = 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;
}
/*
* draw bottom
*/
-static void drawfilledbox(boxedstruct *boxed)
+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(GL_QUADS);
+ glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
glTexCoord2f(0,1);
glVertex3f(-1.0,1.0,1.0);
glTexCoord2f(1,1);
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);
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);
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);
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);
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);
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;
}
/*
* Draw ball
*/
-static void drawball(boxedstruct *gp, ball *b)
+static int drawball(boxedstruct *gp, ball *b, int wire)
{
+ int polys = 0;
int i,pos,cnt;
GLint *spherei = gp->spherei;
vectorf *spherev = gp->spherev;
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; i<cnt; i++) {
pos = i * 3;
- glBegin(GL_TRIANGLES);
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);
+ 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)
+static int drawtriman(triman *t, int wire)
{
- int i,pos;
- vectorf *spherev = t->vertices;
+ int polys = 0;
+ int i;
GLfloat col[3];
glPushMatrix();
col[1] *= 0.3;
col[2] *= 0.3;
glMaterialfv(GL_FRONT, GL_EMISSION,col);
+ glBegin(wire ? GL_LINES : GL_TRIANGLES);
for (i=0; i<t->num_tri; i++) {
- pos = i*3;
- glPushMatrix();
- glTranslatef(t->tris[i].loc.x,t->tris[i].loc.y,t->tris[i].loc.z);
- glBegin(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;
}
static void draw(ModeInfo * mi)
{
boxedstruct *gp = &boxed[MI_SCREEN(mi)];
- vectorf v1;
- GLfloat dcam;
+ int wire = MI_IS_WIREFRAME (mi);
+ vectorf v1,v2;
+ GLfloat r;
int dx, dz;
int i;
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();
- gp->tic += 0.01f;
+ glRotatef(current_device_rotation(), 0, 0, 1);
+ 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;
- 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);
+ 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;
+
+ 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);
+ 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 */
/* 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);
+ mi->polygon_count += drawfilledbox(gp, wire);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
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();
- 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);
updatetris(&gp->tman[i]);
}
glDisable(GL_CULL_FACE);
- drawtriman(&gp->tman[i]);
- glEnable(GL_CULL_FACE);
+ mi->polygon_count += drawtriman(&gp->tman[i], wire);
+ if (!wire) glEnable(GL_CULL_FACE);
} else {
- drawball(gp, &gp->bman.balls[i]);
+ mi->polygon_count += drawball(gp, &gp->bman.balls[i], wire);
}
}
/*
* 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;
pinit(ModeInfo * mi)
{
boxedstruct *gp = &boxed[MI_SCREEN(mi)];
+ int wire = MI_IS_WIREFRAME (mi);
ballman *bman;
int i,texpixels;
char *texpixeldata;
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;
for(i=0;i<bman->num_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;
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));
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;
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)
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);
-void
+ENTRYPOINT void
init_boxed(ModeInfo * mi)
{
int screen = MI_SCREEN(mi);
}
-void
+ENTRYPOINT void
draw_boxed(ModeInfo * mi)
{
boxedstruct *gp = &boxed[MI_SCREEN(mi)];
glXSwapBuffers(display, window);
}
-void
+ENTRYPOINT void
release_boxed(ModeInfo * mi)
{
int i;
}
+XSCREENSAVER_MODULE ("Boxed", boxed)
+
/*********************************************************/
#endif