diff options
Diffstat (limited to 'hacks/glx/menger.c')
| -rw-r--r-- | hacks/glx/menger.c | 573 |
1 files changed, 0 insertions, 573 deletions
diff --git a/hacks/glx/menger.c b/hacks/glx/menger.c deleted file mode 100644 index a118400..0000000 --- a/hacks/glx/menger.c +++ /dev/null @@ -1,573 +0,0 @@ -/* menger, Copyright (c) 2001-2014 Jamie Zawinski <jwz@jwz.org> - * Copyright (c) 2002 Aurelien Jacobs <aurel@gnuage.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. - * - * Generates a 3D Menger Sponge gasket: - * - * ___+._______ - * __-"" -- __"""----._____ - * __.--"" -- ___--+---_____. __ .+'| - * _.-'"" __ +:"__ | ._..+"" __ .+' F - * J"--.____ __ """""+" .+' .J F - * J """""---.___ -- .+'" F' F - * L """""--...+' .J F - * L F"9 --. | . F' J - * L -_J L_J F"9 | ;'J .+J .J J - * | L_J | F.' .'| J F' J - * | |"""--.__ | ' |"" J J - * J ._ J ;;; | "L | . |-___J | - * J L J J ;-' | L | .'J |_ .' . | - * J "" J .---_L F"9 | F.' | .' FJ | - * L J .-' __ | L_J | ' :' ' .+ - * L '--.___ | | .J .' - * | F"9 """' | . F' .' - * | -_J F"9 | .'J .' - * +__ -_J F"9 | F.' .' - * """--___ L_J | ' .' - * """---___ | .' - * ""---._|.' - * - * The straightforward way to generate this object creates way more polygons - * than are needed, since there end up being many buried, interior faces. - * So during the recursive building of the object we store which face of - * each unitary cube we need to draw. Doing this reduces the polygon count - * by 40% - 60%. - * - * Another optimization we could do to reduce the polygon count would be to - * merge adjascent coplanar squares together into rectangles. This would - * result in the outer faces being composed of 1xN strips. It's tricky to - * to find these adjascent faces in non-exponential time, though. - * - * We could actually simulate large depths with a texture map -- if the - * depth is such that the smallest holes are only a few pixels across, - * just draw them as spots on the surface! It would look the same. - */ - -#define DEFAULTS "*delay: 30000 \n" \ - "*showFPS: False \n" \ - "*wireframe: False \n" \ - "*suppressRotationAnimation: True\n" \ - - -# define release_sponge 0 - -#include "xlockmore.h" -#include "colors.h" -#include "rotator.h" -#include "gltrackball.h" -#include <ctype.h> - -#ifdef USE_GL /* whole file */ - -#define DEF_SPIN "True" -#define DEF_WANDER "True" -#define DEF_SPEED "150" -#define DEF_MAX_DEPTH "3" - -typedef struct { - GLXContext *glx_context; - rotator *rot; - trackball_state *trackball; - Bool button_down_p; - GLuint sponge_list0; /* we store X, Y, and Z-facing surfaces */ - GLuint sponge_list1; /* in their own lists, to make it easy */ - GLuint sponge_list2; /* to color them differently. */ - - unsigned long squares_fp; - - int current_depth; - - int ncolors; - XColor *colors; - int ccolor0; - int ccolor1; - int ccolor2; - - int draw_tick; - -} sponge_configuration; - -static sponge_configuration *sps = NULL; - -static Bool do_spin; -static Bool do_wander; -static int speed; -static int max_depth; - -static XrmOptionDescRec opts[] = { - { "-wander", ".wander", XrmoptionNoArg, "True" }, - { "+wander", ".wander", XrmoptionNoArg, "False" }, - { "-spin", ".spin", XrmoptionSepArg, 0 }, - { "-speed", ".speed", XrmoptionSepArg, 0 }, - { "-depth", ".maxDepth", XrmoptionSepArg, 0 }, -}; - -static argtype vars[] = { - {&do_spin, "spin", "Spin", DEF_SPIN, t_Bool}, - {&do_wander, "wander", "Wander", DEF_WANDER, t_Bool}, - {&speed, "speed", "Speed", DEF_SPEED, t_Int}, - {&max_depth, "maxDepth", "MaxDepth", DEF_MAX_DEPTH, t_Int}, -}; - -ENTRYPOINT ModeSpecOpt sponge_opts = {countof(opts), opts, countof(vars), vars, NULL}; - - -/* Window management, etc - */ -ENTRYPOINT void -reshape_sponge (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 (30.0, 1/h, 1.0, 100.0); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt( 0.0, 0.0, 30.0, - 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0); - - { - GLfloat s = (MI_WIDTH(mi) < MI_HEIGHT(mi) - ? (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi)) - : 1); - glScalef (s, s, s); - } - - glClear(GL_COLOR_BUFFER_BIT); -} - - -#define X0 0x01 -#define X1 0x02 -#define Y0 0x04 -#define Y1 0x08 -#define Z0 0x10 -#define Z1 0x20 - -static int -cube (float x0, float x1, float y0, float y1, float z0, float z1, - int faces, int wireframe) -{ - int n = 0; - - if (faces & X0) - { - glBegin (wireframe ? GL_LINE_LOOP : GL_POLYGON); - glNormal3f (-1.0, 0.0, 0.0); - glVertex3f (x0, y1, z0); - glVertex3f (x0, y0, z0); - glVertex3f (x0, y0, z1); - glVertex3f (x0, y1, z1); - glEnd (); - n++; - } - if (faces & X1) - { - glBegin (wireframe ? GL_LINE_LOOP : GL_POLYGON); - glNormal3f (1.0, 0.0, 0.0); - glVertex3f (x1, y1, z1); - glVertex3f (x1, y0, z1); - glVertex3f (x1, y0, z0); - glVertex3f (x1, y1, z0); - glEnd (); - n++; - } - if (faces & Y0) - { - glBegin (wireframe ? GL_LINE_LOOP : GL_POLYGON); - glNormal3f (0.0, -1.0, 0.0); - glVertex3f (x0, y0, z0); - glVertex3f (x0, y0, z1); - glVertex3f (x1, y0, z1); - glVertex3f (x1, y0, z0); - glEnd (); - n++; - } - if (faces & Y1) - { - glBegin (wireframe ? GL_LINE_LOOP : GL_POLYGON); - glNormal3f (0.0, 1.0, 0.0); - glVertex3f (x0, y1, z0); - glVertex3f (x0, y1, z1); - glVertex3f (x1, y1, z1); - glVertex3f (x1, y1, z0); - glEnd (); - n++; - } - if (faces & Z0) - { - glBegin (wireframe ? GL_LINE_LOOP : GL_POLYGON); - glNormal3f (0.0, 0.0, -1.0); - glVertex3f (x1, y1, z0); - glVertex3f (x1, y0, z0); - glVertex3f (x0, y0, z0); - glVertex3f (x0, y1, z0); - glEnd (); - n++; - } - if (faces & Z1) - { - glBegin (wireframe ? GL_LINE_LOOP : GL_POLYGON); - glNormal3f (0.0, 0.0, 1.0); - glVertex3f (x0, y1, z1); - glVertex3f (x0, y0, z1); - glVertex3f (x1, y0, z1); - glVertex3f (x1, y1, z1); - glEnd (); - n++; - } - - return n; -} - -static int -menger_recurs_1 (int level, float x0, float x1, float y0, float y1, - float z0, float z1, int faces, Bool wireframe, - int orig, int forig) -{ - float xi, yi, zi; - int f, x, y, z; - int n = 0; - - if (orig) - { - if (wireframe) - n += cube (x0, x1, y0, y1, z0, z1, - faces & (X0 | X1 | Y0 | Y1), wireframe); - } - - if (level == 0) - { - if (!wireframe) - n += cube (x0, x1, y0, y1, z0, z1, faces, wireframe); - } - else - { - xi = (x1 - x0) / 3; - yi = (y1 - y0) / 3; - zi = (z1 - z0) / 3; - - for (x = 0; x < 3; x++) - for (y = 0; y < 3; y++) - for (z = 0; z < 3; z++) - { - if ((x != 1 && y != 1) - || (y != 1 && z != 1) - || (x != 1 && z != 1)) - { - f = faces; - - if (x == 1 || (x == 2 && (y != 1 && z != 1))) - f &= ~X0; - if (x == 1 || (x == 0 && (y != 1 && z != 1))) - f &= ~X1; - if (forig & X0 && x == 2 && (y == 1 || z == 1)) - f |= X0; - if (forig & X1 && x == 0 && (y == 1 || z == 1)) - f |= X1; - - if (y == 1 || (y == 2 && (x != 1 && z != 1))) - f &= ~Y0; - if (y == 1 || (y == 0 && (x != 1 && z != 1))) - f &= ~Y1; - if (forig & Y0 && y == 2 && (x == 1 || z == 1)) - f |= Y0; - if (forig & Y1 && y == 0 && (x == 1 || z == 1)) - f |= Y1; - - if (z == 1 || (z == 2 && (x != 1 && y != 1))) - f &= ~Z0; - if (z == 1 || (z == 0 && (x != 1 && y != 1))) - f &= ~Z1; - if (forig & Z0 && z == 2 && (x == 1 || y == 1)) - f |= Z0; - if (forig & Z1 && z == 0 && (x == 1 || y == 1)) - f |= Z1; - - n += menger_recurs_1 (level-1, - x0+x*xi, x0+(x+1)*xi, - y0+y*yi, y0+(y+1)*yi, - z0+z*zi, z0+(z+1)*zi, f, wireframe, 0, - forig); - } - else if (wireframe && (x != 1 || y != 1 || z != 1)) - n += cube (x0+x*xi, x0+(x+1)*xi, - y0+y*yi, y0+(y+1)*yi, - z0+z*zi, z0+(z+1)*zi, - forig & (X0 | X1 | Y0 | Y1), wireframe); - } - } - - return n; -} - -static int -menger_recurs (int level, float x0, float x1, float y0, float y1, - float z0, float z1, int faces, Bool wireframe, - int orig) -{ - return menger_recurs_1 (level, x0, x1, y0, y1, z0, z1, faces, - wireframe, orig, faces); -} - - -static void -build_sponge (sponge_configuration *sp, Bool wireframe, int level) -{ - glDeleteLists (sp->sponge_list0, 1); - glNewList(sp->sponge_list0, GL_COMPILE); - sp->squares_fp = menger_recurs (level, -1.5, 1.5, -1.5, 1.5, -1.5, 1.5, - X0 | X1, wireframe,1); - glEndList(); - - glDeleteLists (sp->sponge_list1, 1); - glNewList(sp->sponge_list1, GL_COMPILE); - sp->squares_fp += menger_recurs (level, -1.5, 1.5, -1.5, 1.5, -1.5, 1.5, - Y0 | Y1, wireframe,1); - glEndList(); - - glDeleteLists (sp->sponge_list2, 1); - glNewList(sp->sponge_list2, GL_COMPILE); - sp->squares_fp += menger_recurs (level, -1.5, 1.5, -1.5, 1.5, -1.5, 1.5, - Z0 | Z1, wireframe,1); - glEndList(); -} - - -ENTRYPOINT Bool -sponge_handle_event (ModeInfo *mi, XEvent *event) -{ - sponge_configuration *sp = &sps[MI_SCREEN(mi)]; - - if (gltrackball_event_handler (event, sp->trackball, - MI_WIDTH (mi), MI_HEIGHT (mi), - &sp->button_down_p)) - return True; - else if (event->xany.type == KeyPress) - { - KeySym keysym; - char c = 0; - XLookupString (&event->xkey, &c, 1, &keysym, 0); - if (c == '+' || c == '=' || - keysym == XK_Up || keysym == XK_Right || keysym == XK_Next) - { - sp->draw_tick = speed; - sp->current_depth += (sp->current_depth > 0 ? 1 : -1); - sp->current_depth--; - return True; - } - else if (c == '-' || c == '_' || - keysym == XK_Down || keysym == XK_Left || keysym == XK_Prior) - { - sp->draw_tick = speed; - sp->current_depth -= (sp->current_depth > 0 ? 1 : -1); - sp->current_depth--; - return True; - } - else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event)) - goto DEF; - } - else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event)) - { - DEF: - sp->draw_tick = speed; - return True; - } - - return False; -} - - - -ENTRYPOINT void -init_sponge (ModeInfo *mi) -{ - sponge_configuration *sp; - int wire = MI_IS_WIREFRAME(mi); - - MI_INIT (mi, sps); - - sp = &sps[MI_SCREEN(mi)]; - - if ((sp->glx_context = init_GL(mi)) != NULL) { - reshape_sponge (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - } - - if (!wire) - { - static const GLfloat pos0[4] = {-1.0, -1.0, 1.0, 0.1}; - static const GLfloat pos1[4] = { 1.0, -0.2, 0.2, 0.1}; - static const GLfloat dif0[4] = {1.0, 1.0, 1.0, 1.0}; - static const GLfloat dif1[4] = {1.0, 1.0, 1.0, 1.0}; - - glLightfv(GL_LIGHT0, GL_POSITION, pos0); - glLightfv(GL_LIGHT1, GL_POSITION, pos1); - glLightfv(GL_LIGHT0, GL_DIFFUSE, dif0); - glLightfv(GL_LIGHT1, GL_DIFFUSE, dif1); - - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_NORMALIZE); - - glShadeModel(GL_SMOOTH); - } - - { - double spin_speed = 1.0; - double wander_speed = 0.03; - sp->rot = make_rotator (do_spin ? spin_speed : 0, - do_spin ? spin_speed : 0, - do_spin ? spin_speed : 0, - 1.0, - do_wander ? wander_speed : 0, - True); - sp->trackball = gltrackball_init (True); - } - - sp->ncolors = 128; - sp->colors = (XColor *) calloc(sp->ncolors, sizeof(XColor)); - make_smooth_colormap (0, 0, 0, - sp->colors, &sp->ncolors, - False, 0, False); - sp->ccolor0 = 0; - sp->ccolor1 = sp->ncolors / 3; - sp->ccolor2 = sp->ccolor1 * 2; - - sp->sponge_list0 = glGenLists (1); - sp->sponge_list1 = glGenLists (1); - sp->sponge_list2 = glGenLists (1); - - sp->draw_tick = 9999999; -} - - -ENTRYPOINT void -draw_sponge (ModeInfo *mi) -{ - sponge_configuration *sp = &sps[MI_SCREEN(mi)]; - Display *dpy = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - - GLfloat color0[4] = {0.0, 0.0, 0.0, 1.0}; - GLfloat color1[4] = {0.0, 0.0, 0.0, 1.0}; - GLfloat color2[4] = {0.0, 0.0, 0.0, 1.0}; - - if (!sp->glx_context) - return; - - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *sp->glx_context); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glPushMatrix (); - - glScalef(1.1, 1.1, 1.1); - - { - double x, y, z; - get_position (sp->rot, &x, &y, &z, !sp->button_down_p); - glTranslatef((x - 0.5) * 8, - (y - 0.5) * 6, - (z - 0.5) * 15); - - gltrackball_rotate (sp->trackball); - - get_rotation (sp->rot, &x, &y, &z, !sp->button_down_p); - glRotatef (x * 360, 1.0, 0.0, 0.0); - glRotatef (y * 360, 0.0, 1.0, 0.0); - glRotatef (z * 360, 0.0, 0.0, 1.0); - } - - color0[0] = sp->colors[sp->ccolor0].red / 65536.0; - color0[1] = sp->colors[sp->ccolor0].green / 65536.0; - color0[2] = sp->colors[sp->ccolor0].blue / 65536.0; - - color1[0] = sp->colors[sp->ccolor1].red / 65536.0; - color1[1] = sp->colors[sp->ccolor1].green / 65536.0; - color1[2] = sp->colors[sp->ccolor1].blue / 65536.0; - - color2[0] = sp->colors[sp->ccolor2].red / 65536.0; - color2[1] = sp->colors[sp->ccolor2].green / 65536.0; - color2[2] = sp->colors[sp->ccolor2].blue / 65536.0; - - - sp->ccolor0++; - sp->ccolor1++; - sp->ccolor2++; - if (sp->ccolor0 >= sp->ncolors) sp->ccolor0 = 0; - if (sp->ccolor1 >= sp->ncolors) sp->ccolor1 = 0; - if (sp->ccolor2 >= sp->ncolors) sp->ccolor2 = 0; - - if (sp->draw_tick++ >= speed) - { - sp->draw_tick = 0; - if (sp->current_depth >= max_depth) - sp->current_depth = -max_depth; - sp->current_depth++; - build_sponge (sp, - MI_IS_WIREFRAME(mi), - (sp->current_depth < 0 - ? -sp->current_depth : sp->current_depth)); - - mi->polygon_count = sp->squares_fp; /* for FPS display */ - mi->recursion_depth = (sp->current_depth < 0 - ? -sp->current_depth : sp->current_depth); - } - - glScalef (2.0, 2.0, 2.0); - - glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color0); - glCallList (sp->sponge_list0); - glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color1); - glCallList (sp->sponge_list1); - glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color2); - glCallList (sp->sponge_list2); - - glPopMatrix (); - - if (mi->fps_p) do_fps (mi); - glFinish(); - - glXSwapBuffers(dpy, window); -} - - -ENTRYPOINT void -free_sponge (ModeInfo *mi) -{ - sponge_configuration *sp = &sps[MI_SCREEN(mi)]; - if (!sp->glx_context) return; - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *sp->glx_context); - if (sp->colors) free (sp->colors); - if (sp->rot) free_rotator (sp->rot); - if (sp->trackball) gltrackball_free (sp->trackball); - if (glIsList(sp->sponge_list0)) glDeleteLists(sp->sponge_list0, 1); - if (glIsList(sp->sponge_list1)) glDeleteLists(sp->sponge_list1, 1); - if (glIsList(sp->sponge_list2)) glDeleteLists(sp->sponge_list2, 1); -} - -XSCREENSAVER_MODULE_2 ("Menger", menger, sponge) - -#endif /* USE_GL */ |
