1 /* xscreensaver, Copyright (c) 1998 Jamie Zawinski <jwz@jwz.org>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
12 /* Animates Lemarchand's Box, the Lament Configuration. By jwz, 25-Jul-98.
16 * The "gold" color isn't quite right; it looks more like "yellow" than
19 * For some reason, the interior surfaces are shinier than the exterior
20 surfaces. I don't understand why, but this should be remedied.
22 * Perhaps use a slightly-bumpy or oily texture for the interior surfaces?
24 * Some of the edges don't line up perfectly (since the images are not
25 perfectly symetrical.) Something should be done about this; either
26 making the edges overlap slightly (instead of leaving gaps) or fixing
27 the images so that the edges may be symmetrical.
29 * I want the gold leaf to seem to be raised up from the surface, but I
30 think this isn't possible with OpenGL. Supposedly, OpenGL only
31 supports Gouraud shading (interpolating edge normals from face normals,
32 and shading smoothly) but bump-maps only work with Phong shading
33 (computing a normal for each rendered pixel.)
35 * As far as I can tell, OpenGL doesn't do shadows. As a result, the
36 forward-facing interior walls are drawn bright, not dark. If it was
37 casting shadows properly, it wouldn't matter so much that the edges
38 don't quite line up, because the lines would be black, and thus not
39 visible. But the edges don't match up, and so the bright interior
40 faces show through, and that sucks.
42 But apparently there are tricky ways around this:
43 http://reality.sgi.com/opengl/tips/rts/
44 I think these techniques require GLUT, however, which isn't
45 (currently) required by any other xscreensaver hacks.
47 * There should be strange lighting effects playing across the surface:
48 electric sparks, or little glittery blobs of light.
49 http://reality.sgi.com/opengl/tips/lensflare/ might provide guidance.
51 * Need to add some more modes, to effect the transition from the cube
52 shapes to the "spike" or "leviathan" shapes. I have extensive notes
53 on how these transformations occur, but unfortunately, due to camera
54 trickery, the transitions require dematerializations which do not
55 preserve object volume. But I suppose that's allowed, in
56 non-Euclidian or hyperdimensional spaces (since the extra mass could
57 simply be rotated along the axis to which one cannot point.)
59 The other hard thing about this is that the "leviathan" shapes contain
60 a much larger number of facets, and I modelled this whole thing by
61 hand, since I don't have any 3d-object-editing tools that I know how
62 to use (or that look like they would take any less than several months
63 to become even marginally proficient with...)
65 * Perhaps there should be a table top, on which it casts a shadow?
66 And then multiple light sources (for multiple shadows)?
68 * Needs music. ("Hellraiser Themes" by Coil: TORSO CD161; also
69 duplicated on the "Unnatural History 2" compilation, WORLN M04699.)
71 * I'm not totally happy with the spinning motion; I like the
72 acceleration and deceleration, but it often feels like it's going too
73 fast, or not naturally enough, or something.
75 * However, the motion is better than that used by gears, superquadrics,
76 etc.; so maybe I should make them all share the same motion code.
79 #include <X11/Intrinsic.h>
81 #define PROGCLASS "Lament"
82 #define HACK_INIT init_lament
83 #define HACK_DRAW draw_lament
84 #define lament_opts xlockmore_opts
85 #define DEFAULTS "*delay: 10000 \n" \
86 "*wireframe: False \n" \
88 #include "xlockmore.h"
90 #ifdef USE_GL /* whole file */
93 #define countof(x) (sizeof((x))/sizeof((*x)))
95 #define DEF_TEXTURE "True"
97 static int do_texture;
98 static XrmOptionDescRec opts[] = {
99 {"-texture", ".lament.texture", XrmoptionNoArg, (caddr_t) "true" },
100 {"+texture", ".lament.texture", XrmoptionNoArg, (caddr_t) "false" },
103 static argtype vars[] = {
104 {(caddr_t *) &do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool},
107 ModeSpecOpt lament_opts = {countof(opts), opts, countof(vars), vars, NULL};
110 # include <X11/xpm.h>
111 # include "../images/lament.xpm"
112 #endif /* HAVE_XPM */
114 #define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n))))
115 #define RANDSIGN() ((random() & 1) ? 1 : -1)
138 LAMENT_TASER_SLIDE_IN,
143 static GLfloat exterior_color[] = { 0.70, 0.60, 0.00, 1.00 };
144 static GLfloat interior_color[] = { 0.25, 0.25, 0.20, 1.00 };
148 GLXContext *glx_context;
150 GLuint box; /* display list IDs */
152 GLuint tetra_une, tetra_usw, tetra_dwn, tetra_dse, tetra_mid;
153 GLuint lid_0, lid_1, lid_2, lid_3, lid_4;
154 GLuint taser_base, taser_lifter, taser_slider;
156 GLfloat rotx, roty, rotz; /* current object rotation */
157 GLfloat dx, dy, dz; /* current rotational velocity */
158 GLfloat ddx, ddy, ddz; /* current rotational acceleration */
159 GLfloat d_max; /* max velocity */
160 XImage *texture; /* image bits */
161 GLuint texids[6]; /* texture map IDs */
162 lament_type type; /* which mode of the object is current */
164 int anim_pause; /* countdown before animating again */
165 GLfloat anim_r, anim_y, anim_z; /* relative position during anims */
167 } lament_configuration;
169 static lament_configuration *lcs = NULL;
182 union { int i; char c[sizeof(int)]; } u;
186 #endif /* HAVE_XPM */
190 parse_image_data(ModeInfo *mi)
193 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
195 /* All we want to do is get RGB data out of the XPM file built in to this
196 program. This is a pain, because there is no way (as of XPM version
197 4.6, at least) to get libXpm to make an XImage without also allocating
198 colors with XAllocColor. So, instead, we create an XpmImage and parse
199 out the RGB values of the pixels ourselves; and construct an XImage
200 by hand. Regardless of the depth of the visual we're using, this
201 XImage will have 32 bits per pixel, 8 each per R, G, and B. We put
202 0xFF in the fourth slot, as GL will interpret that as "alpha".
211 result = XpmCreateXpmImageFromData(lament_faces, &xpm_image, &xpm_info);
212 if (result != XpmSuccess)
214 fprintf(stderr, "%s: unable to parse xpm data (%d).\n", progname,
219 lc->texture = XCreateImage(mi->dpy, mi->xgwa.visual, 32, ZPixmap, 0, 0,
220 xpm_image.width, xpm_image.height, 32, 0);
222 bpl = lc->texture->bytes_per_line;
225 lc->texture->data = (char *) malloc(xpm_image.height * bpl);
227 /* Parse the colors in the XPM into RGB values. */
228 for (i = 0; i < xpm_image.ncolors; i++)
229 if (!XParseColor(mi->dpy, mi->xgwa.colormap,
230 xpm_image.colorTable[i].c_color,
233 fprintf(stderr, "%s: unparsable color: %s\n", progname,
234 xpm_image.colorTable[i].c_color);
238 /* Translate the XpmImage to an RGB XImage. */
240 int rpos, gpos, bpos, apos; /* bitfield positions */
242 /* Note that unlike X, which is endianness-agnostic (since any XImage
243 can have its own specific bit ordering, with the server reversing
244 things as necessary) OpenGL pretends everything is client-side, so
245 we need to pack things in the right order for the client machine.
248 rpos = 24, gpos = 16, bpos = 8, apos = 0;
250 rpos = 0, gpos = 8, bpos = 16, apos = 24;
252 for (y = 0; y < xpm_image.height; y++)
254 int y2 = (xpm_image.height-1-y); /* Texture maps are upside down. */
256 unsigned int *oline = (unsigned int *) (lc->texture->data + (y *bpl));
257 unsigned int *iline = (unsigned int *) (xpm_image.data + (y2*wpl));
259 for (x = 0; x < xpm_image.width; x++)
261 XColor *c = &colors[iline[x]];
262 /* pack it as RGBA */
263 oline[x] = (((c->red >> 8) << rpos) |
264 ((c->green >> 8) << gpos) |
265 ((c->blue >> 8) << bpos) |
271 /* I sure hope these only free the contents, and not the args. */
272 XpmFreeXpmImage(&xpm_image);
273 XpmFreeXpmInfo(&xpm_info);
275 #else /* !HAVE_XPM */
276 fprintf(stderr, "%s: not compiled with XPM support.\n", progname);
278 #endif /* !HAVE_XPM */
283 /* Computing normal vectors (thanks to Nat Friedman <ndf@mit.edu>)
286 typedef struct vector {
290 typedef struct plane {
295 vector_set(vector *v, GLfloat x, GLfloat y, GLfloat z)
303 vector_cross(vector v1, vector v2, vector *v3)
305 v3->x = (v1.y * v2.z) - (v1.z * v2.y);
306 v3->y = (v1.z * v2.x) - (v1.x * v2.z);
307 v3->z = (v1.x * v2.y) - (v1.y * v2.x);
311 vector_subtract(vector v1, vector v2, vector *res)
313 res->x = v1.x - v2.x;
314 res->y = v1.y - v2.y;
315 res->z = v1.z - v2.z;
319 plane_normal(plane p, vector *n)
322 vector_subtract(p.p1, p.p2, &v1);
323 vector_subtract(p.p1, p.p3, &v2);
324 vector_cross(v2, v1, n);
328 do_normal(GLfloat x1, GLfloat y1, GLfloat z1,
329 GLfloat x2, GLfloat y2, GLfloat z2,
330 GLfloat x3, GLfloat y3, GLfloat z3)
334 vector_set(&plane.p1, x1, y1, z1);
335 vector_set(&plane.p2, x2, y2, z2);
336 vector_set(&plane.p3, x3, y3, z3);
337 plane_normal(plane, &n);
338 n.x = -n.x; n.y = -n.y; n.z = -n.z;
340 glNormal3f(n.x, n.y, n.z);
343 /* Draw a line in the direction of this face's normal. */
345 GLfloat ax = n.x > 0 ? n.x : -n.x;
346 GLfloat ay = n.y > 0 ? n.y : -n.y;
347 GLfloat az = n.z > 0 ? n.z : -n.z;
348 GLfloat mx = (x1 + x2 + x3) / 3;
349 GLfloat my = (y1 + y2 + y3) / 3;
350 GLfloat mz = (z1 + z2 + z3) / 3;
353 GLfloat max = ax > ay ? ax : ay;
354 if (az > max) max = az;
360 glBegin(GL_LINE_LOOP);
361 glVertex3f(mx, my, mz);
362 glVertex3f(mx+xx, my+yy, mz+zz);
370 /* Shorthand utilities for making faces, with proper normals.
374 face3(GLint texture, GLfloat *color, Bool wire,
375 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
376 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
377 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3)
379 #ifdef HAVE_GLBINDTEXTURE
380 glBindTexture(GL_TEXTURE_2D, texture);
381 #endif /* HAVE_GLBINDTEXTURE */
382 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
383 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
384 glBegin(wire ? GL_LINE_LOOP : GL_TRIANGLES);
385 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
386 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
387 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
392 face4(GLint texture, GLfloat *color, Bool wire,
393 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
394 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
395 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3,
396 GLfloat s4, GLfloat t4, GLfloat x4, GLfloat y4, GLfloat z4)
398 #ifdef HAVE_GLBINDTEXTURE
399 glBindTexture(GL_TEXTURE_2D, texture);
400 #endif /* HAVE_GLBINDTEXTURE */
401 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
402 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
403 glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
404 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
405 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
406 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
407 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
412 face5(GLint texture, GLfloat *color, Bool wire,
413 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
414 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
415 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3,
416 GLfloat s4, GLfloat t4, GLfloat x4, GLfloat y4, GLfloat z4,
417 GLfloat s5, GLfloat t5, GLfloat x5, GLfloat y5, GLfloat z5)
419 #ifdef HAVE_GLBINDTEXTURE
420 glBindTexture(GL_TEXTURE_2D, texture);
421 #endif /* HAVE_GLBINDTEXTURE */
422 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
423 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
424 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
425 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
426 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
427 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
428 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
429 glTexCoord2f(s5, t5); glVertex3f(x5, y5, z5);
435 /* Creating object models
439 box(ModeInfo *mi, Bool wire)
441 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
443 glNewList(lc->box, GL_COMPILE);
444 glShadeModel(GL_SMOOTH);
447 face4(lc->texids[FACE_N], exterior_color, wire,
448 0.0, 0.0, -0.5, 0.5, 0.5,
449 1.0, 0.0, 0.5, 0.5, 0.5,
450 1.0, 1.0, 0.5, 0.5, -0.5,
451 0.0, 1.0, -0.5, 0.5, -0.5);
454 face4(lc->texids[FACE_S], exterior_color, wire,
455 0.0, 0.0, -0.5, -0.5, -0.5,
456 1.0, 0.0, 0.5, -0.5, -0.5,
457 1.0, 1.0, 0.5, -0.5, 0.5,
458 0.0, 1.0, -0.5, -0.5, 0.5);
461 face4(lc->texids[FACE_E], exterior_color, wire,
462 0.0, 0.0, 0.5, -0.5, -0.5,
463 1.0, 0.0, 0.5, 0.5, -0.5,
464 1.0, 1.0, 0.5, 0.5, 0.5,
465 0.0, 1.0, 0.5, -0.5, 0.5);
468 face4(lc->texids[FACE_W], exterior_color, wire,
469 1.0, 1.0, -0.5, -0.5, 0.5,
470 0.0, 1.0, -0.5, 0.5, 0.5,
471 0.0, 0.0, -0.5, 0.5, -0.5,
472 1.0, 0.0, -0.5, -0.5, -0.5);
475 face4(lc->texids[FACE_U], exterior_color, wire,
476 1.0, 0.0, 0.5, -0.5, 0.5,
477 1.0, 1.0, 0.5, 0.5, 0.5,
478 0.0, 1.0, -0.5, 0.5, 0.5,
479 0.0, 0.0, -0.5, -0.5, 0.5);
482 face4(lc->texids[FACE_D], exterior_color, wire,
483 0.0, 1.0, -0.5, -0.5, -0.5,
484 0.0, 0.0, -0.5, 0.5, -0.5,
485 1.0, 0.0, 0.5, 0.5, -0.5,
486 1.0, 1.0, 0.5, -0.5, -0.5);
493 star(ModeInfo *mi, Bool top, Bool wire)
495 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
499 { 77, 74 }, { 60, 98 }, { 0, 71 }, { 0, 0 }, /* L1 */
500 { 60, 98 }, { 55, 127 }, { 0, 127 }, { 0, 71 }, /* L2 */
501 { 55, 127 }, { 60, 154 }, { 0, 179 }, { 0, 127 }, /* L3 */
502 { 60, 154 }, { 76, 176 }, { 0, 255 }, { 0, 179 }, /* L4 */
503 { 76, 176 }, { 100, 193 }, { 74, 255 }, { 0, 255 }, /* B1 */
504 { 100, 193 }, { 127, 198 }, { 127, 255 }, { 74, 255 }, /* B2 */
505 { 127, 198 }, { 151, 193 }, { 180, 255 }, { 127, 255 }, /* B3 */
506 { 151, 193 }, { 178, 177 }, { 255, 255 }, { 180, 255 }, /* B4 */
507 { 178, 177 }, { 193, 155 }, { 255, 181 }, { 255, 255 }, /* R4 */
508 { 193, 155 }, { 199, 127 }, { 255, 127 }, { 255, 181 }, /* R3 */
509 { 199, 127 }, { 194, 99 }, { 255, 74 }, { 255, 127 }, /* R2 */
510 { 194, 99 }, { 179, 76 }, { 255, 0 }, { 255, 74 }, /* R1 */
511 { 179, 76 }, { 155, 60 }, { 180, 0 }, { 255, 0 }, /* T4 */
512 { 155, 60 }, { 126, 55 }, { 126, 0 }, { 180, 0 }, /* T3 */
513 { 126, 55 }, { 100, 60 }, { 75, 0 }, { 126, 0 }, /* T2 */
514 { 100, 60 }, { 77, 74 }, { 0, 0 }, { 75, 0 }, /* T1 */
517 for (i = 0; i < countof(points); i++)
518 points[i][1] = 255-points[i][1];
521 glNewList(lc->star1, GL_COMPILE);
523 glNewList(lc->star2, GL_COMPILE);
526 glRotatef(-180.0, 1.0, 0.0, 0.0);
528 for (i = 0; i < countof(points)/4; i += 2)
535 GLfloat s[4], t[4], x[4], y[4], z[4];
536 for (j = 3, k = 0; j >= 0; j--, k++)
538 GLfloat xx = points[(i*4)+j][0] / 255.0L;
539 GLfloat yy = points[(i*4)+j][1] / 255.0L;
546 face4(lc->texids[top ? FACE_U : FACE_D], exterior_color, wire,
547 s[0], t[0], x[0], y[0], z[0],
548 s[1], t[1], x[1], y[1], z[1],
549 s[2], t[2], x[2], y[2], z[2],
550 s[3], t[3], x[3], y[3], z[3]);
554 for (j = 0, k = 0; j < 4; j++, k++)
556 GLfloat xx = points[(i*4)+j][0] / 255.0L;
557 GLfloat yy = points[(i*4)+j][1] / 255.0L;
564 face4(lc->texids[top ? FACE_U : FACE_D], exterior_color, wire,
565 s[0], t[0], x[0], y[0], z[0],
566 s[1], t[1], x[1], y[1], z[1],
567 s[2], t[2], x[2], y[2], z[2],
568 s[3], t[3], x[3], y[3], z[3]);
572 for (j = 3; j >= 0; j--)
574 int k = (j == 0 ? 3 : j-1);
575 Bool front_p = (j == 3);
576 GLfloat x1 = points[(i*4)+j][0] / 255.0L;
577 GLfloat y1 = points[(i*4)+j][1] / 255.0L;
578 GLfloat x2 = points[(i*4)+k][0] / 255.0L;
579 GLfloat y2 = points[(i*4)+k][1] / 255.0L;
581 GLfloat tx1=0.0, tx2=1.0, ty1=0.0, ty2=1.0;
585 facing = (facing + j + 5) % 4;
591 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
592 ty1 = 0.0; ty2 = 1.0;
595 ty1 = 1.0; ty2 = 0.0;
599 texture = top ? FACE_S : FACE_N;
601 ty1 = 0.0; ty2 = 1.0;
607 ty1 = 0.0; ty2 = 1.0;
609 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
610 ty1 = 1.0; ty2 = 0.0;
614 texture = top ? FACE_N : FACE_S;
616 ty1 = 1.0; ty2 = 0.0;
620 x1 -= 0.5; x2 -= 0.5;
621 y1 -= 0.5; y2 -= 0.5;
623 face4(front_p ? lc->texids[texture] : 0,
624 front_p ? exterior_color : interior_color,
626 tx1, ty2, x1, y1, 0.5,
627 tx1, ty1, x1, y1, -0.5,
628 tx2, ty1, x2, y2, -0.5,
629 tx2, ty2, x2, y2, 0.5);
634 /* Central core top cap.
636 #ifdef HAVE_GLBINDTEXTURE
637 glBindTexture(GL_TEXTURE_2D, lc->texids[top ? FACE_U : FACE_D]);
638 #endif /* HAVE_GLBINDTEXTURE */
639 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
642 do_normal(points[i+0][0], points[i+0][1], 0,
643 points[i+4][0], points[i+4][1], 0,
644 points[i+8][0], points[i+8][1], 0);
645 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
646 for (i = 1; i < countof(points); i += 4)
648 GLfloat x = points[i][0] / 255.0L;
649 GLfloat y = points[i][1] / 255.0L;
651 glVertex3f(x-0.5, y-0.5, 0.5);
656 /* Central core bottom cap.
658 #ifdef HAVE_GLBINDTEXTURE
659 glBindTexture(GL_TEXTURE_2D, 0);
660 #endif /* HAVE_GLBINDTEXTURE */
661 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color);
663 i = countof(points) - 3;
664 do_normal(points[i+0][0], points[i+0][1], 0,
665 points[i+4][0], points[i+4][1], 0,
666 points[i+8][0], points[i+8][1], 0);
668 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
669 for (i = countof(points) - 3; i >= 0; i -= 4)
671 GLfloat x = points[i][0] / 255.0L;
672 GLfloat y = points[i][1] / 255.0L;
673 glVertex3f(x-0.5, y-0.5, 0);
678 /* Central core walls.
680 for (i = 1; i < countof(points); i += 4)
683 GLfloat x1 = points[i-1][0] / 255.0L;
684 GLfloat y1 = points[i-1][1] / 255.0L;
685 GLfloat x2 = points[i][0] / 255.0L;
686 GLfloat y2 = points[i][1] / 255.0L;
687 face4(0, interior_color, wire,
688 0.0, 0.0, x1-0.5, y1-0.5, 0.5,
689 0.0, 0.0, x1-0.5, y1-0.5, 0.0,
690 0.0, 0.0, x2-0.5, y2-0.5, 0.0,
691 0.0, 0.0, x2-0.5, y2-0.5, 0.5);
699 tetra(ModeInfo *mi, Bool wire)
701 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
703 glNewList(lc->tetra_une, GL_COMPILE);
705 glShadeModel(GL_SMOOTH);
708 face3(lc->texids[FACE_U], exterior_color, wire,
709 1.0, 0.0, 0.5, -0.5, 0.5,
710 1.0, 1.0, 0.5, 0.5, 0.5,
711 0.0, 1.0, -0.5, 0.5, 0.5);
714 face3(lc->texids[FACE_N], exterior_color, wire,
715 0.0, 0.0, -0.5, 0.5, 0.5,
716 1.0, 0.0, 0.5, 0.5, 0.5,
717 1.0, 1.0, 0.5, 0.5, -0.5);
720 face3(lc->texids[FACE_E], exterior_color, wire,
721 1.0, 0.0, 0.5, 0.5, -0.5,
722 1.0, 1.0, 0.5, 0.5, 0.5,
723 0.0, 1.0, 0.5, -0.5, 0.5);
725 face3(0, interior_color, wire,
726 0.0, 0.0, 0.5, 0.5, -0.5,
727 0.0, 0.0, 0.5, -0.5, 0.5,
728 0.0, 0.0, -0.5, 0.5, 0.5);
732 glNewList(lc->tetra_usw, GL_COMPILE);
735 face3(lc->texids[FACE_U], exterior_color, wire,
736 0.0, 1.0, -0.5, 0.5, 0.5,
737 0.0, 0.0, -0.5, -0.5, 0.5,
738 1.0, 0.0, 0.5, -0.5, 0.5);
741 face3(lc->texids[FACE_S], exterior_color, wire,
742 1.0, 1.0, 0.5, -0.5, 0.5,
743 0.0, 1.0, -0.5, -0.5, 0.5,
744 0.0, 0.0, -0.5, -0.5, -0.5);
747 face3(lc->texids[FACE_W], exterior_color, wire,
748 1.0, 0.0, -0.5, -0.5, -0.5,
749 1.0, 1.0, -0.5, -0.5, 0.5,
750 0.0, 1.0, -0.5, 0.5, 0.5);
752 face3(0, interior_color, wire,
753 0.0,0.0, -0.5, -0.5, -0.5,
754 0.0,0.0, -0.5, 0.5, 0.5,
755 0.0,0.0, 0.5, -0.5, 0.5);
759 glNewList(lc->tetra_dwn, GL_COMPILE);
762 face3(lc->texids[FACE_D], exterior_color, wire,
763 0.0, 1.0, -0.5, -0.5, -0.5,
764 0.0, 0.0, -0.5, 0.5, -0.5,
765 1.0, 0.0, 0.5, 0.5, -0.5);
768 face3(lc->texids[FACE_W], exterior_color, wire,
769 0.0, 1.0, -0.5, 0.5, 0.5,
770 0.0, 0.0, -0.5, 0.5, -0.5,
771 1.0, 0.0, -0.5, -0.5, -0.5);
774 face3(lc->texids[FACE_N], exterior_color, wire,
775 1.0, 1.0, 0.5, 0.5, -0.5,
776 0.0, 1.0, -0.5, 0.5, -0.5,
777 0.0, 0.0, -0.5, 0.5, 0.5);
779 face3(0, interior_color, wire,
780 0.0, 0.0, 0.5, 0.5, -0.5,
781 0.0, 0.0, -0.5, 0.5, 0.5,
782 0.0, 0.0, -0.5, -0.5, -0.5);
786 glNewList(lc->tetra_dse, GL_COMPILE);
789 face3(lc->texids[FACE_S], exterior_color, wire,
790 0.0, 0.0, -0.5, -0.5, -0.5,
791 1.0, 0.0, 0.5, -0.5, -0.5,
792 1.0, 1.0, 0.5, -0.5, 0.5);
795 face3(lc->texids[FACE_E], exterior_color, wire,
796 0.0, 1.0, 0.5, -0.5, 0.5,
797 0.0, 0.0, 0.5, -0.5, -0.5,
798 1.0, 0.0, 0.5, 0.5, -0.5);
801 face3(lc->texids[FACE_D], exterior_color, wire,
802 1.0, 0.0, 0.5, 0.5, -0.5,
803 1.0, 1.0, 0.5, -0.5, -0.5,
804 0.0, 1.0, -0.5, -0.5, -0.5);
806 face3(0, interior_color, wire,
807 0.0, 0.0, 0.5, -0.5, 0.5,
808 0.0, 0.0, 0.5, 0.5, -0.5,
809 0.0, 0.0, -0.5, -0.5, -0.5);
814 glNewList(lc->tetra_mid, GL_COMPILE);
816 face3(0, interior_color, wire,
817 0.0, 0.0, 0.5, -0.5, 0.5,
818 0.0, 0.0, 0.5, 0.5, -0.5,
819 0.0, 0.0, -0.5, 0.5, 0.5);
821 face3(0, interior_color, wire,
822 0.0, 0.0, -0.5, 0.5, 0.5,
823 0.0, 0.0, -0.5, -0.5, -0.5,
824 0.0, 0.0, 0.5, -0.5, 0.5);
826 face3(0, interior_color, wire,
827 0.0, 0.0, -0.5, 0.5, 0.5,
828 0.0, 0.0, 0.5, 0.5, -0.5,
829 0.0, 0.0, -0.5, -0.5, -0.5);
831 face3(0, interior_color, wire,
832 0.0, 0.0, 0.5, 0.5, -0.5,
833 0.0, 0.0, 0.5, -0.5, 0.5,
834 0.0, 0.0, -0.5, -0.5, -0.5);
836 face3(0, interior_color, wire,
837 0.0, 0.0, 0.5, -0.5, 0.5,
838 0.0, 0.0, 0.5, 0.5, -0.5,
839 0.0, 0.0, -0.5, -0.5, -0.5);
846 lid(ModeInfo *mi, Bool wire)
848 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
852 { 128, 20 },{ 21, 129 },{ 0, 129 },{ 0, 0 },{ 128, 0 }, /* L1 */
853 { 21, 129 },{ 127, 234 },{ 127, 255 },{ 0, 255 },{ 0, 129 }, /* L2 */
854 { 127, 234 },{ 233, 127 },{ 255, 127 },{ 255, 255 },{ 127, 255 }, /* R2 */
855 { 233, 127 },{ 128, 20 },{ 128, 0 },{ 255, 0 },{ 255, 127 }, /* R1 */
858 for (i = 0; i < countof(points); i++)
859 points[i][1] = 255-points[i][1];
861 glNewList(lc->lid_0, GL_COMPILE);
862 glShadeModel(GL_SMOOTH);
865 face4(lc->texids[FACE_N], exterior_color, wire,
866 0.0, 0.0, -0.5, 0.5, 0.5,
867 1.0, 0.0, 0.5, 0.5, 0.5,
868 1.0, 1.0, 0.5, 0.5, -0.5,
869 0.0, 1.0, -0.5, 0.5, -0.5);
872 face4(lc->texids[FACE_S], exterior_color, wire,
873 0.0, 0.0, -0.5, -0.5, -0.5,
874 1.0, 0.0, 0.5, -0.5, -0.5,
875 1.0, 1.0, 0.5, -0.5, 0.5,
876 0.0, 1.0, -0.5, -0.5, 0.5);
879 face4(lc->texids[FACE_E], exterior_color, wire,
880 0.0, 0.0, 0.5, -0.5, -0.5,
881 1.0, 0.0, 0.5, 0.5, -0.5,
882 1.0, 1.0, 0.5, 0.5, 0.5,
883 0.0, 1.0, 0.5, -0.5, 0.5);
886 face4(lc->texids[FACE_U], exterior_color, wire,
887 1.0, 0.0, 0.5, -0.5, 0.5,
888 1.0, 1.0, 0.5, 0.5, 0.5,
889 0.0, 1.0, -0.5, 0.5, 0.5,
890 0.0, 0.0, -0.5, -0.5, 0.5);
893 face4(lc->texids[FACE_D], exterior_color, wire,
894 0.0, 1.0, -0.5, -0.5, -0.5,
895 0.0, 0.0, -0.5, 0.5, -0.5,
896 1.0, 0.0, 0.5, 0.5, -0.5,
897 1.0, 1.0, 0.5, -0.5, -0.5);
900 for (i = 0; i < countof(points)/5; i++)
903 GLfloat s[5], t[5], x[5], y[5], z[5];
904 for (j = 0; j < 5; j++)
906 GLfloat xx = points[(i*5)+j][0] / 255.0L;
907 GLfloat yy = points[(i*5)+j][1] / 255.0L;
914 face5(lc->texids[FACE_W], exterior_color, wire,
915 s[0], t[0], x[0], y[0], z[0],
916 s[1], t[1], x[1], y[1], z[1],
917 s[2], t[2], x[2], y[2], z[2],
918 s[3], t[3], x[3], y[3], z[3],
919 s[4], t[4], x[4], y[4], z[4]);
924 /* W -- lid_1 through lid_4 */
925 for (i = 0; i < 4; i++)
927 GLfloat x1, y1, x2, y2, x3, y3;
929 glNewList(lc->lid_1 + i, GL_COMPILE);
930 glShadeModel(GL_SMOOTH);
932 x1 = points[(i*5)+1][0] / 255.0L;
933 y1 = points[(i*5)+1][1] / 255.0L;
934 x2 = points[(i*5)][0] / 255.0L;
935 y2 = points[(i*5)][1] / 255.0L;
940 face3(lc->texids[FACE_W], exterior_color, wire,
941 1.0-x1, y1, -0.5, x1-0.5, y1-0.5,
942 1.0-x2, y2, -0.5, x2-0.5, y2-0.5,
943 1.0-x3, y3, -0.5, x3-0.5, y3-0.5);
946 face3(0, interior_color, wire,
947 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
948 0.0, 0.0, -0.48, x1-0.5, y1-0.5,
949 0.0, 0.0, -0.48, x3-0.5, y3-0.5);
952 face4(0, interior_color, wire,
953 0.0, 0.0, -0.5, x1-0.5, y1-0.5,
954 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
955 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
956 0.0, 0.0, -0.48, x1-0.5, y1-0.5);
959 face4(0, interior_color, wire,
960 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
961 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
962 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
963 0.0, 0.0, -0.5, x2-0.5, y2-0.5);
970 taser(ModeInfo *mi, Bool wire)
972 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
975 int slider_face_points[][2] = {
976 { 86, 58 },{ 38, 106 },{ 70, 106 },{ 118, 58 },{ -1, -1 }, /* a */
977 { 136, 58 },{ 184, 106 },{ 216, 106 },{ 168, 58 },{ -1, -1 }, /* b */
978 { 38, 106 },{ 0, 144 },{ 0, 190 },{ 60, 190 },{ 108, 106 }, /* c */
979 { 144, 106 },{ 194, 190 },{ 254, 190 },{ 254, 144 },{ 216, 106 }, /* d */
980 { 98, 124 },{ 60, 190 },{ 92, 190 },{ 126, 158 },{ 126, 124 }, /* e */
981 { 126, 124 },{ 126, 158 },{ 160, 190 },{ 194, 190 },{ 154, 124 }, /* f */
982 { 22, 190 },{ 22, 254 },{ 60, 254 },{ 60, 190 },{ -1, -1 }, /* g */
983 { 194, 190 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ -1, -1 }, /* h */
984 { 60, 190 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ -1, -1 }, /* i */
985 { 160, 190 },{ 160, 210 },{ 194, 210 },{ 194, 190 },{ -1, -1 }, /* j */
986 { 110, 172 },{ 92, 190 },{ 110, 190 },{ -1, -1 },{ -1, -1 }, /* k */
987 { 140, 172 },{ 140, 190 },{ 160, 190 },{ -1, -1 },{ -1, -1 }, /* l */
988 { 110, 172 },{ 140, 172 },{ 126, 156 },{ -1, -1 },{ -1, -1 }, /* m */
991 int body_face_points[][2] = {
992 { 0, 0 },{ 0, 58 },{ 254, 58 },{ 254, 0 },{ -1, -1 }, /* A */
993 { 0, 58 },{ 0, 144 },{ 86, 58 },{ -1, -1 },{ -1, -1 }, /* B */
994 { 168, 58 },{ 254, 144 },{ 254, 58 },{ -1, -1 },{ -1, -1 }, /* C */
995 { 118, 58 },{ 70, 106 },{ 184, 106 },{ 136, 58 },{ -1, -1 }, /* F */
996 { 108, 106 },{ 98, 124 },{ 154, 124 },{ 144, 106 },{ -1, -1 }, /* G */
999 int lifter_face_points[][2] = {
1000 { 0, 190 },{ 0, 254 },{ 22, 254 },{ 22, 190 },{ -1, -1 }, /* D */
1001 { 230, 190 },{ 230, 254 },{ 254, 254 },{ 254, 190 },{ -1, -1 }, /* E */
1002 { 60, 210 },{ 60, 254 },{ 194, 254 },{ 194, 210 },{ -1, -1 }, /* H */
1003 { 92, 190 },{ 92, 210 },{ 160, 210 },{ 160, 190 },{ -1, -1 }, /* I */
1004 { 110, 172 },{ 110, 190 },{ 140, 190 },{ 140, 172 },{ -1, -1 }, /* J */
1007 int body_perimiter_points[][2] = {
1008 { 0, 144 },{ 86, 59 },{ 119, 58 },{ 71, 107 },
1009 { 108, 107 },{ 98, 124 },{ 155, 124 },{ 144, 107 },
1010 { 185, 106 },{ 136, 59 },{ 169, 59 },{ 255, 145 },
1011 { 255, 0 },{ 0, 0 },
1014 int slider_perimiter_points[][2] = {
1015 { 86, 58 },{ 0, 144 },{ 0, 190 },{ 22, 190 },{ 22, 254 },
1016 { 60, 254 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ 110, 190 },
1017 { 110, 172 },{ 140, 172 },{ 140, 190 },{ 160, 190 },{ 160, 210 },
1018 { 194, 210 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ 254, 190 },
1019 { 254, 144 },{ 168, 58 },{ 136, 58 },{ 184, 106 },{ 144, 106 },
1020 { 154, 124 },{ 98, 124 },{ 108, 106 },{ 70, 106 },{ 118, 58 },
1023 int lifter_perimiter_points_1[][2] = {
1024 { 0, 189 },{ 0, 254 },{ 22, 255 },{ 23, 190 },
1027 int lifter_perimiter_points_2[][2] = {
1028 { 230, 254 },{ 255, 255 },{ 254, 190 },{ 230, 190 },
1031 int lifter_perimiter_points_3[][2] = {
1032 { 60, 254 },{ 194, 254 },{ 194, 211 },{ 160, 210 },
1033 { 160, 190 },{ 140, 191 },{ 141, 172 },{ 111, 172 },
1034 { 110, 190 },{ 93, 190 },{ 92, 210 },{ 60, 211 },
1037 for (i = 0; i < countof(slider_face_points); i++)
1038 slider_face_points[i][1] = 255-slider_face_points[i][1];
1039 for (i = 0; i < countof(body_face_points); i++)
1040 body_face_points[i][1] = 255-body_face_points[i][1];
1041 for (i = 0; i < countof(lifter_face_points); i++)
1042 lifter_face_points[i][1] = 255-lifter_face_points[i][1];
1043 for (i = 0; i < countof(body_perimiter_points); i++)
1044 body_perimiter_points[i][1] = 255-body_perimiter_points[i][1];
1045 for (i = 0; i < countof(slider_perimiter_points); i++)
1046 slider_perimiter_points[i][1] = 255-slider_perimiter_points[i][1];
1047 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
1048 lifter_perimiter_points_1[i][1] = 255-lifter_perimiter_points_1[i][1];
1049 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
1050 lifter_perimiter_points_2[i][1] = 255-lifter_perimiter_points_2[i][1];
1051 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
1052 lifter_perimiter_points_3[i][1] = 255-lifter_perimiter_points_3[i][1];
1054 /* -------------------------------------------------------------------- */
1056 glNewList(lc->taser_base, GL_COMPILE);
1057 glShadeModel(GL_SMOOTH);
1060 face4(lc->texids[FACE_N], exterior_color, wire,
1061 0.0, 0.0, -0.5, 0.5, 0.5,
1062 0.75, 0.0, 0.25, 0.5, 0.5,
1063 0.75, 0.75, 0.25, 0.5, -0.25,
1064 0.0, 0.75, -0.5, 0.5, -0.25);
1067 face4(lc->texids[FACE_S], exterior_color, wire,
1068 0.0, 0.25, -0.5, -0.5, -0.25,
1069 0.75, 0.25, 0.25, -0.5, -0.25,
1070 0.75, 1.0, 0.25, -0.5, 0.5,
1071 0.0, 1.0, -0.5, -0.5, 0.5);
1074 face4(0, interior_color, wire,
1075 0.0, 0.0, 0.25, -0.5, -0.25,
1076 1.0, 0.0, 0.25, 0.5, -0.25,
1077 1.0, 1.0, 0.25, 0.5, 0.5,
1078 0.0, 1.0, 0.25, -0.5, 0.5);
1081 face4(lc->texids[FACE_W], exterior_color, wire,
1082 1.0, 1.0, -0.5, -0.5, 0.5,
1083 0.0, 1.0, -0.5, 0.5, 0.5,
1084 0.0, 0.25, -0.5, 0.5, -0.25,
1085 1.0, 0.25, -0.5, -0.5, -0.25);
1088 face4(lc->texids[FACE_U], exterior_color, wire,
1089 0.75, 0.0, 0.25, -0.5, 0.5,
1090 0.75, 1.0, 0.25, 0.5, 0.5,
1091 0.0, 1.0, -0.5, 0.5, 0.5,
1092 0.0, 0.0, -0.5, -0.5, 0.5);
1095 face4(0, interior_color, wire,
1096 0.0, 1.0, -0.5, -0.5, -0.25,
1097 0.0, 0.0, -0.5, 0.5, -0.25,
1098 1.0, 0.0, 0.25, 0.5, -0.25,
1099 1.0, 1.0, 0.25, -0.5, -0.25);
1102 for (i = 0; i < countof(body_face_points)/5; i++)
1105 #ifdef HAVE_GLBINDTEXTURE
1106 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1107 #endif /* HAVE_GLBINDTEXTURE */
1108 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1110 do_normal(0, body_face_points[(i*5)+0][0], body_face_points[(i*5)+0][1],
1111 0, body_face_points[(i*5)+1][0], body_face_points[(i*5)+1][1],
1112 0, body_face_points[(i*5)+2][0], body_face_points[(i*5)+2][1]
1114 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1115 for (j = 0; j < 5; j++)
1117 int ix = body_face_points[(i*5)+j][0];
1118 int iy = body_face_points[(i*5)+j][1];
1120 if (ix == -1) /* these are padding: ignore them */
1125 glVertex3f(0.5, x-0.5, y-0.5);
1131 for (i = 0; i < countof(body_perimiter_points); i++)
1133 int j = (i+1 >= countof(body_perimiter_points) ? 0 : i+1);
1134 GLfloat x1 = body_perimiter_points[i][0] / 255.0;
1135 GLfloat y1 = body_perimiter_points[i][1] / 255.0;
1136 GLfloat x2 = body_perimiter_points[j][0] / 255.0;
1137 GLfloat y2 = body_perimiter_points[j][1] / 255.0;
1139 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1143 texture = lc->texids[FACE_N];
1145 s2 = 1.0; t2 = 0.568;
1146 s3 = 0.75, t3 = 0.568;
1147 s4 = 0.75; t4 = 0.0;
1151 texture = lc->texids[FACE_U];
1154 s3 = 0.75, t3 = 1.0;
1155 s4 = 0.75; t4 = 0.0;
1159 texture = lc->texids[FACE_S];
1160 s1 = 1.0; t1 = 0.437;
1162 s3 = 0.75; t3 = 1.0;
1163 s4 = 0.75; t4 = 0.437;
1166 face4((texture == -1 ? 0 : texture),
1167 (texture == -1 ? interior_color : exterior_color),
1169 s1, t1, 0.5, x2-0.5, y2-0.5,
1170 s2, t2, 0.5, x1-0.5, y1-0.5,
1171 s3, t3, 0.25, x1-0.5, y1-0.5,
1172 s4, t4, 0.25, x2-0.5, y2-0.5);
1177 /* -------------------------------------------------------------------- */
1179 glNewList(lc->taser_lifter, GL_COMPILE);
1180 glShadeModel(GL_SMOOTH);
1183 face4(lc->texids[FACE_N], exterior_color, wire,
1184 0.0, 0.75, -0.5, 0.5, -0.25,
1185 0.75, 0.75, 0.25, 0.5, -0.25,
1186 0.75, 1.0, 0.25, 0.5, -0.5,
1187 0.0, 1.0, -0.5, 0.5, -0.5);
1190 face4(lc->texids[FACE_S], exterior_color, wire,
1191 0.0, 0.0, -0.5, -0.5, -0.5,
1192 0.75, 0.0, 0.25, -0.5, -0.5,
1193 0.75, 0.25, 0.25, -0.5, -0.25,
1194 0.0, 0.25, -0.5, -0.5, -0.25);
1197 face4(0, interior_color, wire,
1198 0.0, 1.0, 0.25, -0.5, -0.5,
1199 1.0, 1.0, 0.25, 0.5, -0.5,
1200 1.0, 0.0, 0.25, 0.5, -0.25,
1201 0.0, 0.0, 0.25, -0.5, -0.25);
1204 face4(lc->texids[FACE_W], exterior_color, wire,
1205 1.0, 0.25, -0.5, -0.5, -0.25,
1206 0.0, 0.25, -0.5, 0.5, -0.25,
1207 0.0, 0.0, -0.5, 0.5, -0.5,
1208 1.0, 0.0, -0.5, -0.5, -0.5);
1211 face4(0, interior_color, wire,
1212 1.0, 0.0, 0.25, -0.5, -0.25,
1213 1.0, 1.0, 0.25, 0.5, -0.25,
1214 0.0, 1.0, -0.5, 0.5, -0.25,
1215 0.0, 0.0, -0.5, -0.5, -0.25);
1218 face4(lc->texids[FACE_D], exterior_color, wire,
1219 0.0, 1.0, -0.5, -0.5, -0.5,
1220 0.0, 0.0, -0.5, 0.5, -0.5,
1221 0.75, 0.0, 0.25, 0.5, -0.5,
1222 0.75, 1.0, 0.25, -0.5, -0.5);
1226 for (i = 0; i < countof(lifter_face_points)/5; i++)
1230 #ifdef HAVE_GLBINDTEXTURE
1231 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1232 #endif /* HAVE_GLBINDTEXTURE */
1233 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1236 0, lifter_face_points[(i*5)+0][0], lifter_face_points[(i*5)+0][1],
1237 0, lifter_face_points[(i*5)+1][0], lifter_face_points[(i*5)+1][1],
1238 0, lifter_face_points[(i*5)+2][0], lifter_face_points[(i*5)+2][1]);
1240 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1241 for (j = 0; j < 5; j++)
1243 int ix = lifter_face_points[(i*5)+j][0];
1244 int iy = lifter_face_points[(i*5)+j][1];
1246 if (ix == -1) /* these are padding: ignore them */
1251 glVertex3f(0.5, x-0.5, y-0.5);
1257 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
1259 int j = (i+1 >= countof(lifter_perimiter_points_1) ? 0 : i+1);
1260 GLfloat x1 = lifter_perimiter_points_1[i][0] / 255.0;
1261 GLfloat y1 = lifter_perimiter_points_1[i][1] / 255.0;
1262 GLfloat x2 = lifter_perimiter_points_1[j][0] / 255.0;
1263 GLfloat y2 = lifter_perimiter_points_1[j][1] / 255.0;
1265 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1269 texture = lc->texids[FACE_S];
1271 s2 = 1.0; t2 = 0.26;
1272 s3 = 0.75, t3 = 0.26;
1273 s4 = 0.75; t4 = 0.0;
1277 texture = lc->texids[FACE_D];
1278 s1 = 1.0; t1 = 0.914;
1280 s3 = 0.75; t3 = 1.0;
1281 s4 = 0.75; t4 = 0.914;
1284 face4((texture == -1 ? 0 : texture),
1285 (texture == -1 ? interior_color : exterior_color),
1287 s1, t1, 0.5, x2-0.5, y2-0.5,
1288 s2, t2, 0.5, x1-0.5, y1-0.5,
1289 s3, t3, 0.25, x1-0.5, y1-0.5,
1290 s4, t4, 0.25, x2-0.5, y2-0.5);
1293 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
1295 int j = (i+1 >= countof(lifter_perimiter_points_2) ? 0 : i+1);
1296 GLfloat x1 = lifter_perimiter_points_2[i][0] / 255.0;
1297 GLfloat y1 = lifter_perimiter_points_2[i][1] / 255.0;
1298 GLfloat x2 = lifter_perimiter_points_2[j][0] / 255.0;
1299 GLfloat y2 = lifter_perimiter_points_2[j][1] / 255.0;
1301 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1305 texture = lc->texids[FACE_D];
1307 s2 = 1.0; t2 = 0.095;
1308 s3 = 0.75; t3 = 0.095;
1309 s4 = 0.75; t4 = 0.0;
1313 texture = lc->texids[FACE_N];
1314 s1 = 1.0; t1 = 0.745;
1316 s3 = 0.75; t3 = 1.0;
1317 s4 = 0.75; t4 = 0.745;
1320 face4((texture == -1 ? 0 : texture),
1321 (texture == -1 ? interior_color : exterior_color),
1323 s1, t1, 0.5, x2-0.5, y2-0.5,
1324 s2, t2, 0.5, x1-0.5, y1-0.5,
1325 s3, t3, 0.25, x1-0.5, y1-0.5,
1326 s4, t4, 0.25, x2-0.5, y2-0.5);
1329 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
1331 int j = (i+1 >= countof(lifter_perimiter_points_3) ? 0 : i+1);
1332 GLfloat x1 = lifter_perimiter_points_3[i][0] / 255.0;
1333 GLfloat y1 = lifter_perimiter_points_3[i][1] / 255.0;
1334 GLfloat x2 = lifter_perimiter_points_3[j][0] / 255.0;
1335 GLfloat y2 = lifter_perimiter_points_3[j][1] / 255.0;
1337 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1341 texture = lc->texids[FACE_D];
1342 s1 = 1.0; t1 = 0.235;
1343 s2 = 1.0; t2 = 0.765;
1344 s3 = 0.75; t3 = 0.765;
1345 s4 = 0.75; t4 = 0.235;
1348 face4((texture == -1 ? 0 : texture),
1349 (texture == -1 ? interior_color : exterior_color),
1351 s1, t1, 0.5, x2-0.5, y2-0.5,
1352 s2, t2, 0.5, x1-0.5, y1-0.5,
1353 s3, t3, 0.25, x1-0.5, y1-0.5,
1354 s4, t4, 0.25, x2-0.5, y2-0.5);
1359 /* -------------------------------------------------------------------- */
1361 glNewList(lc->taser_slider, GL_COMPILE);
1362 glShadeModel(GL_SMOOTH);
1365 for (i = 0; i < countof(slider_face_points)/5; i++)
1368 #ifdef HAVE_GLBINDTEXTURE
1369 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1370 #endif /* HAVE_GLBINDTEXTURE */
1371 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1374 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1],
1375 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1376 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1]);
1377 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1378 for (j = 0; j < 5; j++)
1380 int ix = slider_face_points[(i*5)+j][0];
1381 int iy = slider_face_points[(i*5)+j][1];
1383 if (ix == -1) /* these are padding: ignore them */
1388 glVertex3f(0.5, x-0.5, y-0.5);
1394 for (i = countof(slider_face_points)/5 - 1; i >= 0; i--)
1397 #ifdef HAVE_GLBINDTEXTURE
1398 glBindTexture(GL_TEXTURE_2D, 0);
1399 #endif /* HAVE_GLBINDTEXTURE */
1400 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color);
1403 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1],
1404 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1405 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1]);
1406 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1407 for (j = 4; j >= 0; j--)
1409 int ix = slider_face_points[(i*5)+j][0];
1410 int iy = slider_face_points[(i*5)+j][1];
1412 if (ix == -1) /* these are padding: ignore them */
1417 glVertex3f(0.25, x-0.5, y-0.5);
1423 for (i = 0; i < countof(slider_perimiter_points); i++)
1425 int j = (i+1 >= countof(slider_perimiter_points) ? 0 : i+1);
1426 GLfloat x1 = slider_perimiter_points[i][0] / 255.0;
1427 GLfloat y1 = slider_perimiter_points[i][1] / 255.0;
1428 GLfloat x2 = slider_perimiter_points[j][0] / 255.0;
1429 GLfloat y2 = slider_perimiter_points[j][1] / 255.0;
1431 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1435 texture = lc->texids[FACE_S];
1436 s1 = 1.0; t1 = 0.255;
1437 s2 = 1.0; t2 = 0.435;
1438 s3 = 0.75; t3 = 0.435;
1439 s4 = 0.75; t4 = 0.255;
1443 texture = lc->texids[FACE_D];
1444 s1 = 1.0; t1 = 0.758;
1445 s2 = 1.0; t2 = 0.915;
1446 s3 = 0.75; t3 = 0.915;
1447 s4 = 0.75; t4 = 0.758;
1451 texture = lc->texids[FACE_D];
1452 s1 = 1.0; t1 = 0.095;
1453 s2 = 1.0; t2 = 0.24;
1454 s3 = 0.75; t3 = 0.24;
1455 s4 = 0.75; t4 = 0.095;
1459 texture = lc->texids[FACE_N];
1460 s1 = 1.0; t1 = 0.568;
1461 s2 = 1.0; t2 = 0.742;
1462 s3 = 0.75; t3 = 0.742;
1463 s4 = 0.75; t4 = 0.568;
1466 face4((texture == -1 ? 0 : texture),
1467 (texture == -1 ? interior_color : exterior_color),
1469 s1, t1, 0.5, x2-0.5, y2-0.5,
1470 s2, t2, 0.5, x1-0.5, y1-0.5,
1471 s3, t3, 0.25, x1-0.5, y1-0.5,
1472 s4, t4, 0.25, x2-0.5, y2-0.5);
1480 /* Rendering and animating object models
1486 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1487 Bool wire = MI_IS_WIREFRAME(mi);
1490 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1492 glClear(GL_COLOR_BUFFER_BIT);
1496 GLfloat x = lc->rotx;
1497 GLfloat y = lc->roty;
1498 GLfloat z = lc->rotz;
1504 if (x < 0) x = 1 - (x + 1);
1505 if (y < 0) y = 1 - (y + 1);
1506 if (z < 0) z = 1 - (z + 1);
1508 /* Make into the screen be +Y right be +X, and up be +Z. */
1509 glRotatef(-90.0, 1.0, 0.0, 0.0);
1512 glScalef(4.0, 4.0, 4.0);
1517 /* Shift to the upper left, and draw the vanilla box. */
1518 glTranslatef(-0.6, 0.0, 0.6);
1520 /* Apply rotation to the object. */
1521 glRotatef(x * 360, 1.0, 0.0, 0.0);
1522 glRotatef(y * 360, 0.0, 1.0, 0.0);
1523 glRotatef(z * 360, 0.0, 0.0, 1.0);
1526 glCallList(lc->box);
1530 /* Shift to the lower right, and draw the animated object. */
1531 glTranslatef(0.6, 0.0, -0.6);
1537 /* Apply rotation to the object. */
1538 glRotatef(x * 360, 1.0, 0.0, 0.0);
1539 glRotatef(y * 360, 0.0, 1.0, 0.0);
1540 glRotatef(z * 360, 0.0, 0.0, 1.0);
1545 glCallList(lc->box);
1548 case LAMENT_STAR_OUT:
1549 case LAMENT_STAR_ROT:
1550 case LAMENT_STAR_ROT_IN:
1551 case LAMENT_STAR_ROT_OUT:
1552 case LAMENT_STAR_UNROT:
1553 case LAMENT_STAR_IN:
1554 glTranslatef(0.0, 0.0, lc->anim_z/2);
1555 glRotatef(lc->anim_r/2, 0.0, 0.0, 1.0);
1556 glCallList(lc->star1);
1558 glTranslatef(0.0, 0.0, -lc->anim_z);
1559 glRotatef(-lc->anim_r, 0.0, 0.0, 1.0);
1560 glCallList(lc->star2);
1563 case LAMENT_TETRA_UNE:
1564 case LAMENT_TETRA_USW:
1565 case LAMENT_TETRA_DWN:
1566 case LAMENT_TETRA_DSE:
1571 case LAMENT_TETRA_UNE: magic = lc->tetra_une;
1572 x = 1.0; y = 1.0; z = 1.0; break;
1573 case LAMENT_TETRA_USW: magic = lc->tetra_usw;
1574 x = 1.0; y = 1.0; z = -1.0; break;
1575 case LAMENT_TETRA_DWN: magic = lc->tetra_dwn;
1576 x = 1.0; y = -1.0; z = 1.0; break;
1577 case LAMENT_TETRA_DSE: magic = lc->tetra_dse;
1578 x = -1.0; y = 1.0; z = 1.0; break;
1579 default: abort(); break;
1581 glCallList(lc->tetra_mid);
1582 if (magic != lc->tetra_une) glCallList(lc->tetra_une);
1583 if (magic != lc->tetra_usw) glCallList(lc->tetra_usw);
1584 if (magic != lc->tetra_dwn) glCallList(lc->tetra_dwn);
1585 if (magic != lc->tetra_dse) glCallList(lc->tetra_dse);
1586 glRotatef(lc->anim_r, x, y, z);
1591 case LAMENT_LID_OPEN:
1592 case LAMENT_LID_CLOSE:
1593 case LAMENT_LID_ZOOM:
1597 glTranslatef(lc->anim_z, 0.0, 0.0);
1599 glCallList(lc->lid_0);
1602 glTranslatef(-0.5, -d, 0.0);
1603 glRotatef(-lc->anim_r, 0.0, -1.0, -1.0);
1604 glTranslatef( 0.5, d, 0.0);
1605 glCallList(lc->lid_1);
1608 glTranslatef(-0.5, -d, 0.0);
1609 glRotatef( lc->anim_r, 0.0, -1.0, 1.0);
1610 glTranslatef( 0.5, d, 0.0);
1611 glCallList(lc->lid_2);
1614 glTranslatef(-0.5, d, 0.0);
1615 glRotatef( lc->anim_r, 0.0, -1.0, -1.0);
1616 glTranslatef( 0.5, -d, 0.0);
1617 glCallList(lc->lid_3);
1620 glTranslatef(-0.5, d, 0.0);
1621 glRotatef(-lc->anim_r, 0.0, -1.0, 1.0);
1622 glTranslatef( 0.5, -d, 0.0);
1623 glCallList(lc->lid_4);
1628 case LAMENT_TASER_OUT:
1629 case LAMENT_TASER_SLIDE:
1630 case LAMENT_TASER_SLIDE_IN:
1631 case LAMENT_TASER_IN:
1633 glTranslatef(-lc->anim_z/2, 0.0, 0.0);
1634 glCallList(lc->taser_base);
1636 glTranslatef(lc->anim_z, 0.0, 0.0);
1637 glCallList(lc->taser_lifter);
1639 glTranslatef(0.0, 0.0, lc->anim_y);
1640 glCallList(lc->taser_slider);
1656 animate(ModeInfo *mi)
1658 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1660 /* int pause2 = 60;*/
1667 /* Rather than just picking states randomly, pick an ordering randomly,
1668 do it, and then re-randomize. That way one can be assured of seeing
1669 all states in a short time period, though not always in the same
1670 order (it's frustrating to see it pick the same state 5x in a row.)
1672 static lament_type states[] = {
1673 LAMENT_STAR_OUT, LAMENT_STAR_OUT,
1674 LAMENT_TETRA_UNE, LAMENT_TETRA_USW,
1675 LAMENT_TETRA_DWN, LAMENT_TETRA_DSE,
1676 LAMENT_LID_OPEN, LAMENT_LID_OPEN, LAMENT_LID_OPEN,
1677 LAMENT_TASER_OUT, LAMENT_TASER_OUT,
1678 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1679 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1681 static int state = countof(states);
1683 if (state < countof(states))
1685 lc->type = states[state++];
1691 for (i = 0; i < countof(states); i++)
1693 int a = random() % countof(states);
1694 lament_type swap = states[a];
1695 states[a] = states[i];
1700 if (lc->type == LAMENT_BOX)
1701 lc->anim_pause = pause3;
1709 /* -------------------------------------------------------------- */
1711 case LAMENT_STAR_OUT:
1713 if (lc->anim_z >= 1.0)
1716 lc->type = LAMENT_STAR_ROT;
1717 lc->anim_pause = pause;
1721 case LAMENT_STAR_ROT:
1723 if (lc->anim_r >= 45.0)
1726 lc->type = LAMENT_STAR_ROT_IN;
1727 lc->anim_pause = pause;
1731 case LAMENT_STAR_ROT_IN:
1733 if (lc->anim_z <= 0.0)
1736 lc->type = LAMENT_STAR_ROT_OUT;
1737 lc->anim_pause = pause3 * (1 + (random() % 4) + (random() % 4));
1741 case LAMENT_STAR_ROT_OUT:
1743 if (lc->anim_z >= 1.0)
1746 lc->type = LAMENT_STAR_UNROT;
1747 lc->anim_pause = pause;
1751 case LAMENT_STAR_UNROT:
1753 if (lc->anim_r <= 0.0)
1756 lc->type = LAMENT_STAR_IN;
1757 lc->anim_pause = pause;
1761 case LAMENT_STAR_IN:
1763 if (lc->anim_z <= 0.0)
1766 lc->type = LAMENT_BOX;
1767 lc->anim_pause = pause3;
1771 /* -------------------------------------------------------------- */
1773 case LAMENT_TETRA_UNE:
1774 case LAMENT_TETRA_USW:
1775 case LAMENT_TETRA_DWN:
1776 case LAMENT_TETRA_DSE:
1779 if (lc->anim_r >= 360.0)
1782 lc->type = LAMENT_BOX;
1783 lc->anim_pause = pause3;
1785 else if (lc->anim_r > 119.0 && lc->anim_r <= 120.0)
1788 lc->anim_pause = pause;
1790 else if (lc->anim_r > 239.0 && lc->anim_r <= 240.0)
1793 lc->anim_pause = pause;
1797 /* -------------------------------------------------------------- */
1799 case LAMENT_LID_OPEN:
1802 if (lc->anim_r >= 112.0)
1804 GLfloat hysteresis = 0.05;
1808 lc->anim_pause = pause3;
1810 if (lc->rotx >= -hysteresis &&
1811 lc->rotx <= hysteresis &&
1812 ((lc->rotz >= (0.25 - hysteresis) &&
1813 lc->rotz <= (0.25 + hysteresis)) ||
1814 (lc->rotz >= (-0.25 - hysteresis) &&
1815 lc->rotz <= (-0.25 + hysteresis))))
1817 lc->type = LAMENT_LID_ZOOM;
1819 lc->rotz = (lc->rotz < 0 ? -0.25 : 0.25);
1823 lc->type = LAMENT_LID_CLOSE;
1828 case LAMENT_LID_CLOSE:
1830 if (lc->anim_r <= 0.0)
1833 lc->type = LAMENT_BOX;
1834 lc->anim_pause = pause3;
1838 case LAMENT_LID_ZOOM:
1840 if (lc->anim_z < -50.0)
1844 lc->rotx = frand(1.0) * RANDSIGN();
1845 lc->roty = frand(1.0) * RANDSIGN();
1846 lc->rotz = frand(1.0) * RANDSIGN();
1847 lc->type = LAMENT_BOX;
1851 /* -------------------------------------------------------------- */
1853 case LAMENT_TASER_OUT:
1854 lc->anim_z += 0.0025;
1855 if (lc->anim_z >= 0.25)
1858 lc->type = LAMENT_TASER_SLIDE;
1859 lc->anim_pause = pause * (1 + (random() % 5) + (random() % 5));
1863 case LAMENT_TASER_SLIDE:
1864 lc->anim_y += 0.0025;
1865 if (lc->anim_y >= 0.23)
1868 lc->type = LAMENT_TASER_SLIDE_IN;
1869 lc->anim_pause = pause3 * (1 + (random() % 5) + (random() % 5));
1873 case LAMENT_TASER_SLIDE_IN:
1874 lc->anim_y -= 0.0025;
1875 if (lc->anim_y <= 0.0)
1878 lc->type = LAMENT_TASER_IN;
1879 lc->anim_pause = pause;
1883 case LAMENT_TASER_IN:
1884 lc->anim_z -= 0.0025;
1885 if (lc->anim_z <= 0.0)
1888 lc->type = LAMENT_BOX;
1889 lc->anim_pause = pause3;
1901 rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v)
1907 ppos = -(ppos + *v);
1916 if (ppos < 0) abort();
1917 if (ppos > 1.0) abort();
1918 *pos = (*pos > 0 ? ppos : -ppos);
1923 /* clamp velocity */
1924 if (*v > max_v || *v < -max_v)
1928 /* If it stops, start it going in the other direction. */
1935 /* keep going in the same direction */
1950 /* Alter direction of rotational acceleration randomly. */
1951 if (! (random() % 120))
1954 /* Change acceleration very occasionally. */
1955 if (! (random() % 200))
1959 else if (random() & 1)
1968 /* Window management, etc
1972 reshape(int width, int height)
1974 int target_size = 180;
1975 int win_size = (width > height ? height : width);
1976 GLfloat h = (GLfloat) height / (GLfloat) width;
1978 glViewport(0, 0, (GLint) width, (GLint) height);
1980 /* glViewport(-600, -600, 1800, 1800); */
1982 glMatrixMode(GL_PROJECTION);
1984 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
1985 glMatrixMode(GL_MODELVIEW);
1987 glTranslatef(0.0, 0.0, -40.0);
1989 /* This scale makes the box take up most of the window */
1990 glScalef(2.0, 2.0, 2.0);
1992 /* But if the window is more than a little larger than our target size,
1993 scale the object back down, so that the bits drawn on the screen end
1994 up rougly target_size across (actually it ends up a little larger.)
1995 Note that the image-map bits we have are 128x128. Therefore, if the
1996 image is magnified a lot, it looks pretty blocky. So it's better to
1997 have a 128x128 animation on a 1280x1024 screen that looks good, than
1998 a 1024x1024 animation that looks really pixellated.
2000 if (win_size > target_size * 1.5)
2002 GLfloat ratio = ((GLfloat) target_size / (GLfloat) win_size);
2004 glScalef(ratio, ratio, ratio);
2007 /* The depth buffer will be cleared, if needed, before the
2008 * next frame. Right now we just want to black the screen.
2010 glClear(GL_COLOR_BUFFER_BIT);
2015 gl_init(ModeInfo *mi)
2017 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
2018 Bool wire = MI_IS_WIREFRAME(mi);
2025 static GLfloat pos0[] = { -4.0, 2.0, 5.0, 1.0 };
2026 static GLfloat pos1[] = { 12.0, 5.0, 1.0, 1.0 };
2027 static GLfloat local[] = { 0.0 };
2028 static GLfloat ambient[] = { 0.3, 0.3, 0.3, 1.0 };
2029 static GLfloat spec[] = { 1.0, 1.0, 1.0, 1.0 };
2030 static GLfloat shine[] = { 100.0 };
2032 glLightfv(GL_LIGHT0, GL_POSITION, pos0);
2033 glLightfv(GL_LIGHT1, GL_POSITION, pos1);
2035 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
2036 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
2038 glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
2039 glLightfv(GL_LIGHT1, GL_SPECULAR, spec);
2041 glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local);
2042 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
2043 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
2044 glMaterialfv(GL_FRONT, GL_SHININESS, shine);
2046 glEnable(GL_LIGHTING);
2047 glEnable(GL_LIGHT0);
2048 glEnable(GL_LIGHT1);
2049 glDisable(GL_LIGHT1);
2051 glEnable(GL_DEPTH_TEST);
2052 glEnable(GL_TEXTURE_2D);
2053 glEnable(GL_NORMALIZE);
2054 glEnable(GL_CULL_FACE);
2059 #ifdef HAVE_GLBINDTEXTURE
2061 for (i = 0; i < 6; i++)
2062 glGenTextures(1, &lc->texids[i]);
2064 parse_image_data(mi);
2066 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2067 glPixelStorei(GL_UNPACK_ROW_LENGTH, lc->texture->width);
2069 for (i = 0; i < 6; i++)
2071 int height = lc->texture->width; /* assume square */
2072 glBindTexture(GL_TEXTURE_2D, lc->texids[i]);
2073 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
2074 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
2075 lc->texture->width, height, 0,
2076 GL_RGBA, GL_UNSIGNED_BYTE,
2077 (lc->texture->data +
2078 (lc->texture->bytes_per_line * height * i)));
2080 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2081 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2082 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2083 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2084 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
2085 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
2088 #else /* !HAVE_GLBINDTEXTURE */
2090 "%s: this version of GL doesn't support multiple texture maps.\n"
2091 "\tGet OpenGL 1.1.\n",
2094 #endif /* !HAVE_GLBINDTEXTURE */
2097 lc->box = glGenLists(16);
2098 lc->star1 = lc->box+1;
2099 lc->star2 = lc->box+2;
2100 lc->tetra_une = lc->box+3;
2101 lc->tetra_usw = lc->box+4;
2102 lc->tetra_dwn = lc->box+5;
2103 lc->tetra_dse = lc->box+6;
2104 lc->tetra_mid = lc->box+7;
2105 lc->lid_0 = lc->box+8;
2106 lc->lid_1 = lc->box+9;
2107 lc->lid_2 = lc->box+10;
2108 lc->lid_3 = lc->box+11;
2109 lc->lid_4 = lc->box+12;
2110 lc->taser_base = lc->box+13;
2111 lc->taser_lifter = lc->box+14;
2112 lc->taser_slider = lc->box+15;
2115 star(mi, True, wire);
2116 star(mi, False, wire);
2124 init_lament(ModeInfo *mi)
2126 lament_configuration *lc;
2129 lcs = (lament_configuration *)
2130 calloc(MI_NUM_SCREENS(mi), sizeof (lament_configuration));
2133 fprintf(stderr, "%s: out of memory\n", progname);
2138 lc = &lcs[MI_SCREEN(mi)];
2140 lc->rotx = frand(1.0) * RANDSIGN();
2141 lc->roty = frand(1.0) * RANDSIGN();
2142 lc->rotz = frand(1.0) * RANDSIGN();
2144 /* bell curve from 0-1.5 degrees, avg 0.75 */
2145 lc->dx = (frand(1) + frand(1) + frand(1)) / (360*2);
2146 lc->dy = (frand(1) + frand(1) + frand(1)) / (360*2);
2147 lc->dz = (frand(1) + frand(1) + frand(1)) / (360*2);
2149 lc->d_max = lc->dx * 2;
2151 lc->ddx = 0.00006 + frand(0.00003);
2152 lc->ddy = 0.00006 + frand(0.00003);
2153 lc->ddz = 0.00006 + frand(0.00003);
2159 lc->type = LAMENT_BOX;
2160 lc->anim_pause = 300 + (random() % 100);
2162 if ((lc->glx_context = init_GL(mi)) != NULL)
2164 reshape(MI_WIDTH(mi), MI_HEIGHT(mi));
2171 draw_lament(ModeInfo *mi)
2173 static int tick = 0;
2174 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
2175 Display *dpy = MI_DISPLAY(mi);
2176 Window window = MI_WINDOW(mi);
2178 if (!lc->glx_context)
2181 glDrawBuffer(GL_BACK);
2183 glXMakeCurrent(dpy, window, *(lc->glx_context));
2186 glXSwapBuffers(dpy, window);
2188 if (lc->type != LAMENT_LID_ZOOM)
2190 rotate(&lc->rotx, &lc->dx, &lc->ddx, lc->d_max);
2191 rotate(&lc->roty, &lc->dy, &lc->ddy, lc->d_max);
2192 rotate(&lc->rotz, &lc->dz, &lc->ddz, lc->d_max);
2203 reshape(MI_WIDTH(mi), MI_HEIGHT(mi));