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};
109 #include "xpm-ximage.h"
110 #include "../images/lament.xpm"
112 #define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n))))
113 #define RANDSIGN() ((random() & 1) ? 1 : -1)
136 LAMENT_TASER_SLIDE_IN,
141 static GLfloat exterior_color[] = { 0.70, 0.60, 0.00, 1.00 };
142 static GLfloat interior_color[] = { 0.25, 0.25, 0.20, 1.00 };
146 GLXContext *glx_context;
148 GLuint box; /* display list IDs */
150 GLuint tetra_une, tetra_usw, tetra_dwn, tetra_dse, tetra_mid;
151 GLuint lid_0, lid_1, lid_2, lid_3, lid_4;
152 GLuint taser_base, taser_lifter, taser_slider;
154 GLfloat rotx, roty, rotz; /* current object rotation */
155 GLfloat dx, dy, dz; /* current rotational velocity */
156 GLfloat ddx, ddy, ddz; /* current rotational acceleration */
157 GLfloat d_max; /* max velocity */
158 XImage *texture; /* image bits */
159 GLuint texids[6]; /* texture map IDs */
160 lament_type type; /* which mode of the object is current */
162 int anim_pause; /* countdown before animating again */
163 GLfloat anim_r, anim_y, anim_z; /* relative position during anims */
165 } lament_configuration;
167 static lament_configuration *lcs = NULL;
177 parse_image_data(ModeInfo *mi)
179 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
180 lc->texture = xpm_to_ximage (mi->dpy,
187 /* Computing normal vectors (thanks to Nat Friedman <ndf@mit.edu>)
190 typedef struct vector {
194 typedef struct plane {
199 vector_set(vector *v, GLfloat x, GLfloat y, GLfloat z)
207 vector_cross(vector v1, vector v2, vector *v3)
209 v3->x = (v1.y * v2.z) - (v1.z * v2.y);
210 v3->y = (v1.z * v2.x) - (v1.x * v2.z);
211 v3->z = (v1.x * v2.y) - (v1.y * v2.x);
215 vector_subtract(vector v1, vector v2, vector *res)
217 res->x = v1.x - v2.x;
218 res->y = v1.y - v2.y;
219 res->z = v1.z - v2.z;
223 plane_normal(plane p, vector *n)
226 vector_subtract(p.p1, p.p2, &v1);
227 vector_subtract(p.p1, p.p3, &v2);
228 vector_cross(v2, v1, n);
232 do_normal(GLfloat x1, GLfloat y1, GLfloat z1,
233 GLfloat x2, GLfloat y2, GLfloat z2,
234 GLfloat x3, GLfloat y3, GLfloat z3)
238 vector_set(&plane.p1, x1, y1, z1);
239 vector_set(&plane.p2, x2, y2, z2);
240 vector_set(&plane.p3, x3, y3, z3);
241 plane_normal(plane, &n);
242 n.x = -n.x; n.y = -n.y; n.z = -n.z;
244 glNormal3f(n.x, n.y, n.z);
247 /* Draw a line in the direction of this face's normal. */
249 GLfloat ax = n.x > 0 ? n.x : -n.x;
250 GLfloat ay = n.y > 0 ? n.y : -n.y;
251 GLfloat az = n.z > 0 ? n.z : -n.z;
252 GLfloat mx = (x1 + x2 + x3) / 3;
253 GLfloat my = (y1 + y2 + y3) / 3;
254 GLfloat mz = (z1 + z2 + z3) / 3;
257 GLfloat max = ax > ay ? ax : ay;
258 if (az > max) max = az;
264 glBegin(GL_LINE_LOOP);
265 glVertex3f(mx, my, mz);
266 glVertex3f(mx+xx, my+yy, mz+zz);
274 /* Shorthand utilities for making faces, with proper normals.
278 face3(GLint texture, GLfloat *color, Bool wire,
279 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
280 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
281 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3)
283 #ifdef HAVE_GLBINDTEXTURE
284 glBindTexture(GL_TEXTURE_2D, texture);
285 #endif /* HAVE_GLBINDTEXTURE */
286 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
287 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
288 glBegin(wire ? GL_LINE_LOOP : GL_TRIANGLES);
289 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
290 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
291 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
296 face4(GLint texture, GLfloat *color, Bool wire,
297 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
298 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
299 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3,
300 GLfloat s4, GLfloat t4, GLfloat x4, GLfloat y4, GLfloat z4)
302 #ifdef HAVE_GLBINDTEXTURE
303 glBindTexture(GL_TEXTURE_2D, texture);
304 #endif /* HAVE_GLBINDTEXTURE */
305 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
306 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
307 glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
308 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
309 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
310 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
311 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
316 face5(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,
321 GLfloat s5, GLfloat t5, GLfloat x5, GLfloat y5, GLfloat z5)
323 #ifdef HAVE_GLBINDTEXTURE
324 glBindTexture(GL_TEXTURE_2D, texture);
325 #endif /* HAVE_GLBINDTEXTURE */
326 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
327 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
328 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
329 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
330 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
331 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
332 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
333 glTexCoord2f(s5, t5); glVertex3f(x5, y5, z5);
339 /* Creating object models
343 box(ModeInfo *mi, Bool wire)
345 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
347 glNewList(lc->box, GL_COMPILE);
348 glShadeModel(GL_SMOOTH);
351 face4(lc->texids[FACE_N], exterior_color, wire,
352 0.0, 0.0, -0.5, 0.5, 0.5,
353 1.0, 0.0, 0.5, 0.5, 0.5,
354 1.0, 1.0, 0.5, 0.5, -0.5,
355 0.0, 1.0, -0.5, 0.5, -0.5);
358 face4(lc->texids[FACE_S], exterior_color, wire,
359 0.0, 0.0, -0.5, -0.5, -0.5,
360 1.0, 0.0, 0.5, -0.5, -0.5,
361 1.0, 1.0, 0.5, -0.5, 0.5,
362 0.0, 1.0, -0.5, -0.5, 0.5);
365 face4(lc->texids[FACE_E], exterior_color, wire,
366 0.0, 0.0, 0.5, -0.5, -0.5,
367 1.0, 0.0, 0.5, 0.5, -0.5,
368 1.0, 1.0, 0.5, 0.5, 0.5,
369 0.0, 1.0, 0.5, -0.5, 0.5);
372 face4(lc->texids[FACE_W], exterior_color, wire,
373 1.0, 1.0, -0.5, -0.5, 0.5,
374 0.0, 1.0, -0.5, 0.5, 0.5,
375 0.0, 0.0, -0.5, 0.5, -0.5,
376 1.0, 0.0, -0.5, -0.5, -0.5);
379 face4(lc->texids[FACE_U], exterior_color, wire,
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,
383 0.0, 0.0, -0.5, -0.5, 0.5);
386 face4(lc->texids[FACE_D], exterior_color, wire,
387 0.0, 1.0, -0.5, -0.5, -0.5,
388 0.0, 0.0, -0.5, 0.5, -0.5,
389 1.0, 0.0, 0.5, 0.5, -0.5,
390 1.0, 1.0, 0.5, -0.5, -0.5);
397 star(ModeInfo *mi, Bool top, Bool wire)
399 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
403 { 77, 74 }, { 60, 98 }, { 0, 71 }, { 0, 0 }, /* L1 */
404 { 60, 98 }, { 55, 127 }, { 0, 127 }, { 0, 71 }, /* L2 */
405 { 55, 127 }, { 60, 154 }, { 0, 179 }, { 0, 127 }, /* L3 */
406 { 60, 154 }, { 76, 176 }, { 0, 255 }, { 0, 179 }, /* L4 */
407 { 76, 176 }, { 100, 193 }, { 74, 255 }, { 0, 255 }, /* B1 */
408 { 100, 193 }, { 127, 198 }, { 127, 255 }, { 74, 255 }, /* B2 */
409 { 127, 198 }, { 151, 193 }, { 180, 255 }, { 127, 255 }, /* B3 */
410 { 151, 193 }, { 178, 177 }, { 255, 255 }, { 180, 255 }, /* B4 */
411 { 178, 177 }, { 193, 155 }, { 255, 181 }, { 255, 255 }, /* R4 */
412 { 193, 155 }, { 199, 127 }, { 255, 127 }, { 255, 181 }, /* R3 */
413 { 199, 127 }, { 194, 99 }, { 255, 74 }, { 255, 127 }, /* R2 */
414 { 194, 99 }, { 179, 76 }, { 255, 0 }, { 255, 74 }, /* R1 */
415 { 179, 76 }, { 155, 60 }, { 180, 0 }, { 255, 0 }, /* T4 */
416 { 155, 60 }, { 126, 55 }, { 126, 0 }, { 180, 0 }, /* T3 */
417 { 126, 55 }, { 100, 60 }, { 75, 0 }, { 126, 0 }, /* T2 */
418 { 100, 60 }, { 77, 74 }, { 0, 0 }, { 75, 0 }, /* T1 */
421 for (i = 0; i < countof(points); i++)
422 points[i][1] = 255-points[i][1];
425 glNewList(lc->star1, GL_COMPILE);
427 glNewList(lc->star2, GL_COMPILE);
430 glRotatef(-180.0, 1.0, 0.0, 0.0);
432 for (i = 0; i < countof(points)/4; i += 2)
439 GLfloat s[4], t[4], x[4], y[4], z[4];
440 for (j = 3, k = 0; j >= 0; j--, k++)
442 GLfloat xx = points[(i*4)+j][0] / 255.0L;
443 GLfloat yy = points[(i*4)+j][1] / 255.0L;
450 face4(lc->texids[top ? FACE_U : FACE_D], exterior_color, wire,
451 s[0], t[0], x[0], y[0], z[0],
452 s[1], t[1], x[1], y[1], z[1],
453 s[2], t[2], x[2], y[2], z[2],
454 s[3], t[3], x[3], y[3], z[3]);
458 for (j = 0, k = 0; j < 4; j++, k++)
460 GLfloat xx = points[(i*4)+j][0] / 255.0L;
461 GLfloat yy = points[(i*4)+j][1] / 255.0L;
468 face4(lc->texids[top ? FACE_U : FACE_D], exterior_color, wire,
469 s[0], t[0], x[0], y[0], z[0],
470 s[1], t[1], x[1], y[1], z[1],
471 s[2], t[2], x[2], y[2], z[2],
472 s[3], t[3], x[3], y[3], z[3]);
476 for (j = 3; j >= 0; j--)
478 int k = (j == 0 ? 3 : j-1);
479 Bool front_p = (j == 3);
480 GLfloat x1 = points[(i*4)+j][0] / 255.0L;
481 GLfloat y1 = points[(i*4)+j][1] / 255.0L;
482 GLfloat x2 = points[(i*4)+k][0] / 255.0L;
483 GLfloat y2 = points[(i*4)+k][1] / 255.0L;
485 GLfloat tx1=0.0, tx2=1.0, ty1=0.0, ty2=1.0;
489 facing = (facing + j + 5) % 4;
495 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
496 ty1 = 0.0; ty2 = 1.0;
499 ty1 = 1.0; ty2 = 0.0;
503 texture = top ? FACE_S : FACE_N;
505 ty1 = 0.0; ty2 = 1.0;
511 ty1 = 0.0; ty2 = 1.0;
513 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
514 ty1 = 1.0; ty2 = 0.0;
518 texture = top ? FACE_N : FACE_S;
520 ty1 = 1.0; ty2 = 0.0;
524 x1 -= 0.5; x2 -= 0.5;
525 y1 -= 0.5; y2 -= 0.5;
527 face4(front_p ? lc->texids[texture] : 0,
528 front_p ? exterior_color : interior_color,
530 tx1, ty2, x1, y1, 0.5,
531 tx1, ty1, x1, y1, -0.5,
532 tx2, ty1, x2, y2, -0.5,
533 tx2, ty2, x2, y2, 0.5);
538 /* Central core top cap.
540 #ifdef HAVE_GLBINDTEXTURE
541 glBindTexture(GL_TEXTURE_2D, lc->texids[top ? FACE_U : FACE_D]);
542 #endif /* HAVE_GLBINDTEXTURE */
543 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
546 do_normal(points[i+0][0], points[i+0][1], 0,
547 points[i+4][0], points[i+4][1], 0,
548 points[i+8][0], points[i+8][1], 0);
549 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
550 for (i = 1; i < countof(points); i += 4)
552 GLfloat x = points[i][0] / 255.0L;
553 GLfloat y = points[i][1] / 255.0L;
555 glVertex3f(x-0.5, y-0.5, 0.5);
560 /* Central core bottom cap.
562 #ifdef HAVE_GLBINDTEXTURE
563 glBindTexture(GL_TEXTURE_2D, 0);
564 #endif /* HAVE_GLBINDTEXTURE */
565 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color);
567 i = countof(points) - 9;
568 do_normal(points[i+0][0], points[i+0][1], 0,
569 points[i+4][0], points[i+4][1], 0,
570 points[i+8][0], points[i+8][1], 0);
572 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
573 for (i = countof(points) - 3; i >= 0; i -= 4)
575 GLfloat x = points[i][0] / 255.0L;
576 GLfloat y = points[i][1] / 255.0L;
577 glVertex3f(x-0.5, y-0.5, 0);
582 /* Central core walls.
584 for (i = 1; i < countof(points); i += 4)
587 GLfloat x1 = points[i-1][0] / 255.0L;
588 GLfloat y1 = points[i-1][1] / 255.0L;
589 GLfloat x2 = points[i][0] / 255.0L;
590 GLfloat y2 = points[i][1] / 255.0L;
591 face4(0, interior_color, wire,
592 0.0, 0.0, x1-0.5, y1-0.5, 0.5,
593 0.0, 0.0, x1-0.5, y1-0.5, 0.0,
594 0.0, 0.0, x2-0.5, y2-0.5, 0.0,
595 0.0, 0.0, x2-0.5, y2-0.5, 0.5);
603 tetra(ModeInfo *mi, Bool wire)
605 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
607 glNewList(lc->tetra_une, GL_COMPILE);
609 glShadeModel(GL_SMOOTH);
612 face3(lc->texids[FACE_U], exterior_color, wire,
613 1.0, 0.0, 0.5, -0.5, 0.5,
614 1.0, 1.0, 0.5, 0.5, 0.5,
615 0.0, 1.0, -0.5, 0.5, 0.5);
618 face3(lc->texids[FACE_N], exterior_color, wire,
619 0.0, 0.0, -0.5, 0.5, 0.5,
620 1.0, 0.0, 0.5, 0.5, 0.5,
621 1.0, 1.0, 0.5, 0.5, -0.5);
624 face3(lc->texids[FACE_E], exterior_color, wire,
625 1.0, 0.0, 0.5, 0.5, -0.5,
626 1.0, 1.0, 0.5, 0.5, 0.5,
627 0.0, 1.0, 0.5, -0.5, 0.5);
629 face3(0, interior_color, wire,
630 0.0, 0.0, 0.5, 0.5, -0.5,
631 0.0, 0.0, 0.5, -0.5, 0.5,
632 0.0, 0.0, -0.5, 0.5, 0.5);
636 glNewList(lc->tetra_usw, GL_COMPILE);
639 face3(lc->texids[FACE_U], exterior_color, wire,
640 0.0, 1.0, -0.5, 0.5, 0.5,
641 0.0, 0.0, -0.5, -0.5, 0.5,
642 1.0, 0.0, 0.5, -0.5, 0.5);
645 face3(lc->texids[FACE_S], exterior_color, wire,
646 1.0, 1.0, 0.5, -0.5, 0.5,
647 0.0, 1.0, -0.5, -0.5, 0.5,
648 0.0, 0.0, -0.5, -0.5, -0.5);
651 face3(lc->texids[FACE_W], exterior_color, wire,
652 1.0, 0.0, -0.5, -0.5, -0.5,
653 1.0, 1.0, -0.5, -0.5, 0.5,
654 0.0, 1.0, -0.5, 0.5, 0.5);
656 face3(0, interior_color, wire,
657 0.0,0.0, -0.5, -0.5, -0.5,
658 0.0,0.0, -0.5, 0.5, 0.5,
659 0.0,0.0, 0.5, -0.5, 0.5);
663 glNewList(lc->tetra_dwn, GL_COMPILE);
666 face3(lc->texids[FACE_D], exterior_color, wire,
667 0.0, 1.0, -0.5, -0.5, -0.5,
668 0.0, 0.0, -0.5, 0.5, -0.5,
669 1.0, 0.0, 0.5, 0.5, -0.5);
672 face3(lc->texids[FACE_W], exterior_color, wire,
673 0.0, 1.0, -0.5, 0.5, 0.5,
674 0.0, 0.0, -0.5, 0.5, -0.5,
675 1.0, 0.0, -0.5, -0.5, -0.5);
678 face3(lc->texids[FACE_N], exterior_color, wire,
679 1.0, 1.0, 0.5, 0.5, -0.5,
680 0.0, 1.0, -0.5, 0.5, -0.5,
681 0.0, 0.0, -0.5, 0.5, 0.5);
683 face3(0, interior_color, wire,
684 0.0, 0.0, 0.5, 0.5, -0.5,
685 0.0, 0.0, -0.5, 0.5, 0.5,
686 0.0, 0.0, -0.5, -0.5, -0.5);
690 glNewList(lc->tetra_dse, GL_COMPILE);
693 face3(lc->texids[FACE_S], exterior_color, wire,
694 0.0, 0.0, -0.5, -0.5, -0.5,
695 1.0, 0.0, 0.5, -0.5, -0.5,
696 1.0, 1.0, 0.5, -0.5, 0.5);
699 face3(lc->texids[FACE_E], exterior_color, wire,
700 0.0, 1.0, 0.5, -0.5, 0.5,
701 0.0, 0.0, 0.5, -0.5, -0.5,
702 1.0, 0.0, 0.5, 0.5, -0.5);
705 face3(lc->texids[FACE_D], exterior_color, wire,
706 1.0, 0.0, 0.5, 0.5, -0.5,
707 1.0, 1.0, 0.5, -0.5, -0.5,
708 0.0, 1.0, -0.5, -0.5, -0.5);
710 face3(0, interior_color, wire,
711 0.0, 0.0, 0.5, -0.5, 0.5,
712 0.0, 0.0, 0.5, 0.5, -0.5,
713 0.0, 0.0, -0.5, -0.5, -0.5);
717 glNewList(lc->tetra_mid, GL_COMPILE);
719 face3(0, interior_color, wire,
720 0.0, 0.0, 0.5, -0.5, 0.5,
721 0.0, 0.0, 0.5, 0.5, -0.5,
722 0.0, 0.0, -0.5, 0.5, 0.5);
724 face3(0, interior_color, wire,
725 0.0, 0.0, -0.5, 0.5, 0.5,
726 0.0, 0.0, -0.5, -0.5, -0.5,
727 0.0, 0.0, 0.5, -0.5, 0.5);
729 face3(0, interior_color, wire,
730 0.0, 0.0, -0.5, 0.5, 0.5,
731 0.0, 0.0, 0.5, 0.5, -0.5,
732 0.0, 0.0, -0.5, -0.5, -0.5);
734 face3(0, interior_color, wire,
735 0.0, 0.0, 0.5, 0.5, -0.5,
736 0.0, 0.0, 0.5, -0.5, 0.5,
737 0.0, 0.0, -0.5, -0.5, -0.5);
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);
749 lid(ModeInfo *mi, Bool wire)
751 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
755 { 128, 20 },{ 21, 129 },{ 0, 129 },{ 0, 0 },{ 128, 0 }, /* L1 */
756 { 21, 129 },{ 127, 234 },{ 127, 255 },{ 0, 255 },{ 0, 129 }, /* L2 */
757 { 127, 234 },{ 233, 127 },{ 255, 127 },{ 255, 255 },{ 127, 255 }, /* R2 */
758 { 233, 127 },{ 128, 20 },{ 128, 0 },{ 255, 0 },{ 255, 127 }, /* R1 */
761 for (i = 0; i < countof(points); i++)
762 points[i][1] = 255-points[i][1];
764 glNewList(lc->lid_0, GL_COMPILE);
765 glShadeModel(GL_SMOOTH);
768 face4(lc->texids[FACE_N], exterior_color, wire,
769 0.0, 0.0, -0.5, 0.5, 0.5,
770 1.0, 0.0, 0.5, 0.5, 0.5,
771 1.0, 1.0, 0.5, 0.5, -0.5,
772 0.0, 1.0, -0.5, 0.5, -0.5);
775 face4(lc->texids[FACE_S], exterior_color, wire,
776 0.0, 0.0, -0.5, -0.5, -0.5,
777 1.0, 0.0, 0.5, -0.5, -0.5,
778 1.0, 1.0, 0.5, -0.5, 0.5,
779 0.0, 1.0, -0.5, -0.5, 0.5);
782 face4(lc->texids[FACE_E], exterior_color, wire,
783 0.0, 0.0, 0.5, -0.5, -0.5,
784 1.0, 0.0, 0.5, 0.5, -0.5,
785 1.0, 1.0, 0.5, 0.5, 0.5,
786 0.0, 1.0, 0.5, -0.5, 0.5);
789 face4(lc->texids[FACE_U], exterior_color, wire,
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,
793 0.0, 0.0, -0.5, -0.5, 0.5);
796 face4(lc->texids[FACE_D], exterior_color, wire,
797 0.0, 1.0, -0.5, -0.5, -0.5,
798 0.0, 0.0, -0.5, 0.5, -0.5,
799 1.0, 0.0, 0.5, 0.5, -0.5,
800 1.0, 1.0, 0.5, -0.5, -0.5);
803 for (i = 0; i < countof(points)/5; i++)
806 GLfloat s[5], t[5], x[5], y[5], z[5];
807 for (j = 0; j < 5; j++)
809 GLfloat xx = points[(i*5)+j][0] / 255.0L;
810 GLfloat yy = points[(i*5)+j][1] / 255.0L;
817 face5(lc->texids[FACE_W], exterior_color, wire,
818 s[0], t[0], x[0], y[0], z[0],
819 s[1], t[1], x[1], y[1], z[1],
820 s[2], t[2], x[2], y[2], z[2],
821 s[3], t[3], x[3], y[3], z[3],
822 s[4], t[4], x[4], y[4], z[4]);
827 /* W -- lid_1 through lid_4 */
828 for (i = 0; i < 4; i++)
830 GLfloat x1, y1, x2, y2, x3, y3;
832 glNewList(lc->lid_1 + i, GL_COMPILE);
833 glShadeModel(GL_SMOOTH);
835 x1 = points[(i*5)+1][0] / 255.0L;
836 y1 = points[(i*5)+1][1] / 255.0L;
837 x2 = points[(i*5)][0] / 255.0L;
838 y2 = points[(i*5)][1] / 255.0L;
843 face3(lc->texids[FACE_W], exterior_color, wire,
844 1.0-x1, y1, -0.5, x1-0.5, y1-0.5,
845 1.0-x2, y2, -0.5, x2-0.5, y2-0.5,
846 1.0-x3, y3, -0.5, x3-0.5, y3-0.5);
849 face3(0, interior_color, wire,
850 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
851 0.0, 0.0, -0.48, x1-0.5, y1-0.5,
852 0.0, 0.0, -0.48, x3-0.5, y3-0.5);
855 face4(0, interior_color, wire,
856 0.0, 0.0, -0.5, x1-0.5, y1-0.5,
857 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
858 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
859 0.0, 0.0, -0.48, x1-0.5, y1-0.5);
862 face4(0, interior_color, wire,
863 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
864 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
865 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
866 0.0, 0.0, -0.5, x2-0.5, y2-0.5);
873 taser(ModeInfo *mi, Bool wire)
875 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
878 int slider_face_points[][2] = {
879 { 86, 58 },{ 38, 106 },{ 70, 106 },{ 118, 58 },{ -1, -1 }, /* a */
880 { 136, 58 },{ 184, 106 },{ 216, 106 },{ 168, 58 },{ -1, -1 }, /* b */
881 { 38, 106 },{ 0, 144 },{ 0, 190 },{ 60, 190 },{ 108, 106 }, /* c */
882 { 144, 106 },{ 194, 190 },{ 254, 190 },{ 254, 144 },{ 216, 106 }, /* d */
883 { 98, 124 },{ 60, 190 },{ 92, 190 },{ 126, 158 },{ 126, 124 }, /* e */
884 { 126, 124 },{ 126, 158 },{ 160, 190 },{ 194, 190 },{ 154, 124 }, /* f */
885 { 22, 190 },{ 22, 254 },{ 60, 254 },{ 60, 190 },{ -1, -1 }, /* g */
886 { 194, 190 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ -1, -1 }, /* h */
887 { 60, 190 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ -1, -1 }, /* i */
888 { 160, 190 },{ 160, 210 },{ 194, 210 },{ 194, 190 },{ -1, -1 }, /* j */
889 { 110, 172 },{ 92, 190 },{ 110, 190 },{ -1, -1 },{ -1, -1 }, /* k */
890 { 140, 172 },{ 140, 190 },{ 160, 190 },{ -1, -1 },{ -1, -1 }, /* l */
891 { 110, 172 },{ 140, 172 },{ 126, 156 },{ -1, -1 },{ -1, -1 }, /* m */
894 int body_face_points[][2] = {
895 { 0, 0 },{ 0, 58 },{ 254, 58 },{ 254, 0 },{ -1, -1 }, /* A */
896 { 0, 58 },{ 0, 144 },{ 86, 58 },{ -1, -1 },{ -1, -1 }, /* B */
897 { 168, 58 },{ 254, 144 },{ 254, 58 },{ -1, -1 },{ -1, -1 }, /* C */
898 { 118, 58 },{ 70, 106 },{ 184, 106 },{ 136, 58 },{ -1, -1 }, /* F */
899 { 108, 106 },{ 98, 124 },{ 154, 124 },{ 144, 106 },{ -1, -1 }, /* G */
902 int lifter_face_points[][2] = {
903 { 0, 190 },{ 0, 254 },{ 22, 254 },{ 22, 190 },{ -1, -1 }, /* D */
904 { 230, 190 },{ 230, 254 },{ 254, 254 },{ 254, 190 },{ -1, -1 }, /* E */
905 { 60, 210 },{ 60, 254 },{ 194, 254 },{ 194, 210 },{ -1, -1 }, /* H */
906 { 92, 190 },{ 92, 210 },{ 160, 210 },{ 160, 190 },{ -1, -1 }, /* I */
907 { 110, 172 },{ 110, 190 },{ 140, 190 },{ 140, 172 },{ -1, -1 }, /* J */
910 int body_perimiter_points[][2] = {
911 { 0, 144 },{ 86, 59 },{ 119, 58 },{ 71, 107 },
912 { 108, 107 },{ 98, 124 },{ 155, 124 },{ 144, 107 },
913 { 185, 106 },{ 136, 59 },{ 169, 59 },{ 255, 145 },
917 int slider_perimiter_points[][2] = {
918 { 86, 58 },{ 0, 144 },{ 0, 190 },{ 22, 190 },{ 22, 254 },
919 { 60, 254 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ 110, 190 },
920 { 110, 172 },{ 140, 172 },{ 140, 190 },{ 160, 190 },{ 160, 210 },
921 { 194, 210 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ 254, 190 },
922 { 254, 144 },{ 168, 58 },{ 136, 58 },{ 184, 106 },{ 144, 106 },
923 { 154, 124 },{ 98, 124 },{ 108, 106 },{ 70, 106 },{ 118, 58 },
926 int lifter_perimiter_points_1[][2] = {
927 { 0, 189 },{ 0, 254 },{ 22, 255 },{ 23, 190 },
930 int lifter_perimiter_points_2[][2] = {
931 { 230, 254 },{ 255, 255 },{ 254, 190 },{ 230, 190 },
934 int lifter_perimiter_points_3[][2] = {
935 { 60, 254 },{ 194, 254 },{ 194, 211 },{ 160, 210 },
936 { 160, 190 },{ 140, 191 },{ 141, 172 },{ 111, 172 },
937 { 110, 190 },{ 93, 190 },{ 92, 210 },{ 60, 211 },
940 for (i = 0; i < countof(slider_face_points); i++)
941 slider_face_points[i][1] = 255-slider_face_points[i][1];
942 for (i = 0; i < countof(body_face_points); i++)
943 body_face_points[i][1] = 255-body_face_points[i][1];
944 for (i = 0; i < countof(lifter_face_points); i++)
945 lifter_face_points[i][1] = 255-lifter_face_points[i][1];
946 for (i = 0; i < countof(body_perimiter_points); i++)
947 body_perimiter_points[i][1] = 255-body_perimiter_points[i][1];
948 for (i = 0; i < countof(slider_perimiter_points); i++)
949 slider_perimiter_points[i][1] = 255-slider_perimiter_points[i][1];
950 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
951 lifter_perimiter_points_1[i][1] = 255-lifter_perimiter_points_1[i][1];
952 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
953 lifter_perimiter_points_2[i][1] = 255-lifter_perimiter_points_2[i][1];
954 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
955 lifter_perimiter_points_3[i][1] = 255-lifter_perimiter_points_3[i][1];
957 /* -------------------------------------------------------------------- */
959 glNewList(lc->taser_base, GL_COMPILE);
960 glShadeModel(GL_SMOOTH);
963 face4(lc->texids[FACE_N], exterior_color, wire,
964 0.0, 0.0, -0.5, 0.5, 0.5,
965 0.75, 0.0, 0.25, 0.5, 0.5,
966 0.75, 0.75, 0.25, 0.5, -0.25,
967 0.0, 0.75, -0.5, 0.5, -0.25);
970 face4(lc->texids[FACE_S], exterior_color, wire,
971 0.0, 0.25, -0.5, -0.5, -0.25,
972 0.75, 0.25, 0.25, -0.5, -0.25,
973 0.75, 1.0, 0.25, -0.5, 0.5,
974 0.0, 1.0, -0.5, -0.5, 0.5);
977 face4(0, interior_color, wire,
978 0.0, 0.0, 0.25, -0.5, -0.25,
979 1.0, 0.0, 0.25, 0.5, -0.25,
980 1.0, 1.0, 0.25, 0.5, 0.5,
981 0.0, 1.0, 0.25, -0.5, 0.5);
984 face4(lc->texids[FACE_W], exterior_color, wire,
985 1.0, 1.0, -0.5, -0.5, 0.5,
986 0.0, 1.0, -0.5, 0.5, 0.5,
987 0.0, 0.25, -0.5, 0.5, -0.25,
988 1.0, 0.25, -0.5, -0.5, -0.25);
991 face4(lc->texids[FACE_U], exterior_color, wire,
992 0.75, 0.0, 0.25, -0.5, 0.5,
993 0.75, 1.0, 0.25, 0.5, 0.5,
994 0.0, 1.0, -0.5, 0.5, 0.5,
995 0.0, 0.0, -0.5, -0.5, 0.5);
998 face4(0, interior_color, wire,
999 0.0, 1.0, -0.5, -0.5, -0.25,
1000 0.0, 0.0, -0.5, 0.5, -0.25,
1001 1.0, 0.0, 0.25, 0.5, -0.25,
1002 1.0, 1.0, 0.25, -0.5, -0.25);
1005 for (i = 0; i < countof(body_face_points)/5; i++)
1008 #ifdef HAVE_GLBINDTEXTURE
1009 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1010 #endif /* HAVE_GLBINDTEXTURE */
1011 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1013 do_normal(0, body_face_points[(i*5)+0][0], body_face_points[(i*5)+0][1],
1014 0, body_face_points[(i*5)+1][0], body_face_points[(i*5)+1][1],
1015 0, body_face_points[(i*5)+2][0], body_face_points[(i*5)+2][1]
1017 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1018 for (j = 0; j < 5; j++)
1020 int ix = body_face_points[(i*5)+j][0];
1021 int iy = body_face_points[(i*5)+j][1];
1023 if (ix == -1) /* these are padding: ignore them */
1028 glVertex3f(0.5, x-0.5, y-0.5);
1034 for (i = 0; i < countof(body_perimiter_points); i++)
1036 int j = (i+1 >= countof(body_perimiter_points) ? 0 : i+1);
1037 GLfloat x1 = body_perimiter_points[i][0] / 255.0;
1038 GLfloat y1 = body_perimiter_points[i][1] / 255.0;
1039 GLfloat x2 = body_perimiter_points[j][0] / 255.0;
1040 GLfloat y2 = body_perimiter_points[j][1] / 255.0;
1042 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1046 texture = lc->texids[FACE_N];
1048 s2 = 1.0; t2 = 0.568;
1049 s3 = 0.75, t3 = 0.568;
1050 s4 = 0.75; t4 = 0.0;
1054 texture = lc->texids[FACE_U];
1057 s3 = 0.75, t3 = 1.0;
1058 s4 = 0.75; t4 = 0.0;
1062 texture = lc->texids[FACE_S];
1063 s1 = 1.0; t1 = 0.437;
1065 s3 = 0.75; t3 = 1.0;
1066 s4 = 0.75; t4 = 0.437;
1069 face4((texture == -1 ? 0 : texture),
1070 (texture == -1 ? interior_color : exterior_color),
1072 s1, t1, 0.5, x2-0.5, y2-0.5,
1073 s2, t2, 0.5, x1-0.5, y1-0.5,
1074 s3, t3, 0.25, x1-0.5, y1-0.5,
1075 s4, t4, 0.25, x2-0.5, y2-0.5);
1080 /* -------------------------------------------------------------------- */
1082 glNewList(lc->taser_lifter, GL_COMPILE);
1083 glShadeModel(GL_SMOOTH);
1086 face4(lc->texids[FACE_N], exterior_color, wire,
1087 0.0, 0.75, -0.5, 0.5, -0.25,
1088 0.75, 0.75, 0.25, 0.5, -0.25,
1089 0.75, 1.0, 0.25, 0.5, -0.5,
1090 0.0, 1.0, -0.5, 0.5, -0.5);
1093 face4(lc->texids[FACE_S], exterior_color, wire,
1094 0.0, 0.0, -0.5, -0.5, -0.5,
1095 0.75, 0.0, 0.25, -0.5, -0.5,
1096 0.75, 0.25, 0.25, -0.5, -0.25,
1097 0.0, 0.25, -0.5, -0.5, -0.25);
1100 face4(0, interior_color, wire,
1101 0.0, 1.0, 0.25, -0.5, -0.5,
1102 1.0, 1.0, 0.25, 0.5, -0.5,
1103 1.0, 0.0, 0.25, 0.5, -0.25,
1104 0.0, 0.0, 0.25, -0.5, -0.25);
1107 face4(lc->texids[FACE_W], exterior_color, wire,
1108 1.0, 0.25, -0.5, -0.5, -0.25,
1109 0.0, 0.25, -0.5, 0.5, -0.25,
1110 0.0, 0.0, -0.5, 0.5, -0.5,
1111 1.0, 0.0, -0.5, -0.5, -0.5);
1114 face4(0, interior_color, wire,
1115 1.0, 0.0, 0.25, -0.5, -0.25,
1116 1.0, 1.0, 0.25, 0.5, -0.25,
1117 0.0, 1.0, -0.5, 0.5, -0.25,
1118 0.0, 0.0, -0.5, -0.5, -0.25);
1121 face4(lc->texids[FACE_D], exterior_color, wire,
1122 0.0, 1.0, -0.5, -0.5, -0.5,
1123 0.0, 0.0, -0.5, 0.5, -0.5,
1124 0.75, 0.0, 0.25, 0.5, -0.5,
1125 0.75, 1.0, 0.25, -0.5, -0.5);
1129 for (i = 0; i < countof(lifter_face_points)/5; i++)
1133 #ifdef HAVE_GLBINDTEXTURE
1134 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1135 #endif /* HAVE_GLBINDTEXTURE */
1136 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1139 0, lifter_face_points[(i*5)+0][0], lifter_face_points[(i*5)+0][1],
1140 0, lifter_face_points[(i*5)+1][0], lifter_face_points[(i*5)+1][1],
1141 0, lifter_face_points[(i*5)+2][0], lifter_face_points[(i*5)+2][1]);
1143 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1144 for (j = 0; j < 5; j++)
1146 int ix = lifter_face_points[(i*5)+j][0];
1147 int iy = lifter_face_points[(i*5)+j][1];
1149 if (ix == -1) /* these are padding: ignore them */
1154 glVertex3f(0.5, x-0.5, y-0.5);
1160 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
1162 int j = (i+1 >= countof(lifter_perimiter_points_1) ? 0 : i+1);
1163 GLfloat x1 = lifter_perimiter_points_1[i][0] / 255.0;
1164 GLfloat y1 = lifter_perimiter_points_1[i][1] / 255.0;
1165 GLfloat x2 = lifter_perimiter_points_1[j][0] / 255.0;
1166 GLfloat y2 = lifter_perimiter_points_1[j][1] / 255.0;
1168 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1172 texture = lc->texids[FACE_S];
1174 s2 = 1.0; t2 = 0.26;
1175 s3 = 0.75, t3 = 0.26;
1176 s4 = 0.75; t4 = 0.0;
1180 texture = lc->texids[FACE_D];
1181 s1 = 1.0; t1 = 0.914;
1183 s3 = 0.75; t3 = 1.0;
1184 s4 = 0.75; t4 = 0.914;
1187 face4((texture == -1 ? 0 : texture),
1188 (texture == -1 ? interior_color : exterior_color),
1190 s1, t1, 0.5, x2-0.5, y2-0.5,
1191 s2, t2, 0.5, x1-0.5, y1-0.5,
1192 s3, t3, 0.25, x1-0.5, y1-0.5,
1193 s4, t4, 0.25, x2-0.5, y2-0.5);
1196 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
1198 int j = (i+1 >= countof(lifter_perimiter_points_2) ? 0 : i+1);
1199 GLfloat x1 = lifter_perimiter_points_2[i][0] / 255.0;
1200 GLfloat y1 = lifter_perimiter_points_2[i][1] / 255.0;
1201 GLfloat x2 = lifter_perimiter_points_2[j][0] / 255.0;
1202 GLfloat y2 = lifter_perimiter_points_2[j][1] / 255.0;
1204 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1208 texture = lc->texids[FACE_D];
1210 s2 = 1.0; t2 = 0.095;
1211 s3 = 0.75; t3 = 0.095;
1212 s4 = 0.75; t4 = 0.0;
1216 texture = lc->texids[FACE_N];
1217 s1 = 1.0; t1 = 0.745;
1219 s3 = 0.75; t3 = 1.0;
1220 s4 = 0.75; t4 = 0.745;
1223 face4((texture == -1 ? 0 : texture),
1224 (texture == -1 ? interior_color : exterior_color),
1226 s1, t1, 0.5, x2-0.5, y2-0.5,
1227 s2, t2, 0.5, x1-0.5, y1-0.5,
1228 s3, t3, 0.25, x1-0.5, y1-0.5,
1229 s4, t4, 0.25, x2-0.5, y2-0.5);
1232 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
1234 int j = (i+1 >= countof(lifter_perimiter_points_3) ? 0 : i+1);
1235 GLfloat x1 = lifter_perimiter_points_3[i][0] / 255.0;
1236 GLfloat y1 = lifter_perimiter_points_3[i][1] / 255.0;
1237 GLfloat x2 = lifter_perimiter_points_3[j][0] / 255.0;
1238 GLfloat y2 = lifter_perimiter_points_3[j][1] / 255.0;
1240 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1244 texture = lc->texids[FACE_D];
1245 s1 = 1.0; t1 = 0.235;
1246 s2 = 1.0; t2 = 0.765;
1247 s3 = 0.75; t3 = 0.765;
1248 s4 = 0.75; t4 = 0.235;
1251 face4((texture == -1 ? 0 : texture),
1252 (texture == -1 ? interior_color : exterior_color),
1254 s1, t1, 0.5, x2-0.5, y2-0.5,
1255 s2, t2, 0.5, x1-0.5, y1-0.5,
1256 s3, t3, 0.25, x1-0.5, y1-0.5,
1257 s4, t4, 0.25, x2-0.5, y2-0.5);
1262 /* -------------------------------------------------------------------- */
1264 glNewList(lc->taser_slider, GL_COMPILE);
1265 glShadeModel(GL_SMOOTH);
1268 for (i = 0; i < countof(slider_face_points)/5; i++)
1271 #ifdef HAVE_GLBINDTEXTURE
1272 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1273 #endif /* HAVE_GLBINDTEXTURE */
1274 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1277 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1],
1278 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1279 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1]);
1280 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1281 for (j = 0; j < 5; j++)
1283 int ix = slider_face_points[(i*5)+j][0];
1284 int iy = slider_face_points[(i*5)+j][1];
1286 if (ix == -1) /* these are padding: ignore them */
1291 glVertex3f(0.5, x-0.5, y-0.5);
1297 for (i = countof(slider_face_points)/5 - 1; i >= 0; i--)
1300 #ifdef HAVE_GLBINDTEXTURE
1301 glBindTexture(GL_TEXTURE_2D, 0);
1302 #endif /* HAVE_GLBINDTEXTURE */
1303 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color);
1306 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1],
1307 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1308 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1]);
1309 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1310 for (j = 4; j >= 0; j--)
1312 int ix = slider_face_points[(i*5)+j][0];
1313 int iy = slider_face_points[(i*5)+j][1];
1315 if (ix == -1) /* these are padding: ignore them */
1320 glVertex3f(0.25, x-0.5, y-0.5);
1326 for (i = 0; i < countof(slider_perimiter_points); i++)
1328 int j = (i+1 >= countof(slider_perimiter_points) ? 0 : i+1);
1329 GLfloat x1 = slider_perimiter_points[i][0] / 255.0;
1330 GLfloat y1 = slider_perimiter_points[i][1] / 255.0;
1331 GLfloat x2 = slider_perimiter_points[j][0] / 255.0;
1332 GLfloat y2 = slider_perimiter_points[j][1] / 255.0;
1334 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1338 texture = lc->texids[FACE_S];
1339 s1 = 1.0; t1 = 0.255;
1340 s2 = 1.0; t2 = 0.435;
1341 s3 = 0.75; t3 = 0.435;
1342 s4 = 0.75; t4 = 0.255;
1346 texture = lc->texids[FACE_D];
1347 s1 = 1.0; t1 = 0.758;
1348 s2 = 1.0; t2 = 0.915;
1349 s3 = 0.75; t3 = 0.915;
1350 s4 = 0.75; t4 = 0.758;
1354 texture = lc->texids[FACE_D];
1355 s1 = 1.0; t1 = 0.095;
1356 s2 = 1.0; t2 = 0.24;
1357 s3 = 0.75; t3 = 0.24;
1358 s4 = 0.75; t4 = 0.095;
1362 texture = lc->texids[FACE_N];
1363 s1 = 1.0; t1 = 0.568;
1364 s2 = 1.0; t2 = 0.742;
1365 s3 = 0.75; t3 = 0.742;
1366 s4 = 0.75; t4 = 0.568;
1369 face4((texture == -1 ? 0 : texture),
1370 (texture == -1 ? interior_color : exterior_color),
1372 s1, t1, 0.5, x2-0.5, y2-0.5,
1373 s2, t2, 0.5, x1-0.5, y1-0.5,
1374 s3, t3, 0.25, x1-0.5, y1-0.5,
1375 s4, t4, 0.25, x2-0.5, y2-0.5);
1383 /* Rendering and animating object models
1389 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1390 Bool wire = MI_IS_WIREFRAME(mi);
1393 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1395 glClear(GL_COLOR_BUFFER_BIT);
1399 GLfloat x = lc->rotx;
1400 GLfloat y = lc->roty;
1401 GLfloat z = lc->rotz;
1407 if (x < 0) x = 1 - (x + 1);
1408 if (y < 0) y = 1 - (y + 1);
1409 if (z < 0) z = 1 - (z + 1);
1411 /* Make into the screen be +Y right be +X, and up be +Z. */
1412 glRotatef(-90.0, 1.0, 0.0, 0.0);
1415 glScalef(4.0, 4.0, 4.0);
1420 /* Shift to the upper left, and draw the vanilla box. */
1421 glTranslatef(-0.6, 0.0, 0.6);
1423 /* Apply rotation to the object. */
1424 glRotatef(x * 360, 1.0, 0.0, 0.0);
1425 glRotatef(y * 360, 0.0, 1.0, 0.0);
1426 glRotatef(z * 360, 0.0, 0.0, 1.0);
1429 glCallList(lc->box);
1433 /* Shift to the lower right, and draw the animated object. */
1434 glTranslatef(0.6, 0.0, -0.6);
1440 /* Apply rotation to the object. */
1441 glRotatef(x * 360, 1.0, 0.0, 0.0);
1442 glRotatef(y * 360, 0.0, 1.0, 0.0);
1443 glRotatef(z * 360, 0.0, 0.0, 1.0);
1448 glCallList(lc->box);
1451 case LAMENT_STAR_OUT:
1452 case LAMENT_STAR_ROT:
1453 case LAMENT_STAR_ROT_IN:
1454 case LAMENT_STAR_ROT_OUT:
1455 case LAMENT_STAR_UNROT:
1456 case LAMENT_STAR_IN:
1457 glTranslatef(0.0, 0.0, lc->anim_z/2);
1458 glRotatef(lc->anim_r/2, 0.0, 0.0, 1.0);
1459 glCallList(lc->star1);
1461 glTranslatef(0.0, 0.0, -lc->anim_z);
1462 glRotatef(-lc->anim_r, 0.0, 0.0, 1.0);
1463 glCallList(lc->star2);
1466 case LAMENT_TETRA_UNE:
1467 case LAMENT_TETRA_USW:
1468 case LAMENT_TETRA_DWN:
1469 case LAMENT_TETRA_DSE:
1474 case LAMENT_TETRA_UNE: magic = lc->tetra_une;
1475 x = 1.0; y = 1.0; z = 1.0; break;
1476 case LAMENT_TETRA_USW: magic = lc->tetra_usw;
1477 x = 1.0; y = 1.0; z = -1.0; break;
1478 case LAMENT_TETRA_DWN: magic = lc->tetra_dwn;
1479 x = 1.0; y = -1.0; z = 1.0; break;
1480 case LAMENT_TETRA_DSE: magic = lc->tetra_dse;
1481 x = -1.0; y = 1.0; z = 1.0; break;
1482 default: abort(); break;
1484 glCallList(lc->tetra_mid);
1485 if (magic != lc->tetra_une) glCallList(lc->tetra_une);
1486 if (magic != lc->tetra_usw) glCallList(lc->tetra_usw);
1487 if (magic != lc->tetra_dwn) glCallList(lc->tetra_dwn);
1488 if (magic != lc->tetra_dse) glCallList(lc->tetra_dse);
1489 glRotatef(lc->anim_r, x, y, z);
1494 case LAMENT_LID_OPEN:
1495 case LAMENT_LID_CLOSE:
1496 case LAMENT_LID_ZOOM:
1500 glTranslatef(lc->anim_z, 0.0, 0.0);
1502 glCallList(lc->lid_0);
1505 glTranslatef(-0.5, -d, 0.0);
1506 glRotatef(-lc->anim_r, 0.0, -1.0, -1.0);
1507 glTranslatef( 0.5, d, 0.0);
1508 glCallList(lc->lid_1);
1511 glTranslatef(-0.5, -d, 0.0);
1512 glRotatef( lc->anim_r, 0.0, -1.0, 1.0);
1513 glTranslatef( 0.5, d, 0.0);
1514 glCallList(lc->lid_2);
1517 glTranslatef(-0.5, d, 0.0);
1518 glRotatef( lc->anim_r, 0.0, -1.0, -1.0);
1519 glTranslatef( 0.5, -d, 0.0);
1520 glCallList(lc->lid_3);
1523 glTranslatef(-0.5, d, 0.0);
1524 glRotatef(-lc->anim_r, 0.0, -1.0, 1.0);
1525 glTranslatef( 0.5, -d, 0.0);
1526 glCallList(lc->lid_4);
1531 case LAMENT_TASER_OUT:
1532 case LAMENT_TASER_SLIDE:
1533 case LAMENT_TASER_SLIDE_IN:
1534 case LAMENT_TASER_IN:
1536 glTranslatef(-lc->anim_z/2, 0.0, 0.0);
1537 glCallList(lc->taser_base);
1539 glTranslatef(lc->anim_z, 0.0, 0.0);
1540 glCallList(lc->taser_lifter);
1542 glTranslatef(0.0, 0.0, lc->anim_y);
1543 glCallList(lc->taser_slider);
1559 animate(ModeInfo *mi)
1561 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1563 /* int pause2 = 60;*/
1570 /* Rather than just picking states randomly, pick an ordering randomly,
1571 do it, and then re-randomize. That way one can be assured of seeing
1572 all states in a short time period, though not always in the same
1573 order (it's frustrating to see it pick the same state 5x in a row.)
1575 static lament_type states[] = {
1576 LAMENT_STAR_OUT, LAMENT_STAR_OUT,
1577 LAMENT_TETRA_UNE, LAMENT_TETRA_USW,
1578 LAMENT_TETRA_DWN, LAMENT_TETRA_DSE,
1579 LAMENT_LID_OPEN, LAMENT_LID_OPEN, LAMENT_LID_OPEN,
1580 LAMENT_TASER_OUT, LAMENT_TASER_OUT,
1581 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1582 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1584 static int state = countof(states);
1586 if (state < countof(states))
1588 lc->type = states[state++];
1594 for (i = 0; i < countof(states); i++)
1596 int a = random() % countof(states);
1597 lament_type swap = states[a];
1598 states[a] = states[i];
1603 if (lc->type == LAMENT_BOX)
1604 lc->anim_pause = pause3;
1612 /* -------------------------------------------------------------- */
1614 case LAMENT_STAR_OUT:
1616 if (lc->anim_z >= 1.0)
1619 lc->type = LAMENT_STAR_ROT;
1620 lc->anim_pause = pause;
1624 case LAMENT_STAR_ROT:
1626 if (lc->anim_r >= 45.0)
1629 lc->type = LAMENT_STAR_ROT_IN;
1630 lc->anim_pause = pause;
1634 case LAMENT_STAR_ROT_IN:
1636 if (lc->anim_z <= 0.0)
1639 lc->type = LAMENT_STAR_ROT_OUT;
1640 lc->anim_pause = pause3 * (1 + (random() % 4) + (random() % 4));
1644 case LAMENT_STAR_ROT_OUT:
1646 if (lc->anim_z >= 1.0)
1649 lc->type = LAMENT_STAR_UNROT;
1650 lc->anim_pause = pause;
1654 case LAMENT_STAR_UNROT:
1656 if (lc->anim_r <= 0.0)
1659 lc->type = LAMENT_STAR_IN;
1660 lc->anim_pause = pause;
1664 case LAMENT_STAR_IN:
1666 if (lc->anim_z <= 0.0)
1669 lc->type = LAMENT_BOX;
1670 lc->anim_pause = pause3;
1674 /* -------------------------------------------------------------- */
1676 case LAMENT_TETRA_UNE:
1677 case LAMENT_TETRA_USW:
1678 case LAMENT_TETRA_DWN:
1679 case LAMENT_TETRA_DSE:
1682 if (lc->anim_r >= 360.0)
1685 lc->type = LAMENT_BOX;
1686 lc->anim_pause = pause3;
1688 else if (lc->anim_r > 119.0 && lc->anim_r <= 120.0)
1691 lc->anim_pause = pause;
1693 else if (lc->anim_r > 239.0 && lc->anim_r <= 240.0)
1696 lc->anim_pause = pause;
1700 /* -------------------------------------------------------------- */
1702 case LAMENT_LID_OPEN:
1705 if (lc->anim_r >= 112.0)
1707 GLfloat hysteresis = 0.05;
1711 lc->anim_pause = pause3;
1713 if (lc->rotx >= -hysteresis &&
1714 lc->rotx <= hysteresis &&
1715 ((lc->rotz >= (0.25 - hysteresis) &&
1716 lc->rotz <= (0.25 + hysteresis)) ||
1717 (lc->rotz >= (-0.25 - hysteresis) &&
1718 lc->rotz <= (-0.25 + hysteresis))))
1720 lc->type = LAMENT_LID_ZOOM;
1722 lc->rotz = (lc->rotz < 0 ? -0.25 : 0.25);
1726 lc->type = LAMENT_LID_CLOSE;
1731 case LAMENT_LID_CLOSE:
1733 if (lc->anim_r <= 0.0)
1736 lc->type = LAMENT_BOX;
1737 lc->anim_pause = pause3;
1741 case LAMENT_LID_ZOOM:
1743 if (lc->anim_z < -50.0)
1747 lc->rotx = frand(1.0) * RANDSIGN();
1748 lc->roty = frand(1.0) * RANDSIGN();
1749 lc->rotz = frand(1.0) * RANDSIGN();
1750 lc->type = LAMENT_BOX;
1754 /* -------------------------------------------------------------- */
1756 case LAMENT_TASER_OUT:
1757 lc->anim_z += 0.0025;
1758 if (lc->anim_z >= 0.25)
1761 lc->type = LAMENT_TASER_SLIDE;
1762 lc->anim_pause = pause * (1 + (random() % 5) + (random() % 5));
1766 case LAMENT_TASER_SLIDE:
1767 lc->anim_y += 0.0025;
1768 if (lc->anim_y >= 0.23)
1771 lc->type = LAMENT_TASER_SLIDE_IN;
1772 lc->anim_pause = pause3 * (1 + (random() % 5) + (random() % 5));
1776 case LAMENT_TASER_SLIDE_IN:
1777 lc->anim_y -= 0.0025;
1778 if (lc->anim_y <= 0.0)
1781 lc->type = LAMENT_TASER_IN;
1782 lc->anim_pause = pause;
1786 case LAMENT_TASER_IN:
1787 lc->anim_z -= 0.0025;
1788 if (lc->anim_z <= 0.0)
1791 lc->type = LAMENT_BOX;
1792 lc->anim_pause = pause3;
1804 rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v)
1810 ppos = -(ppos + *v);
1819 if (ppos < 0) abort();
1820 if (ppos > 1.0) abort();
1821 *pos = (*pos > 0 ? ppos : -ppos);
1826 /* clamp velocity */
1827 if (*v > max_v || *v < -max_v)
1831 /* If it stops, start it going in the other direction. */
1838 /* keep going in the same direction */
1853 /* Alter direction of rotational acceleration randomly. */
1854 if (! (random() % 120))
1857 /* Change acceleration very occasionally. */
1858 if (! (random() % 200))
1862 else if (random() & 1)
1871 /* Window management, etc
1875 reshape(int width, int height)
1877 int target_size = 180;
1878 int win_size = (width > height ? height : width);
1879 GLfloat h = (GLfloat) height / (GLfloat) width;
1881 glViewport(0, 0, (GLint) width, (GLint) height);
1883 /* glViewport(-600, -600, 1800, 1800); */
1885 glMatrixMode(GL_PROJECTION);
1887 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
1888 glMatrixMode(GL_MODELVIEW);
1890 glTranslatef(0.0, 0.0, -40.0);
1892 /* This scale makes the box take up most of the window */
1893 glScalef(2.0, 2.0, 2.0);
1895 /* But if the window is more than a little larger than our target size,
1896 scale the object back down, so that the bits drawn on the screen end
1897 up rougly target_size across (actually it ends up a little larger.)
1898 Note that the image-map bits we have are 128x128. Therefore, if the
1899 image is magnified a lot, it looks pretty blocky. So it's better to
1900 have a 128x128 animation on a 1280x1024 screen that looks good, than
1901 a 1024x1024 animation that looks really pixellated.
1903 if (win_size > target_size * 1.5)
1905 GLfloat ratio = ((GLfloat) target_size / (GLfloat) win_size);
1907 glScalef(ratio, ratio, ratio);
1910 /* The depth buffer will be cleared, if needed, before the
1911 * next frame. Right now we just want to black the screen.
1913 glClear(GL_COLOR_BUFFER_BIT);
1918 gl_init(ModeInfo *mi)
1920 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1921 Bool wire = MI_IS_WIREFRAME(mi);
1928 static GLfloat pos0[] = { -4.0, 2.0, 5.0, 1.0 };
1929 static GLfloat pos1[] = { 12.0, 5.0, 1.0, 1.0 };
1930 static GLfloat local[] = { 0.0 };
1931 static GLfloat ambient[] = { 0.3, 0.3, 0.3, 1.0 };
1932 static GLfloat spec[] = { 1.0, 1.0, 1.0, 1.0 };
1933 static GLfloat shine[] = { 100.0 };
1935 glLightfv(GL_LIGHT0, GL_POSITION, pos0);
1936 glLightfv(GL_LIGHT1, GL_POSITION, pos1);
1938 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
1939 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
1941 glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
1942 glLightfv(GL_LIGHT1, GL_SPECULAR, spec);
1944 glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local);
1945 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1946 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
1947 glMaterialfv(GL_FRONT, GL_SHININESS, shine);
1949 glEnable(GL_LIGHTING);
1950 glEnable(GL_LIGHT0);
1951 glEnable(GL_LIGHT1);
1952 glDisable(GL_LIGHT1);
1954 glEnable(GL_DEPTH_TEST);
1955 glEnable(GL_TEXTURE_2D);
1956 glEnable(GL_NORMALIZE);
1957 glEnable(GL_CULL_FACE);
1962 #ifdef HAVE_GLBINDTEXTURE
1964 for (i = 0; i < 6; i++)
1965 glGenTextures(1, &lc->texids[i]);
1967 parse_image_data(mi);
1969 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1970 glPixelStorei(GL_UNPACK_ROW_LENGTH, lc->texture->width);
1972 for (i = 0; i < 6; i++)
1974 int height = lc->texture->width; /* assume square */
1975 glBindTexture(GL_TEXTURE_2D, lc->texids[i]);
1976 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1979 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
1980 lc->texture->width, height, 0,
1981 GL_RGBA, GL_UNSIGNED_BYTE,
1982 (lc->texture->data +
1983 (lc->texture->bytes_per_line * height * i)));
1984 check_gl_error("texture");
1986 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1987 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1988 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1989 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1990 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1991 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1994 #else /* !HAVE_GLBINDTEXTURE */
1996 "%s: this version of GL doesn't support multiple texture maps.\n"
1997 "\tGet OpenGL 1.1.\n",
2000 #endif /* !HAVE_GLBINDTEXTURE */
2003 lc->box = glGenLists(16);
2004 lc->star1 = lc->box+1;
2005 lc->star2 = lc->box+2;
2006 lc->tetra_une = lc->box+3;
2007 lc->tetra_usw = lc->box+4;
2008 lc->tetra_dwn = lc->box+5;
2009 lc->tetra_dse = lc->box+6;
2010 lc->tetra_mid = lc->box+7;
2011 lc->lid_0 = lc->box+8;
2012 lc->lid_1 = lc->box+9;
2013 lc->lid_2 = lc->box+10;
2014 lc->lid_3 = lc->box+11;
2015 lc->lid_4 = lc->box+12;
2016 lc->taser_base = lc->box+13;
2017 lc->taser_lifter = lc->box+14;
2018 lc->taser_slider = lc->box+15;
2021 star(mi, True, wire);
2022 star(mi, False, wire);
2029 # ifdef HAVE_MESA_GL
2031 # include <signal.h>
2034 lament_signal_kludge (int sig)
2036 signal (sig, SIG_DFL);
2039 "%s: dying with signal %d (%s).\n"
2041 "\tThis is almost certainly a bug in the MesaGL library,\n"
2042 "\tespecially if the stack trace in the core file mentions\n"
2043 "\t`lambda_textured_triangle' or `render_quad'.\n"
2045 "\tI encourage you to report this to the Mesa maintainers\n"
2046 "\tat <http://www.mesa3d.org/>. I reported this bug more\n"
2047 "\tthan a year ago, and it is trivially reproducible.\n"
2048 "\tI do not know a workaround.\n"
2052 (sig == SIGILL ? "SIGILL" :
2053 sig == SIGFPE ? "SIGFPE" :
2054 sig == SIGBUS ? "SIGBUS" :
2055 sig == SIGSEGV ? "SIGSEGV" : "???"));
2057 kill (getpid (), sig);
2061 handle_signals (void)
2063 signal (SIGILL, lament_signal_kludge);
2064 signal (SIGFPE, lament_signal_kludge);
2065 signal (SIGBUS, lament_signal_kludge);
2066 signal (SIGSEGV, lament_signal_kludge);
2068 # endif /* HAVE_MESA_GL */
2072 init_lament(ModeInfo *mi)
2074 lament_configuration *lc;
2077 lcs = (lament_configuration *)
2078 calloc(MI_NUM_SCREENS(mi), sizeof (lament_configuration));
2081 fprintf(stderr, "%s: out of memory\n", progname);
2086 lc = &lcs[MI_SCREEN(mi)];
2088 lc->rotx = frand(1.0) * RANDSIGN();
2089 lc->roty = frand(1.0) * RANDSIGN();
2090 lc->rotz = frand(1.0) * RANDSIGN();
2092 /* bell curve from 0-1.5 degrees, avg 0.75 */
2093 lc->dx = (frand(1) + frand(1) + frand(1)) / (360*2);
2094 lc->dy = (frand(1) + frand(1) + frand(1)) / (360*2);
2095 lc->dz = (frand(1) + frand(1) + frand(1)) / (360*2);
2097 lc->d_max = lc->dx * 2;
2099 lc->ddx = 0.00006 + frand(0.00003);
2100 lc->ddy = 0.00006 + frand(0.00003);
2101 lc->ddz = 0.00006 + frand(0.00003);
2107 lc->type = LAMENT_BOX;
2108 lc->anim_pause = 300 + (random() % 100);
2110 if ((lc->glx_context = init_GL(mi)) != NULL)
2112 reshape(MI_WIDTH(mi), MI_HEIGHT(mi));
2116 # ifdef HAVE_MESA_GL
2118 # endif /* HAVE_MESA_GL */
2123 draw_lament(ModeInfo *mi)
2125 static int tick = 0;
2126 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
2127 Display *dpy = MI_DISPLAY(mi);
2128 Window window = MI_WINDOW(mi);
2130 if (!lc->glx_context)
2133 glDrawBuffer(GL_BACK);
2135 glXMakeCurrent(dpy, window, *(lc->glx_context));
2138 glXSwapBuffers(dpy, window);
2140 if (lc->type != LAMENT_LID_ZOOM)
2142 rotate(&lc->rotx, &lc->dx, &lc->ddx, lc->d_max);
2143 rotate(&lc->roty, &lc->dy, &lc->ddy, lc->d_max);
2144 rotate(&lc->rotz, &lc->dz, &lc->ddz, lc->d_max);
2155 reshape(MI_WIDTH(mi), MI_HEIGHT(mi));