X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fstairs.c;h=10f96b5f55dffa674361d1d5b94c257dbeaebb7e;hb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;hp=c12316a148251cbe2946f143db156c7d2238e855;hpb=df7adbee81405e2849728a24b498ad2117784b1f;p=xscreensaver diff --git a/hacks/glx/stairs.c b/hacks/glx/stairs.c index c12316a1..10f96b5f 100644 --- a/hacks/glx/stairs.c +++ b/hacks/glx/stairs.c @@ -1,9 +1,8 @@ /* -*- Mode: C; tab-width: 4 -*- */ /* stairs --- Infinite Stairs, and Escher-like scene. */ -#if !defined( lint ) && !defined( SABER ) +#if 0 static const char sccsid[] = "@(#)stairs.c 4.07 97/11/24 xlockmore"; - #endif #undef DEBUG_LISTS @@ -58,16 +57,11 @@ static const char sccsid[] = "@(#)stairs.c 4.07 97/11/24 xlockmore"; * In real OpenGL, PseudoColor DO NOT support texture map (as far as I know). */ -#include - #ifdef STANDALONE -# define PROGCLASS "Stairs" -# define HACK_INIT init_stairs -# define HACK_DRAW draw_stairs -# define stairs_opts xlockmore_opts -# define DEFAULTS "*cycles: 1 \n" \ - "*delay: 200000 \n" \ - "*wireframe: False \n" +# define DEFAULTS "*delay: 20000 \n" \ + "*showFPS: False \n" +# define refresh_stairs 0 +# define stairs_handle_event 0 # include "xlockmore.h" /* from the xscreensaver distribution */ #else /* !STANDALONE */ # include "xlock.h" /* from the xlockmore distribution */ @@ -76,10 +70,9 @@ static const char sccsid[] = "@(#)stairs.c 4.07 97/11/24 xlockmore"; #ifdef USE_GL -#include #include "e_textures.h" -ModeSpecOpt stairs_opts = +ENTRYPOINT ModeSpecOpt stairs_opts = {0, NULL, 0, NULL, NULL}; #ifdef USE_MODULES @@ -108,53 +101,36 @@ typedef struct { Bool direction; int AreObjectsDefined[1]; int sphere_position; + int sphere_tick; GLXContext *glx_context; + GLuint objects; } stairsstruct; -static float front_shininess[] = -{60.0}; -static float front_specular[] = -{0.7, 0.7, 0.7, 1.0}; -static float ambient[] = -{0.0, 0.0, 0.0, 1.0}; -static float diffuse[] = -{1.0, 1.0, 1.0, 1.0}; -static float position0[] = -{1.0, 1.0, 1.0, 0.0}; -static float position1[] = -{-1.0, -1.0, 1.0, 0.0}; -static float lmodel_ambient[] = -{0.5, 0.5, 0.5, 1.0}; -static float lmodel_twoside[] = -{GL_TRUE}; +static const float front_shininess[] = {60.0}; +static const float front_specular[] = {0.7, 0.7, 0.7, 1.0}; +static const float ambient[] = {0.0, 0.0, 0.0, 1.0}; +static const float diffuse[] = {1.0, 1.0, 1.0, 1.0}; +static const float position0[] = {1.0, 1.0, 1.0, 0.0}; +static const float position1[] = {-1.0, -1.0, 1.0, 0.0}; +static const float lmodel_ambient[] = {0.5, 0.5, 0.5, 1.0}; +static const float lmodel_twoside[] = {GL_TRUE}; #if 0 -static float MaterialRed[] = -{0.7, 0.0, 0.0, 1.0}; -static float MaterialGreen[] = -{0.1, 0.5, 0.2, 1.0}; -static float MaterialBlue[] = -{0.0, 0.0, 0.7, 1.0}; -static float MaterialCyan[] = -{0.2, 0.5, 0.7, 1.0}; -static float MaterialMagenta[] = -{0.6, 0.2, 0.5, 1.0}; -static float MaterialGray[] = -{0.2, 0.2, 0.2, 1.0}; -static float MaterialGray5[] = -{0.5, 0.5, 0.5, 1.0}; -static float MaterialGray6[] = -{0.6, 0.6, 0.6, 1.0}; -static float MaterialGray8[] = -{0.8, 0.8, 0.8, 1.0}; +static const float MaterialRed[] = {0.7, 0.0, 0.0, 1.0}; +static const float MaterialGreen[] = {0.1, 0.5, 0.2, 1.0}; +static const float MaterialBlue[] = {0.0, 0.0, 0.7, 1.0}; +static const float MaterialCyan[] = {0.2, 0.5, 0.7, 1.0}; +static const float MaterialMagenta[] = {0.6, 0.2, 0.5, 1.0}; +static const float MaterialGray[] = {0.2, 0.2, 0.2, 1.0}; +static const float MaterialGray5[] = {0.5, 0.5, 0.5, 1.0}; +static const float MaterialGray6[] = {0.6, 0.6, 0.6, 1.0}; +static const float MaterialGray8[] = {0.8, 0.8, 0.8, 1.0}; #endif -static float MaterialYellow[] = -{0.7, 0.7, 0.0, 1.0}; -static float MaterialWhite[] = -{0.7, 0.7, 0.7, 1.0}; +static const float MaterialYellow[] = {0.7, 0.7, 0.0, 1.0}; +static const float MaterialWhite[] = {0.7, 0.7, 0.7, 1.0}; -static float positions[] = +static const float positions[] = { -2.5, 4.0, 0.0, /* First one is FUDGED :) */ -3.0, 3.25, 1.0, @@ -195,8 +171,9 @@ static float positions[] = #define NPOSITIONS ((sizeof positions) / (sizeof positions[0])) +#define SPHERE_TICKS 8 + static stairsstruct *stairs = NULL; -static GLuint objects; #define ObjSphere 0 @@ -313,21 +290,106 @@ draw_stairs_internal(ModeInfo * mi) glPushMatrix(); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialYellow); - glTranslatef((GLfloat) positions[sp->sphere_position], - (GLfloat) positions[sp->sphere_position + 1], - (GLfloat) positions[sp->sphere_position + 2]); + { + int pos = sp->sphere_position; + int ppos = sp->sphere_position - 3; + int npos = sp->sphere_position + 3; + GLfloat spx, spy, spz; + GLfloat dx, dy, dz; + int div; + + if (ppos < 0) ppos += NPOSITIONS; + if (npos >= NPOSITIONS) npos -= NPOSITIONS; + + if (sp->sphere_tick < 0) + { + dx = positions[ppos] - positions[pos]; + dy = positions[ppos+1] - positions[pos+1]; + dz = positions[ppos+2] - positions[pos+2]; + div = SPHERE_TICKS + sp->sphere_tick; + } + else + { + dx = positions[npos] - positions[pos]; + dy = positions[npos+1] - positions[pos+1]; + dz = positions[npos+2] - positions[ppos+2]; + div = SPHERE_TICKS - sp->sphere_tick; + } + + spx = positions[pos]; + spy = positions[pos+1]; + spz = positions[pos+2]; + if (div != 0) + { + spx += dx / div; + spy += dy / div; + spz += dz / div; + } + + + spy -= 0.5; /* move the bottom of the ball closer to the stairs */ + + +#ifdef DEBUG + fprintf(stderr, "%3d %3d %2.2f %2.2f %2.2f %2.2f %2.2f %2.2f\n", + sp->sphere_position, sp->sphere_tick, + dx, dy, dz, + spx, spy, spz); + + glBegin(GL_LINE_LOOP); /* path 1 */ + glVertex3f(positions[pos], positions[pos+1], positions[pos+2]); + glVertex3f(positions[npos], positions[npos+1], positions[npos+2]); + glEnd(); + + glBegin(GL_LINE_LOOP); /* path 2 */ + glVertex3f(positions[pos], positions[pos+1], positions[pos+2]); + glVertex3f(positions[ppos], positions[ppos+1], positions[ppos+2]); + glEnd(); + + glBegin(GL_LINE_LOOP); /* base origin */ + glVertex3f(positions[pos], positions[pos+1]-10, positions[pos+2]); + glVertex3f(positions[pos], positions[pos+1]+10, positions[pos+2]); + glEnd(); + + glBegin(GL_LINE_LOOP); /* base origin */ + glVertex3f(positions[pos]-10, positions[pos+1], positions[pos+2]); + glVertex3f(positions[pos]+10, positions[pos+1], positions[pos+2]); + glEnd(); + + glBegin(GL_LINE_LOOP); /* base origin */ + glVertex3f(positions[pos], positions[pos+1], positions[pos+2]-10); + glVertex3f(positions[pos], positions[pos+1], positions[pos+2]+10); + glEnd(); +#endif /* DEBUG */ + + glTranslatef(spx, spy, spz); + +#ifdef DEBUG /* ball origin */ + glBegin(GL_LINE_LOOP); glVertex3f(0,-2,0); glVertex3f(0,2,0); glEnd(); + glBegin(GL_LINE_LOOP); glVertex3f(-2,0,0); glVertex3f(2,0,0); glEnd(); + glBegin(GL_LINE_LOOP); glVertex3f(0,0,-2); glVertex3f(0,0,2); glEnd(); +#endif /* DEBUG */ + } + if (sp->sphere_position == 0) /* FUDGE soo its not so obvious */ mySphere(0.48); else mySphere(0.5); glPopMatrix(); - sp->sphere_position += 3; + + if (++sp->sphere_tick >= SPHERE_TICKS-1) + { + sp->sphere_tick = -(SPHERE_TICKS-2); + sp->sphere_position += 3; + sp->sphere_position += 3; + } + if (sp->sphere_position >= NPOSITIONS) sp->sphere_position = 0; } -static void -reshape(ModeInfo * mi, int width, int height) +ENTRYPOINT void +reshape_stairs (ModeInfo * mi, int width, int height) { stairsstruct *sp = &stairs[MI_SCREEN(mi)]; @@ -351,6 +413,7 @@ reshape(ModeInfo * mi, int width, int height) static void pinit(void) { + int status; glClearDepth(1.0); glClearColor(0.0, 0.0, 0.0, 1.0); @@ -376,8 +439,21 @@ pinit(void) glEnable(GL_CULL_FACE); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - gluBuild2DMipmaps(GL_TEXTURE_2D, 3, WoodTextureWidth, WoodTextureHeight, - GL_RGB, GL_UNSIGNED_BYTE, WoodTextureData); + + clear_gl_error(); + status = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, + WoodTextureWidth, WoodTextureHeight, + GL_RGB, GL_UNSIGNED_BYTE, WoodTextureData); + if (status) + { + const char *s = (char *) gluErrorString (status); + fprintf (stderr, "%s: error mipmapping %dx%d texture: %s\n", + progname, WoodTextureWidth, WoodTextureHeight, + (s ? s : "(unknown)")); + exit (1); + } + check_gl_error("mipmapping"); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -388,8 +464,8 @@ pinit(void) glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular); } -void -init_stairs(ModeInfo * mi) +ENTRYPOINT void +init_stairs (ModeInfo * mi) { int screen = MI_SCREEN(mi); stairsstruct *sp; @@ -401,23 +477,28 @@ init_stairs(ModeInfo * mi) } sp = &stairs[screen]; sp->step = 0.0; + + /* make multiple screens rotate at slightly different rates. */ + sp->step -= frand(5.0); + sp->direction = LRAND() & 1; sp->sphere_position = NRAND(NPOSITIONS / 3) * 3; + sp->sphere_tick = 0; if ((sp->glx_context = init_GL(mi)) != NULL) { - reshape(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + reshape_stairs(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); glDrawBuffer(GL_BACK); - if (!glIsList(objects)) - objects = glGenLists(1); + if (!glIsList(sp->objects)) + sp->objects = glGenLists(1); pinit(); } else { MI_CLEARWINDOW(mi); } } -void -draw_stairs(ModeInfo * mi) +ENTRYPOINT void +draw_stairs (ModeInfo * mi) { stairsstruct *sp = &stairs[MI_SCREEN(mi)]; @@ -452,6 +533,7 @@ draw_stairs(ModeInfo * mi) glPopMatrix(); + if (mi->fps_p) do_fps (mi); glFlush(); glXSwapBuffers(display, window); @@ -459,8 +541,9 @@ draw_stairs(ModeInfo * mi) sp->step += 0.025; } -void -change_stairs(ModeInfo * mi) +#ifndef STANDALONE +ENTRYPOINT void +change_stairs (ModeInfo * mi) { stairsstruct *sp = &stairs[MI_SCREEN(mi)]; @@ -470,18 +553,25 @@ change_stairs(ModeInfo * mi) glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(sp->glx_context)); pinit(); } +#endif /* !STANDALONE */ -void -release_stairs(ModeInfo * mi) +ENTRYPOINT void +release_stairs (ModeInfo * mi) { if (stairs != NULL) { - (void) free((void *) stairs); - stairs = NULL; - } - if (glIsList(objects)) { - glDeleteLists(objects, 1); + int i; + for (i = 0; i < MI_NUM_SCREENS(mi); i++) { + stairsstruct *sp = &stairs[i]; + if (glIsList(sp->objects)) { + glDeleteLists(sp->objects, 1); + } + } + free(stairs); + stairs = NULL; } FreeAllGL(mi); } +XSCREENSAVER_MODULE ("Stairs", stairs) + #endif