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 HACK_RESHAPE reshape_lament
85 #define lament_opts xlockmore_opts
86 #define DEFAULTS "*delay: 10000 \n" \
87 "*showFPS: False \n" \
88 "*wireframe: False \n" \
90 #include "xlockmore.h"
92 #ifdef USE_GL /* whole file */
95 #define countof(x) (sizeof((x))/sizeof((*x)))
97 #define DEF_TEXTURE "True"
99 static int do_texture;
100 static XrmOptionDescRec opts[] = {
101 {"-texture", ".lament.texture", XrmoptionNoArg, (caddr_t) "true" },
102 {"+texture", ".lament.texture", XrmoptionNoArg, (caddr_t) "false" },
105 static argtype vars[] = {
106 {(caddr_t *) &do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool},
109 ModeSpecOpt lament_opts = {countof(opts), opts, countof(vars), vars, NULL};
111 #include "xpm-ximage.h"
112 #include "../images/lament.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.33, 0.22, 0.03, 1.00, /* ambient */
144 0.78, 0.57, 0.11, 1.00, /* specular */
145 0.99, 0.91, 0.81, 1.00, /* diffuse */
146 27.80 /* shininess */
148 static GLfloat interior_color[] = { 0.20, 0.20, 0.15, 1.00, /* ambient */
149 0.40, 0.40, 0.32, 1.00, /* specular */
150 0.99, 0.99, 0.81, 1.00, /* diffuse */
151 50.80 /* shininess */
156 GLXContext *glx_context;
158 GLuint box; /* display list IDs */
160 GLuint tetra_une, tetra_usw, tetra_dwn, tetra_dse, tetra_mid;
161 GLuint lid_0, lid_1, lid_2, lid_3, lid_4;
162 GLuint taser_base, taser_lifter, taser_slider;
164 GLfloat rotx, roty, rotz; /* current object rotation */
165 GLfloat dx, dy, dz; /* current rotational velocity */
166 GLfloat ddx, ddy, ddz; /* current rotational acceleration */
167 GLfloat d_max; /* max velocity */
168 XImage *texture; /* image bits */
169 GLuint texids[6]; /* texture map IDs */
170 lament_type type; /* which mode of the object is current */
172 int anim_pause; /* countdown before animating again */
173 GLfloat anim_r, anim_y, anim_z; /* relative position during anims */
175 } lament_configuration;
177 static lament_configuration *lcs = NULL;
187 parse_image_data(ModeInfo *mi)
189 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
190 lc->texture = xpm_to_ximage (mi->dpy,
197 /* Computing normal vectors (thanks to Nat Friedman <ndf@mit.edu>)
200 typedef struct vector {
204 typedef struct plane {
209 vector_set(vector *v, GLfloat x, GLfloat y, GLfloat z)
217 vector_cross(vector v1, vector v2, vector *v3)
219 v3->x = (v1.y * v2.z) - (v1.z * v2.y);
220 v3->y = (v1.z * v2.x) - (v1.x * v2.z);
221 v3->z = (v1.x * v2.y) - (v1.y * v2.x);
225 vector_subtract(vector v1, vector v2, vector *res)
227 res->x = v1.x - v2.x;
228 res->y = v1.y - v2.y;
229 res->z = v1.z - v2.z;
233 plane_normal(plane p, vector *n)
236 vector_subtract(p.p1, p.p2, &v1);
237 vector_subtract(p.p1, p.p3, &v2);
238 vector_cross(v2, v1, n);
242 do_normal(GLfloat x1, GLfloat y1, GLfloat z1,
243 GLfloat x2, GLfloat y2, GLfloat z2,
244 GLfloat x3, GLfloat y3, GLfloat z3)
248 vector_set(&plane.p1, x1, y1, z1);
249 vector_set(&plane.p2, x2, y2, z2);
250 vector_set(&plane.p3, x3, y3, z3);
251 plane_normal(plane, &n);
252 n.x = -n.x; n.y = -n.y; n.z = -n.z;
254 glNormal3f(n.x, n.y, n.z);
257 /* Draw a line in the direction of this face's normal. */
259 GLfloat ax = n.x > 0 ? n.x : -n.x;
260 GLfloat ay = n.y > 0 ? n.y : -n.y;
261 GLfloat az = n.z > 0 ? n.z : -n.z;
262 GLfloat mx = (x1 + x2 + x3) / 3;
263 GLfloat my = (y1 + y2 + y3) / 3;
264 GLfloat mz = (z1 + z2 + z3) / 3;
267 GLfloat max = ax > ay ? ax : ay;
268 if (az > max) max = az;
274 glBegin(GL_LINE_LOOP);
275 glVertex3f(mx, my, mz);
276 glVertex3f(mx+xx, my+yy, mz+zz);
284 /* Shorthand utilities for making faces, with proper normals.
288 set_colors (GLfloat *color)
290 glMaterialfv(GL_FRONT, GL_AMBIENT, color+0);
291 glMaterialfv(GL_FRONT, GL_DIFFUSE, color+4);
292 glMaterialfv(GL_FRONT, GL_SPECULAR, color+8);
293 glMaterialfv(GL_FRONT, GL_SHININESS, color+12);
297 face3(GLint texture, GLfloat *color, Bool wire,
298 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
299 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
300 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3)
302 #ifdef HAVE_GLBINDTEXTURE
303 glBindTexture(GL_TEXTURE_2D, texture);
304 #endif /* HAVE_GLBINDTEXTURE */
307 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
308 glBegin(wire ? GL_LINE_LOOP : GL_TRIANGLES);
309 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
310 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
311 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
316 face4(GLint texture, GLfloat *color, Bool wire,
317 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
318 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
319 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3,
320 GLfloat s4, GLfloat t4, GLfloat x4, GLfloat y4, GLfloat z4)
322 #ifdef HAVE_GLBINDTEXTURE
323 glBindTexture(GL_TEXTURE_2D, texture);
324 #endif /* HAVE_GLBINDTEXTURE */
326 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
327 glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
328 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
329 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
330 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
331 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
336 face5(GLint texture, GLfloat *color, Bool wire,
337 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
338 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
339 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3,
340 GLfloat s4, GLfloat t4, GLfloat x4, GLfloat y4, GLfloat z4,
341 GLfloat s5, GLfloat t5, GLfloat x5, GLfloat y5, GLfloat z5)
343 #ifdef HAVE_GLBINDTEXTURE
344 glBindTexture(GL_TEXTURE_2D, texture);
345 #endif /* HAVE_GLBINDTEXTURE */
347 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
348 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
349 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
350 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
351 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
352 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
353 glTexCoord2f(s5, t5); glVertex3f(x5, y5, z5);
359 /* Creating object models
363 box(ModeInfo *mi, Bool wire)
365 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
367 glNewList(lc->box, GL_COMPILE);
368 glShadeModel(GL_SMOOTH);
371 face4(lc->texids[FACE_N], exterior_color, wire,
372 0.0, 0.0, -0.5, 0.5, 0.5,
373 1.0, 0.0, 0.5, 0.5, 0.5,
374 1.0, 1.0, 0.5, 0.5, -0.5,
375 0.0, 1.0, -0.5, 0.5, -0.5);
378 face4(lc->texids[FACE_S], exterior_color, wire,
379 0.0, 0.0, -0.5, -0.5, -0.5,
380 1.0, 0.0, 0.5, -0.5, -0.5,
381 1.0, 1.0, 0.5, -0.5, 0.5,
382 0.0, 1.0, -0.5, -0.5, 0.5);
385 face4(lc->texids[FACE_E], exterior_color, wire,
386 0.0, 0.0, 0.5, -0.5, -0.5,
387 1.0, 0.0, 0.5, 0.5, -0.5,
388 1.0, 1.0, 0.5, 0.5, 0.5,
389 0.0, 1.0, 0.5, -0.5, 0.5);
392 face4(lc->texids[FACE_W], exterior_color, wire,
393 1.0, 1.0, -0.5, -0.5, 0.5,
394 0.0, 1.0, -0.5, 0.5, 0.5,
395 0.0, 0.0, -0.5, 0.5, -0.5,
396 1.0, 0.0, -0.5, -0.5, -0.5);
399 face4(lc->texids[FACE_U], exterior_color, wire,
400 1.0, 0.0, 0.5, -0.5, 0.5,
401 1.0, 1.0, 0.5, 0.5, 0.5,
402 0.0, 1.0, -0.5, 0.5, 0.5,
403 0.0, 0.0, -0.5, -0.5, 0.5);
406 face4(lc->texids[FACE_D], exterior_color, wire,
407 0.0, 1.0, -0.5, -0.5, -0.5,
408 0.0, 0.0, -0.5, 0.5, -0.5,
409 1.0, 0.0, 0.5, 0.5, -0.5,
410 1.0, 1.0, 0.5, -0.5, -0.5);
417 star(ModeInfo *mi, Bool top, Bool wire)
419 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
423 { 77, 74 }, { 60, 98 }, { 0, 71 }, { 0, 0 }, /* L1 */
424 { 60, 98 }, { 55, 127 }, { 0, 127 }, { 0, 71 }, /* L2 */
425 { 55, 127 }, { 60, 154 }, { 0, 179 }, { 0, 127 }, /* L3 */
426 { 60, 154 }, { 76, 176 }, { 0, 255 }, { 0, 179 }, /* L4 */
427 { 76, 176 }, { 100, 193 }, { 74, 255 }, { 0, 255 }, /* B1 */
428 { 100, 193 }, { 127, 198 }, { 127, 255 }, { 74, 255 }, /* B2 */
429 { 127, 198 }, { 151, 193 }, { 180, 255 }, { 127, 255 }, /* B3 */
430 { 151, 193 }, { 178, 177 }, { 255, 255 }, { 180, 255 }, /* B4 */
431 { 178, 177 }, { 193, 155 }, { 255, 181 }, { 255, 255 }, /* R4 */
432 { 193, 155 }, { 199, 127 }, { 255, 127 }, { 255, 181 }, /* R3 */
433 { 199, 127 }, { 194, 99 }, { 255, 74 }, { 255, 127 }, /* R2 */
434 { 194, 99 }, { 179, 76 }, { 255, 0 }, { 255, 74 }, /* R1 */
435 { 179, 76 }, { 155, 60 }, { 180, 0 }, { 255, 0 }, /* T4 */
436 { 155, 60 }, { 126, 55 }, { 126, 0 }, { 180, 0 }, /* T3 */
437 { 126, 55 }, { 100, 60 }, { 75, 0 }, { 126, 0 }, /* T2 */
438 { 100, 60 }, { 77, 74 }, { 0, 0 }, { 75, 0 }, /* T1 */
441 for (i = 0; i < countof(points); i++)
442 points[i][1] = 255-points[i][1];
445 glNewList(lc->star1, GL_COMPILE);
447 glNewList(lc->star2, GL_COMPILE);
450 glRotatef(-180.0, 1.0, 0.0, 0.0);
452 for (i = 0; i < countof(points)/4; i += 2)
459 GLfloat s[4], t[4], x[4], y[4], z[4];
460 for (j = 3, k = 0; j >= 0; j--, k++)
462 GLfloat xx = points[(i*4)+j][0] / 255.0L;
463 GLfloat yy = points[(i*4)+j][1] / 255.0L;
470 face4(lc->texids[top ? FACE_U : FACE_D], exterior_color, wire,
471 s[0], t[0], x[0], y[0], z[0],
472 s[1], t[1], x[1], y[1], z[1],
473 s[2], t[2], x[2], y[2], z[2],
474 s[3], t[3], x[3], y[3], z[3]);
478 for (j = 0, k = 0; j < 4; j++, k++)
480 GLfloat xx = points[(i*4)+j][0] / 255.0L;
481 GLfloat yy = points[(i*4)+j][1] / 255.0L;
488 face4(lc->texids[top ? FACE_U : FACE_D], exterior_color, wire,
489 s[0], t[0], x[0], y[0], z[0],
490 s[1], t[1], x[1], y[1], z[1],
491 s[2], t[2], x[2], y[2], z[2],
492 s[3], t[3], x[3], y[3], z[3]);
496 for (j = 3; j >= 0; j--)
498 int k = (j == 0 ? 3 : j-1);
499 Bool front_p = (j == 3);
500 GLfloat x1 = points[(i*4)+j][0] / 255.0L;
501 GLfloat y1 = points[(i*4)+j][1] / 255.0L;
502 GLfloat x2 = points[(i*4)+k][0] / 255.0L;
503 GLfloat y2 = points[(i*4)+k][1] / 255.0L;
505 GLfloat tx1=0.0, tx2=1.0, ty1=0.0, ty2=1.0;
509 facing = (facing + j + 5) % 4;
515 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
516 ty1 = 0.0; ty2 = 1.0;
519 ty1 = 1.0; ty2 = 0.0;
523 texture = top ? FACE_S : FACE_N;
525 ty1 = 0.0; ty2 = 1.0;
531 ty1 = 0.0; ty2 = 1.0;
533 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
534 ty1 = 1.0; ty2 = 0.0;
538 texture = top ? FACE_N : FACE_S;
540 ty1 = 1.0; ty2 = 0.0;
544 x1 -= 0.5; x2 -= 0.5;
545 y1 -= 0.5; y2 -= 0.5;
547 face4(front_p ? lc->texids[texture] : 0,
548 front_p ? exterior_color : interior_color,
550 tx1, ty2, x1, y1, 0.5,
551 tx1, ty1, x1, y1, -0.5,
552 tx2, ty1, x2, y2, -0.5,
553 tx2, ty2, x2, y2, 0.5);
558 /* Central core top cap.
560 #ifdef HAVE_GLBINDTEXTURE
561 glBindTexture(GL_TEXTURE_2D, lc->texids[top ? FACE_U : FACE_D]);
562 #endif /* HAVE_GLBINDTEXTURE */
563 set_colors(exterior_color);
566 do_normal(points[i+0][0], points[i+0][1], 0,
567 points[i+4][0], points[i+4][1], 0,
568 points[i+8][0], points[i+8][1], 0);
569 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
570 for (i = 1; i < countof(points); i += 4)
572 GLfloat x = points[i][0] / 255.0L;
573 GLfloat y = points[i][1] / 255.0L;
575 glVertex3f(x-0.5, y-0.5, 0.5);
580 /* Central core bottom cap.
582 #ifdef HAVE_GLBINDTEXTURE
583 glBindTexture(GL_TEXTURE_2D, 0);
584 #endif /* HAVE_GLBINDTEXTURE */
585 set_colors(interior_color);
587 i = countof(points) - 9;
588 do_normal(points[i+0][0], points[i+0][1], 0,
589 points[i+4][0], points[i+4][1], 0,
590 points[i+8][0], points[i+8][1], 0);
592 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
593 for (i = countof(points) - 3; i >= 0; i -= 4)
595 GLfloat x = points[i][0] / 255.0L;
596 GLfloat y = points[i][1] / 255.0L;
597 glVertex3f(x-0.5, y-0.5, 0);
602 /* Central core walls.
604 for (i = 1; i < countof(points); i += 4)
607 GLfloat x1 = points[i-1][0] / 255.0L;
608 GLfloat y1 = points[i-1][1] / 255.0L;
609 GLfloat x2 = points[i][0] / 255.0L;
610 GLfloat y2 = points[i][1] / 255.0L;
611 face4(0, interior_color, wire,
612 0.0, 0.0, x1-0.5, y1-0.5, 0.5,
613 0.0, 0.0, x1-0.5, y1-0.5, 0.0,
614 0.0, 0.0, x2-0.5, y2-0.5, 0.0,
615 0.0, 0.0, x2-0.5, y2-0.5, 0.5);
623 tetra(ModeInfo *mi, Bool wire)
625 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
627 glNewList(lc->tetra_une, GL_COMPILE);
629 glShadeModel(GL_SMOOTH);
632 face3(lc->texids[FACE_U], exterior_color, wire,
633 1.0, 0.0, 0.5, -0.5, 0.5,
634 1.0, 1.0, 0.5, 0.5, 0.5,
635 0.0, 1.0, -0.5, 0.5, 0.5);
638 face3(lc->texids[FACE_N], exterior_color, wire,
639 0.0, 0.0, -0.5, 0.5, 0.5,
640 1.0, 0.0, 0.5, 0.5, 0.5,
641 1.0, 1.0, 0.5, 0.5, -0.5);
644 face3(lc->texids[FACE_E], exterior_color, wire,
645 1.0, 0.0, 0.5, 0.5, -0.5,
646 1.0, 1.0, 0.5, 0.5, 0.5,
647 0.0, 1.0, 0.5, -0.5, 0.5);
649 face3(0, interior_color, wire,
650 0.0, 0.0, 0.5, 0.5, -0.5,
651 0.0, 0.0, 0.5, -0.5, 0.5,
652 0.0, 0.0, -0.5, 0.5, 0.5);
656 glNewList(lc->tetra_usw, GL_COMPILE);
659 face3(lc->texids[FACE_U], exterior_color, wire,
660 0.0, 1.0, -0.5, 0.5, 0.5,
661 0.0, 0.0, -0.5, -0.5, 0.5,
662 1.0, 0.0, 0.5, -0.5, 0.5);
665 face3(lc->texids[FACE_S], exterior_color, wire,
666 1.0, 1.0, 0.5, -0.5, 0.5,
667 0.0, 1.0, -0.5, -0.5, 0.5,
668 0.0, 0.0, -0.5, -0.5, -0.5);
671 face3(lc->texids[FACE_W], exterior_color, wire,
672 1.0, 0.0, -0.5, -0.5, -0.5,
673 1.0, 1.0, -0.5, -0.5, 0.5,
674 0.0, 1.0, -0.5, 0.5, 0.5);
676 face3(0, interior_color, wire,
677 0.0,0.0, -0.5, -0.5, -0.5,
678 0.0,0.0, -0.5, 0.5, 0.5,
679 0.0,0.0, 0.5, -0.5, 0.5);
683 glNewList(lc->tetra_dwn, GL_COMPILE);
686 face3(lc->texids[FACE_D], exterior_color, wire,
687 0.0, 1.0, -0.5, -0.5, -0.5,
688 0.0, 0.0, -0.5, 0.5, -0.5,
689 1.0, 0.0, 0.5, 0.5, -0.5);
692 face3(lc->texids[FACE_W], exterior_color, wire,
693 0.0, 1.0, -0.5, 0.5, 0.5,
694 0.0, 0.0, -0.5, 0.5, -0.5,
695 1.0, 0.0, -0.5, -0.5, -0.5);
698 face3(lc->texids[FACE_N], exterior_color, wire,
699 1.0, 1.0, 0.5, 0.5, -0.5,
700 0.0, 1.0, -0.5, 0.5, -0.5,
701 0.0, 0.0, -0.5, 0.5, 0.5);
703 face3(0, interior_color, wire,
704 0.0, 0.0, 0.5, 0.5, -0.5,
705 0.0, 0.0, -0.5, 0.5, 0.5,
706 0.0, 0.0, -0.5, -0.5, -0.5);
710 glNewList(lc->tetra_dse, GL_COMPILE);
713 face3(lc->texids[FACE_S], exterior_color, wire,
714 0.0, 0.0, -0.5, -0.5, -0.5,
715 1.0, 0.0, 0.5, -0.5, -0.5,
716 1.0, 1.0, 0.5, -0.5, 0.5);
719 face3(lc->texids[FACE_E], exterior_color, wire,
720 0.0, 1.0, 0.5, -0.5, 0.5,
721 0.0, 0.0, 0.5, -0.5, -0.5,
722 1.0, 0.0, 0.5, 0.5, -0.5);
725 face3(lc->texids[FACE_D], exterior_color, wire,
726 1.0, 0.0, 0.5, 0.5, -0.5,
727 1.0, 1.0, 0.5, -0.5, -0.5,
728 0.0, 1.0, -0.5, -0.5, -0.5);
730 face3(0, interior_color, wire,
731 0.0, 0.0, 0.5, -0.5, 0.5,
732 0.0, 0.0, 0.5, 0.5, -0.5,
733 0.0, 0.0, -0.5, -0.5, -0.5);
737 glNewList(lc->tetra_mid, GL_COMPILE);
739 face3(0, interior_color, wire,
740 0.0, 0.0, 0.5, -0.5, 0.5,
741 0.0, 0.0, 0.5, 0.5, -0.5,
742 0.0, 0.0, -0.5, 0.5, 0.5);
744 face3(0, interior_color, wire,
745 0.0, 0.0, -0.5, 0.5, 0.5,
746 0.0, 0.0, -0.5, -0.5, -0.5,
747 0.0, 0.0, 0.5, -0.5, 0.5);
749 face3(0, interior_color, wire,
750 0.0, 0.0, -0.5, 0.5, 0.5,
751 0.0, 0.0, 0.5, 0.5, -0.5,
752 0.0, 0.0, -0.5, -0.5, -0.5);
754 face3(0, interior_color, wire,
755 0.0, 0.0, 0.5, 0.5, -0.5,
756 0.0, 0.0, 0.5, -0.5, 0.5,
757 0.0, 0.0, -0.5, -0.5, -0.5);
759 face3(0, interior_color, wire,
760 0.0, 0.0, 0.5, -0.5, 0.5,
761 0.0, 0.0, 0.5, 0.5, -0.5,
762 0.0, 0.0, -0.5, -0.5, -0.5);
769 lid(ModeInfo *mi, Bool wire)
771 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
775 { 128, 20 },{ 21, 129 },{ 0, 129 },{ 0, 0 },{ 128, 0 }, /* L1 */
776 { 21, 129 },{ 127, 234 },{ 127, 255 },{ 0, 255 },{ 0, 129 }, /* L2 */
777 { 127, 234 },{ 233, 127 },{ 255, 127 },{ 255, 255 },{ 127, 255 }, /* R2 */
778 { 233, 127 },{ 128, 20 },{ 128, 0 },{ 255, 0 },{ 255, 127 }, /* R1 */
781 for (i = 0; i < countof(points); i++)
782 points[i][1] = 255-points[i][1];
784 glNewList(lc->lid_0, GL_COMPILE);
785 glShadeModel(GL_SMOOTH);
788 face4(lc->texids[FACE_N], exterior_color, wire,
789 0.0, 0.0, -0.5, 0.5, 0.5,
790 1.0, 0.0, 0.5, 0.5, 0.5,
791 1.0, 1.0, 0.5, 0.5, -0.5,
792 0.0, 1.0, -0.5, 0.5, -0.5);
795 face4(lc->texids[FACE_S], exterior_color, wire,
796 0.0, 0.0, -0.5, -0.5, -0.5,
797 1.0, 0.0, 0.5, -0.5, -0.5,
798 1.0, 1.0, 0.5, -0.5, 0.5,
799 0.0, 1.0, -0.5, -0.5, 0.5);
802 face4(lc->texids[FACE_E], exterior_color, wire,
803 0.0, 0.0, 0.5, -0.5, -0.5,
804 1.0, 0.0, 0.5, 0.5, -0.5,
805 1.0, 1.0, 0.5, 0.5, 0.5,
806 0.0, 1.0, 0.5, -0.5, 0.5);
809 face4(lc->texids[FACE_U], exterior_color, wire,
810 1.0, 0.0, 0.5, -0.5, 0.5,
811 1.0, 1.0, 0.5, 0.5, 0.5,
812 0.0, 1.0, -0.5, 0.5, 0.5,
813 0.0, 0.0, -0.5, -0.5, 0.5);
816 face4(lc->texids[FACE_D], exterior_color, wire,
817 0.0, 1.0, -0.5, -0.5, -0.5,
818 0.0, 0.0, -0.5, 0.5, -0.5,
819 1.0, 0.0, 0.5, 0.5, -0.5,
820 1.0, 1.0, 0.5, -0.5, -0.5);
823 for (i = 0; i < countof(points)/5; i++)
826 GLfloat s[5], t[5], x[5], y[5], z[5];
827 for (j = 0; j < 5; j++)
829 GLfloat xx = points[(i*5)+j][0] / 255.0L;
830 GLfloat yy = points[(i*5)+j][1] / 255.0L;
837 face5(lc->texids[FACE_W], exterior_color, wire,
838 s[0], t[0], x[0], y[0], z[0],
839 s[1], t[1], x[1], y[1], z[1],
840 s[2], t[2], x[2], y[2], z[2],
841 s[3], t[3], x[3], y[3], z[3],
842 s[4], t[4], x[4], y[4], z[4]);
847 /* W -- lid_1 through lid_4 */
848 for (i = 0; i < 4; i++)
850 GLfloat x1, y1, x2, y2, x3, y3;
852 glNewList(lc->lid_1 + i, GL_COMPILE);
853 glShadeModel(GL_SMOOTH);
855 x1 = points[(i*5)+1][0] / 255.0L;
856 y1 = points[(i*5)+1][1] / 255.0L;
857 x2 = points[(i*5)][0] / 255.0L;
858 y2 = points[(i*5)][1] / 255.0L;
863 face3(lc->texids[FACE_W], exterior_color, wire,
864 1.0-x1, y1, -0.5, x1-0.5, y1-0.5,
865 1.0-x2, y2, -0.5, x2-0.5, y2-0.5,
866 1.0-x3, y3, -0.5, x3-0.5, y3-0.5);
869 face3(0, interior_color, wire,
870 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
871 0.0, 0.0, -0.48, x1-0.5, y1-0.5,
872 0.0, 0.0, -0.48, x3-0.5, y3-0.5);
875 face4(0, interior_color, wire,
876 0.0, 0.0, -0.5, x1-0.5, y1-0.5,
877 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
878 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
879 0.0, 0.0, -0.48, x1-0.5, y1-0.5);
882 face4(0, interior_color, wire,
883 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
884 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
885 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
886 0.0, 0.0, -0.5, x2-0.5, y2-0.5);
893 taser(ModeInfo *mi, Bool wire)
895 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
898 int slider_face_points[][2] = {
899 { 86, 58 },{ 38, 106 },{ 70, 106 },{ 118, 58 },{ -1, -1 }, /* a */
900 { 136, 58 },{ 184, 106 },{ 216, 106 },{ 168, 58 },{ -1, -1 }, /* b */
901 { 38, 106 },{ 0, 144 },{ 0, 190 },{ 60, 190 },{ 108, 106 }, /* c */
902 { 144, 106 },{ 194, 190 },{ 254, 190 },{ 254, 144 },{ 216, 106 }, /* d */
903 { 98, 124 },{ 60, 190 },{ 92, 190 },{ 126, 158 },{ 126, 124 }, /* e */
904 { 126, 124 },{ 126, 158 },{ 160, 190 },{ 194, 190 },{ 154, 124 }, /* f */
905 { 22, 190 },{ 22, 254 },{ 60, 254 },{ 60, 190 },{ -1, -1 }, /* g */
906 { 194, 190 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ -1, -1 }, /* h */
907 { 60, 190 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ -1, -1 }, /* i */
908 { 160, 190 },{ 160, 210 },{ 194, 210 },{ 194, 190 },{ -1, -1 }, /* j */
909 { 110, 172 },{ 92, 190 },{ 110, 190 },{ -1, -1 },{ -1, -1 }, /* k */
910 { 140, 172 },{ 140, 190 },{ 160, 190 },{ -1, -1 },{ -1, -1 }, /* l */
911 { 110, 172 },{ 140, 172 },{ 126, 156 },{ -1, -1 },{ -1, -1 }, /* m */
914 int body_face_points[][2] = {
915 { 0, 0 },{ 0, 58 },{ 254, 58 },{ 254, 0 },{ -1, -1 }, /* A */
916 { 0, 58 },{ 0, 144 },{ 86, 58 },{ -1, -1 },{ -1, -1 }, /* B */
917 { 168, 58 },{ 254, 144 },{ 254, 58 },{ -1, -1 },{ -1, -1 }, /* C */
918 { 118, 58 },{ 70, 106 },{ 184, 106 },{ 136, 58 },{ -1, -1 }, /* F */
919 { 108, 106 },{ 98, 124 },{ 154, 124 },{ 144, 106 },{ -1, -1 }, /* G */
922 int lifter_face_points[][2] = {
923 { 0, 190 },{ 0, 254 },{ 22, 254 },{ 22, 190 },{ -1, -1 }, /* D */
924 { 230, 190 },{ 230, 254 },{ 254, 254 },{ 254, 190 },{ -1, -1 }, /* E */
925 { 60, 210 },{ 60, 254 },{ 194, 254 },{ 194, 210 },{ -1, -1 }, /* H */
926 { 92, 190 },{ 92, 210 },{ 160, 210 },{ 160, 190 },{ -1, -1 }, /* I */
927 { 110, 172 },{ 110, 190 },{ 140, 190 },{ 140, 172 },{ -1, -1 }, /* J */
930 int body_perimiter_points[][2] = {
931 { 0, 144 },{ 86, 59 },{ 119, 58 },{ 71, 107 },
932 { 108, 107 },{ 98, 124 },{ 155, 124 },{ 144, 107 },
933 { 185, 106 },{ 136, 59 },{ 169, 59 },{ 255, 145 },
937 int slider_perimiter_points[][2] = {
938 { 86, 58 },{ 0, 144 },{ 0, 190 },{ 22, 190 },{ 22, 254 },
939 { 60, 254 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ 110, 190 },
940 { 110, 172 },{ 140, 172 },{ 140, 190 },{ 160, 190 },{ 160, 210 },
941 { 194, 210 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ 254, 190 },
942 { 254, 144 },{ 168, 58 },{ 136, 58 },{ 184, 106 },{ 144, 106 },
943 { 154, 124 },{ 98, 124 },{ 108, 106 },{ 70, 106 },{ 118, 58 },
946 int lifter_perimiter_points_1[][2] = {
947 { 0, 189 },{ 0, 254 },{ 22, 255 },{ 23, 190 },
950 int lifter_perimiter_points_2[][2] = {
951 { 230, 254 },{ 255, 255 },{ 254, 190 },{ 230, 190 },
954 int lifter_perimiter_points_3[][2] = {
955 { 60, 254 },{ 194, 254 },{ 194, 211 },{ 160, 210 },
956 { 160, 190 },{ 140, 191 },{ 141, 172 },{ 111, 172 },
957 { 110, 190 },{ 93, 190 },{ 92, 210 },{ 60, 211 },
960 for (i = 0; i < countof(slider_face_points); i++)
961 slider_face_points[i][1] = 255-slider_face_points[i][1];
962 for (i = 0; i < countof(body_face_points); i++)
963 body_face_points[i][1] = 255-body_face_points[i][1];
964 for (i = 0; i < countof(lifter_face_points); i++)
965 lifter_face_points[i][1] = 255-lifter_face_points[i][1];
966 for (i = 0; i < countof(body_perimiter_points); i++)
967 body_perimiter_points[i][1] = 255-body_perimiter_points[i][1];
968 for (i = 0; i < countof(slider_perimiter_points); i++)
969 slider_perimiter_points[i][1] = 255-slider_perimiter_points[i][1];
970 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
971 lifter_perimiter_points_1[i][1] = 255-lifter_perimiter_points_1[i][1];
972 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
973 lifter_perimiter_points_2[i][1] = 255-lifter_perimiter_points_2[i][1];
974 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
975 lifter_perimiter_points_3[i][1] = 255-lifter_perimiter_points_3[i][1];
977 /* -------------------------------------------------------------------- */
979 glNewList(lc->taser_base, GL_COMPILE);
980 glShadeModel(GL_SMOOTH);
983 face4(lc->texids[FACE_N], exterior_color, wire,
984 0.0, 0.0, -0.5, 0.5, 0.5,
985 0.75, 0.0, 0.25, 0.5, 0.5,
986 0.75, 0.75, 0.25, 0.5, -0.25,
987 0.0, 0.75, -0.5, 0.5, -0.25);
990 face4(lc->texids[FACE_S], exterior_color, wire,
991 0.0, 0.25, -0.5, -0.5, -0.25,
992 0.75, 0.25, 0.25, -0.5, -0.25,
993 0.75, 1.0, 0.25, -0.5, 0.5,
994 0.0, 1.0, -0.5, -0.5, 0.5);
997 face4(0, interior_color, wire,
998 0.0, 0.0, 0.25, -0.5, -0.25,
999 1.0, 0.0, 0.25, 0.5, -0.25,
1000 1.0, 1.0, 0.25, 0.5, 0.5,
1001 0.0, 1.0, 0.25, -0.5, 0.5);
1004 face4(lc->texids[FACE_W], exterior_color, wire,
1005 1.0, 1.0, -0.5, -0.5, 0.5,
1006 0.0, 1.0, -0.5, 0.5, 0.5,
1007 0.0, 0.25, -0.5, 0.5, -0.25,
1008 1.0, 0.25, -0.5, -0.5, -0.25);
1011 face4(lc->texids[FACE_U], exterior_color, wire,
1012 0.75, 0.0, 0.25, -0.5, 0.5,
1013 0.75, 1.0, 0.25, 0.5, 0.5,
1014 0.0, 1.0, -0.5, 0.5, 0.5,
1015 0.0, 0.0, -0.5, -0.5, 0.5);
1018 face4(0, interior_color, wire,
1019 0.0, 1.0, -0.5, -0.5, -0.25,
1020 0.0, 0.0, -0.5, 0.5, -0.25,
1021 1.0, 0.0, 0.25, 0.5, -0.25,
1022 1.0, 1.0, 0.25, -0.5, -0.25);
1025 for (i = 0; i < countof(body_face_points)/5; i++)
1028 #ifdef HAVE_GLBINDTEXTURE
1029 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1030 #endif /* HAVE_GLBINDTEXTURE */
1031 set_colors(exterior_color);
1033 do_normal(0, body_face_points[(i*5)+0][0], body_face_points[(i*5)+0][1],
1034 0, body_face_points[(i*5)+1][0], body_face_points[(i*5)+1][1],
1035 0, body_face_points[(i*5)+2][0], body_face_points[(i*5)+2][1]
1037 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1038 for (j = 0; j < 5; j++)
1040 int ix = body_face_points[(i*5)+j][0];
1041 int iy = body_face_points[(i*5)+j][1];
1043 if (ix == -1) /* these are padding: ignore them */
1048 glVertex3f(0.5, x-0.5, y-0.5);
1054 for (i = 0; i < countof(body_perimiter_points); i++)
1056 int j = (i+1 >= countof(body_perimiter_points) ? 0 : i+1);
1057 GLfloat x1 = body_perimiter_points[i][0] / 255.0;
1058 GLfloat y1 = body_perimiter_points[i][1] / 255.0;
1059 GLfloat x2 = body_perimiter_points[j][0] / 255.0;
1060 GLfloat y2 = body_perimiter_points[j][1] / 255.0;
1062 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1066 texture = lc->texids[FACE_N];
1068 s2 = 1.0; t2 = 0.568;
1069 s3 = 0.75, t3 = 0.568;
1070 s4 = 0.75; t4 = 0.0;
1074 texture = lc->texids[FACE_U];
1077 s3 = 0.75, t3 = 1.0;
1078 s4 = 0.75; t4 = 0.0;
1082 texture = lc->texids[FACE_S];
1083 s1 = 1.0; t1 = 0.437;
1085 s3 = 0.75; t3 = 1.0;
1086 s4 = 0.75; t4 = 0.437;
1089 face4((texture == -1 ? 0 : texture),
1090 (texture == -1 ? interior_color : exterior_color),
1092 s1, t1, 0.5, x2-0.5, y2-0.5,
1093 s2, t2, 0.5, x1-0.5, y1-0.5,
1094 s3, t3, 0.25, x1-0.5, y1-0.5,
1095 s4, t4, 0.25, x2-0.5, y2-0.5);
1100 /* -------------------------------------------------------------------- */
1102 glNewList(lc->taser_lifter, GL_COMPILE);
1103 glShadeModel(GL_SMOOTH);
1106 face4(lc->texids[FACE_N], exterior_color, wire,
1107 0.0, 0.75, -0.5, 0.5, -0.25,
1108 0.75, 0.75, 0.25, 0.5, -0.25,
1109 0.75, 1.0, 0.25, 0.5, -0.5,
1110 0.0, 1.0, -0.5, 0.5, -0.5);
1113 face4(lc->texids[FACE_S], exterior_color, wire,
1114 0.0, 0.0, -0.5, -0.5, -0.5,
1115 0.75, 0.0, 0.25, -0.5, -0.5,
1116 0.75, 0.25, 0.25, -0.5, -0.25,
1117 0.0, 0.25, -0.5, -0.5, -0.25);
1120 face4(0, interior_color, wire,
1121 0.0, 1.0, 0.25, -0.5, -0.5,
1122 1.0, 1.0, 0.25, 0.5, -0.5,
1123 1.0, 0.0, 0.25, 0.5, -0.25,
1124 0.0, 0.0, 0.25, -0.5, -0.25);
1127 face4(lc->texids[FACE_W], exterior_color, wire,
1128 1.0, 0.25, -0.5, -0.5, -0.25,
1129 0.0, 0.25, -0.5, 0.5, -0.25,
1130 0.0, 0.0, -0.5, 0.5, -0.5,
1131 1.0, 0.0, -0.5, -0.5, -0.5);
1134 face4(0, interior_color, wire,
1135 1.0, 0.0, 0.25, -0.5, -0.25,
1136 1.0, 1.0, 0.25, 0.5, -0.25,
1137 0.0, 1.0, -0.5, 0.5, -0.25,
1138 0.0, 0.0, -0.5, -0.5, -0.25);
1141 face4(lc->texids[FACE_D], exterior_color, wire,
1142 0.0, 1.0, -0.5, -0.5, -0.5,
1143 0.0, 0.0, -0.5, 0.5, -0.5,
1144 0.75, 0.0, 0.25, 0.5, -0.5,
1145 0.75, 1.0, 0.25, -0.5, -0.5);
1149 for (i = 0; i < countof(lifter_face_points)/5; i++)
1153 #ifdef HAVE_GLBINDTEXTURE
1154 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1155 #endif /* HAVE_GLBINDTEXTURE */
1156 set_colors(exterior_color);
1159 0, lifter_face_points[(i*5)+0][0], lifter_face_points[(i*5)+0][1],
1160 0, lifter_face_points[(i*5)+1][0], lifter_face_points[(i*5)+1][1],
1161 0, lifter_face_points[(i*5)+2][0], lifter_face_points[(i*5)+2][1]);
1163 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1164 for (j = 0; j < 5; j++)
1166 int ix = lifter_face_points[(i*5)+j][0];
1167 int iy = lifter_face_points[(i*5)+j][1];
1169 if (ix == -1) /* these are padding: ignore them */
1174 glVertex3f(0.5, x-0.5, y-0.5);
1180 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
1182 int j = (i+1 >= countof(lifter_perimiter_points_1) ? 0 : i+1);
1183 GLfloat x1 = lifter_perimiter_points_1[i][0] / 255.0;
1184 GLfloat y1 = lifter_perimiter_points_1[i][1] / 255.0;
1185 GLfloat x2 = lifter_perimiter_points_1[j][0] / 255.0;
1186 GLfloat y2 = lifter_perimiter_points_1[j][1] / 255.0;
1188 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1192 texture = lc->texids[FACE_S];
1194 s2 = 1.0; t2 = 0.26;
1195 s3 = 0.75, t3 = 0.26;
1196 s4 = 0.75; t4 = 0.0;
1200 texture = lc->texids[FACE_D];
1201 s1 = 1.0; t1 = 0.914;
1203 s3 = 0.75; t3 = 1.0;
1204 s4 = 0.75; t4 = 0.914;
1207 face4((texture == -1 ? 0 : texture),
1208 (texture == -1 ? interior_color : exterior_color),
1210 s1, t1, 0.5, x2-0.5, y2-0.5,
1211 s2, t2, 0.5, x1-0.5, y1-0.5,
1212 s3, t3, 0.25, x1-0.5, y1-0.5,
1213 s4, t4, 0.25, x2-0.5, y2-0.5);
1216 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
1218 int j = (i+1 >= countof(lifter_perimiter_points_2) ? 0 : i+1);
1219 GLfloat x1 = lifter_perimiter_points_2[i][0] / 255.0;
1220 GLfloat y1 = lifter_perimiter_points_2[i][1] / 255.0;
1221 GLfloat x2 = lifter_perimiter_points_2[j][0] / 255.0;
1222 GLfloat y2 = lifter_perimiter_points_2[j][1] / 255.0;
1224 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1228 texture = lc->texids[FACE_D];
1230 s2 = 1.0; t2 = 0.095;
1231 s3 = 0.75; t3 = 0.095;
1232 s4 = 0.75; t4 = 0.0;
1236 texture = lc->texids[FACE_N];
1237 s1 = 1.0; t1 = 0.745;
1239 s3 = 0.75; t3 = 1.0;
1240 s4 = 0.75; t4 = 0.745;
1243 face4((texture == -1 ? 0 : texture),
1244 (texture == -1 ? interior_color : exterior_color),
1246 s1, t1, 0.5, x2-0.5, y2-0.5,
1247 s2, t2, 0.5, x1-0.5, y1-0.5,
1248 s3, t3, 0.25, x1-0.5, y1-0.5,
1249 s4, t4, 0.25, x2-0.5, y2-0.5);
1252 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
1254 int j = (i+1 >= countof(lifter_perimiter_points_3) ? 0 : i+1);
1255 GLfloat x1 = lifter_perimiter_points_3[i][0] / 255.0;
1256 GLfloat y1 = lifter_perimiter_points_3[i][1] / 255.0;
1257 GLfloat x2 = lifter_perimiter_points_3[j][0] / 255.0;
1258 GLfloat y2 = lifter_perimiter_points_3[j][1] / 255.0;
1260 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1264 texture = lc->texids[FACE_D];
1265 s1 = 1.0; t1 = 0.235;
1266 s2 = 1.0; t2 = 0.765;
1267 s3 = 0.75; t3 = 0.765;
1268 s4 = 0.75; t4 = 0.235;
1271 face4((texture == -1 ? 0 : texture),
1272 (texture == -1 ? interior_color : exterior_color),
1274 s1, t1, 0.5, x2-0.5, y2-0.5,
1275 s2, t2, 0.5, x1-0.5, y1-0.5,
1276 s3, t3, 0.25, x1-0.5, y1-0.5,
1277 s4, t4, 0.25, x2-0.5, y2-0.5);
1282 /* -------------------------------------------------------------------- */
1284 glNewList(lc->taser_slider, GL_COMPILE);
1285 glShadeModel(GL_SMOOTH);
1288 for (i = 0; i < countof(slider_face_points)/5; i++)
1291 #ifdef HAVE_GLBINDTEXTURE
1292 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1293 #endif /* HAVE_GLBINDTEXTURE */
1294 set_colors(exterior_color);
1297 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1],
1298 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1299 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1]);
1300 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1301 for (j = 0; j < 5; j++)
1303 int ix = slider_face_points[(i*5)+j][0];
1304 int iy = slider_face_points[(i*5)+j][1];
1306 if (ix == -1) /* these are padding: ignore them */
1311 glVertex3f(0.5, x-0.5, y-0.5);
1317 for (i = countof(slider_face_points)/5 - 1; i >= 0; i--)
1320 #ifdef HAVE_GLBINDTEXTURE
1321 glBindTexture(GL_TEXTURE_2D, 0);
1322 #endif /* HAVE_GLBINDTEXTURE */
1323 set_colors(interior_color);
1326 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1],
1327 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1328 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1]);
1329 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1330 for (j = 4; j >= 0; j--)
1332 int ix = slider_face_points[(i*5)+j][0];
1333 int iy = slider_face_points[(i*5)+j][1];
1335 if (ix == -1) /* these are padding: ignore them */
1340 glVertex3f(0.25, x-0.5, y-0.5);
1346 for (i = 0; i < countof(slider_perimiter_points); i++)
1348 int j = (i+1 >= countof(slider_perimiter_points) ? 0 : i+1);
1349 GLfloat x1 = slider_perimiter_points[i][0] / 255.0;
1350 GLfloat y1 = slider_perimiter_points[i][1] / 255.0;
1351 GLfloat x2 = slider_perimiter_points[j][0] / 255.0;
1352 GLfloat y2 = slider_perimiter_points[j][1] / 255.0;
1354 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1358 texture = lc->texids[FACE_S];
1359 s1 = 1.0; t1 = 0.255;
1360 s2 = 1.0; t2 = 0.435;
1361 s3 = 0.75; t3 = 0.435;
1362 s4 = 0.75; t4 = 0.255;
1366 texture = lc->texids[FACE_D];
1367 s1 = 1.0; t1 = 0.758;
1368 s2 = 1.0; t2 = 0.915;
1369 s3 = 0.75; t3 = 0.915;
1370 s4 = 0.75; t4 = 0.758;
1374 texture = lc->texids[FACE_D];
1375 s1 = 1.0; t1 = 0.095;
1376 s2 = 1.0; t2 = 0.24;
1377 s3 = 0.75; t3 = 0.24;
1378 s4 = 0.75; t4 = 0.095;
1382 texture = lc->texids[FACE_N];
1383 s1 = 1.0; t1 = 0.568;
1384 s2 = 1.0; t2 = 0.742;
1385 s3 = 0.75; t3 = 0.742;
1386 s4 = 0.75; t4 = 0.568;
1389 face4((texture == -1 ? 0 : texture),
1390 (texture == -1 ? interior_color : exterior_color),
1392 s1, t1, 0.5, x2-0.5, y2-0.5,
1393 s2, t2, 0.5, x1-0.5, y1-0.5,
1394 s3, t3, 0.25, x1-0.5, y1-0.5,
1395 s4, t4, 0.25, x2-0.5, y2-0.5);
1403 /* Rendering and animating object models
1409 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1410 Bool wire = MI_IS_WIREFRAME(mi);
1413 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1415 glClear(GL_COLOR_BUFFER_BIT);
1419 GLfloat x = lc->rotx;
1420 GLfloat y = lc->roty;
1421 GLfloat z = lc->rotz;
1427 if (x < 0) x = 1 - (x + 1);
1428 if (y < 0) y = 1 - (y + 1);
1429 if (z < 0) z = 1 - (z + 1);
1431 /* Make into the screen be +Y right be +X, and up be +Z. */
1432 glRotatef(-90.0, 1.0, 0.0, 0.0);
1435 glScalef(4.0, 4.0, 4.0);
1440 /* Shift to the upper left, and draw the vanilla box. */
1441 glTranslatef(-0.6, 0.0, 0.6);
1443 /* Apply rotation to the object. */
1444 glRotatef(x * 360, 1.0, 0.0, 0.0);
1445 glRotatef(y * 360, 0.0, 1.0, 0.0);
1446 glRotatef(z * 360, 0.0, 0.0, 1.0);
1449 glCallList(lc->box);
1453 /* Shift to the lower right, and draw the animated object. */
1454 glTranslatef(0.6, 0.0, -0.6);
1460 /* Apply rotation to the object. */
1461 glRotatef(x * 360, 1.0, 0.0, 0.0);
1462 glRotatef(y * 360, 0.0, 1.0, 0.0);
1463 glRotatef(z * 360, 0.0, 0.0, 1.0);
1468 glCallList(lc->box);
1471 case LAMENT_STAR_OUT:
1472 case LAMENT_STAR_ROT:
1473 case LAMENT_STAR_ROT_IN:
1474 case LAMENT_STAR_ROT_OUT:
1475 case LAMENT_STAR_UNROT:
1476 case LAMENT_STAR_IN:
1477 glTranslatef(0.0, 0.0, lc->anim_z/2);
1478 glRotatef(lc->anim_r/2, 0.0, 0.0, 1.0);
1479 glCallList(lc->star1);
1481 glTranslatef(0.0, 0.0, -lc->anim_z);
1482 glRotatef(-lc->anim_r, 0.0, 0.0, 1.0);
1483 glCallList(lc->star2);
1486 case LAMENT_TETRA_UNE:
1487 case LAMENT_TETRA_USW:
1488 case LAMENT_TETRA_DWN:
1489 case LAMENT_TETRA_DSE:
1494 case LAMENT_TETRA_UNE: magic = lc->tetra_une;
1495 x = 1.0; y = 1.0; z = 1.0; break;
1496 case LAMENT_TETRA_USW: magic = lc->tetra_usw;
1497 x = 1.0; y = 1.0; z = -1.0; break;
1498 case LAMENT_TETRA_DWN: magic = lc->tetra_dwn;
1499 x = 1.0; y = -1.0; z = 1.0; break;
1500 case LAMENT_TETRA_DSE: magic = lc->tetra_dse;
1501 x = -1.0; y = 1.0; z = 1.0; break;
1502 default: abort(); break;
1504 glCallList(lc->tetra_mid);
1505 if (magic != lc->tetra_une) glCallList(lc->tetra_une);
1506 if (magic != lc->tetra_usw) glCallList(lc->tetra_usw);
1507 if (magic != lc->tetra_dwn) glCallList(lc->tetra_dwn);
1508 if (magic != lc->tetra_dse) glCallList(lc->tetra_dse);
1509 glRotatef(lc->anim_r, x, y, z);
1514 case LAMENT_LID_OPEN:
1515 case LAMENT_LID_CLOSE:
1516 case LAMENT_LID_ZOOM:
1520 glTranslatef(lc->anim_z, 0.0, 0.0);
1522 glCallList(lc->lid_0);
1525 glTranslatef(-0.5, -d, 0.0);
1526 glRotatef(-lc->anim_r, 0.0, -1.0, -1.0);
1527 glTranslatef( 0.5, d, 0.0);
1528 glCallList(lc->lid_1);
1531 glTranslatef(-0.5, -d, 0.0);
1532 glRotatef( lc->anim_r, 0.0, -1.0, 1.0);
1533 glTranslatef( 0.5, d, 0.0);
1534 glCallList(lc->lid_2);
1537 glTranslatef(-0.5, d, 0.0);
1538 glRotatef( lc->anim_r, 0.0, -1.0, -1.0);
1539 glTranslatef( 0.5, -d, 0.0);
1540 glCallList(lc->lid_3);
1543 glTranslatef(-0.5, d, 0.0);
1544 glRotatef(-lc->anim_r, 0.0, -1.0, 1.0);
1545 glTranslatef( 0.5, -d, 0.0);
1546 glCallList(lc->lid_4);
1551 case LAMENT_TASER_OUT:
1552 case LAMENT_TASER_SLIDE:
1553 case LAMENT_TASER_SLIDE_IN:
1554 case LAMENT_TASER_IN:
1556 glTranslatef(-lc->anim_z/2, 0.0, 0.0);
1557 glCallList(lc->taser_base);
1559 glTranslatef(lc->anim_z, 0.0, 0.0);
1560 glCallList(lc->taser_lifter);
1562 glTranslatef(0.0, 0.0, lc->anim_y);
1563 glCallList(lc->taser_slider);
1579 animate(ModeInfo *mi)
1581 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1583 /* int pause2 = 60;*/
1590 /* Rather than just picking states randomly, pick an ordering randomly,
1591 do it, and then re-randomize. That way one can be assured of seeing
1592 all states in a short time period, though not always in the same
1593 order (it's frustrating to see it pick the same state 5x in a row.)
1595 static lament_type states[] = {
1596 LAMENT_STAR_OUT, LAMENT_STAR_OUT,
1597 LAMENT_TETRA_UNE, LAMENT_TETRA_USW,
1598 LAMENT_TETRA_DWN, LAMENT_TETRA_DSE,
1599 LAMENT_LID_OPEN, LAMENT_LID_OPEN, LAMENT_LID_OPEN,
1600 LAMENT_TASER_OUT, LAMENT_TASER_OUT,
1601 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1602 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1604 static int state = countof(states);
1606 if (state < countof(states))
1608 lc->type = states[state++];
1614 for (i = 0; i < countof(states); i++)
1616 int a = random() % countof(states);
1617 lament_type swap = states[a];
1618 states[a] = states[i];
1623 if (lc->type == LAMENT_BOX)
1624 lc->anim_pause = pause3;
1632 /* -------------------------------------------------------------- */
1634 case LAMENT_STAR_OUT:
1636 if (lc->anim_z >= 1.0)
1639 lc->type = LAMENT_STAR_ROT;
1640 lc->anim_pause = pause;
1644 case LAMENT_STAR_ROT:
1646 if (lc->anim_r >= 45.0)
1649 lc->type = LAMENT_STAR_ROT_IN;
1650 lc->anim_pause = pause;
1654 case LAMENT_STAR_ROT_IN:
1656 if (lc->anim_z <= 0.0)
1659 lc->type = LAMENT_STAR_ROT_OUT;
1660 lc->anim_pause = pause3 * (1 + (random() % 4) + (random() % 4));
1664 case LAMENT_STAR_ROT_OUT:
1666 if (lc->anim_z >= 1.0)
1669 lc->type = LAMENT_STAR_UNROT;
1670 lc->anim_pause = pause;
1674 case LAMENT_STAR_UNROT:
1676 if (lc->anim_r <= 0.0)
1679 lc->type = LAMENT_STAR_IN;
1680 lc->anim_pause = pause;
1684 case LAMENT_STAR_IN:
1686 if (lc->anim_z <= 0.0)
1689 lc->type = LAMENT_BOX;
1690 lc->anim_pause = pause3;
1694 /* -------------------------------------------------------------- */
1696 case LAMENT_TETRA_UNE:
1697 case LAMENT_TETRA_USW:
1698 case LAMENT_TETRA_DWN:
1699 case LAMENT_TETRA_DSE:
1702 if (lc->anim_r >= 360.0)
1705 lc->type = LAMENT_BOX;
1706 lc->anim_pause = pause3;
1708 else if (lc->anim_r > 119.0 && lc->anim_r <= 120.0)
1711 lc->anim_pause = pause;
1713 else if (lc->anim_r > 239.0 && lc->anim_r <= 240.0)
1716 lc->anim_pause = pause;
1720 /* -------------------------------------------------------------- */
1722 case LAMENT_LID_OPEN:
1725 if (lc->anim_r >= 112.0)
1727 GLfloat hysteresis = 0.05;
1731 lc->anim_pause = pause3;
1733 if (lc->rotx >= -hysteresis &&
1734 lc->rotx <= hysteresis &&
1735 ((lc->rotz >= (0.25 - hysteresis) &&
1736 lc->rotz <= (0.25 + hysteresis)) ||
1737 (lc->rotz >= (-0.25 - hysteresis) &&
1738 lc->rotz <= (-0.25 + hysteresis))))
1740 lc->type = LAMENT_LID_ZOOM;
1742 lc->rotz = (lc->rotz < 0 ? -0.25 : 0.25);
1746 lc->type = LAMENT_LID_CLOSE;
1751 case LAMENT_LID_CLOSE:
1753 if (lc->anim_r <= 0.0)
1756 lc->type = LAMENT_BOX;
1757 lc->anim_pause = pause3;
1761 case LAMENT_LID_ZOOM:
1763 if (lc->anim_z < -50.0)
1767 lc->rotx = frand(1.0) * RANDSIGN();
1768 lc->roty = frand(1.0) * RANDSIGN();
1769 lc->rotz = frand(1.0) * RANDSIGN();
1770 lc->type = LAMENT_BOX;
1774 /* -------------------------------------------------------------- */
1776 case LAMENT_TASER_OUT:
1777 lc->anim_z += 0.0025;
1778 if (lc->anim_z >= 0.25)
1781 lc->type = LAMENT_TASER_SLIDE;
1782 lc->anim_pause = pause * (1 + (random() % 5) + (random() % 5));
1786 case LAMENT_TASER_SLIDE:
1787 lc->anim_y += 0.0025;
1788 if (lc->anim_y >= 0.23)
1791 lc->type = LAMENT_TASER_SLIDE_IN;
1792 lc->anim_pause = pause3 * (1 + (random() % 5) + (random() % 5));
1796 case LAMENT_TASER_SLIDE_IN:
1797 lc->anim_y -= 0.0025;
1798 if (lc->anim_y <= 0.0)
1801 lc->type = LAMENT_TASER_IN;
1802 lc->anim_pause = pause;
1806 case LAMENT_TASER_IN:
1807 lc->anim_z -= 0.0025;
1808 if (lc->anim_z <= 0.0)
1811 lc->type = LAMENT_BOX;
1812 lc->anim_pause = pause3;
1824 rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v)
1830 ppos = -(ppos + *v);
1839 if (ppos < 0) abort();
1840 if (ppos > 1.0) abort();
1841 *pos = (*pos > 0 ? ppos : -ppos);
1846 /* clamp velocity */
1847 if (*v > max_v || *v < -max_v)
1851 /* If it stops, start it going in the other direction. */
1858 /* keep going in the same direction */
1873 /* Alter direction of rotational acceleration randomly. */
1874 if (! (random() % 120))
1877 /* Change acceleration very occasionally. */
1878 if (! (random() % 200))
1882 else if (random() & 1)
1891 /* Window management, etc
1895 reshape_lament(ModeInfo *mi, int width, int height)
1897 int target_size = 180;
1898 int win_size = (width > height ? height : width);
1899 GLfloat h = (GLfloat) height / (GLfloat) width;
1901 glViewport(0, 0, (GLint) width, (GLint) height);
1903 /* glViewport(-600, -600, 1800, 1800); */
1905 glMatrixMode(GL_PROJECTION);
1907 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
1908 glMatrixMode(GL_MODELVIEW);
1910 glTranslatef(0.0, 0.0, -40.0);
1912 /* This scale makes the box take up most of the window */
1913 glScalef(2.0, 2.0, 2.0);
1915 /* But if the window is more than a little larger than our target size,
1916 scale the object back down, so that the bits drawn on the screen end
1917 up rougly target_size across (actually it ends up a little larger.)
1918 Note that the image-map bits we have are 128x128. Therefore, if the
1919 image is magnified a lot, it looks pretty blocky. So it's better to
1920 have a 128x128 animation on a 1280x1024 screen that looks good, than
1921 a 1024x1024 animation that looks really pixellated.
1923 if (win_size > target_size * 1.5)
1925 GLfloat ratio = ((GLfloat) target_size / (GLfloat) win_size);
1927 glScalef(ratio, ratio, ratio);
1930 /* The depth buffer will be cleared, if needed, before the
1931 * next frame. Right now we just want to black the screen.
1933 glClear(GL_COLOR_BUFFER_BIT);
1938 gl_init(ModeInfo *mi)
1940 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1941 Bool wire = MI_IS_WIREFRAME(mi);
1948 static GLfloat pos0[] = { -4.0, 2.0, 5.0, 1.0 };
1949 static GLfloat pos1[] = { 6.0, -1.0, 3.0, 1.0 };
1951 static GLfloat amb0[] = { 0.7, 0.7, 0.7, 1.0 };
1952 /* static GLfloat amb1[] = { 0.7, 0.0, 0.0, 1.0 }; */
1953 static GLfloat dif0[] = { 1.0, 1.0, 1.0, 1.0 };
1954 static GLfloat dif1[] = { 0.3, 0.1, 0.1, 1.0 };
1956 glLightfv(GL_LIGHT0, GL_POSITION, pos0);
1957 glLightfv(GL_LIGHT1, GL_POSITION, pos1);
1959 glLightfv(GL_LIGHT0, GL_AMBIENT, amb0);
1960 /* glLightfv(GL_LIGHT1, GL_AMBIENT, amb1); */
1961 glLightfv(GL_LIGHT0, GL_DIFFUSE, dif0);
1962 glLightfv(GL_LIGHT1, GL_DIFFUSE, dif1);
1963 set_colors(exterior_color);
1965 glEnable(GL_LIGHTING);
1966 glEnable(GL_LIGHT0);
1967 /* glEnable(GL_LIGHT1); */
1969 glEnable(GL_DEPTH_TEST);
1970 glEnable(GL_TEXTURE_2D);
1971 glEnable(GL_NORMALIZE);
1972 glEnable(GL_CULL_FACE);
1977 #ifdef HAVE_GLBINDTEXTURE
1979 for (i = 0; i < 6; i++)
1980 glGenTextures(1, &lc->texids[i]);
1982 parse_image_data(mi);
1984 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1985 glPixelStorei(GL_UNPACK_ROW_LENGTH, lc->texture->width);
1987 for (i = 0; i < 6; i++)
1989 int height = lc->texture->width; /* assume square */
1990 glBindTexture(GL_TEXTURE_2D, lc->texids[i]);
1991 set_colors(exterior_color);
1994 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
1995 lc->texture->width, height, 0,
1996 GL_RGBA, GL_UNSIGNED_BYTE,
1997 (lc->texture->data +
1998 (lc->texture->bytes_per_line * height * i)));
1999 check_gl_error("texture");
2001 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2002 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2003 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2004 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2005 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
2006 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
2009 #else /* !HAVE_GLBINDTEXTURE */
2011 "%s: this version of GL doesn't support multiple texture maps.\n"
2012 "\tGet OpenGL 1.1.\n",
2015 #endif /* !HAVE_GLBINDTEXTURE */
2018 lc->box = glGenLists(16);
2019 lc->star1 = lc->box+1;
2020 lc->star2 = lc->box+2;
2021 lc->tetra_une = lc->box+3;
2022 lc->tetra_usw = lc->box+4;
2023 lc->tetra_dwn = lc->box+5;
2024 lc->tetra_dse = lc->box+6;
2025 lc->tetra_mid = lc->box+7;
2026 lc->lid_0 = lc->box+8;
2027 lc->lid_1 = lc->box+9;
2028 lc->lid_2 = lc->box+10;
2029 lc->lid_3 = lc->box+11;
2030 lc->lid_4 = lc->box+12;
2031 lc->taser_base = lc->box+13;
2032 lc->taser_lifter = lc->box+14;
2033 lc->taser_slider = lc->box+15;
2036 star(mi, True, wire);
2037 star(mi, False, wire);
2044 # ifdef HAVE_MESA_GL
2046 # include <signal.h>
2049 lament_signal_kludge (int sig)
2051 signal (sig, SIG_DFL);
2054 "%s: dying with signal %d (%s).\n"
2056 "\tThis is almost certainly a bug in the Mesa GL library,\n"
2057 "\tespecially if the stack trace in the core file mentions\n"
2058 "\t`lambda_textured_triangle' or `render_quad'.\n"
2060 "\tFirst make sure that you have the latest version of Mesa.\n"
2061 "\tIf that doesn't fix it, then I encourage you to report this\n"
2062 "\tbug to the Mesa maintainers at <http://www.mesa3d.org/>.\n"
2066 (sig == SIGILL ? "SIGILL" :
2067 sig == SIGFPE ? "SIGFPE" :
2068 sig == SIGBUS ? "SIGBUS" :
2069 sig == SIGSEGV ? "SIGSEGV" : "???"));
2071 kill (getpid (), sig);
2075 handle_signals (void)
2077 signal (SIGILL, lament_signal_kludge);
2078 signal (SIGFPE, lament_signal_kludge);
2079 signal (SIGBUS, lament_signal_kludge);
2080 signal (SIGSEGV, lament_signal_kludge);
2082 # endif /* HAVE_MESA_GL */
2086 init_lament(ModeInfo *mi)
2088 lament_configuration *lc;
2091 lcs = (lament_configuration *)
2092 calloc(MI_NUM_SCREENS(mi), sizeof (lament_configuration));
2095 fprintf(stderr, "%s: out of memory\n", progname);
2100 lc = &lcs[MI_SCREEN(mi)];
2102 lc->rotx = frand(1.0) * RANDSIGN();
2103 lc->roty = frand(1.0) * RANDSIGN();
2104 lc->rotz = frand(1.0) * RANDSIGN();
2106 /* bell curve from 0-1.5 degrees, avg 0.75 */
2107 lc->dx = (frand(1) + frand(1) + frand(1)) / (360*2);
2108 lc->dy = (frand(1) + frand(1) + frand(1)) / (360*2);
2109 lc->dz = (frand(1) + frand(1) + frand(1)) / (360*2);
2111 lc->d_max = lc->dx * 2;
2113 lc->ddx = 0.00006 + frand(0.00003);
2114 lc->ddy = 0.00006 + frand(0.00003);
2115 lc->ddz = 0.00006 + frand(0.00003);
2117 lc->type = LAMENT_BOX;
2118 lc->anim_pause = 300 + (random() % 100);
2120 if ((lc->glx_context = init_GL(mi)) != NULL)
2122 reshape_lament(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
2126 # ifdef HAVE_MESA_GL
2128 # endif /* HAVE_MESA_GL */
2133 draw_lament(ModeInfo *mi)
2135 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
2136 Display *dpy = MI_DISPLAY(mi);
2137 Window window = MI_WINDOW(mi);
2139 if (!lc->glx_context)
2142 glDrawBuffer(GL_BACK);
2144 glXMakeCurrent(dpy, window, *(lc->glx_context));
2146 if (mi->fps_p) do_fps (mi);
2149 glXSwapBuffers(dpy, window);
2151 if (lc->type != LAMENT_LID_ZOOM)
2153 rotate(&lc->rotx, &lc->dx, &lc->ddx, lc->d_max);
2154 rotate(&lc->roty, &lc->dy, &lc->ddy, lc->d_max);
2155 rotate(&lc->rotz, &lc->dz, &lc->ddz, lc->d_max);