X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Flament.c;h=3f5080c04d0b0b0650b988c7df94d29c732c7850;hb=3c58fb6311db49c46f1670922933b27c6ea0c065;hp=75321a48c129635a056ffcf585e3b2270c0bba4d;hpb=ce3185de9d9705e259f2b60dd4b5509007fa17d4;p=xscreensaver diff --git a/hacks/glx/lament.c b/hacks/glx/lament.c index 75321a48..3f5080c0 100644 --- a/hacks/glx/lament.c +++ b/hacks/glx/lament.c @@ -81,8 +81,10 @@ #define PROGCLASS "Lament" #define HACK_INIT init_lament #define HACK_DRAW draw_lament +#define HACK_RESHAPE reshape_lament #define lament_opts xlockmore_opts #define DEFAULTS "*delay: 10000 \n" \ + "*showFPS: False \n" \ "*wireframe: False \n" \ "*texture: True \n" #include "xlockmore.h" @@ -106,10 +108,8 @@ static argtype vars[] = { ModeSpecOpt lament_opts = {countof(opts), opts, countof(vars), vars, NULL}; -#ifdef HAVE_XPM -# include -# include "../images/lament.xpm" -#endif /* HAVE_XPM */ +#include "xpm-ximage.h" +#include "../images/lament.xpm" #define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n)))) #define RANDSIGN() ((random() & 1) ? 1 : -1) @@ -140,8 +140,16 @@ typedef enum { } lament_type; -static GLfloat exterior_color[] = { 0.70, 0.60, 0.00, 1.00 }; -static GLfloat interior_color[] = { 0.25, 0.25, 0.20, 1.00 }; +static GLfloat exterior_color[] = { 0.33, 0.22, 0.03, 1.00, /* ambient */ + 0.78, 0.57, 0.11, 1.00, /* specular */ + 0.99, 0.91, 0.81, 1.00, /* diffuse */ + 27.80 /* shininess */ + }; +static GLfloat interior_color[] = { 0.20, 0.20, 0.15, 1.00, /* ambient */ + 0.40, 0.40, 0.32, 1.00, /* specular */ + 0.99, 0.99, 0.81, 1.00, /* diffuse */ + 50.80 /* shininess */ + }; typedef struct { @@ -175,110 +183,16 @@ static lament_configuration *lcs = NULL; #define FACE_U 5 #define FACE_D 1 -#ifdef HAVE_XPM -static Bool -bigendian(void) -{ - union { int i; char c[sizeof(int)]; } u; - u.i = 1; - return !u.c[0]; -} -#endif /* HAVE_XPM */ - - static void parse_image_data(ModeInfo *mi) { -#ifdef HAVE_XPM lament_configuration *lc = &lcs[MI_SCREEN(mi)]; - - /* All we want to do is get RGB data out of the XPM file built in to this - program. This is a pain, because there is no way (as of XPM version - 4.6, at least) to get libXpm to make an XImage without also allocating - colors with XAllocColor. So, instead, we create an XpmImage and parse - out the RGB values of the pixels ourselves; and construct an XImage - by hand. Regardless of the depth of the visual we're using, this - XImage will have 32 bits per pixel, 8 each per R, G, and B. We put - 0xFF in the fourth slot, as GL will interpret that as "alpha". - */ - XpmImage xpm_image; - XpmInfo xpm_info; - int result; - int x, y, i; - int bpl, wpl; - XColor colors[255]; - - result = XpmCreateXpmImageFromData(lament_faces, &xpm_image, &xpm_info); - if (result != XpmSuccess) - { - fprintf(stderr, "%s: unable to parse xpm data (%d).\n", progname, - result); - exit (1); - } - - lc->texture = XCreateImage(mi->dpy, mi->xgwa.visual, 32, ZPixmap, 0, 0, - xpm_image.width, xpm_image.height, 32, 0); - - bpl = lc->texture->bytes_per_line; - wpl = bpl/4; - - lc->texture->data = (char *) malloc(xpm_image.height * bpl); - - /* Parse the colors in the XPM into RGB values. */ - for (i = 0; i < xpm_image.ncolors; i++) - if (!XParseColor(mi->dpy, mi->xgwa.colormap, - xpm_image.colorTable[i].c_color, - &colors[i])) - { - fprintf(stderr, "%s: unparsable color: %s\n", progname, - xpm_image.colorTable[i].c_color); - exit(1); - } - - /* Translate the XpmImage to an RGB XImage. */ - { - int rpos, gpos, bpos, apos; /* bitfield positions */ - - /* Note that unlike X, which is endianness-agnostic (since any XImage - can have its own specific bit ordering, with the server reversing - things as necessary) OpenGL pretends everything is client-side, so - we need to pack things in the right order for the client machine. - */ - if (bigendian()) - rpos = 24, gpos = 16, bpos = 8, apos = 0; - else - rpos = 0, gpos = 8, bpos = 16, apos = 24; - - for (y = 0; y < xpm_image.height; y++) - { - int y2 = (xpm_image.height-1-y); /* Texture maps are upside down. */ - - unsigned int *oline = (unsigned int *) (lc->texture->data + (y *bpl)); - unsigned int *iline = (unsigned int *) (xpm_image.data + (y2*wpl)); - - for (x = 0; x < xpm_image.width; x++) - { - XColor *c = &colors[iline[x]]; - /* pack it as RGBA */ - oline[x] = (((c->red >> 8) << rpos) | - ((c->green >> 8) << gpos) | - ((c->blue >> 8) << bpos) | - (0xFF << apos)); - } - } - } - - /* I sure hope these only free the contents, and not the args. */ - XpmFreeXpmImage(&xpm_image); - XpmFreeXpmInfo(&xpm_info); - -#else /* !HAVE_XPM */ - fprintf(stderr, "%s: not compiled with XPM support.\n", progname); - exit (1); -#endif /* !HAVE_XPM */ + lc->texture = xpm_to_ximage (mi->dpy, + mi->xgwa.visual, + mi->xgwa.colormap, + lament_faces); } - /* Computing normal vectors (thanks to Nat Friedman ) */ @@ -370,6 +284,15 @@ do_normal(GLfloat x1, GLfloat y1, GLfloat z1, /* Shorthand utilities for making faces, with proper normals. */ +static void +set_colors (GLfloat *color) +{ + glMaterialfv(GL_FRONT, GL_AMBIENT, color+0); + glMaterialfv(GL_FRONT, GL_DIFFUSE, color+4); + glMaterialfv(GL_FRONT, GL_SPECULAR, color+8); + glMaterialfv(GL_FRONT, GL_SHININESS, color+12); +} + static void face3(GLint texture, GLfloat *color, Bool wire, GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1, @@ -379,7 +302,8 @@ face3(GLint texture, GLfloat *color, Bool wire, #ifdef HAVE_GLBINDTEXTURE glBindTexture(GL_TEXTURE_2D, texture); #endif /* HAVE_GLBINDTEXTURE */ - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color); + set_colors(color); + do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3); glBegin(wire ? GL_LINE_LOOP : GL_TRIANGLES); glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1); @@ -398,7 +322,7 @@ face4(GLint texture, GLfloat *color, Bool wire, #ifdef HAVE_GLBINDTEXTURE glBindTexture(GL_TEXTURE_2D, texture); #endif /* HAVE_GLBINDTEXTURE */ - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color); + set_colors(color); do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3); glBegin(wire ? GL_LINE_LOOP : GL_QUADS); glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1); @@ -419,7 +343,7 @@ face5(GLint texture, GLfloat *color, Bool wire, #ifdef HAVE_GLBINDTEXTURE glBindTexture(GL_TEXTURE_2D, texture); #endif /* HAVE_GLBINDTEXTURE */ - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color); + set_colors(color); do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3); glBegin(wire ? GL_LINE_LOOP : GL_POLYGON); glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1); @@ -636,7 +560,7 @@ star(ModeInfo *mi, Bool top, Bool wire) #ifdef HAVE_GLBINDTEXTURE glBindTexture(GL_TEXTURE_2D, lc->texids[top ? FACE_U : FACE_D]); #endif /* HAVE_GLBINDTEXTURE */ - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color); + set_colors(exterior_color); i = 1; do_normal(points[i+0][0], points[i+0][1], 0, @@ -658,9 +582,9 @@ star(ModeInfo *mi, Bool top, Bool wire) #ifdef HAVE_GLBINDTEXTURE glBindTexture(GL_TEXTURE_2D, 0); #endif /* HAVE_GLBINDTEXTURE */ - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color); + set_colors(interior_color); - i = countof(points) - 3; + i = countof(points) - 9; do_normal(points[i+0][0], points[i+0][1], 0, points[i+4][0], points[i+4][1], 0, points[i+8][0], points[i+8][1], 0); @@ -807,7 +731,6 @@ tetra(ModeInfo *mi, Bool wire) 0.0, 0.0, 0.5, -0.5, 0.5, 0.0, 0.0, 0.5, 0.5, -0.5, 0.0, 0.0, -0.5, -0.5, -0.5); - glEnd(); } glEndList(); @@ -1105,7 +1028,7 @@ taser(ModeInfo *mi, Bool wire) #ifdef HAVE_GLBINDTEXTURE glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]); #endif /* HAVE_GLBINDTEXTURE */ - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color); + set_colors(exterior_color); do_normal(0, body_face_points[(i*5)+0][0], body_face_points[(i*5)+0][1], 0, body_face_points[(i*5)+1][0], body_face_points[(i*5)+1][1], @@ -1230,7 +1153,7 @@ taser(ModeInfo *mi, Bool wire) #ifdef HAVE_GLBINDTEXTURE glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]); #endif /* HAVE_GLBINDTEXTURE */ - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color); + set_colors(exterior_color); do_normal( 0, lifter_face_points[(i*5)+0][0], lifter_face_points[(i*5)+0][1], @@ -1368,7 +1291,7 @@ taser(ModeInfo *mi, Bool wire) #ifdef HAVE_GLBINDTEXTURE glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]); #endif /* HAVE_GLBINDTEXTURE */ - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color); + set_colors(exterior_color); do_normal( 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1], @@ -1397,7 +1320,7 @@ taser(ModeInfo *mi, Bool wire) #ifdef HAVE_GLBINDTEXTURE glBindTexture(GL_TEXTURE_2D, 0); #endif /* HAVE_GLBINDTEXTURE */ - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color); + set_colors(interior_color); do_normal( 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1], @@ -1968,8 +1891,8 @@ rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v) /* Window management, etc */ -static void -reshape(int width, int height) +void +reshape_lament(ModeInfo *mi, int width, int height) { int target_size = 180; int win_size = (width > height ? height : width); @@ -2022,31 +1945,26 @@ gl_init(ModeInfo *mi) if (!wire) { - static GLfloat pos0[] = { -4.0, 2.0, 5.0, 1.0 }; - static GLfloat pos1[] = { 12.0, 5.0, 1.0, 1.0 }; - static GLfloat local[] = { 0.0 }; - static GLfloat ambient[] = { 0.3, 0.3, 0.3, 1.0 }; - static GLfloat spec[] = { 1.0, 1.0, 1.0, 1.0 }; - static GLfloat shine[] = { 100.0 }; + static GLfloat pos0[] = { -4.0, 2.0, 5.0, 1.0 }; + static GLfloat pos1[] = { 6.0, -1.0, 3.0, 1.0 }; + + static GLfloat amb0[] = { 0.7, 0.7, 0.7, 1.0 }; +/* static GLfloat amb1[] = { 0.7, 0.0, 0.0, 1.0 }; */ + static GLfloat dif0[] = { 1.0, 1.0, 1.0, 1.0 }; + static GLfloat dif1[] = { 0.3, 0.1, 0.1, 1.0 }; glLightfv(GL_LIGHT0, GL_POSITION, pos0); glLightfv(GL_LIGHT1, GL_POSITION, pos1); - glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); - glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); - - glLightfv(GL_LIGHT0, GL_SPECULAR, spec); - glLightfv(GL_LIGHT1, GL_SPECULAR, spec); - - glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color); - glMaterialfv(GL_FRONT, GL_SPECULAR, spec); - glMaterialfv(GL_FRONT, GL_SHININESS, shine); + glLightfv(GL_LIGHT0, GL_AMBIENT, amb0); +/* glLightfv(GL_LIGHT1, GL_AMBIENT, amb1); */ + glLightfv(GL_LIGHT0, GL_DIFFUSE, dif0); + glLightfv(GL_LIGHT1, GL_DIFFUSE, dif1); + set_colors(exterior_color); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); - glDisable(GL_LIGHT1); +/* glEnable(GL_LIGHT1); */ glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); @@ -2070,12 +1988,15 @@ gl_init(ModeInfo *mi) { int height = lc->texture->width; /* assume square */ glBindTexture(GL_TEXTURE_2D, lc->texids[i]); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color); + set_colors(exterior_color); + + clear_gl_error(); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lc->texture->width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (lc->texture->data + (lc->texture->bytes_per_line * height * i))); + check_gl_error("texture"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -2120,6 +2041,47 @@ gl_init(ModeInfo *mi) } +# ifdef HAVE_MESA_GL + +# include + +static RETSIGTYPE +lament_signal_kludge (int sig) +{ + signal (sig, SIG_DFL); + fprintf (stderr, + "\n" + "%s: dying with signal %d (%s).\n" + "\n" + "\tThis is almost certainly a bug in the Mesa GL library,\n" + "\tespecially if the stack trace in the core file mentions\n" + "\t`lambda_textured_triangle' or `render_quad'.\n" + "\n" + "\tFirst make sure that you have the latest version of Mesa.\n" + "\tIf that doesn't fix it, then I encourage you to report this\n" + "\tbug to the Mesa maintainers at .\n" + "\n", + progname, + sig, + (sig == SIGILL ? "SIGILL" : + sig == SIGFPE ? "SIGFPE" : + sig == SIGBUS ? "SIGBUS" : + sig == SIGSEGV ? "SIGSEGV" : "???")); + fflush (stderr); + kill (getpid (), sig); +} + +static void +handle_signals (void) +{ + signal (SIGILL, lament_signal_kludge); + signal (SIGFPE, lament_signal_kludge); + signal (SIGBUS, lament_signal_kludge); + signal (SIGSEGV, lament_signal_kludge); +} +# endif /* HAVE_MESA_GL */ + + void init_lament(ModeInfo *mi) { @@ -2152,25 +2114,24 @@ init_lament(ModeInfo *mi) lc->ddy = 0.00006 + frand(0.00003); lc->ddz = 0.00006 + frand(0.00003); - lc->ddx = 0.00001; - lc->ddy = 0.00001; - lc->ddz = 0.00001; - lc->type = LAMENT_BOX; lc->anim_pause = 300 + (random() % 100); if ((lc->glx_context = init_GL(mi)) != NULL) { - reshape(MI_WIDTH(mi), MI_HEIGHT(mi)); + reshape_lament(mi, MI_WIDTH(mi), MI_HEIGHT(mi)); gl_init(mi); } + +# ifdef HAVE_MESA_GL + handle_signals (); +# endif /* HAVE_MESA_GL */ } void draw_lament(ModeInfo *mi) { - static int tick = 0; lament_configuration *lc = &lcs[MI_SCREEN(mi)]; Display *dpy = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); @@ -2182,6 +2143,8 @@ draw_lament(ModeInfo *mi) glXMakeCurrent(dpy, window, *(lc->glx_context)); draw(mi); + if (mi->fps_p) do_fps (mi); + glFinish(); glXSwapBuffers(dpy, window); @@ -2196,12 +2159,6 @@ draw_lament(ModeInfo *mi) lc->anim_pause--; else animate(mi); - - if (++tick > 500) - { - tick = 0; - reshape(MI_WIDTH(mi), MI_HEIGHT(mi)); - } } #endif /* USE_GL */