From d3a98cf6cbc3bd0b9efc570f58e8812c03931c18 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 16 Oct 2018 10:08:48 +0200 Subject: Original 5.40 --- hacks/glx/blocktube.c | 457 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 457 insertions(+) create mode 100644 hacks/glx/blocktube.c (limited to 'hacks/glx/blocktube.c') diff --git a/hacks/glx/blocktube.c b/hacks/glx/blocktube.c new file mode 100644 index 0000000..d4a402e --- /dev/null +++ b/hacks/glx/blocktube.c @@ -0,0 +1,457 @@ +/* blocktube, Copyright (c) 2003 Lars Damerow + * + * Based on Jamie Zawinski's original dangerball code. + * + * 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. + */ + +#define DEBUG 1 + +#define DEFAULTS "*delay: 40000 \n" \ + "*wireframe: False \n" \ + "*showFPS: False \n" \ + "*suppressRotationAnimation: True\n" \ + +# define release_blocktube 0 +# define blocktube_handle_event xlockmore_no_events +#undef countof +#define countof(x) (sizeof((x))/sizeof((*x))) + +#include "xlockmore.h" +#include "colors.h" +#include +#include + +#ifdef USE_GL /* whole file */ + +#define DEF_HOLDTIME "1000" +#define DEF_CHANGETIME "200" +#define MAX_ENTITIES 1000 +#define DEF_TEXTURE "True" +#define DEF_FOG "True" + +#if defined(USE_XPM) || defined(USE_XPMINC) || defined(STANDALONE) +/* USE_XPM & USE_XPMINC in xlock mode ; HAVE_XPM in xscreensaver mode */ +#include "ximage-loader.h" +#define I_HAVE_XPM + +#include "images/gen/blocktube_png.h" +#endif /* HAVE_XPM */ + +typedef struct { + int id, r, g, b; + GLfloat tVal; + int age; + int lifetime; + GLfloat position[3]; + GLfloat angle; + GLfloat angularVelocity; +} entity; + +typedef struct { + GLXContext *glx_context; + GLuint block_dlist; + int nextID; + + entity entities[MAX_ENTITIES]; + float targetR, targetG, targetB, + currentR, currentG, currentB, + deltaR, deltaG, deltaB; + int counter; + int changing; + GLfloat zoom; + GLfloat tilt; + GLuint envTexture; + XImage *texti; + + GLfloat tunnelLength; + GLfloat tunnelWidth; + int polys; + +} blocktube_configuration; + +static blocktube_configuration *lps = NULL; + +static GLint holdtime; +static GLint changetime; +static int do_texture; +static int do_fog; + +static XrmOptionDescRec opts[] = { + { "-holdtime", ".holdtime", XrmoptionSepArg, 0 }, + { "-changetime", ".changetime", XrmoptionSepArg, 0 }, + {"-texture", ".texture", XrmoptionNoArg, "True" }, + {"+texture", ".texture", XrmoptionNoArg, "False" }, + {"-fog", ".fog", XrmoptionNoArg, "True" }, + {"+fog", ".fog", XrmoptionNoArg, "False" }, +}; + +static argtype vars[] = { + {&holdtime, "holdtime", "Hold Time", DEF_HOLDTIME, t_Int}, + {&changetime, "changetime", "Change Time", DEF_CHANGETIME, \ + t_Int}, + {&do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool}, + {&do_fog, "fog", "Fog", DEF_FOG, t_Bool}, +}; + +static OptionStruct desc[] = { + {"-holdtime", "how long to stay on the same color"}, + {"-changetime", "how long it takes to fade to a new color"}, +}; + +ENTRYPOINT ModeSpecOpt blocktube_opts = {countof(opts), opts, countof(vars), vars, desc}; + +#ifdef USE_MODULES +ModStruct blocktube_description = + {"blocktube", "init_blocktube", "draw_blocktube", (char *)NULL, + "draw_blocktube", "init_blocktube", "free_blocktube", &blocktube_opts, + 40000, 30, 1, 1, 64, 1.0, "", + "A shifting tunnel of reflective blocks", 0, NULL}; +#endif /* USE_MODULES */ + +#if defined( I_HAVE_XPM ) +static Bool LoadGLTextures(ModeInfo *mi) +{ + blocktube_configuration *lp = &lps[MI_SCREEN(mi)]; + Bool status; + + status = True; + glGenTextures(1, &lp->envTexture); + glBindTexture(GL_TEXTURE_2D, lp->envTexture); + lp->texti = image_data_to_ximage(MI_DISPLAY(mi), MI_VISUAL(mi), + blocktube_png, sizeof(blocktube_png)); + if (!lp->texti) { + status = False; + } else { + glPixelStorei(GL_UNPACK_ALIGNMENT,1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lp->texti->width, lp->texti->height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, lp->texti->data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +# ifndef HAVE_JWZGLES /* #### Sphere maps unimplemented */ + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); +# endif + } + return status; +} +#endif + +static void newTargetColor(blocktube_configuration *lp) +{ + int luminance = 0; + + while (luminance <= 150) { + lp->targetR = random() % 256; + lp->targetG = random() % 256; + lp->targetB = random() % 256; + lp->deltaR = (lp->targetR - lp->currentR) / changetime; + lp->deltaG = (lp->targetG - lp->currentG) / changetime; + lp->deltaB = (lp->targetB - lp->currentB) / changetime; + luminance = 0.3 * lp->targetR + 0.59 * lp->targetG + 0.11 * lp->targetB; + } +} + +static void randomize_entity (blocktube_configuration *lp, entity *ent) +{ + ent->id = lp->nextID++; + ent->tVal = 1 - ((float)random() / RAND_MAX / 1.5); + ent->age = 0; + ent->lifetime = 100; + ent->angle = random() % 360; + ent->angularVelocity = 0.5-((float)(random()) / RAND_MAX); + ent->position[0] = (float)(random()) / RAND_MAX + lp->tunnelWidth; + ent->position[1] = (float)(random()) / RAND_MAX * 2; + ent->position[2] = -(float)(random()) / RAND_MAX * lp->tunnelLength; +} + +static void entityTick(blocktube_configuration *lp, entity *ent) +{ + ent->angle += ent->angularVelocity; + ent->position[2] += 0.1; + if (ent->position[2] > lp->zoom) { + ent->position[2] = -lp->tunnelLength + ((float)(random()) / RAND_MAX) * 20; + } + ent->age += 0.1; +} + +static void tick(blocktube_configuration *lp) +{ + lp->counter--; + if (!lp->counter) { + if (!lp->changing) { + newTargetColor(lp); + lp->counter = changetime; + } else { + lp->counter = holdtime; + } + lp->changing = (!lp->changing); + } else { + if (lp->changing) { + lp->currentR += lp->deltaR; + lp->currentG += lp->deltaG; + lp->currentB += lp->deltaB; + } + } +} + +static int cube_vertices(float x, float y, float z, int wire); + +ENTRYPOINT void reshape_blocktube (ModeInfo *mi, int width, int height); + +ENTRYPOINT void init_blocktube (ModeInfo *mi) +{ + int loop; + GLfloat fogColor[4] = {0,0,0,1}; + blocktube_configuration *lp; + int wire = MI_IS_WIREFRAME(mi); + + MI_INIT(mi, lps); + + lp = &lps[MI_SCREEN(mi)]; + lp->glx_context = init_GL(mi); + + lp->zoom = 30; + lp->tilt = 4.5; + lp->tunnelLength = 200; + lp->tunnelWidth = 5; + + if (wire) { + do_fog = False; + do_texture = False; + glLineWidth(2); + } + + lp->block_dlist = glGenLists (1); + glNewList (lp->block_dlist, GL_COMPILE); + lp->polys = cube_vertices(0.15, 1.2, 5.25, wire); + glEndList (); + +#if defined( I_HAVE_XPM ) + if (do_texture) { + if (!LoadGLTextures(mi)) { + fprintf(stderr, "%s: can't load textures!\n", progname); + exit(1); + } + glEnable(GL_TEXTURE_2D); + } +#endif + + /* kick on the fog machine */ + if (do_fog) { + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_LINEAR); + glHint(GL_FOG_HINT, GL_NICEST); + glFogf(GL_FOG_START, 0); + glFogf(GL_FOG_END, lp->tunnelLength/1.8); + glFogfv(GL_FOG_COLOR, fogColor); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + } + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glClearDepth(1.0f); + + if (!do_texture && !wire) { + /* If there is no texture, the boxes don't show up without a light. + Though I don't understand why all the blocks come out gray. + */ + GLfloat pos[4] = {0.0, 1.0, 1.0, 0.0}; + GLfloat amb[4] = {0.2, 0.2, 0.2, 1.0}; + GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0}; + GLfloat spc[4] = {1.0, 1.0, 1.0, 1.0}; + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glLightfv(GL_LIGHT0, GL_AMBIENT, amb); + glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); + glLightfv(GL_LIGHT0, GL_SPECULAR, spc); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + } + + lp->counter = holdtime; + lp->currentR = random() % 256; + lp->currentG = random() % 256; + lp->currentB = random() % 256; + newTargetColor(lp); + for (loop = 0; loop < MAX_ENTITIES; loop++) + { + randomize_entity(lp, &lp->entities[loop]); + } + reshape_blocktube(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); + glFlush(); +} + +ENTRYPOINT void free_blocktube (ModeInfo *mi) +{ + blocktube_configuration *lp = &lps[MI_SCREEN(mi)]; +# if defined ( I_HAVE_XPM ) + if (lp->glx_context) { + glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(lp->glx_context)); + + if (lp->envTexture) + glDeleteTextures(1, &lp->envTexture); + if (lp->texti) + XDestroyImage(lp->texti); + } +# endif +} + +ENTRYPOINT void reshape_blocktube (ModeInfo *mi, int width, int height) +{ + blocktube_configuration *lp = &lps[MI_SCREEN(mi)]; + GLfloat h = (GLfloat) height / (GLfloat) width; + int y = 0; + + glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(lp->glx_context)); + + if (width > height * 5) { /* tiny window: show middle */ + height = width; + y = -height/2; + h = height / (GLfloat) width; + } + + glViewport(0, y, (GLint) width, (GLint) height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, 1/h, 1.0, 100.0); + glMatrixMode(GL_MODELVIEW); + +# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */ + { + int o = (int) current_device_rotation(); + if (o != 0 && o != 180 && o != -180) + glScalef (1/h, 1/h, 1/h); + } +# endif +} + +static int cube_vertices(float x, float y, float z, int wire) +{ + int polygon_count = 0; + float x2, y2, z2, nv = 0.7; + x2 = x/2; + y2 = y/2; + z2 = z/2; + + glFrontFace(GL_CW); + + glNormal3f(0, 0, nv); + glBegin (wire ? GL_LINE_LOOP : GL_QUADS); + glTexCoord2f(0.0, 0.0); glVertex3f(-x2, y2, z2); + glTexCoord2f(1.0, 0.0); glVertex3f( x2, y2, z2); + glTexCoord2f(1.0, 1.0); glVertex3f( x2, -y2, z2); + glTexCoord2f(0.0, 1.0); glVertex3f(-x2, -y2, z2); + polygon_count++; + glEnd(); + + glNormal3f(0, 0, -nv); + glBegin (wire ? GL_LINE_LOOP : GL_QUADS); + glTexCoord2f(1.0, 0.0); glVertex3f(-x2, -y2, -z2); + glTexCoord2f(1.0, 1.0); glVertex3f( x2, -y2, -z2); + glTexCoord2f(0.0, 1.0); glVertex3f( x2, y2, -z2); + glTexCoord2f(0.0, 0.0); glVertex3f(-x2, y2, -z2); + polygon_count++; + glEnd(); + + glNormal3f(0, nv, 0); + glBegin (wire ? GL_LINE_LOOP : GL_QUADS); + glTexCoord2f(0.0, 1.0); glVertex3f(-x2, y2, -z2); + glTexCoord2f(0.0, 0.0); glVertex3f( x2, y2, -z2); + glTexCoord2f(1.0, 0.0); glVertex3f( x2, y2, z2); + glTexCoord2f(1.0, 1.0); glVertex3f(-x2, y2, z2); + polygon_count++; + glEnd(); + + glNormal3f(0, -nv, 0); + glBegin (wire ? GL_LINE_LOOP : GL_QUADS); + glTexCoord2f(1.0, 1.0); glVertex3f(-x2, -y2, -z2); + glTexCoord2f(0.0, 1.0); glVertex3f(-x2, -y2, z2); + glTexCoord2f(0.0, 0.0); glVertex3f( x2, -y2, z2); + glTexCoord2f(1.0, 0.0); glVertex3f( x2, -y2, -z2); + polygon_count++; + glEnd(); + + if (wire) return polygon_count; + + glNormal3f(nv, 0, 0); + glBegin (wire ? GL_LINE_LOOP : GL_QUADS); + glTexCoord2f(1.0, 0.0); glVertex3f( x2, -y2, -z2); + glTexCoord2f(1.0, 1.0); glVertex3f( x2, -y2, z2); + glTexCoord2f(0.0, 1.0); glVertex3f( x2, y2, z2); + glTexCoord2f(0.0, 0.0); glVertex3f( x2, y2, -z2); + polygon_count++; + glEnd(); + + glNormal3f(-nv, 0, 0); + glBegin (wire ? GL_LINE_LOOP : GL_QUADS); + glTexCoord2f(0.0, 0.0); glVertex3f(-x2, -y2, -z2); + glTexCoord2f(1.0, 0.0); glVertex3f(-x2, y2, -z2); + glTexCoord2f(1.0, 1.0); glVertex3f(-x2, y2, z2); + glTexCoord2f(0.0, 1.0); glVertex3f(-x2, -y2, z2); + polygon_count++; + glEnd(); + + return polygon_count; +} + +static void draw_block(ModeInfo *mi, entity *ent) +{ + blocktube_configuration *lp = &lps[MI_SCREEN(mi)]; + glCallList (lp->block_dlist); + mi->polygon_count += lp->polys; +} + +ENTRYPOINT void +draw_blocktube (ModeInfo *mi) +{ + blocktube_configuration *lp = &lps[MI_SCREEN(mi)]; + Display *dpy = MI_DISPLAY(mi); + Window window = MI_WINDOW(mi); + entity *cEnt = NULL; + int loop = 0; + + if (!lp->glx_context) + return; + + mi->polygon_count = 0; + + glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(lp->glx_context)); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (do_texture) { + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glBindTexture(GL_TEXTURE_2D, lp->envTexture); + } + + for (loop = 0; loop < MAX_ENTITIES; loop++) { + cEnt = &lp->entities[loop]; + + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, lp->zoom); + glRotatef(lp->tilt, 1.0f, 0.0f, 0.0f); + glRotatef(cEnt->angle, 0.0f, 0.0f, 1.0f); + glTranslatef(cEnt->position[0], cEnt->position[1], cEnt->position[2]); + glColor4ub((int)(lp->currentR * cEnt->tVal), + (int)(lp->currentG * cEnt->tVal), + (int)(lp->currentB * cEnt->tVal), 255); + draw_block(mi, cEnt); + entityTick(lp, cEnt); + } + tick(lp); + + if (mi->fps_p) do_fps (mi); + glFinish(); + glXSwapBuffers(dpy, window); +} + +XSCREENSAVER_MODULE ("BlockTube", blocktube) + +#endif /* USE_GL */ -- cgit v1.2.3-55-g7522