X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fpolyhedra-gl.c;h=44badca99ba0314e4227c4f89b8aa32a3d61be63;hp=cdc7888632ef4a05869ebd50ba1df5b307c7628e;hb=6b1c86cf395f59389e4ece4ea8f4bea2c332745b;hpb=ffd8c0873576a9e3065696a624dce6b766b77062 diff --git a/hacks/glx/polyhedra-gl.c b/hacks/glx/polyhedra-gl.c index cdc78886..44badca9 100644 --- a/hacks/glx/polyhedra-gl.c +++ b/hacks/glx/polyhedra-gl.c @@ -1,4 +1,4 @@ -/* polyhedra, Copyright (c) 2004 Jamie Zawinski +/* polyhedra, Copyright (c) 2004-2008 Jamie Zawinski * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -15,54 +15,38 @@ * is in "polyhedra.c". */ -#include - -extern XtAppContext app; - -#define PROGCLASS "Polyhedra" -#define HACK_INIT init_polyhedra -#define HACK_DRAW draw_polyhedra -#define HACK_RESHAPE reshape_polyhedra -#define HACK_HANDLE_EVENT polyhedra_handle_event -#define EVENT_MASK PointerMotionMask -#define sws_opts xlockmore_opts - -#define DEF_SPIN "True" -#define DEF_WANDER "True" -#define DEF_SPEED "1.0" -#define DEF_TITLES "True" -#define DEF_DURATION "12" -#define DEF_WHICH "-1" - #define DEFAULTS "*delay: 30000 \n" \ "*showFPS: False \n" \ "*wireframe: False \n" \ - "*speed: " DEF_SPEED "\n" \ - "*spin: " DEF_SPIN "\n" \ - "*wander: " DEF_WANDER "\n" \ - "*duration: " DEF_DURATION "\n" \ - "*which: " DEF_WHICH "\n" \ "*titleFont: -*-times-bold-r-normal-*-180-*\n" \ "*titleFont2: -*-times-bold-r-normal-*-120-*\n" \ "*titleFont3: -*-times-bold-r-normal-*-80-*\n" \ +# define refresh_polyhedra 0 +# define release_polyhedra 0 #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) #include "xlockmore.h" -#include + +#define DEF_SPIN "True" +#define DEF_WANDER "True" +#define DEF_SPEED "1.0" +#define DEF_TITLES "True" +#define DEF_DURATION "12" +#define DEF_WHICH "random" + +#include "glxfonts.h" +#include "normals.h" #include "polyhedra.h" #include "colors.h" #include "rotator.h" #include "gltrackball.h" -#include #ifdef USE_GL /* whole file */ -#include - typedef struct { GLXContext *glx_context; rotator *rot; @@ -86,6 +70,9 @@ typedef struct { XFontStruct *xfont1, *xfont2, *xfont3; GLuint font1_dlist, font2_dlist, font3_dlist; + time_t last_change_time; + int change_tick; + } polyhedra_configuration; static polyhedra_configuration *bps = NULL; @@ -119,56 +106,10 @@ static argtype vars[] = { {&do_which_str,"which", "Which", DEF_WHICH, t_String}, }; -ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL}; +ENTRYPOINT ModeSpecOpt polyhedra_opts = {countof(opts), opts, countof(vars), vars, NULL}; -typedef struct { - double x,y,z; -} XYZ; - -static void -normalize (XYZ *p) -{ - double length; - length = sqrt (p->x * p->x + - p->y * p->y + - p->z * p->z); - if (length != 0) - { - p->x /= length; - p->y /= length; - p->z /= length; - } - else - { - p->x = 0; - p->y = 0; - p->z = 0; - } -} - -/* Calculate the unit normal at p given two other points p1,p2 on the - surface. The normal points in the direction of p1 crossproduct p2 - */ -static XYZ -calc_normal (XYZ p, XYZ p1, XYZ p2) -{ - XYZ n, pa, pb; - pa.x = p1.x - p.x; - pa.y = p1.y - p.y; - pa.z = p1.z - p.z; - pb.x = p2.x - p.x; - pb.y = p2.y - p.y; - pb.z = p2.z - p.z; - n.x = pa.y * pb.z - pa.z * pb.y; - n.y = pa.z * pb.x - pa.x * pb.z; - n.z = pa.x * pb.y - pa.y * pb.x; - normalize (&n); - return (n); -} - - /* Calculate the normals at each vertex of a face, and use the sum to decide which normal to assign to the entire face. This also solves problems caused by nonconvex faces, in most (but not all) cases. @@ -177,7 +118,7 @@ static void kludge_normal (int n, const int *indices, const point *points) { XYZ normal = { 0, 0, 0 }; - XYZ p; + XYZ p = { 0, 0, 0 }; int i; for (i = 0; i < n; ++i) { @@ -196,7 +137,7 @@ kludge_normal (int n, const int *indices, const point *points) normal.z += p.z; } - normalize(&normal); + /*normalize(&normal);*/ if (normal.x == 0 && normal.y == 0 && normal.z == 0) { glNormal3f (p.x, p.y, p.z); } else { @@ -204,147 +145,29 @@ kludge_normal (int n, const int *indices, const point *points) } } -static void -load_font (ModeInfo *mi, char *res, XFontStruct **fontP, GLuint *dlistP) -{ - const char *font = get_string_resource (res, "Font"); - XFontStruct *f; - Font id; - int first, last; - - if (!font) font = "-*-times-bold-r-normal-*-180-*"; - - f = XLoadQueryFont(mi->dpy, font); - if (!f) f = XLoadQueryFont(mi->dpy, "fixed"); - - id = f->fid; - first = f->min_char_or_byte2; - last = f->max_char_or_byte2; - - clear_gl_error (); - *dlistP = glGenLists ((GLuint) last+1); - check_gl_error ("glGenLists"); - glXUseXFont(id, first, last-first+1, *dlistP + first); - check_gl_error ("glXUseXFont"); - - *fontP = f; -} - static void load_fonts (ModeInfo *mi) { polyhedra_configuration *bp = &bps[MI_SCREEN(mi)]; - load_font (mi, "titleFont", &bp->xfont1, &bp->font1_dlist); - load_font (mi, "titleFont2", &bp->xfont2, &bp->font2_dlist); - load_font (mi, "titleFont3", &bp->xfont3, &bp->font3_dlist); + load_font (mi->dpy, "titleFont", &bp->xfont1, &bp->font1_dlist); + load_font (mi->dpy, "titleFont2", &bp->xfont2, &bp->font2_dlist); + load_font (mi->dpy, "titleFont3", &bp->xfont3, &bp->font3_dlist); } -static int -string_width (XFontStruct *f, const char *c) -{ - int w = 0; - while (*c) - { - int cc = *((unsigned char *) c); - w += (f->per_char - ? f->per_char[cc-f->min_char_or_byte2].rbearing - : f->min_bounds.rbearing); - c++; - } - return w; -} - -static void -print_title_string (ModeInfo *mi, const char *string, - GLfloat x, GLfloat y, - XFontStruct *font, int font_dlist) -{ - GLfloat line_height = font->ascent + font->descent; - GLfloat sub_shift = (line_height * 0.3); - int cw = string_width (font, "m"); - int tabs = cw * 7; - - y -= line_height; - - glPushAttrib (GL_TRANSFORM_BIT | /* for matrix contents */ - GL_ENABLE_BIT); /* for various glDisable calls */ - glDisable (GL_LIGHTING); - glDisable (GL_DEPTH_TEST); - { - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - { - glLoadIdentity(); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - { - int i; - int x2 = x; - Bool sub_p = False; - glLoadIdentity(); - - gluOrtho2D (0, mi->xgwa.width, 0, mi->xgwa.height); - - glColor3f (0.8, 0.8, 0); - - glRasterPos2f (x, y); - for (i = 0; i < strlen(string); i++) - { - char c = string[i]; - if (c == '\n') - { - glRasterPos2f (x, (y -= line_height)); - x2 = x; - } - else if (c == '\t') - { - x2 -= x; - x2 = ((x2 + tabs) / tabs) * tabs; /* tab to tab stop */ - x2 += x; - glRasterPos2f (x2, y); - } - else if (c == '[' && (isdigit (string[i+1]))) - { - sub_p = True; - glRasterPos2f (x2, (y -= sub_shift)); - } - else if (c == ']' && sub_p) - { - sub_p = False; - glRasterPos2f (x2, (y += sub_shift)); - } - else - { - glCallList (font_dlist + (int)(c)); - x2 += (font->per_char - ? font->per_char[c - font->min_char_or_byte2].width - : font->min_bounds.width); - } - } - } - glPopMatrix(); - } - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - } - glPopAttrib(); - - glMatrixMode(GL_MODELVIEW); -} - static void startup_blurb (ModeInfo *mi) { polyhedra_configuration *bp = &bps[MI_SCREEN(mi)]; const char *s = "Computing polyhedra..."; - print_title_string (mi, s, - mi->xgwa.width - (string_width (bp->xfont1, s) + 40), - 10 + bp->xfont1->ascent + bp->xfont1->descent, - bp->xfont1, bp->font1_dlist); + glColor3f (0.8, 0.8, 0); + print_gl_string (mi->dpy, bp->xfont1, bp->font1_dlist, + mi->xgwa.width, mi->xgwa.height, + mi->xgwa.width - (string_width (bp->xfont1, s) + 40), + mi->xgwa.height - 10, + s); glFinish(); glXSwapBuffers(MI_DISPLAY(mi), MI_WINDOW(mi)); } @@ -355,7 +178,7 @@ startup_blurb (ModeInfo *mi) */ static void new_label (ModeInfo *mi); -void +ENTRYPOINT void reshape_polyhedra (ModeInfo *mi, int width, int height) { GLfloat h = (GLfloat) height / (GLfloat) width; @@ -379,13 +202,13 @@ reshape_polyhedra (ModeInfo *mi, int width, int height) } -Bool +ENTRYPOINT Bool polyhedra_handle_event (ModeInfo *mi, XEvent *event) { polyhedra_configuration *bp = &bps[MI_SCREEN(mi)]; if (event->xany.type == ButtonPress && - event->xbutton.button & Button1) + event->xbutton.button == Button1) { bp->button_down_p = True; gltrackball_start (bp->trackball, @@ -394,11 +217,21 @@ polyhedra_handle_event (ModeInfo *mi, XEvent *event) return True; } else if (event->xany.type == ButtonRelease && - event->xbutton.button & Button1) + event->xbutton.button == Button1) { bp->button_down_p = False; return True; } + else if (event->xany.type == ButtonPress && + (event->xbutton.button == Button4 || + event->xbutton.button == Button5 || + event->xbutton.button == Button6 || + event->xbutton.button == Button7)) + { + gltrackball_mousewheel (bp->trackball, event->xbutton.button, 10, + !!event->xbutton.state); + return True; + } else if (event->xany.type == KeyPress) { KeySym keysym; @@ -472,9 +305,11 @@ new_label (ModeInfo *mi) else f = bp->xfont3, fl = bp->font3_dlist; /* tiny font */ - print_title_string (mi, label, - 10, mi->xgwa.height - 10, - f, fl); + glColor3f (0.8, 0.8, 0); + print_gl_string (mi->dpy, f, fl, + mi->xgwa.width, mi->xgwa.height, + 10, mi->xgwa.height - 10, + label); } } glEndList (); @@ -495,17 +330,16 @@ new_polyhedron (ModeInfo *mi) polyhedra_configuration *bp = &bps[MI_SCREEN(mi)]; polyhedron *p; int wire = MI_IS_WIREFRAME(mi); - static GLfloat bcolor[4] = {0.0, 0.0, 0.0, 1.0}; int i; /* Use the GLU polygon tesselator so that nonconvex faces are displayed correctly (e.g., for the "pentagrammic concave deltohedron"). */ GLUtesselator *tobj = gluNewTess(); - gluTessCallback (tobj, GLU_TESS_BEGIN, (_GLUfuncptr) &glBegin); - gluTessCallback (tobj, GLU_TESS_END, (_GLUfuncptr) &glEnd); - gluTessCallback (tobj, GLU_TESS_VERTEX, (_GLUfuncptr) &glVertex3dv); - gluTessCallback (tobj, GLU_TESS_ERROR, (_GLUfuncptr) &tess_error); + gluTessCallback (tobj, GLU_TESS_BEGIN, (void (*) (void)) &glBegin); + gluTessCallback (tobj, GLU_TESS_END, (void (*) (void)) &glEnd); + gluTessCallback (tobj, GLU_TESS_VERTEX, (void (*) (void)) &glVertex3dv); + gluTessCallback (tobj, GLU_TESS_ERROR, (void (*) (void)) &tess_error); mi->polygon_count = 0; @@ -526,6 +360,9 @@ new_polyhedron (ModeInfo *mi) new_label (mi); + if (wire) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glNewList (bp->object_list, GL_COMPILE); for (i = 0; i < p->nfaces; i++) { @@ -537,9 +374,11 @@ new_polyhedron (ModeInfo *mi) glColor3f (0, 1, 0); else { + GLfloat bcolor[4]; bcolor[0] = bp->colors[f->color].red / 65536.0; bcolor[1] = bp->colors[f->color].green / 65536.0; bcolor[2] = bp->colors[f->color].blue / 65536.0; + bcolor[2] = 1.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, bcolor); } @@ -562,7 +401,7 @@ new_polyhedron (ModeInfo *mi) } -void +ENTRYPOINT void init_polyhedra (ModeInfo *mi) { polyhedra_configuration *bp; @@ -636,7 +475,9 @@ init_polyhedra (ModeInfo *mi) int x; char c; do_which = -1; - if (1 == sscanf (do_which_str, " %d %c", &x, &c)) + if (!strcasecmp (do_which_str, "random")) + ; + else if (1 == sscanf (do_which_str, " %d %c", &x, &c)) do_which = x; else if (*do_which_str) { @@ -665,39 +506,37 @@ init_polyhedra (ModeInfo *mi) } -void +ENTRYPOINT void draw_polyhedra (ModeInfo *mi) { polyhedra_configuration *bp = &bps[MI_SCREEN(mi)]; Display *dpy = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); - static time_t last_time = 0; - - static GLfloat bspec[4] = {1.0, 1.0, 1.0, 1.0}; - static GLfloat bshiny = 128.0; + static const GLfloat bspec[4] = {1.0, 1.0, 1.0, 1.0}; + GLfloat bshiny = 128.0; if (!bp->glx_context) return; + glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context)); + if (bp->mode == 0 && do_which >= 0 && bp->change_to < 0) ; else if (bp->mode == 0) { - static int tick = 0; - if (bp->change_to >= 0) - tick = 999, last_time = 1; - if (tick++ > 10) + bp->change_tick = 999, bp->last_change_time = 1; + if (bp->change_tick++ > 10) { time_t now = time((time_t *) 0); - if (last_time == 0) last_time = now; - tick = 0; - if (!bp->button_down_p && now - last_time >= duration) + if (bp->last_change_time == 0) bp->last_change_time = now; + bp->change_tick = 0; + if (!bp->button_down_p && now - bp->last_change_time >= duration) { bp->mode = 1; /* go out */ bp->mode_tick = 20 * speed; - last_time = now; + bp->last_change_time = now; } } } @@ -768,4 +607,6 @@ draw_polyhedra (ModeInfo *mi) glXSwapBuffers(dpy, window); } +XSCREENSAVER_MODULE ("Polyhedra", polyhedra) + #endif /* USE_GL */