X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fpolyhedra-gl.c;h=507d295790768be406a9086e3f4f0e7feb427589;hb=39809ded547bdbb08207d3e514950425215b4410;hp=1b2d7eb7a787027610dba9656bf9b8317205f543;hpb=f8cf5ac7b2f53510f80a0eaf286a25298be17bfe;p=xscreensaver diff --git a/hacks/glx/polyhedra-gl.c b/hacks/glx/polyhedra-gl.c index 1b2d7eb7..507d2957 100644 --- a/hacks/glx/polyhedra-gl.c +++ b/hacks/glx/polyhedra-gl.c @@ -1,4 +1,4 @@ -/* polyhedra, Copyright (c) 2004-2011 Jamie Zawinski +/* polyhedra, Copyright (c) 2004-2014 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 @@ -18,19 +18,20 @@ #define DEFAULTS "*delay: 30000 \n" \ "*showFPS: False \n" \ "*wireframe: False \n" \ - "*titleFont: -*-helvetica-medium-r-normal-*-140-*\n" \ - "*titleFont2: -*-helvetica-medium-r-normal-*-100-*\n" \ - "*titleFont3: -*-helvetica-medium-r-normal-*-80-*\n" \ + "*titleFont: -*-helvetica-medium-r-normal-*-*-140-*-*-*-*-*-*\n" \ + "*titleFont2: -*-helvetica-medium-r-normal-*-*-100-*-*-*-*-*-*\n" \ + "*titleFont3: -*-helvetica-medium-r-normal-*-*-80-*-*-*-*-*-*\n" \ + "*suppressRotationAnimation: True\n" \ -# define refresh_polyhedra 0 +# define free_polyhedra 0 # define release_polyhedra 0 #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) #include "xlockmore.h" -#ifdef HAVE_COCOA +#ifdef HAVE_JWXYZ # include "jwxyz.h" #else # include @@ -49,7 +50,7 @@ #define DEF_DURATION "12" #define DEF_WHICH "random" -#include "glxfonts.h" +#include "texfont.h" #include "normals.h" #include "polyhedra.h" #include "colors.h" @@ -57,11 +58,16 @@ #include "gltrackball.h" #include "teapot.h" -#ifndef HAVE_COCOA +#ifndef HAVE_JWXYZ # define XK_MISCELLANY # include #endif +#ifndef HAVE_JWZGLES +# define HAVE_TESS +#endif + + #ifdef USE_GL /* whole file */ typedef struct { @@ -76,7 +82,6 @@ typedef struct { int which; int change_to; GLuint object_list; - GLuint title_list; int mode; /* 0 = normal, 1 = out, 2 = in */ int mode_tick; @@ -84,12 +89,7 @@ typedef struct { int ncolors; XColor *colors; -# ifdef HAVE_GLBITMAP - XFontStruct *xfont1, *xfont2, *xfont3; - GLuint font1_dlist, font2_dlist, font3_dlist; -# else texture_font_data *font1_data, *font2_data, *font3_data; -# endif time_t last_change_time; int change_tick; @@ -171,15 +171,9 @@ static void load_fonts (ModeInfo *mi) { polyhedra_configuration *bp = &bps[MI_SCREEN(mi)]; -# ifdef HAVE_GLBITMAP - 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); -# else /* !HAVE_GLBITMAP */ bp->font1_data = load_texture_font (mi->dpy, "titleFont"); bp->font2_data = load_texture_font (mi->dpy, "titleFont2"); bp->font3_data = load_texture_font (mi->dpy, "titleFont3"); -# endif /* !HAVE_GLBITMAP */ } @@ -189,29 +183,12 @@ startup_blurb (ModeInfo *mi) { polyhedra_configuration *bp = &bps[MI_SCREEN(mi)]; const char *s = "Computing polyhedra..."; -# ifdef HAVE_GLBITMAP - XFontStruct *f = bp->xfont1; -# else /* !HAVE_GLBITMAP */ texture_font_data *f = bp->font1_data; -# endif /* !HAVE_GLBITMAP */ glColor3f (0.8, 0.8, 0); - print_gl_string (mi->dpy, -# ifdef HAVE_GLBITMAP - bp->xfont1, bp->font1_dlist, -# else /* !HAVE_GLBITMAP */ - bp->font1_data, -# endif /* !HAVE_GLBITMAP */ - mi->xgwa.width, mi->xgwa.height, - mi->xgwa.width - ( -# ifdef HAVE_GLBITMAP - string_width (f, s, 0) -# else /* !HAVE_GLBITMAP */ - texture_string_width (f, s, 0) -# endif /* !HAVE_GLBITMAP */ - + 40), - mi->xgwa.height - 10, - s, False); + print_texture_label (mi->dpy, f, + mi->xgwa.width, mi->xgwa.height, + 0, s); glFinish(); glXSwapBuffers(MI_DISPLAY(mi), MI_WINDOW(mi)); } @@ -220,14 +197,19 @@ startup_blurb (ModeInfo *mi) /* Window management, etc */ -static void new_label (ModeInfo *mi); - ENTRYPOINT void reshape_polyhedra (ModeInfo *mi, int width, int height) { GLfloat h = (GLfloat) height / (GLfloat) width; + int y = 0; - glViewport (0, 0, (GLint) width, (GLint) height); + 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(); @@ -240,9 +222,6 @@ reshape_polyhedra (ModeInfo *mi, int width, int height) 0.0, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); - - /* need to re-render the text when the window size changes */ - new_label (mi); } @@ -251,31 +230,10 @@ polyhedra_handle_event (ModeInfo *mi, XEvent *event) { polyhedra_configuration *bp = &bps[MI_SCREEN(mi)]; - if (event->xany.type == ButtonPress && - event->xbutton.button == Button1) - { - bp->button_down_p = True; - gltrackball_start (bp->trackball, - event->xbutton.x, event->xbutton.y, - MI_WIDTH (mi), MI_HEIGHT (mi)); - return True; - } - else if (event->xany.type == ButtonRelease && - 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; - } + if (gltrackball_event_handler (event, bp->trackball, + MI_WIDTH (mi), MI_HEIGHT (mi), + &bp->button_down_p)) + return True; else if (event->xany.type == KeyPress) { KeySym keysym; @@ -286,22 +244,22 @@ polyhedra_handle_event (ModeInfo *mi, XEvent *event) if (c == ' ' || c == '\t' || c == '\r' || c == '\n') bp->change_to = random() % bp->npolyhedra; else if (c == '>' || c == '.' || c == '+' || c == '=' || - keysym == XK_Right || keysym == XK_Up) + keysym == XK_Right || keysym == XK_Up || keysym == XK_Next) bp->change_to = (bp->which + 1) % bp->npolyhedra; else if (c == '<' || c == ',' || c == '-' || c == '_' || c == '\010' || c == '\177' || - keysym == XK_Left || keysym == XK_Down) + keysym == XK_Left || keysym == XK_Down || keysym == XK_Prior) bp->change_to = (bp->which + bp->npolyhedra - 1) % bp->npolyhedra; + else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event)) + goto DEF; if (bp->change_to != -1) return True; } - else if (event->xany.type == MotionNotify && - bp->button_down_p) + else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event)) { - gltrackball_track (bp->trackball, - event->xmotion.x, event->xmotion.y, - MI_WIDTH (mi), MI_HEIGHT (mi)); + DEF: + bp->change_to = random() % bp->npolyhedra; return True; } @@ -310,84 +268,63 @@ polyhedra_handle_event (ModeInfo *mi, XEvent *event) static void -new_label (ModeInfo *mi) +draw_label (ModeInfo *mi) { polyhedra_configuration *bp = &bps[MI_SCREEN(mi)]; polyhedron *p = bp->which >= 0 ? bp->polyhedra[bp->which] : 0; + char label[1024]; + char name2[255]; + GLfloat color[4] = { 0.8, 0.8, 0.8, 1 }; + texture_font_data *f; + + if (!p || !do_titles) return; + + strcpy (name2, p->name); + if (*p->class) + sprintf (name2 + strlen(name2), " (%s)", p->class); + + sprintf (label, + "Polyhedron %d: \t%s\n\n" + "Wythoff Symbol:\t%s\n" + "Vertex Configuration:\t%s\n" + "Symmetry Group:\t%s\n" + /* "Dual of: \t%s\n" */ + "\n" + "Faces:\t %d\n" + "Edges:\t %d\n" + "Vertices:\t %d\n" + "Density:\t %d\n" + "Euler:\t%s%d\n", + bp->which, name2, p->wythoff, p->config, p->group, + /* p->dual, */ + p->logical_faces, p->nedges, p->logical_vertices, + p->density, (p->chi < 0 ? "" : " "), p->chi); + + if (MI_WIDTH(mi) >= 500 && MI_HEIGHT(mi) >= 375) + f = bp->font1_data; + else if (MI_WIDTH(mi) >= 350 && MI_HEIGHT(mi) >= 260) + f = bp->font2_data; /* small font */ + else + f = bp->font3_data; /* tiny font */ - glNewList (bp->title_list, GL_COMPILE); - if (p && do_titles) - { - char label[1024]; - char name2[255]; - strcpy (name2, p->name); - if (*p->class) - sprintf (name2 + strlen(name2), " (%s)", p->class); - - sprintf (label, - "Polyhedron %d: \t%s\n\n" - "Wythoff Symbol:\t%s\n" - "Vertex Configuration:\t%s\n" - "Symmetry Group:\t%s\n" - /* "Dual of: \t%s\n" */ - "\n" - "Faces:\t %d\n" - "Edges:\t %d\n" - "Vertices:\t %d\n" - "Density:\t %d\n" - "Euler:\t%s%d\n", - bp->which, name2, p->wythoff, p->config, p->group, - /* p->dual, */ - p->logical_faces, p->nedges, p->logical_vertices, - p->density, (p->chi < 0 ? "" : " "), p->chi); - - { -# ifdef HAVE_GLBITMAP - XFontStruct *f; - GLuint fl; -# else /* !HAVE_GLBITMAP */ - texture_font_data *f; -# endif /* !HAVE_GLBITMAP */ - if (MI_WIDTH(mi) >= 500 && MI_HEIGHT(mi) >= 375) -# ifdef HAVE_GLBITMAP - f = bp->xfont1, fl = bp->font1_dlist; /* big font */ -# else /* !HAVE_GLBITMAP */ - f = bp->font1_data; -# endif /* !HAVE_GLBITMAP */ - else if (MI_WIDTH(mi) >= 350 && MI_HEIGHT(mi) >= 260) -# ifdef HAVE_GLBITMAP - f = bp->xfont2, fl = bp->font2_dlist; /* small font */ -# else /* !HAVE_GLBITMAP */ - f = bp->font2_data; /* small font */ -# endif /* !HAVE_GLBITMAP */ - else -# ifdef HAVE_GLBITMAP - f = bp->xfont3, fl = bp->font3_dlist; /* tiny font */ -# else /* !HAVE_GLBITMAP */ - f = bp->font3_data; /* tiny font */ -# endif /* !HAVE_GLBITMAP */ - - glColor3f (0.8, 0.8, 0); - print_gl_string (mi->dpy, f, -# ifdef HAVE_GLBITMAP - fl, -# endif /* HAVE_GLBITMAP */ - mi->xgwa.width, mi->xgwa.height, - 10, mi->xgwa.height - 10, - label, False); - } - } - glEndList (); + glColor4fv (color); + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); + print_texture_label (mi->dpy, f, + mi->xgwa.width, mi->xgwa.height, + 1, label); } +#ifdef HAVE_TESS static void tess_error (GLenum errorCode) { fprintf (stderr, "%s: tesselation error: %s\n", progname, gluErrorString(errorCode)); - exit (0); + abort(); } +#endif /* HAVE_TESS */ + static void new_polyhedron (ModeInfo *mi) @@ -400,11 +337,13 @@ new_polyhedron (ModeInfo *mi) /* Use the GLU polygon tesselator so that nonconvex faces are displayed correctly (e.g., for the "pentagrammic concave deltohedron"). */ +# ifdef HAVE_TESS GLUtesselator *tobj = gluNewTess(); 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); +# endif /* HAVE_TESS */ mi->polygon_count = 0; @@ -423,18 +362,26 @@ new_polyhedron (ModeInfo *mi) bp->change_to = -1; p = bp->polyhedra[bp->which]; - new_label (mi); - if (wire) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glNewList (bp->object_list, GL_COMPILE); if (bp->which == bp->npolyhedra-1) { + GLfloat bcolor[4]; + bcolor[0] = bp->colors[0].red / 65536.0; + bcolor[1] = bp->colors[0].green / 65536.0; + bcolor[2] = bp->colors[0].blue / 65536.0; + bcolor[3] = 1.0; + if (wire) + glColor3f (0, 1, 0); + else + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, bcolor); + glScalef (0.8, 0.8, 0.8); p->nfaces = unit_teapot (6, wire); - p->nedges = p->nfaces * 2; /* #### is this right? */ - p->npoints = p->nfaces / 3; /* #### is this right? */ + p->nedges = p->nfaces * 3 / 2; + p->npoints = p->nfaces * 3; p->logical_faces = p->nfaces; p->logical_vertices = p->npoints; } @@ -455,12 +402,13 @@ new_polyhedron (ModeInfo *mi) 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; + bcolor[3] = 1.0; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, bcolor); } kludge_normal (f->npoints, f->points, p->points); +# ifdef HAVE_TESS gluTessBeginPolygon (tobj, 0); gluTessBeginContour (tobj); for (j = 0; j < f->npoints; j++) @@ -470,12 +418,26 @@ new_polyhedron (ModeInfo *mi) } gluTessEndContour (tobj); gluTessEndPolygon (tobj); +# else /* !HAVE_TESS */ + glBegin (wire ? GL_LINE_LOOP : + f->npoints == 3 ? GL_TRIANGLES : + f->npoints == 4 ? GL_QUADS : + GL_POLYGON); + for (j = 0; j < f->npoints; j++) + { + point *pp = &p->points[f->points[j]]; + glVertex3f (pp->x, pp->y, pp->z); + } + glEnd(); +# endif /* !HAVE_TESS */ } } glEndList (); mi->polygon_count += p->nfaces; +# ifdef HAVE_TESS gluDeleteTess (tobj); +# endif } @@ -502,14 +464,12 @@ init_polyhedra (ModeInfo *mi) polyhedra_configuration *bp; int wire = MI_IS_WIREFRAME(mi); - if (!bps) { - bps = (polyhedra_configuration *) - calloc (MI_NUM_SCREENS(mi), sizeof (polyhedra_configuration)); - if (!bps) { - fprintf(stderr, "%s: out of memory\n", progname); - exit(1); - } - } +# ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */ + MI_IS_WIREFRAME(mi) = 0; + wire = 0; +# endif + + MI_INIT (mi, bps); bp = &bps[MI_SCREEN(mi)]; @@ -553,14 +513,13 @@ init_polyhedra (ModeInfo *mi) spin_accel, do_wander ? wander_speed : 0, True); - bp->trackball = gltrackball_init (); + bp->trackball = gltrackball_init (True); } bp->npolyhedra = construct_polyhedra (&bp->polyhedra); construct_teapot (mi); bp->object_list = glGenLists (1); - bp->title_list = glGenLists (1); bp->change_to = -1; { @@ -638,7 +597,7 @@ draw_polyhedra (ModeInfo *mi) if (!bp->button_down_p && now - bp->last_change_time >= duration) { bp->mode = 1; /* go out */ - bp->mode_tick = 20 * speed; + bp->mode_tick = 20 / speed; bp->last_change_time = now; } } @@ -648,7 +607,7 @@ draw_polyhedra (ModeInfo *mi) if (--bp->mode_tick <= 0) { new_polyhedron (mi); - bp->mode_tick = 20 * speed; + bp->mode_tick = 20 / speed; bp->mode = 2; /* go in */ } } @@ -667,6 +626,15 @@ draw_polyhedra (ModeInfo *mi) glPushMatrix (); +# ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */ + { + GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi); + int o = (int) current_device_rotation(); + if (o != 0 && o != 180 && o != -180) + glScalef (1/h, 1/h, 1/h); + } +# endif + glScalef(1.1, 1.1, 1.1); { @@ -692,15 +660,15 @@ draw_polyhedra (ModeInfo *mi) if (bp->mode != 0) { GLfloat s = (bp->mode == 1 - ? bp->mode_tick / (20 * speed) - : ((20 * speed) - bp->mode_tick + 1) / (20 * speed)); + ? bp->mode_tick / (20 / speed) + : ((20 / speed) - bp->mode_tick + 1) / (20 / speed)); glScalef (s, s, s); } glScalef (2, 2, 2); glCallList (bp->object_list); if (bp->mode == 0 && !bp->button_down_p) - glCallList (bp->title_list); + draw_label (mi); /* print_texture_font can't go inside a display list */ glPopMatrix ();