diff options
Diffstat (limited to 'hacks/glx/timetunnel.c')
| -rw-r--r-- | hacks/glx/timetunnel.c | 1258 |
1 files changed, 0 insertions, 1258 deletions
diff --git a/hacks/glx/timetunnel.c b/hacks/glx/timetunnel.c deleted file mode 100644 index ee216cc..0000000 --- a/hacks/glx/timetunnel.c +++ /dev/null @@ -1,1258 +0,0 @@ -/* timetunnel. Based on dangerball.c, hack by Sean Brennan <zettix@yahoo.com>*/ -/* dangerball, Copyright (c) 2001-2018 Jamie Zawinski <jwz@jwz.org> - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. No representations are made about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - */ - -#include <math.h> /* for log2 */ - -#define DEFAULTS "*delay: 30000 \n" \ - "*count: 30 \n" \ - "*showFPS: False \n" \ - "*timeStart: 0.0 \n" \ - "*timeEnd: 27.79 \n" \ - "*wireframe: False \n" \ - - - -# define release_tunnel 0 - -#include "xlockmore.h" -#include "colors.h" -#include "rotator.h" -#include "gltrackball.h" - -#define DEF_START "0.00" -#define DEF_DILATE "1.00" -#define DEF_END "27.79" -#define DEF_LOCKLOGO "False" -#define DEF_DRAWLOGO "True" -#define DEF_REVERSE "False" -#define DEF_FOG "True" -#define DEF_TEXTURE "True" -#define MAX_TEXTURE 10 -#define CYL_LEN 14.0 -#define DIAMOND_LEN 10.0 - -static float start, end, dilate; -static Bool do_texture, drawlogo, wire, reverse, do_fog; -static const char *do_tx1, *do_tx2, *do_tx3, *do_tun1, *do_tun2, *do_tun3; - -static XrmOptionDescRec opts[] = { - {"-texture" , ".texture", XrmoptionNoArg, "true" }, - {"+texture" , ".texture", XrmoptionNoArg, "false" }, - {"-start" , ".start", XrmoptionSepArg, 0 }, - {"-end" , ".end", XrmoptionSepArg, 0 }, - {"-dilate" , ".dilate", XrmoptionSepArg, 0 }, - {"+logo" , ".drawlogo", XrmoptionNoArg, "false" }, - {"-reverse" , ".reverse", XrmoptionNoArg, "true" }, - {"+fog" , ".fog", XrmoptionNoArg, "false" }, - {"-marquee" , ".marquee", XrmoptionSepArg, 0}, - /* {"+marquee" , ".marquee", XrmoptionNoArg, "(none)"}, */ - {"-tardis" , ".tardis", XrmoptionSepArg, 0}, - /* {"+tardis" , ".tardis", XrmoptionNoArg, "(none)"}, */ - {"-head" , ".head", XrmoptionSepArg, 0}, - /* {"+head" , ".head", XrmoptionNoArg, "(none)"}, */ - {"-tun1" , ".tun1", XrmoptionSepArg, 0}, - /* {"+tun1" , ".tun1", XrmoptionNoArg, "(none)"}, */ - {"-tun2" , ".tun2", XrmoptionSepArg, 0}, - /* {"+tun2" , ".tun2", XrmoptionNoArg, "(none)"}, */ - {"-tun3" , ".tun3", XrmoptionSepArg, 0}, - /* {"+tun3" , ".tun3", XrmoptionNoArg, "(none)"}, */ -}; - -static argtype vars[] = { - {&do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool}, - {&start, "start", "Start", DEF_START, t_Float}, - {&end, "end", "End", DEF_END , t_Float}, - {&dilate, "dilate", "Dilate", DEF_DILATE , t_Float}, - {&drawlogo, "drawlogo", "DrawLogo", DEF_DRAWLOGO , t_Bool}, - {&reverse, "reverse", "Reverse", DEF_REVERSE , t_Bool}, - {&do_fog, "fog", "Fog", DEF_FOG , t_Bool}, - {&do_tx1, "marquee", "Marquee", "(none)", t_String}, - {&do_tx2, "tardis", "Tardis", "(none)", t_String}, - {&do_tx3, "head", "Head", "(none)", t_String}, - {&do_tun1, "tun1", "Tunnel 1", "(none)", t_String}, - {&do_tun2, "tun2", "Tunnel 2", "(none)", t_String}, - {&do_tun3, "tun3", "Tunnel 3", "(none)", t_String}, -}; - -ENTRYPOINT ModeSpecOpt tunnel_opts = {countof(opts), opts, countof(vars), vars, NULL}; -#include "ximage-loader.h" -#include "images/gen/logo-180_png.h" -#include "images/gen/tunnelstar_png.h" -#include "images/gen/timetunnel0_png.h" -#include "images/gen/timetunnel1_png.h" -#include "images/gen/timetunnel2_png.h" - - -#ifdef USE_GL /* whole file */ - -/* ANIMATION CONTROLS */ -/* an effect is a collection of floating point variables that vary with time. -A knot is a timestamp with an array of floats. State is the current values of the floats. -State is set by linearly interpolating between knots */ -typedef struct { - float *knots, *state; - int numknots, knotwidth; - float direction; -} effect_t; - -typedef struct { - GLXContext *glx_context; - rotator *rot; - trackball_state *trackball; - Bool button_down_p; - - int time_oldusec, time_oldsec; - - int num_texshifts; /* animates tunnels. Not an effect. */ - GLfloat pos, *texshift; - - GLuint texture_binds[MAX_TEXTURE], cyllist, diamondlist; - - float effect_time, effect_maxsecs; /* global time controls */ - float start_time, end_time; - - int num_effects; - effect_t *effects; /* array of all effects */ - -} tunnel_configuration; - -static tunnel_configuration *tconf = NULL; - -/* allocate memory and populate effect with knot data */ -static void init_effect(effect_t *e, int numk, int kwidth, - float dir, float *data ) -{ - int i, j; - - e->numknots = numk; - e->knotwidth = kwidth; - e->direction = dir; - e->knots = calloc(numk * kwidth, sizeof(float)); - e->state = calloc(numk, sizeof(float)); - for ( i = 0 ; i < e->numknots ; i++) - for ( j = 0 ; j < e->knotwidth; j++) - e->knots[i * kwidth + j] = data[i * kwidth + j]; -} - -/* static knot data. each effect is listed and knot data is hard coded. - Knots are linerally interpolated to yield float values, depending on - knot width. knot format is [time, data, data, data...]. - Data can be alpha, zvalue, etc. */ -static void init_effects(effect_t *e, int effectnum) -{ - /* effect 1: wall tunnel. percent closed */ - float e1d[6][2] = - {{0.0, 0.055}, - {2.77, 0.055}, - {3.07,1.0}, - {8.08, 1.0}, - {8.08, 0.0}, - {10.0, 0.0}}; - /* effect 2: tardis. distance and alpha */ - float e2d[8][3] = - { {0.0, 0.0 , 0.0}, - {3.44, 0.0 , 0.0}, - {3.36, 5.4 , 0.0}, - {4.24, 3.66, 1.0}, - {6.51, 2.4, 0.94}, - {8.08, 0.75 , 0.0}, - {8.08, 0.0 , 0.0}, - {10.0, 0.0, 0.0}}; - /* effect 3: cylinder. alpha */ - float e3d[5][2] = - {{0.0, 0.0}, - {6.41, 0.00}, - {8.08, 1.0}, - {14.81, 1.0}, - {15.65, 0.0}}; - - /* effect 4: fog. color, density, start, end */ - float e4d[9][5] = - {{0.0 , 1.0, 0.45, 3.0, 15.0}, - {6.40, 1.0, 0.45, 3.0, 14.0}, - {8.08, 1.0, 0.95, 1.0, 14.0}, - {15.17, 1.0, 0.95, 1.0, 6.0}, - {15.51, 1.0, 0.95, 3.0, 8.0}, - {23.35, 1.0, 0.95, 3.0, 8.0}, - {24.02, 0.0, 0.95, 2.3, 5.0}, - {26.02, 0.0, 0.95, 2.3, 5.0}, - {27.72, 0.0, 1.00, 0.3, 0.9} - }; - - /* effect 5: logo. dist, alpha */ - float e5d[7][3] = - {{0.0, 0.0, 0.0}, - {16.52, 0.00, 0.0}, - {16.52, 0.80, 0.01}, - {17.18, 1.15, 1.0}, - {22.36, 5.3, 1.0}, - {22.69, 5.7, 0.0}, - {22.69, 0.0, 0.0} - }; - /* effect 6: diamond tunnel. alpha */ - float e6d[3][2] = - {{0.0, 0.00}, - {15.17, 0.00}, - {15.51,1.0}}; - - /* effect 7: tardis cap draw . positive draws cap*/ - float e7d[3][2] = - {{0.0, -1.00}, - {4.24, -1.00}, - {4.24, 1.00}}; - - /* effect 8: star/asterisk: alpha */ - float e8d[5][2] = - {{0.0, .00}, - {10.77, .00}, - {11.48, 1.00}, - {15.35, 1.00}, - {16.12, 0.00}}; - - /* effect 9: whohead 1 alpha */ - float e9d[5][2] = - {{0.0, .00}, - {13.35, .00}, - {14.48, 1.00}, - {15.17, 1.00}, - {15.97, 0.00}}; - /* {14.87, 1.00}, - {15.17, 0.00}}; */ - - /* effect 10: whohead-brite alpha */ - float e10d[5][2] = - {{0.0, .00}, - {11.34, .00}, - {12.34, .20}, - {13.35, 0.60}, - {14.48, 0.00}}; - /* {13.95, 0.00}}; */ - - /* effect 11: whohead-psy alpha */ - float e11d[5][2] = - {{0.0, .00}, - {14.87, .00}, - {15.17, 1.00}, - {15.91, 0.00}, - {16.12, 0.00}}; - - /* effect 12: whohead-silhouette pos-z, alpha */ - float e12d[6][3] = - {{0.0, 1.0, .00}, - {15.07, 1.0, 0.00}, - {15.07, 1.0, 1.00}, - {16.01, 1.0, 1.00}, - {16.78, 0.5, 1.00}, - {16.78, 0.1, 0.00} }; - - /* effect 1: wall tunnel */ - if (effectnum == 1) - init_effect(e, 6, 2, -0.2, (float *) e1d); - - /* effect 2: tardisl */ - if (effectnum == 2) - init_effect(e, 8, 3, 1.0, (float *) e2d); - - /* effect 3: cylinder tunnel */ - if (effectnum == 3) - init_effect(e, 5, 2, 0.889 , (float *) e3d); - - /* effect 4: fog color */ - if (effectnum == 4) - init_effect(e, 9, 5, 1.0, (float *) e4d); - /* effect 5: logo distance, alpha*/ - if (effectnum == 5) - init_effect(e, 7, 3, 1.0, (float *) e5d); - /* effect 6: diamond tunnel, alpha*/ - if (effectnum == 6) - init_effect(e, 3, 2, 0.24 , (float *) e6d); - - /* effect 7: cap wall tunnel*/ - if (effectnum == 7) - init_effect(e, 3, 2, 1.0, (float *) e7d); - - /* effect 8: asterisk */ - if (effectnum == 8) - init_effect(e, 5, 2, 1.0, (float *) e8d); - - /* effect 9, 10, 11, 12: whoheads */ - if (effectnum == 9 ) - init_effect(e, 5, 2, 1.0, (float *) e9d); - if (effectnum == 10 ) - init_effect(e, 5, 2, 1.0, (float *) e10d); - if (effectnum == 11 ) - init_effect(e, 5, 2, 1.0, (float *) e11d); - if (effectnum == 12 ) - init_effect(e, 6, 3, 1.0, (float *) e12d); -} - - -/* set fog parameters, controlled by effect */ -static void update_fog(float color, float density, float start, float end) -{ - GLfloat col[4]; - - col[0] = col[1] = col[2] = color; - col[3] = 1.0; - - glFogi(GL_FOG_MODE, GL_LINEAR); - glFogfv(GL_FOG_COLOR, col); - glFogf(GL_FOG_DENSITY, density); - glFogf(GL_FOG_START, start); - glFogf(GL_FOG_END, end); -} - -/* set effect's floating point data values by linearally interpolating -between two knots whose times bound the current time: eff_time */ - -static void update_knots(effect_t *e, float eff_time) -{ - int i, j; - float timedelta, lowknot, highknot, *curknot, *nextknot; - - for ( i = 0 ; i < e->numknots ; i++) - if (e->knots[i * e->knotwidth] <= eff_time) { - if ( i < e->numknots - 1) - nextknot = e->knots + (i + 1) * e->knotwidth; - else - /*repeat last knot to carry knot data forward*/ - nextknot = e->knots + (i) * e->knotwidth; - curknot = e->knots + i * e->knotwidth; - if (*nextknot - *curknot <= 0.0) timedelta = 1.0; - else - timedelta = (eff_time-*curknot)/(*nextknot-*curknot); - if (timedelta > 1.0) timedelta = 1.0; - for (j = 1 ; j < e->knotwidth ; j++) { - highknot = (float) *(nextknot + j); - lowknot = (float) *(curknot + j); - e->state[j - 1 ] = lowknot+(highknot-lowknot)*timedelta; - } - } - -} - - -/* Window management, etc - */ -ENTRYPOINT void -reshape_tunnel (ModeInfo *mi, int width, int height) -{ - GLfloat h = (GLfloat) height / (GLfloat) width; - int y = 0; - - if (width > height * 5) { /* tiny window: show middle */ - height = width * 9/16; - y = -height/2; - h = height / (GLfloat) width; - } - - glViewport (0, y, (GLint) width, (GLint) height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective (90.0, 1/h, 0.2, 50.0); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt( 0.0, 0.0, 0.3, - 0.0, 0.0, 1.0, - 0.0, 1.0, 0.0); - - glClear(GL_COLOR_BUFFER_BIT); -} - - - - -ENTRYPOINT Bool -tunnel_handle_event (ModeInfo *mi, XEvent *event) -{ - tunnel_configuration *tc = &tconf[MI_SCREEN(mi)]; - - if (gltrackball_event_handler (event, tc->trackball, - MI_WIDTH (mi), MI_HEIGHT (mi), - &tc->button_down_p)) - return True; - - return False; -} - -static void setTexParams(void) -{ - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); -} - -static void update_animation(tunnel_configuration *tc) { - - /* time based, of course*/ - /* shift texture based on elapsed time since previous call*/ - struct timeval tv; - struct timezone tz; - int elapsed_usecs, elapsed_secs, i; - float computed_timeshift; - - /* get new animation time */ - gettimeofday(&tv, &tz); - elapsed_secs = tv.tv_sec - tc->time_oldsec; - elapsed_usecs = tv.tv_usec - tc->time_oldusec; - /* store current time */ - tc->time_oldsec = tv.tv_sec ; - tc->time_oldusec = tv.tv_usec; - /* elaped time. computed timeshift is tenths of a second */ - computed_timeshift = (float) (elapsed_secs * 1000000. + elapsed_usecs)/ - 100000.0; - - /* calibrate effect time to lie between start and end times */ - /* loop if time exceeds end time */ - if (reverse) - tc->effect_time -= computed_timeshift / 10.0 * dilate; - else - tc->effect_time += computed_timeshift / 10.0 * dilate; - if ( tc->effect_time >= tc->end_time) - tc->effect_time = tc->start_time; - if ( tc->effect_time < tc->start_time) - tc->effect_time = tc->end_time;; - - /* move texture shifters in effect's direction, e.g. tardis - tunnel moves backward, effect 1's direction */ - if (reverse) { - tc->texshift[0] -= tc->effects[1].direction * computed_timeshift/ 10.0; - tc->texshift[1] -= tc->effects[3].direction * computed_timeshift/ 10.0; - tc->texshift[2] -= tc->effects[6].direction * computed_timeshift/ 10.0; - - } else { - tc->texshift[0] += tc->effects[1].direction * computed_timeshift/ 10.0; - tc->texshift[1] += tc->effects[3].direction * computed_timeshift/ 10.0; - tc->texshift[2] += tc->effects[6].direction * computed_timeshift/ 10.0; - } - - /* loop texture shifters if necessary */ - for ( i = 0 ; i < tc->num_texshifts; i++) { - if (tc->texshift[i] > 1.0) - tc->texshift[i] -= (int) tc->texshift[i]; - if (tc->texshift[i]< -1.0) - tc->texshift[i] -= (int) tc->texshift[i]; - } - - /* update effect data with current time. Uses linear interpolation */ - for ( i = 1 ; i <= tc->num_effects ; i++) - update_knots(&tc->effects[i], tc->effect_time); - -} /*update_animation*/ - -/* draw a textured(tex) quad at a certain depth (z), and certain alpha (alpha), -with aspect ratio (aspect), and blending mode (blend_mode) of either adding -or subtracting. if alpha is zero or less, nothing happens */ -static void draw_sign(ModeInfo *mi, tunnel_configuration *tc, float z, float alpha, float aspect, - GLuint tex, int blend_mode) -{ - -#ifndef HAVE_JWZGLES - if (alpha > 0.0) { - mi->polygon_count ++; - /* glEnable(GL_BLEND); */ - glBlendColor(0.0, 0.0, 0.0, alpha); - /*glBlendColor(0.0, 0.0, 0.0, 0.0); */ - if (blend_mode == 1) { - glBlendFunc(GL_CONSTANT_ALPHA, - GL_ONE); - glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); - } else if (blend_mode == 2) { - glBlendFunc(GL_CONSTANT_ALPHA, - GL_ONE); - glBlendEquation(GL_FUNC_ADD); - } else { - glBlendFunc(GL_CONSTANT_ALPHA, - GL_ONE_MINUS_CONSTANT_ALPHA); - glBlendEquation(GL_FUNC_ADD); - } /* blend mode switch */ - -#ifdef HAVE_GLBINDTEXTURE - if (do_texture) - glBindTexture(GL_TEXTURE_2D, tc->texture_binds[tex]); -#endif - glBegin(GL_QUADS); - glTexCoord2f(1.0, 0.0); - glVertex3f(-1.0 , -1.0 * aspect , z); - glTexCoord2f(1.0, 1.0); - glVertex3f(-1.0 , 1.0 * aspect , z); - glTexCoord2f(0.0, 1.0); - glVertex3f(1.0 , 1.0 * aspect , z); - glTexCoord2f(0.0, 0.0); - glVertex3f(1.0 , -1.0 * aspect , z); - glEnd(); - if (blend_mode != 0) { - glBlendFunc(GL_CONSTANT_ALPHA, - GL_ONE_MINUS_CONSTANT_ALPHA); - glBlendEquation(GL_FUNC_ADD); - } - /* glDisable(GL_BLEND); */ - - } -#endif /* !HAVE_JWZGLES */ -} /* draw sign */ - - -/* draw a time tunnel. used for both cylinder and diamond tunnels. - uses texture shifter (indexed by shiftnum) to simulate motion. - tunnel does not move, and is acutally a display list. if alpha = 0, skip */ -static void draw_cyl(ModeInfo *mi, tunnel_configuration *tc, float alpha, int texnum, int listnum, int shiftnum) -{ -#ifndef HAVE_JWZGLES - if (alpha > 0.0) { - if (listnum == tc->diamondlist) - mi->polygon_count += 4; - if (listnum == tc->cyllist) - mi->polygon_count += 30; - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glTranslatef(tc->texshift[shiftnum], 0.0, 0.0); - glMatrixMode(GL_MODELVIEW); - /* glEnable(GL_BLEND); */ - glBlendColor(0.0, 0.0, 0.0, alpha); - glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA); - -#ifdef HAVE_GLBINDTEXTURE - if (do_texture) - glBindTexture(GL_TEXTURE_2D, tc->texture_binds[texnum]); -#endif - glCallList(listnum); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - /* glDisable(GL_BLEND); */ - } -#endif /* HAVE_JWZGLES */ -} - - -/* make tardis type tunnel. Starts as walls and then -grows to outline of tardis. percent is how complete -tardis outline is. cap is to draw cap for nice fog effects */ - -static void make_wall_tunnel(ModeInfo *mi, tunnel_configuration *tc, float percent, float cap) -{ - /* tardis is about 2x1, so wrap tex around, starting at the base*/ - /* tex coords are: - - _tl__tr_ - | | -l| |r - | | - -bl__br_ - that's br=bottom right, etc. ttr is top-top-right */ - - float half_floor= 0.08333333333333333, - full_wall = 0.33333333333333333; - float br1, - r0 , r1 , - tr0, tr1, - tl0, tl1, - l0 , l1 , - depth=0.3, zdepth=15.0; - /* zdepth is how far back tunnel goes */ - /* depth is tex coord scale. low number = fast texture shifting */ - - float textop, texbot; - float height; - - br1 = half_floor; - r0 = br1 ; - r1 = r0 + full_wall; - tr0 = r1; - tr1 = r1 + half_floor; - tl0 = tr1; - tl1 = tl0 + half_floor; - l0 = tr1; - l1 = l0 + full_wall; - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glRotatef(90.0, 0.0, 0.0, 1.0); - glTranslatef(tc->texshift[0], 0.0, 0.0); - glMatrixMode(GL_MODELVIEW); - -#ifdef HAVE_GLBINDTEXTURE - if (do_texture) - glBindTexture(GL_TEXTURE_2D, tc->texture_binds[0]); -#endif - glColor3f(1.0, 1.0, 0.0); - if (cap > 0.0 && percent > 0.0 && drawlogo && do_fog) { - mi->polygon_count += 6; - glBegin(GL_TRIANGLE_FAN); - glVertex3f(0.0, 0.0, zdepth); - glVertex3f(-1.0, -2.0, zdepth); - glVertex3f(1.0, -2.0, zdepth); - glVertex3f(1.0, 2.0, zdepth); - glVertex3f(0.2, 2.0, zdepth); - glVertex3f(0.2, 2.2, zdepth); - glVertex3f(-0.2, 2.2, zdepth); - glVertex3f(-0.2, 2.0, zdepth); - glVertex3f(-1.0, 2.0, zdepth); - glVertex3f(-1.0, -2.0, zdepth); - glEnd(); - } - if (percent > ( full_wall * 2.0)) { - glBegin(GL_QUADS); - - height = (percent - full_wall * 2.0) /( 1.0 - full_wall * 2.0); - if (height > 1.0) height = 1.0; - - - if ( height > 0.8) { - mi->polygon_count += 2; - if ( height > 0.90) { - mi->polygon_count += 2; - /* TTTR */ - texbot = tr0; - textop = tr0 + half_floor * height; - glTexCoord2f(0.0, texbot); - glVertex3f(0.2, 2.2, 0.0); - - glTexCoord2f(0.0, textop); - glVertex3f(2.0 - height * 2.0, 2.2, 0.0); - - glTexCoord2f(depth, textop); - glVertex3f(2.0 - height * 2.0, 2.2, zdepth); - - glTexCoord2f(depth, texbot); - glVertex3f(0.2, 2.2, zdepth); - - /* TTTL */ - texbot = tl1 - half_floor * height; - textop = tl1; - glTexCoord2f(0.0, texbot); - glVertex3f(-2.0 + height * 2.0, 2.2, 0.0); - - glTexCoord2f(0.0, textop); - glVertex3f(-0.2, 2.2, 0.0); - - glTexCoord2f(depth, textop); - glVertex3f(-0.2, 2.2, zdepth); - - glTexCoord2f(depth, texbot); - glVertex3f(-2.0 + height * 2.0, 2.2, zdepth); - } - if (height > 0.90) height = 0.90; - - /* TTR */ - texbot = tr0; - textop = tr0 + half_floor * height; - glTexCoord2f(0.0, texbot); - glVertex3f(0.2, 2.0, 0.0); - - glTexCoord2f(0.0, textop); - glVertex3f(0.2, 0.4 + height * 2.0, 0.0); - - glTexCoord2f(depth, textop); - glVertex3f(0.2, 0.4 + height * 2.0, zdepth); - - glTexCoord2f(depth, texbot); - glVertex3f(0.2, 2.0, zdepth); - - /* TTL */ - texbot = tl1 - half_floor * height; - textop = tl1; - glTexCoord2f(0.0, texbot); - /*glVertex3f(-.2, 2.0 + (0.9 - height) * 2.0, 0.0); */ - glVertex3f(-.2, 0.4 + height * 2.0, 0.0); - - glTexCoord2f(0.0, textop); - glVertex3f(-.2, 2.0, 0.0); - - glTexCoord2f(depth, textop); - glVertex3f(-.2, 2.0, zdepth); - - glTexCoord2f(depth, texbot); - glVertex3f(-.2, 0.4 + height * 2.0, zdepth); - } - - height = (percent - full_wall * 2.0) /( 1.0 - full_wall * 2.0); - if (height > 0.8) height = 0.8; - - - mi->polygon_count += 2; - /* TR */ - texbot = tr0; - textop = tr0 + half_floor * height; - glTexCoord2f(0.0, texbot); - glVertex3f(1.0, 2.0, 0.0); - - glTexCoord2f(0.0, textop); - glVertex3f(1.0 - height, 2.0, 0.0); - - glTexCoord2f(depth, textop); - glVertex3f(1.0 - height, 2.0, zdepth); - - glTexCoord2f(depth, texbot); - glVertex3f(1.0, 2.0, zdepth); - - /* TL */ - texbot = tl1 - half_floor * height; - textop = tl1; - glTexCoord2f(0.0, texbot); - glVertex3f(-1.0 + height, 2.0, 0.0); - - glTexCoord2f(0.0, textop); - glVertex3f(-1.0, 2.0, 0.0); - - glTexCoord2f(depth, textop); - glVertex3f(-1.0, 2.0, zdepth); - - glTexCoord2f(depth, texbot); - glVertex3f(-1.0 + height, 2.0, zdepth); - - height = (percent - full_wall * 2.0) /( 1.0 - full_wall * 2.0); - - if (height > 1.0) height = 1.0; - - - mi->polygon_count += 2; - /* BR */ - texbot = tr0; - textop = tr0 + half_floor * height; - glTexCoord2f(0.0, texbot); - glVertex3f(1.0, -2.0, 0.0); - - glTexCoord2f(0.0, textop); - glVertex3f(1.0 - height, -2.0, 0.0); - - glTexCoord2f(depth, textop); - glVertex3f(1.0 - height, -2.0, zdepth); - - glTexCoord2f(depth, texbot); - glVertex3f(1.0, -2.0, zdepth); - - /* BL */ - texbot = tl1 - half_floor * height; - textop = tl1; - glTexCoord2f(0.0, texbot); - glVertex3f(-1.0 + height, -2.0, 0.0); - - glTexCoord2f(0.0, textop); - glVertex3f(-1.0, -2.0, 0.0); - - glTexCoord2f(depth, textop); - glVertex3f(-1.0, -2.0, zdepth); - - glTexCoord2f(depth, texbot); - glVertex3f(-1.0 + height, -2.0, zdepth); - - - glEnd(); - } - - if (percent > 0.0) { - mi->polygon_count += 2; - glBegin(GL_QUADS); - height = percent / ( full_wall * 2.0); - if (height > 1.0) height = 1.0; - textop = (l0 + l1) / 2.0 - full_wall * 0.5 * height; - texbot = (l0 + l1) / 2.0 + full_wall * 0.5 * height; - - glTexCoord2f(0.0, textop); - glVertex3f(-1.0, height * 2, 0.0); - - glTexCoord2f(0.0, texbot); - glVertex3f(-1.0, -height * 2, 0.0); - - glTexCoord2f(depth, texbot); - glVertex3f(-1.0, -height * 2, zdepth); - - glTexCoord2f(depth, textop); - glVertex3f(-1.0, height * 2, zdepth); - - textop = (r0 + r1) / 2.0 - full_wall * 0.5 * height; - texbot = (r0 + r1) / 2.0 + full_wall * 0.5 * height; - - glTexCoord2f(0.0, texbot); - glVertex3f(1.0, height * 2, 0.0); - - glTexCoord2f(0.0, textop); - glVertex3f(1.0, -height * 2, 0.0); - - glTexCoord2f(depth, textop); - glVertex3f(1.0, -height * 2, zdepth); - - glTexCoord2f(depth, texbot); - glVertex3f(1.0, height * 2, zdepth); - glEnd(); - } - - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); -} /* make_wall_tunnel */ - -/* wraps an int to between min and max. - Kind of like the remainder when devided by (max - min). - Used to create torus mapping on square array */ -static int wrapVal(int val, int min, int max) -{ - int ret; - - ret = val; - if (val >= max) - ret = min + (val - max ) % (max - min); - if (val < min) - ret = max - (min - val) % (max - min); - return(ret); -} - -/*=================== Load Texture =========================================*/ -/* ripped from atunnel.c, Copyright (c) E. Lassauge, 2003-2004. */ -/* modified like so by Sean Brennan: - take texture object for glbind - removed xlock stuff - Added filters: - blur color / alpha channel [3x3 box filter, done [blur] times - anegative : create b/w image from zero alpha. zero alpha gets bw_color, - nonzero alpha gets 1.0 - bwcolor, then alpha flipped to 1-alpha. - - Inputs: xpm structure, or filename of xmp image. if filename == NULL, use structure. - Outputs: texture bound to texutre Id texbind. - -*/ - -static float mylog2(float x) { return ( log(x) / log(2));} - -static void LoadTexture(ModeInfo * mi, const unsigned char *fn, unsigned long size, const char *filename, GLuint texbind, int blur, float bw_color, Bool anegative, Bool onealpha) -{ - /* looping and temporary array index variables */ - int ix, iy, bx, by, indx, indy, boxsize, cchan, tmpidx, dtaidx; - - float boxdiv, tmpfa, blursum ; - unsigned char *tmpbuf, tmpa; - Bool rescale; - - - XImage *teximage; /* Texture data */ - - rescale = False; - - boxsize = 2; - boxdiv = 1.0 / ( boxsize * 2.0 + 1.0) / ( boxsize * 2.0 + 1.0); - - - if (filename) - teximage = file_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi), - filename); - else - teximage = image_data_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi), - fn, size); - if (teximage == NULL) { - fprintf(stderr, "%s: error reading the texture.\n", progname); - glDeleteTextures(1, &texbind); - do_texture = False; - exit(0); - } - - /* check if image is 2^kumquat, where kumquat is an integer between 1 and 10. Recale to - nearest power of 2. */ - tmpfa = mylog2((float) teximage->width); - bx = 2 << (int) (tmpfa -1); - if (bx != teximage->width) { - rescale = True; - if ((tmpfa - (int) tmpfa) > 0.5849) - bx = bx * 2; - } - tmpfa = mylog2((float) teximage->height); - by = 2 << (int) (tmpfa - 1); - if (by != teximage->height) { - rescale = True; - if ((tmpfa - (int) tmpfa) > 0.5849) - by = by * 2; - } - - if (rescale) { -#ifndef HAVE_JWZGLES - tmpbuf = calloc(bx * by * 4, sizeof(unsigned char)); - if (gluScaleImage(GL_RGBA, teximage->width, teximage->height, GL_UNSIGNED_BYTE, teximage->data, - bx, by, GL_UNSIGNED_BYTE, tmpbuf)) - check_gl_error("scale image"); - - free(teximage->data); - teximage->data = (char *) tmpbuf; - teximage->width = bx; - teximage->height= by; -#endif /* !HAVE_JWZGLES */ - } - /* end rescale code */ - - if (anegative ) { - for (ix = 0 ; ix < teximage->height * teximage->width; ix++) - { - if (!teximage->data[ ix * 4 + 3]) { - teximage->data[ ix * 4 + 3] = (unsigned char) 0xff; - tmpa = (unsigned char) (bw_color * 0xff); - } else { - if (onealpha) - teximage->data[ ix * 4 + 3] = (unsigned char) 0xff; - else - teximage->data[ ix * 4 + 3] = (unsigned char) 0xff - - teximage->data[ ix * 4 + 3]; - tmpa = (unsigned char) ((1.0 - bw_color) * 0xff); - } - /* make texture uniform b/w color */ - teximage->data[ ix * 4 + 0] = - (unsigned char) ( tmpa); - teximage->data[ ix * 4 + 1] = - (unsigned char) ( tmpa); - teximage->data[ ix * 4 + 2] = - (unsigned char) ( tmpa); - /* negate alpha */ - } - } - - if (blur > 0) { - if (! anegative ) /* anegative alread b/w's the whole image */ - for (ix = 0 ; ix < teximage->height * teximage->width; ix++) - if (!teximage->data[ ix * 4 + 3]) - { - teximage->data[ ix * 4 + 0] = - (unsigned char) ( 255.0 * bw_color); - teximage->data[ ix * 4 + 1] = - (unsigned char) ( 255.0 * bw_color); - teximage->data[ ix * 4 + 2] = - (unsigned char) ( 255.0 * bw_color); - } - ; - tmpbuf = calloc(teximage->height * teximage->width * 4, sizeof(unsigned char) ) ; - while (blur--) { - /* zero out tmp alpha buffer */ - for (iy = 0 ; iy <teximage->height * teximage->width * 4 ; iy++) - tmpbuf[iy] = 0; - for (cchan = 0; cchan < 4 ; cchan++) { - for (iy = 0 ; iy < teximage->height ; iy++) { - for (ix = 0 ; ix < teximage->width ; ix++) { - dtaidx = (teximage->width * iy + ix) * 4; - tmpa = teximage->data[dtaidx + cchan]; - tmpfa = (float) tmpa * boxdiv; - /* box filter */ - for (by = -boxsize ; by <= boxsize; by++) { - for (bx = -boxsize ; bx <= boxsize; bx++) { - indx = wrapVal(ix + bx, 0, teximage->width); - indy = wrapVal(iy + by, 0, teximage->height); - tmpidx = (teximage->width * indy + indx) * 4; - blursum = tmpfa; - tmpbuf[tmpidx + cchan] += (unsigned char) blursum; - } /* for bx */ - } /* for by */ - } /* for ix */ - } /* for iy */ - } /* for cchan */ - /* copy back buffer */ - for (ix = 0 ; ix < teximage->height * teximage->width * 4; ix++) - teximage->data[ix] = tmpbuf[ix]; - } /*while blur */ - free(tmpbuf); /*tidy*/ - } /* if blur */ - - - - - clear_gl_error(); -#ifdef HAVE_GLBINDTEXTURE - glBindTexture(GL_TEXTURE_2D, texbind); - clear_gl_error(); /* WTF? sometimes "invalid op" from glBindTexture! */ -#endif - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, teximage->width, teximage->height, - 0, GL_RGBA, GL_UNSIGNED_BYTE, teximage->data); - check_gl_error("texture"); - setTexParams(); - XDestroyImage(teximage); -} - -/* creates cylinder for time tunnel. sides, zmin, zmax, rad(ius) obvious. - stretch scales texture coords; makes tunnel go slower the larger it is. - not drawn, but put into display list. */ -static void makecyl(int sides, float zmin, float zmax, float rad, float stretch) -{ - int i; - float theta; - - /* cap */ - if (do_fog) { - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(1.0, 0.0); - glVertex3f(0.0 , 0.0 , zmax); - for (i = 0 ; i <= sides; i++) { - theta = 2.0 * M_PI * ((float) i / (float) sides); - glVertex3f(cos(theta) * rad, sin(theta) * rad, zmax); - } - glVertex3f(cos(0.0) * rad, sin(0.0) * rad, zmax); - glEnd(); - } - - glBegin(GL_QUAD_STRIP); - for (i = 0 ; i <= sides; i++) - { - if ( i != sides) { - theta = 2.0 * M_PI * ((float) i / (float) sides); - glTexCoord2f(0.0, 1.0 * (float) i / (float) sides); - glVertex3f(cos(theta) * rad, sin(theta) * rad, zmin); - glTexCoord2f(stretch, 1.0 * (float) i / (float) sides); - glVertex3f(cos(theta) * rad, sin(theta) * rad, zmax); - } else { - theta = 0.0; - glTexCoord2f(0.0, 1.0); - glVertex3f(cos(theta) * rad, sin(theta) * rad, zmin); - glTexCoord2f(stretch, 1.0); - glVertex3f(cos(theta) * rad, sin(theta) * rad, zmax); - } - } - glEnd(); -} - -ENTRYPOINT void -init_tunnel (ModeInfo *mi) -{ - int i; - - tunnel_configuration *tc; - - wire = MI_IS_WIREFRAME(mi); - -# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */ - wire = 0; -# endif - - MI_INIT (mi, tconf); - - tc = &tconf[MI_SCREEN(mi)]; - - tc->glx_context = init_GL(mi); - - tc->cyllist = glGenLists(1); - tc->diamondlist = glGenLists(1); - tc->num_effects = 12; - tc->num_texshifts = 3; - tc->effect_time = 0.0; - tc->effect_maxsecs = 30.00; - /* check bounds on cmd line opts */ - if (start > tc->effect_maxsecs) start = tc->effect_maxsecs; - if (end > tc->effect_maxsecs) end = tc->effect_maxsecs; - if (start < tc->effect_time) start = tc->effect_time; - if (end < tc->effect_time) end = tc->effect_time; - - /* set loop times, in seconds */ - tc->start_time = start; - tc->end_time = end; - - /* reset animation knots, effect 0 not defined. */ - tc->effects = calloc(sizeof(effect_t),tc->num_effects + 1); - for ( i = 1; i <= tc->num_effects ; i++) - init_effects(&tc->effects[i], i); - - if (wire) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - do_texture = False; - } - - if (do_texture) - { - /* the following textures are loaded, and possible overridden: - tunnel 1, tunnel 2, tunnel 3, marquee, tardis, head */ - glGenTextures(MAX_TEXTURE, tc->texture_binds); - - /*LoadTexture(*mi, *data, size, *filename, texbind, bluralpha, bw_color, anegative, onealpha)*/ - if (strcasecmp (do_tun1, "(none)")) /* tunnel 1 */ - LoadTexture(mi, NULL, 0, do_tun1, tc->texture_binds[0], 0,0.0, False, False); - else - LoadTexture(mi, timetunnel0_png, sizeof(timetunnel0_png), NULL, tc->texture_binds[0], 0, 0.0, False, False); - if (strcasecmp (do_tun2, "(none)")) /* tunnel 2 */ - LoadTexture(mi, NULL, 0, do_tun2, tc->texture_binds[2], 0,0.0, False, False); - else - LoadTexture(mi, timetunnel1_png, sizeof(timetunnel1_png), NULL, tc->texture_binds[2], 0, 0.0, False, False); - if (strcasecmp (do_tun3, "(none)")) /* tunnel 3 */ - LoadTexture(mi, NULL, 0, do_tun3, tc->texture_binds[5], 0,0.0, False, False); - else - LoadTexture(mi, timetunnel2_png, sizeof(timetunnel2_png), NULL, tc->texture_binds[5], 0, 0.0, False, False); - LoadTexture(mi, tunnelstar_png, sizeof(tunnelstar_png), NULL, tc->texture_binds[4], 0, 0.0, False, False); - if (strcasecmp (do_tx1, "(none)")) /* marquee */ - LoadTexture(mi, NULL, 0, do_tx1, tc->texture_binds[3], 0,0.0, False, False); -#ifndef HAVE_JWZGLES /* logo_180_png is 180px which is not a power of 2! */ - else - LoadTexture(mi, logo_180_png, sizeof(logo_180_png), NULL, tc->texture_binds[3], 0,0.0, False, False); -#endif - if (strcasecmp (do_tx2, "(none)")) /* tardis */ - LoadTexture(mi, NULL, 0, do_tx2, tc->texture_binds[1], 0, 0.0 ,False, False); -#ifndef HAVE_JWZGLES /* logo_180_png is 180px which is not a power of 2! */ - else - LoadTexture(mi, logo_180_png, sizeof(logo_180_png), NULL, tc->texture_binds[1], 0,0.0, False, False); -#endif - if (strcasecmp (do_tx3, "(none)")) { /* head */ - LoadTexture(mi, NULL, 0, do_tx3, tc->texture_binds[6], 0, 0.0 ,False, False); - /* negative */ - LoadTexture(mi, NULL, 0, do_tx3, tc->texture_binds[9], 2,1.0, True, True); -#ifndef HAVE_JWZGLES /* logo_180_png is 180px which is not a power of 2! */ - } else { - LoadTexture(mi, logo_180_png, sizeof(logo_180_png), NULL, tc->texture_binds[6], 0,0.0, False, False); - /* negative */ - LoadTexture(mi, logo_180_png, sizeof(logo_180_png), NULL, tc->texture_binds[9], 2,1.0, True, True); -#endif - } - glEnable(GL_TEXTURE_2D); - check_gl_error("tex"); - } - - reshape_tunnel (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - - glDisable(GL_DEPTH_TEST); /* who needs it? ;-) */ - - if (do_fog) - glEnable(GL_FOG); - - if (!wire) - { - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.5); - } - - tc->trackball = gltrackball_init (True); - - - tc->texshift = calloc(tc->num_texshifts, sizeof(GLfloat)); - for ( i = 0 ; i < tc->num_texshifts; i++) - tc->texshift[i] = 0.0; - - glNewList(tc->cyllist, GL_COMPILE); - makecyl(30, -0.1, CYL_LEN, 1., 10. / 40.0 * CYL_LEN); - /*makecyl(30, -0.5, DIAMOND_LEN, 1., 4. / 40 * DIAMOND_LEN); */ - glEndList(); - - glNewList(tc->diamondlist, GL_COMPILE); - makecyl(4, -0.5, DIAMOND_LEN, 1., 4. / 40 * DIAMOND_LEN); - glEndList(); -} - - -ENTRYPOINT void -draw_tunnel (ModeInfo *mi) -{ - tunnel_configuration *tc = &tconf[MI_SCREEN(mi)]; - Display *dpy = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - - - if (!tc->glx_context) - return; - - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *tc->glx_context); - - glShadeModel(GL_SMOOTH); - - glEnable(GL_NORMALIZE); - /* glEnable(GL_CULL_FACE); */ - - glClear(GL_COLOR_BUFFER_BIT ); - - update_animation(tc); - - - glPushMatrix (); - - glRotatef(180., 0., 1., 0.); - gltrackball_rotate (tc->trackball); - glRotatef(180., 0., 1., 0.); - - - - mi->polygon_count = 0; - - update_fog(tc->effects[4].state[0], /*color*/ - tc->effects[4].state[1], /*density*/ - tc->effects[4].state[2], /*start*/ - tc->effects[4].state[3]); /*end*/ - - /* --- begin composite image assembly --- */ - - /* head mask and draw diamond tunnel */ - - glEnable(GL_BLEND); - draw_cyl(mi, tc, tc->effects[6].state[0], 5, tc->diamondlist, 2); - if (drawlogo) - draw_sign(mi, tc,tc->effects[12].state[0], tc->effects[12].state[1], 1.0 / 1.33, 9, 1); - glDisable(GL_BLEND); - /* then tardis tunnel */ - make_wall_tunnel(mi, tc, tc->effects[1].state[0], tc->effects[7].state[0]); - - /* then cylinder tunnel */ - glEnable(GL_BLEND); - draw_cyl(mi, tc, tc->effects[3].state[0], 2, tc->cyllist, 1); - - /*void draw_sign(mi, tc,z,alpha,aspect,tex,blendmode)*/ - /* tardis */ - if (drawlogo) - draw_sign(mi, tc, tc->effects[2].state[0], tc->effects[2].state[1], 2.0, 1, 0); - /* marquee */ - if (drawlogo) - draw_sign(mi, tc, tc->effects[5].state[0], tc->effects[5].state[1], 1.0, 3, 0); - /*who head brite*/ - if (drawlogo) - draw_sign(mi, tc,1.0, tc->effects[10].state[0], 1.0 / 1.33, 6, 2); - /*who head psychadelic REMOVED*/ - /* draw_sign(mi, tc,1.0, tc->effects[11].state[0], 1.0 / 1.33, 8, 0); */ - - /* star */ - /* draw_sign(mi, tc, tc->effects[8].state[0]tc->effects[8].state[0], 1.0 , 1.0, 4, 1); */ - draw_sign(mi, tc, tc->effects[8].state[0], tc->effects[8].state[0], 1.0, 4, 1); - - /* normal head */ - if (drawlogo) - draw_sign(mi, tc,1.0, tc->effects[9].state[0], 1.0 / 1.33, 6, 0); - - /* --- end composite image assembly --- */ - - - glPopMatrix (); - - if (mi->fps_p) do_fps (mi); - glFinish(); - - check_gl_error("drawing done, calling swap buffers"); - glXSwapBuffers(dpy, window); -} - - -ENTRYPOINT void -free_tunnel (ModeInfo *mi) -{ - tunnel_configuration *tc = &tconf[MI_SCREEN(mi)]; - int i; - if (!tc->glx_context) return; - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *tc->glx_context); - if (tc->trackball) gltrackball_free (tc->trackball); - if (tc->rot) free_rotator (tc->rot); - if (tc->texshift) free (tc->texshift); - if (tc->effects) { - for (i = 0; i < tc->num_effects; i++) { - if (tc->effects[i].knots) free (tc->effects[i].knots); - if (tc->effects[i].state) free (tc->effects[i].state); - } - free (tc->effects); - } - if (glIsList(tc->cyllist)) glDeleteLists(tc->cyllist, 1); - if (glIsList(tc->diamondlist)) glDeleteLists(tc->diamondlist, 1); - glDeleteTextures (MAX_TEXTURE, tc->texture_binds); -} - -XSCREENSAVER_MODULE_2 ("TimeTunnel", timetunnel, tunnel) - -#endif /* USE_GL */ |
