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.70, 0.60, 0.00, 1.00 };
144 static GLfloat interior_color[] = { 0.25, 0.25, 0.20, 1.00 };
148 GLXContext *glx_context;
150 GLuint box; /* display list IDs */
152 GLuint tetra_une, tetra_usw, tetra_dwn, tetra_dse, tetra_mid;
153 GLuint lid_0, lid_1, lid_2, lid_3, lid_4;
154 GLuint taser_base, taser_lifter, taser_slider;
156 GLfloat rotx, roty, rotz; /* current object rotation */
157 GLfloat dx, dy, dz; /* current rotational velocity */
158 GLfloat ddx, ddy, ddz; /* current rotational acceleration */
159 GLfloat d_max; /* max velocity */
160 XImage *texture; /* image bits */
161 GLuint texids[6]; /* texture map IDs */
162 lament_type type; /* which mode of the object is current */
164 int anim_pause; /* countdown before animating again */
165 GLfloat anim_r, anim_y, anim_z; /* relative position during anims */
167 } lament_configuration;
169 static lament_configuration *lcs = NULL;
179 parse_image_data(ModeInfo *mi)
181 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
182 lc->texture = xpm_to_ximage (mi->dpy,
189 /* Computing normal vectors (thanks to Nat Friedman <ndf@mit.edu>)
192 typedef struct vector {
196 typedef struct plane {
201 vector_set(vector *v, GLfloat x, GLfloat y, GLfloat z)
209 vector_cross(vector v1, vector v2, vector *v3)
211 v3->x = (v1.y * v2.z) - (v1.z * v2.y);
212 v3->y = (v1.z * v2.x) - (v1.x * v2.z);
213 v3->z = (v1.x * v2.y) - (v1.y * v2.x);
217 vector_subtract(vector v1, vector v2, vector *res)
219 res->x = v1.x - v2.x;
220 res->y = v1.y - v2.y;
221 res->z = v1.z - v2.z;
225 plane_normal(plane p, vector *n)
228 vector_subtract(p.p1, p.p2, &v1);
229 vector_subtract(p.p1, p.p3, &v2);
230 vector_cross(v2, v1, n);
234 do_normal(GLfloat x1, GLfloat y1, GLfloat z1,
235 GLfloat x2, GLfloat y2, GLfloat z2,
236 GLfloat x3, GLfloat y3, GLfloat z3)
240 vector_set(&plane.p1, x1, y1, z1);
241 vector_set(&plane.p2, x2, y2, z2);
242 vector_set(&plane.p3, x3, y3, z3);
243 plane_normal(plane, &n);
244 n.x = -n.x; n.y = -n.y; n.z = -n.z;
246 glNormal3f(n.x, n.y, n.z);
249 /* Draw a line in the direction of this face's normal. */
251 GLfloat ax = n.x > 0 ? n.x : -n.x;
252 GLfloat ay = n.y > 0 ? n.y : -n.y;
253 GLfloat az = n.z > 0 ? n.z : -n.z;
254 GLfloat mx = (x1 + x2 + x3) / 3;
255 GLfloat my = (y1 + y2 + y3) / 3;
256 GLfloat mz = (z1 + z2 + z3) / 3;
259 GLfloat max = ax > ay ? ax : ay;
260 if (az > max) max = az;
266 glBegin(GL_LINE_LOOP);
267 glVertex3f(mx, my, mz);
268 glVertex3f(mx+xx, my+yy, mz+zz);
276 /* Shorthand utilities for making faces, with proper normals.
280 face3(GLint texture, GLfloat *color, Bool wire,
281 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
282 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
283 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3)
285 #ifdef HAVE_GLBINDTEXTURE
286 glBindTexture(GL_TEXTURE_2D, texture);
287 #endif /* HAVE_GLBINDTEXTURE */
288 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
289 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
290 glBegin(wire ? GL_LINE_LOOP : GL_TRIANGLES);
291 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
292 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
293 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
298 face4(GLint texture, GLfloat *color, Bool wire,
299 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
300 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
301 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3,
302 GLfloat s4, GLfloat t4, GLfloat x4, GLfloat y4, GLfloat z4)
304 #ifdef HAVE_GLBINDTEXTURE
305 glBindTexture(GL_TEXTURE_2D, texture);
306 #endif /* HAVE_GLBINDTEXTURE */
307 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
308 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
309 glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
310 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
311 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
312 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
313 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
318 face5(GLint texture, GLfloat *color, Bool wire,
319 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
320 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
321 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3,
322 GLfloat s4, GLfloat t4, GLfloat x4, GLfloat y4, GLfloat z4,
323 GLfloat s5, GLfloat t5, GLfloat x5, GLfloat y5, GLfloat z5)
325 #ifdef HAVE_GLBINDTEXTURE
326 glBindTexture(GL_TEXTURE_2D, texture);
327 #endif /* HAVE_GLBINDTEXTURE */
328 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
329 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
330 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
331 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
332 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
333 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
334 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
335 glTexCoord2f(s5, t5); glVertex3f(x5, y5, z5);
341 /* Creating object models
345 box(ModeInfo *mi, Bool wire)
347 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
349 glNewList(lc->box, GL_COMPILE);
350 glShadeModel(GL_SMOOTH);
353 face4(lc->texids[FACE_N], exterior_color, wire,
354 0.0, 0.0, -0.5, 0.5, 0.5,
355 1.0, 0.0, 0.5, 0.5, 0.5,
356 1.0, 1.0, 0.5, 0.5, -0.5,
357 0.0, 1.0, -0.5, 0.5, -0.5);
360 face4(lc->texids[FACE_S], exterior_color, wire,
361 0.0, 0.0, -0.5, -0.5, -0.5,
362 1.0, 0.0, 0.5, -0.5, -0.5,
363 1.0, 1.0, 0.5, -0.5, 0.5,
364 0.0, 1.0, -0.5, -0.5, 0.5);
367 face4(lc->texids[FACE_E], exterior_color, wire,
368 0.0, 0.0, 0.5, -0.5, -0.5,
369 1.0, 0.0, 0.5, 0.5, -0.5,
370 1.0, 1.0, 0.5, 0.5, 0.5,
371 0.0, 1.0, 0.5, -0.5, 0.5);
374 face4(lc->texids[FACE_W], exterior_color, wire,
375 1.0, 1.0, -0.5, -0.5, 0.5,
376 0.0, 1.0, -0.5, 0.5, 0.5,
377 0.0, 0.0, -0.5, 0.5, -0.5,
378 1.0, 0.0, -0.5, -0.5, -0.5);
381 face4(lc->texids[FACE_U], exterior_color, wire,
382 1.0, 0.0, 0.5, -0.5, 0.5,
383 1.0, 1.0, 0.5, 0.5, 0.5,
384 0.0, 1.0, -0.5, 0.5, 0.5,
385 0.0, 0.0, -0.5, -0.5, 0.5);
388 face4(lc->texids[FACE_D], exterior_color, wire,
389 0.0, 1.0, -0.5, -0.5, -0.5,
390 0.0, 0.0, -0.5, 0.5, -0.5,
391 1.0, 0.0, 0.5, 0.5, -0.5,
392 1.0, 1.0, 0.5, -0.5, -0.5);
399 star(ModeInfo *mi, Bool top, Bool wire)
401 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
405 { 77, 74 }, { 60, 98 }, { 0, 71 }, { 0, 0 }, /* L1 */
406 { 60, 98 }, { 55, 127 }, { 0, 127 }, { 0, 71 }, /* L2 */
407 { 55, 127 }, { 60, 154 }, { 0, 179 }, { 0, 127 }, /* L3 */
408 { 60, 154 }, { 76, 176 }, { 0, 255 }, { 0, 179 }, /* L4 */
409 { 76, 176 }, { 100, 193 }, { 74, 255 }, { 0, 255 }, /* B1 */
410 { 100, 193 }, { 127, 198 }, { 127, 255 }, { 74, 255 }, /* B2 */
411 { 127, 198 }, { 151, 193 }, { 180, 255 }, { 127, 255 }, /* B3 */
412 { 151, 193 }, { 178, 177 }, { 255, 255 }, { 180, 255 }, /* B4 */
413 { 178, 177 }, { 193, 155 }, { 255, 181 }, { 255, 255 }, /* R4 */
414 { 193, 155 }, { 199, 127 }, { 255, 127 }, { 255, 181 }, /* R3 */
415 { 199, 127 }, { 194, 99 }, { 255, 74 }, { 255, 127 }, /* R2 */
416 { 194, 99 }, { 179, 76 }, { 255, 0 }, { 255, 74 }, /* R1 */
417 { 179, 76 }, { 155, 60 }, { 180, 0 }, { 255, 0 }, /* T4 */
418 { 155, 60 }, { 126, 55 }, { 126, 0 }, { 180, 0 }, /* T3 */
419 { 126, 55 }, { 100, 60 }, { 75, 0 }, { 126, 0 }, /* T2 */
420 { 100, 60 }, { 77, 74 }, { 0, 0 }, { 75, 0 }, /* T1 */
423 for (i = 0; i < countof(points); i++)
424 points[i][1] = 255-points[i][1];
427 glNewList(lc->star1, GL_COMPILE);
429 glNewList(lc->star2, GL_COMPILE);
432 glRotatef(-180.0, 1.0, 0.0, 0.0);
434 for (i = 0; i < countof(points)/4; i += 2)
441 GLfloat s[4], t[4], x[4], y[4], z[4];
442 for (j = 3, k = 0; j >= 0; j--, k++)
444 GLfloat xx = points[(i*4)+j][0] / 255.0L;
445 GLfloat yy = points[(i*4)+j][1] / 255.0L;
452 face4(lc->texids[top ? FACE_U : FACE_D], exterior_color, wire,
453 s[0], t[0], x[0], y[0], z[0],
454 s[1], t[1], x[1], y[1], z[1],
455 s[2], t[2], x[2], y[2], z[2],
456 s[3], t[3], x[3], y[3], z[3]);
460 for (j = 0, k = 0; j < 4; 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 = 3; j >= 0; j--)
480 int k = (j == 0 ? 3 : j-1);
481 Bool front_p = (j == 3);
482 GLfloat x1 = points[(i*4)+j][0] / 255.0L;
483 GLfloat y1 = points[(i*4)+j][1] / 255.0L;
484 GLfloat x2 = points[(i*4)+k][0] / 255.0L;
485 GLfloat y2 = points[(i*4)+k][1] / 255.0L;
487 GLfloat tx1=0.0, tx2=1.0, ty1=0.0, ty2=1.0;
491 facing = (facing + j + 5) % 4;
497 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
498 ty1 = 0.0; ty2 = 1.0;
501 ty1 = 1.0; ty2 = 0.0;
505 texture = top ? FACE_S : FACE_N;
507 ty1 = 0.0; ty2 = 1.0;
513 ty1 = 0.0; ty2 = 1.0;
515 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
516 ty1 = 1.0; ty2 = 0.0;
520 texture = top ? FACE_N : FACE_S;
522 ty1 = 1.0; ty2 = 0.0;
526 x1 -= 0.5; x2 -= 0.5;
527 y1 -= 0.5; y2 -= 0.5;
529 face4(front_p ? lc->texids[texture] : 0,
530 front_p ? exterior_color : interior_color,
532 tx1, ty2, x1, y1, 0.5,
533 tx1, ty1, x1, y1, -0.5,
534 tx2, ty1, x2, y2, -0.5,
535 tx2, ty2, x2, y2, 0.5);
540 /* Central core top cap.
542 #ifdef HAVE_GLBINDTEXTURE
543 glBindTexture(GL_TEXTURE_2D, lc->texids[top ? FACE_U : FACE_D]);
544 #endif /* HAVE_GLBINDTEXTURE */
545 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
548 do_normal(points[i+0][0], points[i+0][1], 0,
549 points[i+4][0], points[i+4][1], 0,
550 points[i+8][0], points[i+8][1], 0);
551 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
552 for (i = 1; i < countof(points); i += 4)
554 GLfloat x = points[i][0] / 255.0L;
555 GLfloat y = points[i][1] / 255.0L;
557 glVertex3f(x-0.5, y-0.5, 0.5);
562 /* Central core bottom cap.
564 #ifdef HAVE_GLBINDTEXTURE
565 glBindTexture(GL_TEXTURE_2D, 0);
566 #endif /* HAVE_GLBINDTEXTURE */
567 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color);
569 i = countof(points) - 9;
570 do_normal(points[i+0][0], points[i+0][1], 0,
571 points[i+4][0], points[i+4][1], 0,
572 points[i+8][0], points[i+8][1], 0);
574 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
575 for (i = countof(points) - 3; i >= 0; i -= 4)
577 GLfloat x = points[i][0] / 255.0L;
578 GLfloat y = points[i][1] / 255.0L;
579 glVertex3f(x-0.5, y-0.5, 0);
584 /* Central core walls.
586 for (i = 1; i < countof(points); i += 4)
589 GLfloat x1 = points[i-1][0] / 255.0L;
590 GLfloat y1 = points[i-1][1] / 255.0L;
591 GLfloat x2 = points[i][0] / 255.0L;
592 GLfloat y2 = points[i][1] / 255.0L;
593 face4(0, interior_color, wire,
594 0.0, 0.0, x1-0.5, y1-0.5, 0.5,
595 0.0, 0.0, x1-0.5, y1-0.5, 0.0,
596 0.0, 0.0, x2-0.5, y2-0.5, 0.0,
597 0.0, 0.0, x2-0.5, y2-0.5, 0.5);
605 tetra(ModeInfo *mi, Bool wire)
607 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
609 glNewList(lc->tetra_une, GL_COMPILE);
611 glShadeModel(GL_SMOOTH);
614 face3(lc->texids[FACE_U], exterior_color, wire,
615 1.0, 0.0, 0.5, -0.5, 0.5,
616 1.0, 1.0, 0.5, 0.5, 0.5,
617 0.0, 1.0, -0.5, 0.5, 0.5);
620 face3(lc->texids[FACE_N], exterior_color, wire,
621 0.0, 0.0, -0.5, 0.5, 0.5,
622 1.0, 0.0, 0.5, 0.5, 0.5,
623 1.0, 1.0, 0.5, 0.5, -0.5);
626 face3(lc->texids[FACE_E], exterior_color, wire,
627 1.0, 0.0, 0.5, 0.5, -0.5,
628 1.0, 1.0, 0.5, 0.5, 0.5,
629 0.0, 1.0, 0.5, -0.5, 0.5);
631 face3(0, interior_color, wire,
632 0.0, 0.0, 0.5, 0.5, -0.5,
633 0.0, 0.0, 0.5, -0.5, 0.5,
634 0.0, 0.0, -0.5, 0.5, 0.5);
638 glNewList(lc->tetra_usw, GL_COMPILE);
641 face3(lc->texids[FACE_U], exterior_color, wire,
642 0.0, 1.0, -0.5, 0.5, 0.5,
643 0.0, 0.0, -0.5, -0.5, 0.5,
644 1.0, 0.0, 0.5, -0.5, 0.5);
647 face3(lc->texids[FACE_S], exterior_color, wire,
648 1.0, 1.0, 0.5, -0.5, 0.5,
649 0.0, 1.0, -0.5, -0.5, 0.5,
650 0.0, 0.0, -0.5, -0.5, -0.5);
653 face3(lc->texids[FACE_W], exterior_color, wire,
654 1.0, 0.0, -0.5, -0.5, -0.5,
655 1.0, 1.0, -0.5, -0.5, 0.5,
656 0.0, 1.0, -0.5, 0.5, 0.5);
658 face3(0, interior_color, wire,
659 0.0,0.0, -0.5, -0.5, -0.5,
660 0.0,0.0, -0.5, 0.5, 0.5,
661 0.0,0.0, 0.5, -0.5, 0.5);
665 glNewList(lc->tetra_dwn, GL_COMPILE);
668 face3(lc->texids[FACE_D], exterior_color, wire,
669 0.0, 1.0, -0.5, -0.5, -0.5,
670 0.0, 0.0, -0.5, 0.5, -0.5,
671 1.0, 0.0, 0.5, 0.5, -0.5);
674 face3(lc->texids[FACE_W], exterior_color, wire,
675 0.0, 1.0, -0.5, 0.5, 0.5,
676 0.0, 0.0, -0.5, 0.5, -0.5,
677 1.0, 0.0, -0.5, -0.5, -0.5);
680 face3(lc->texids[FACE_N], exterior_color, wire,
681 1.0, 1.0, 0.5, 0.5, -0.5,
682 0.0, 1.0, -0.5, 0.5, -0.5,
683 0.0, 0.0, -0.5, 0.5, 0.5);
685 face3(0, interior_color, wire,
686 0.0, 0.0, 0.5, 0.5, -0.5,
687 0.0, 0.0, -0.5, 0.5, 0.5,
688 0.0, 0.0, -0.5, -0.5, -0.5);
692 glNewList(lc->tetra_dse, GL_COMPILE);
695 face3(lc->texids[FACE_S], exterior_color, wire,
696 0.0, 0.0, -0.5, -0.5, -0.5,
697 1.0, 0.0, 0.5, -0.5, -0.5,
698 1.0, 1.0, 0.5, -0.5, 0.5);
701 face3(lc->texids[FACE_E], exterior_color, wire,
702 0.0, 1.0, 0.5, -0.5, 0.5,
703 0.0, 0.0, 0.5, -0.5, -0.5,
704 1.0, 0.0, 0.5, 0.5, -0.5);
707 face3(lc->texids[FACE_D], exterior_color, wire,
708 1.0, 0.0, 0.5, 0.5, -0.5,
709 1.0, 1.0, 0.5, -0.5, -0.5,
710 0.0, 1.0, -0.5, -0.5, -0.5);
712 face3(0, interior_color, wire,
713 0.0, 0.0, 0.5, -0.5, 0.5,
714 0.0, 0.0, 0.5, 0.5, -0.5,
715 0.0, 0.0, -0.5, -0.5, -0.5);
719 glNewList(lc->tetra_mid, GL_COMPILE);
721 face3(0, interior_color, wire,
722 0.0, 0.0, 0.5, -0.5, 0.5,
723 0.0, 0.0, 0.5, 0.5, -0.5,
724 0.0, 0.0, -0.5, 0.5, 0.5);
726 face3(0, interior_color, wire,
727 0.0, 0.0, -0.5, 0.5, 0.5,
728 0.0, 0.0, -0.5, -0.5, -0.5,
729 0.0, 0.0, 0.5, -0.5, 0.5);
731 face3(0, interior_color, wire,
732 0.0, 0.0, -0.5, 0.5, 0.5,
733 0.0, 0.0, 0.5, 0.5, -0.5,
734 0.0, 0.0, -0.5, -0.5, -0.5);
736 face3(0, interior_color, wire,
737 0.0, 0.0, 0.5, 0.5, -0.5,
738 0.0, 0.0, 0.5, -0.5, 0.5,
739 0.0, 0.0, -0.5, -0.5, -0.5);
741 face3(0, interior_color, wire,
742 0.0, 0.0, 0.5, -0.5, 0.5,
743 0.0, 0.0, 0.5, 0.5, -0.5,
744 0.0, 0.0, -0.5, -0.5, -0.5);
751 lid(ModeInfo *mi, Bool wire)
753 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
757 { 128, 20 },{ 21, 129 },{ 0, 129 },{ 0, 0 },{ 128, 0 }, /* L1 */
758 { 21, 129 },{ 127, 234 },{ 127, 255 },{ 0, 255 },{ 0, 129 }, /* L2 */
759 { 127, 234 },{ 233, 127 },{ 255, 127 },{ 255, 255 },{ 127, 255 }, /* R2 */
760 { 233, 127 },{ 128, 20 },{ 128, 0 },{ 255, 0 },{ 255, 127 }, /* R1 */
763 for (i = 0; i < countof(points); i++)
764 points[i][1] = 255-points[i][1];
766 glNewList(lc->lid_0, GL_COMPILE);
767 glShadeModel(GL_SMOOTH);
770 face4(lc->texids[FACE_N], exterior_color, wire,
771 0.0, 0.0, -0.5, 0.5, 0.5,
772 1.0, 0.0, 0.5, 0.5, 0.5,
773 1.0, 1.0, 0.5, 0.5, -0.5,
774 0.0, 1.0, -0.5, 0.5, -0.5);
777 face4(lc->texids[FACE_S], exterior_color, wire,
778 0.0, 0.0, -0.5, -0.5, -0.5,
779 1.0, 0.0, 0.5, -0.5, -0.5,
780 1.0, 1.0, 0.5, -0.5, 0.5,
781 0.0, 1.0, -0.5, -0.5, 0.5);
784 face4(lc->texids[FACE_E], exterior_color, wire,
785 0.0, 0.0, 0.5, -0.5, -0.5,
786 1.0, 0.0, 0.5, 0.5, -0.5,
787 1.0, 1.0, 0.5, 0.5, 0.5,
788 0.0, 1.0, 0.5, -0.5, 0.5);
791 face4(lc->texids[FACE_U], exterior_color, wire,
792 1.0, 0.0, 0.5, -0.5, 0.5,
793 1.0, 1.0, 0.5, 0.5, 0.5,
794 0.0, 1.0, -0.5, 0.5, 0.5,
795 0.0, 0.0, -0.5, -0.5, 0.5);
798 face4(lc->texids[FACE_D], exterior_color, wire,
799 0.0, 1.0, -0.5, -0.5, -0.5,
800 0.0, 0.0, -0.5, 0.5, -0.5,
801 1.0, 0.0, 0.5, 0.5, -0.5,
802 1.0, 1.0, 0.5, -0.5, -0.5);
805 for (i = 0; i < countof(points)/5; i++)
808 GLfloat s[5], t[5], x[5], y[5], z[5];
809 for (j = 0; j < 5; j++)
811 GLfloat xx = points[(i*5)+j][0] / 255.0L;
812 GLfloat yy = points[(i*5)+j][1] / 255.0L;
819 face5(lc->texids[FACE_W], exterior_color, wire,
820 s[0], t[0], x[0], y[0], z[0],
821 s[1], t[1], x[1], y[1], z[1],
822 s[2], t[2], x[2], y[2], z[2],
823 s[3], t[3], x[3], y[3], z[3],
824 s[4], t[4], x[4], y[4], z[4]);
829 /* W -- lid_1 through lid_4 */
830 for (i = 0; i < 4; i++)
832 GLfloat x1, y1, x2, y2, x3, y3;
834 glNewList(lc->lid_1 + i, GL_COMPILE);
835 glShadeModel(GL_SMOOTH);
837 x1 = points[(i*5)+1][0] / 255.0L;
838 y1 = points[(i*5)+1][1] / 255.0L;
839 x2 = points[(i*5)][0] / 255.0L;
840 y2 = points[(i*5)][1] / 255.0L;
845 face3(lc->texids[FACE_W], exterior_color, wire,
846 1.0-x1, y1, -0.5, x1-0.5, y1-0.5,
847 1.0-x2, y2, -0.5, x2-0.5, y2-0.5,
848 1.0-x3, y3, -0.5, x3-0.5, y3-0.5);
851 face3(0, interior_color, wire,
852 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
853 0.0, 0.0, -0.48, x1-0.5, y1-0.5,
854 0.0, 0.0, -0.48, x3-0.5, y3-0.5);
857 face4(0, interior_color, wire,
858 0.0, 0.0, -0.5, x1-0.5, y1-0.5,
859 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
860 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
861 0.0, 0.0, -0.48, x1-0.5, y1-0.5);
864 face4(0, interior_color, wire,
865 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
866 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
867 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
868 0.0, 0.0, -0.5, x2-0.5, y2-0.5);
875 taser(ModeInfo *mi, Bool wire)
877 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
880 int slider_face_points[][2] = {
881 { 86, 58 },{ 38, 106 },{ 70, 106 },{ 118, 58 },{ -1, -1 }, /* a */
882 { 136, 58 },{ 184, 106 },{ 216, 106 },{ 168, 58 },{ -1, -1 }, /* b */
883 { 38, 106 },{ 0, 144 },{ 0, 190 },{ 60, 190 },{ 108, 106 }, /* c */
884 { 144, 106 },{ 194, 190 },{ 254, 190 },{ 254, 144 },{ 216, 106 }, /* d */
885 { 98, 124 },{ 60, 190 },{ 92, 190 },{ 126, 158 },{ 126, 124 }, /* e */
886 { 126, 124 },{ 126, 158 },{ 160, 190 },{ 194, 190 },{ 154, 124 }, /* f */
887 { 22, 190 },{ 22, 254 },{ 60, 254 },{ 60, 190 },{ -1, -1 }, /* g */
888 { 194, 190 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ -1, -1 }, /* h */
889 { 60, 190 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ -1, -1 }, /* i */
890 { 160, 190 },{ 160, 210 },{ 194, 210 },{ 194, 190 },{ -1, -1 }, /* j */
891 { 110, 172 },{ 92, 190 },{ 110, 190 },{ -1, -1 },{ -1, -1 }, /* k */
892 { 140, 172 },{ 140, 190 },{ 160, 190 },{ -1, -1 },{ -1, -1 }, /* l */
893 { 110, 172 },{ 140, 172 },{ 126, 156 },{ -1, -1 },{ -1, -1 }, /* m */
896 int body_face_points[][2] = {
897 { 0, 0 },{ 0, 58 },{ 254, 58 },{ 254, 0 },{ -1, -1 }, /* A */
898 { 0, 58 },{ 0, 144 },{ 86, 58 },{ -1, -1 },{ -1, -1 }, /* B */
899 { 168, 58 },{ 254, 144 },{ 254, 58 },{ -1, -1 },{ -1, -1 }, /* C */
900 { 118, 58 },{ 70, 106 },{ 184, 106 },{ 136, 58 },{ -1, -1 }, /* F */
901 { 108, 106 },{ 98, 124 },{ 154, 124 },{ 144, 106 },{ -1, -1 }, /* G */
904 int lifter_face_points[][2] = {
905 { 0, 190 },{ 0, 254 },{ 22, 254 },{ 22, 190 },{ -1, -1 }, /* D */
906 { 230, 190 },{ 230, 254 },{ 254, 254 },{ 254, 190 },{ -1, -1 }, /* E */
907 { 60, 210 },{ 60, 254 },{ 194, 254 },{ 194, 210 },{ -1, -1 }, /* H */
908 { 92, 190 },{ 92, 210 },{ 160, 210 },{ 160, 190 },{ -1, -1 }, /* I */
909 { 110, 172 },{ 110, 190 },{ 140, 190 },{ 140, 172 },{ -1, -1 }, /* J */
912 int body_perimiter_points[][2] = {
913 { 0, 144 },{ 86, 59 },{ 119, 58 },{ 71, 107 },
914 { 108, 107 },{ 98, 124 },{ 155, 124 },{ 144, 107 },
915 { 185, 106 },{ 136, 59 },{ 169, 59 },{ 255, 145 },
919 int slider_perimiter_points[][2] = {
920 { 86, 58 },{ 0, 144 },{ 0, 190 },{ 22, 190 },{ 22, 254 },
921 { 60, 254 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ 110, 190 },
922 { 110, 172 },{ 140, 172 },{ 140, 190 },{ 160, 190 },{ 160, 210 },
923 { 194, 210 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ 254, 190 },
924 { 254, 144 },{ 168, 58 },{ 136, 58 },{ 184, 106 },{ 144, 106 },
925 { 154, 124 },{ 98, 124 },{ 108, 106 },{ 70, 106 },{ 118, 58 },
928 int lifter_perimiter_points_1[][2] = {
929 { 0, 189 },{ 0, 254 },{ 22, 255 },{ 23, 190 },
932 int lifter_perimiter_points_2[][2] = {
933 { 230, 254 },{ 255, 255 },{ 254, 190 },{ 230, 190 },
936 int lifter_perimiter_points_3[][2] = {
937 { 60, 254 },{ 194, 254 },{ 194, 211 },{ 160, 210 },
938 { 160, 190 },{ 140, 191 },{ 141, 172 },{ 111, 172 },
939 { 110, 190 },{ 93, 190 },{ 92, 210 },{ 60, 211 },
942 for (i = 0; i < countof(slider_face_points); i++)
943 slider_face_points[i][1] = 255-slider_face_points[i][1];
944 for (i = 0; i < countof(body_face_points); i++)
945 body_face_points[i][1] = 255-body_face_points[i][1];
946 for (i = 0; i < countof(lifter_face_points); i++)
947 lifter_face_points[i][1] = 255-lifter_face_points[i][1];
948 for (i = 0; i < countof(body_perimiter_points); i++)
949 body_perimiter_points[i][1] = 255-body_perimiter_points[i][1];
950 for (i = 0; i < countof(slider_perimiter_points); i++)
951 slider_perimiter_points[i][1] = 255-slider_perimiter_points[i][1];
952 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
953 lifter_perimiter_points_1[i][1] = 255-lifter_perimiter_points_1[i][1];
954 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
955 lifter_perimiter_points_2[i][1] = 255-lifter_perimiter_points_2[i][1];
956 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
957 lifter_perimiter_points_3[i][1] = 255-lifter_perimiter_points_3[i][1];
959 /* -------------------------------------------------------------------- */
961 glNewList(lc->taser_base, GL_COMPILE);
962 glShadeModel(GL_SMOOTH);
965 face4(lc->texids[FACE_N], exterior_color, wire,
966 0.0, 0.0, -0.5, 0.5, 0.5,
967 0.75, 0.0, 0.25, 0.5, 0.5,
968 0.75, 0.75, 0.25, 0.5, -0.25,
969 0.0, 0.75, -0.5, 0.5, -0.25);
972 face4(lc->texids[FACE_S], exterior_color, wire,
973 0.0, 0.25, -0.5, -0.5, -0.25,
974 0.75, 0.25, 0.25, -0.5, -0.25,
975 0.75, 1.0, 0.25, -0.5, 0.5,
976 0.0, 1.0, -0.5, -0.5, 0.5);
979 face4(0, interior_color, wire,
980 0.0, 0.0, 0.25, -0.5, -0.25,
981 1.0, 0.0, 0.25, 0.5, -0.25,
982 1.0, 1.0, 0.25, 0.5, 0.5,
983 0.0, 1.0, 0.25, -0.5, 0.5);
986 face4(lc->texids[FACE_W], exterior_color, wire,
987 1.0, 1.0, -0.5, -0.5, 0.5,
988 0.0, 1.0, -0.5, 0.5, 0.5,
989 0.0, 0.25, -0.5, 0.5, -0.25,
990 1.0, 0.25, -0.5, -0.5, -0.25);
993 face4(lc->texids[FACE_U], exterior_color, wire,
994 0.75, 0.0, 0.25, -0.5, 0.5,
995 0.75, 1.0, 0.25, 0.5, 0.5,
996 0.0, 1.0, -0.5, 0.5, 0.5,
997 0.0, 0.0, -0.5, -0.5, 0.5);
1000 face4(0, interior_color, wire,
1001 0.0, 1.0, -0.5, -0.5, -0.25,
1002 0.0, 0.0, -0.5, 0.5, -0.25,
1003 1.0, 0.0, 0.25, 0.5, -0.25,
1004 1.0, 1.0, 0.25, -0.5, -0.25);
1007 for (i = 0; i < countof(body_face_points)/5; i++)
1010 #ifdef HAVE_GLBINDTEXTURE
1011 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1012 #endif /* HAVE_GLBINDTEXTURE */
1013 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1015 do_normal(0, body_face_points[(i*5)+0][0], body_face_points[(i*5)+0][1],
1016 0, body_face_points[(i*5)+1][0], body_face_points[(i*5)+1][1],
1017 0, body_face_points[(i*5)+2][0], body_face_points[(i*5)+2][1]
1019 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1020 for (j = 0; j < 5; j++)
1022 int ix = body_face_points[(i*5)+j][0];
1023 int iy = body_face_points[(i*5)+j][1];
1025 if (ix == -1) /* these are padding: ignore them */
1030 glVertex3f(0.5, x-0.5, y-0.5);
1036 for (i = 0; i < countof(body_perimiter_points); i++)
1038 int j = (i+1 >= countof(body_perimiter_points) ? 0 : i+1);
1039 GLfloat x1 = body_perimiter_points[i][0] / 255.0;
1040 GLfloat y1 = body_perimiter_points[i][1] / 255.0;
1041 GLfloat x2 = body_perimiter_points[j][0] / 255.0;
1042 GLfloat y2 = body_perimiter_points[j][1] / 255.0;
1044 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1048 texture = lc->texids[FACE_N];
1050 s2 = 1.0; t2 = 0.568;
1051 s3 = 0.75, t3 = 0.568;
1052 s4 = 0.75; t4 = 0.0;
1056 texture = lc->texids[FACE_U];
1059 s3 = 0.75, t3 = 1.0;
1060 s4 = 0.75; t4 = 0.0;
1064 texture = lc->texids[FACE_S];
1065 s1 = 1.0; t1 = 0.437;
1067 s3 = 0.75; t3 = 1.0;
1068 s4 = 0.75; t4 = 0.437;
1071 face4((texture == -1 ? 0 : texture),
1072 (texture == -1 ? interior_color : exterior_color),
1074 s1, t1, 0.5, x2-0.5, y2-0.5,
1075 s2, t2, 0.5, x1-0.5, y1-0.5,
1076 s3, t3, 0.25, x1-0.5, y1-0.5,
1077 s4, t4, 0.25, x2-0.5, y2-0.5);
1082 /* -------------------------------------------------------------------- */
1084 glNewList(lc->taser_lifter, GL_COMPILE);
1085 glShadeModel(GL_SMOOTH);
1088 face4(lc->texids[FACE_N], exterior_color, wire,
1089 0.0, 0.75, -0.5, 0.5, -0.25,
1090 0.75, 0.75, 0.25, 0.5, -0.25,
1091 0.75, 1.0, 0.25, 0.5, -0.5,
1092 0.0, 1.0, -0.5, 0.5, -0.5);
1095 face4(lc->texids[FACE_S], exterior_color, wire,
1096 0.0, 0.0, -0.5, -0.5, -0.5,
1097 0.75, 0.0, 0.25, -0.5, -0.5,
1098 0.75, 0.25, 0.25, -0.5, -0.25,
1099 0.0, 0.25, -0.5, -0.5, -0.25);
1102 face4(0, interior_color, wire,
1103 0.0, 1.0, 0.25, -0.5, -0.5,
1104 1.0, 1.0, 0.25, 0.5, -0.5,
1105 1.0, 0.0, 0.25, 0.5, -0.25,
1106 0.0, 0.0, 0.25, -0.5, -0.25);
1109 face4(lc->texids[FACE_W], exterior_color, wire,
1110 1.0, 0.25, -0.5, -0.5, -0.25,
1111 0.0, 0.25, -0.5, 0.5, -0.25,
1112 0.0, 0.0, -0.5, 0.5, -0.5,
1113 1.0, 0.0, -0.5, -0.5, -0.5);
1116 face4(0, interior_color, wire,
1117 1.0, 0.0, 0.25, -0.5, -0.25,
1118 1.0, 1.0, 0.25, 0.5, -0.25,
1119 0.0, 1.0, -0.5, 0.5, -0.25,
1120 0.0, 0.0, -0.5, -0.5, -0.25);
1123 face4(lc->texids[FACE_D], exterior_color, wire,
1124 0.0, 1.0, -0.5, -0.5, -0.5,
1125 0.0, 0.0, -0.5, 0.5, -0.5,
1126 0.75, 0.0, 0.25, 0.5, -0.5,
1127 0.75, 1.0, 0.25, -0.5, -0.5);
1131 for (i = 0; i < countof(lifter_face_points)/5; i++)
1135 #ifdef HAVE_GLBINDTEXTURE
1136 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1137 #endif /* HAVE_GLBINDTEXTURE */
1138 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1141 0, lifter_face_points[(i*5)+0][0], lifter_face_points[(i*5)+0][1],
1142 0, lifter_face_points[(i*5)+1][0], lifter_face_points[(i*5)+1][1],
1143 0, lifter_face_points[(i*5)+2][0], lifter_face_points[(i*5)+2][1]);
1145 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1146 for (j = 0; j < 5; j++)
1148 int ix = lifter_face_points[(i*5)+j][0];
1149 int iy = lifter_face_points[(i*5)+j][1];
1151 if (ix == -1) /* these are padding: ignore them */
1156 glVertex3f(0.5, x-0.5, y-0.5);
1162 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
1164 int j = (i+1 >= countof(lifter_perimiter_points_1) ? 0 : i+1);
1165 GLfloat x1 = lifter_perimiter_points_1[i][0] / 255.0;
1166 GLfloat y1 = lifter_perimiter_points_1[i][1] / 255.0;
1167 GLfloat x2 = lifter_perimiter_points_1[j][0] / 255.0;
1168 GLfloat y2 = lifter_perimiter_points_1[j][1] / 255.0;
1170 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1174 texture = lc->texids[FACE_S];
1176 s2 = 1.0; t2 = 0.26;
1177 s3 = 0.75, t3 = 0.26;
1178 s4 = 0.75; t4 = 0.0;
1182 texture = lc->texids[FACE_D];
1183 s1 = 1.0; t1 = 0.914;
1185 s3 = 0.75; t3 = 1.0;
1186 s4 = 0.75; t4 = 0.914;
1189 face4((texture == -1 ? 0 : texture),
1190 (texture == -1 ? interior_color : exterior_color),
1192 s1, t1, 0.5, x2-0.5, y2-0.5,
1193 s2, t2, 0.5, x1-0.5, y1-0.5,
1194 s3, t3, 0.25, x1-0.5, y1-0.5,
1195 s4, t4, 0.25, x2-0.5, y2-0.5);
1198 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
1200 int j = (i+1 >= countof(lifter_perimiter_points_2) ? 0 : i+1);
1201 GLfloat x1 = lifter_perimiter_points_2[i][0] / 255.0;
1202 GLfloat y1 = lifter_perimiter_points_2[i][1] / 255.0;
1203 GLfloat x2 = lifter_perimiter_points_2[j][0] / 255.0;
1204 GLfloat y2 = lifter_perimiter_points_2[j][1] / 255.0;
1206 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1210 texture = lc->texids[FACE_D];
1212 s2 = 1.0; t2 = 0.095;
1213 s3 = 0.75; t3 = 0.095;
1214 s4 = 0.75; t4 = 0.0;
1218 texture = lc->texids[FACE_N];
1219 s1 = 1.0; t1 = 0.745;
1221 s3 = 0.75; t3 = 1.0;
1222 s4 = 0.75; t4 = 0.745;
1225 face4((texture == -1 ? 0 : texture),
1226 (texture == -1 ? interior_color : exterior_color),
1228 s1, t1, 0.5, x2-0.5, y2-0.5,
1229 s2, t2, 0.5, x1-0.5, y1-0.5,
1230 s3, t3, 0.25, x1-0.5, y1-0.5,
1231 s4, t4, 0.25, x2-0.5, y2-0.5);
1234 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
1236 int j = (i+1 >= countof(lifter_perimiter_points_3) ? 0 : i+1);
1237 GLfloat x1 = lifter_perimiter_points_3[i][0] / 255.0;
1238 GLfloat y1 = lifter_perimiter_points_3[i][1] / 255.0;
1239 GLfloat x2 = lifter_perimiter_points_3[j][0] / 255.0;
1240 GLfloat y2 = lifter_perimiter_points_3[j][1] / 255.0;
1242 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1246 texture = lc->texids[FACE_D];
1247 s1 = 1.0; t1 = 0.235;
1248 s2 = 1.0; t2 = 0.765;
1249 s3 = 0.75; t3 = 0.765;
1250 s4 = 0.75; t4 = 0.235;
1253 face4((texture == -1 ? 0 : texture),
1254 (texture == -1 ? interior_color : exterior_color),
1256 s1, t1, 0.5, x2-0.5, y2-0.5,
1257 s2, t2, 0.5, x1-0.5, y1-0.5,
1258 s3, t3, 0.25, x1-0.5, y1-0.5,
1259 s4, t4, 0.25, x2-0.5, y2-0.5);
1264 /* -------------------------------------------------------------------- */
1266 glNewList(lc->taser_slider, GL_COMPILE);
1267 glShadeModel(GL_SMOOTH);
1270 for (i = 0; i < countof(slider_face_points)/5; i++)
1273 #ifdef HAVE_GLBINDTEXTURE
1274 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1275 #endif /* HAVE_GLBINDTEXTURE */
1276 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1279 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1],
1280 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1281 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1]);
1282 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1283 for (j = 0; j < 5; j++)
1285 int ix = slider_face_points[(i*5)+j][0];
1286 int iy = slider_face_points[(i*5)+j][1];
1288 if (ix == -1) /* these are padding: ignore them */
1293 glVertex3f(0.5, x-0.5, y-0.5);
1299 for (i = countof(slider_face_points)/5 - 1; i >= 0; i--)
1302 #ifdef HAVE_GLBINDTEXTURE
1303 glBindTexture(GL_TEXTURE_2D, 0);
1304 #endif /* HAVE_GLBINDTEXTURE */
1305 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color);
1308 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1],
1309 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1310 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1]);
1311 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1312 for (j = 4; j >= 0; j--)
1314 int ix = slider_face_points[(i*5)+j][0];
1315 int iy = slider_face_points[(i*5)+j][1];
1317 if (ix == -1) /* these are padding: ignore them */
1322 glVertex3f(0.25, x-0.5, y-0.5);
1328 for (i = 0; i < countof(slider_perimiter_points); i++)
1330 int j = (i+1 >= countof(slider_perimiter_points) ? 0 : i+1);
1331 GLfloat x1 = slider_perimiter_points[i][0] / 255.0;
1332 GLfloat y1 = slider_perimiter_points[i][1] / 255.0;
1333 GLfloat x2 = slider_perimiter_points[j][0] / 255.0;
1334 GLfloat y2 = slider_perimiter_points[j][1] / 255.0;
1336 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1340 texture = lc->texids[FACE_S];
1341 s1 = 1.0; t1 = 0.255;
1342 s2 = 1.0; t2 = 0.435;
1343 s3 = 0.75; t3 = 0.435;
1344 s4 = 0.75; t4 = 0.255;
1348 texture = lc->texids[FACE_D];
1349 s1 = 1.0; t1 = 0.758;
1350 s2 = 1.0; t2 = 0.915;
1351 s3 = 0.75; t3 = 0.915;
1352 s4 = 0.75; t4 = 0.758;
1356 texture = lc->texids[FACE_D];
1357 s1 = 1.0; t1 = 0.095;
1358 s2 = 1.0; t2 = 0.24;
1359 s3 = 0.75; t3 = 0.24;
1360 s4 = 0.75; t4 = 0.095;
1364 texture = lc->texids[FACE_N];
1365 s1 = 1.0; t1 = 0.568;
1366 s2 = 1.0; t2 = 0.742;
1367 s3 = 0.75; t3 = 0.742;
1368 s4 = 0.75; t4 = 0.568;
1371 face4((texture == -1 ? 0 : texture),
1372 (texture == -1 ? interior_color : exterior_color),
1374 s1, t1, 0.5, x2-0.5, y2-0.5,
1375 s2, t2, 0.5, x1-0.5, y1-0.5,
1376 s3, t3, 0.25, x1-0.5, y1-0.5,
1377 s4, t4, 0.25, x2-0.5, y2-0.5);
1385 /* Rendering and animating object models
1391 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1392 Bool wire = MI_IS_WIREFRAME(mi);
1395 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1397 glClear(GL_COLOR_BUFFER_BIT);
1401 GLfloat x = lc->rotx;
1402 GLfloat y = lc->roty;
1403 GLfloat z = lc->rotz;
1409 if (x < 0) x = 1 - (x + 1);
1410 if (y < 0) y = 1 - (y + 1);
1411 if (z < 0) z = 1 - (z + 1);
1413 /* Make into the screen be +Y right be +X, and up be +Z. */
1414 glRotatef(-90.0, 1.0, 0.0, 0.0);
1417 glScalef(4.0, 4.0, 4.0);
1422 /* Shift to the upper left, and draw the vanilla box. */
1423 glTranslatef(-0.6, 0.0, 0.6);
1425 /* Apply rotation to the object. */
1426 glRotatef(x * 360, 1.0, 0.0, 0.0);
1427 glRotatef(y * 360, 0.0, 1.0, 0.0);
1428 glRotatef(z * 360, 0.0, 0.0, 1.0);
1431 glCallList(lc->box);
1435 /* Shift to the lower right, and draw the animated object. */
1436 glTranslatef(0.6, 0.0, -0.6);
1442 /* Apply rotation to the object. */
1443 glRotatef(x * 360, 1.0, 0.0, 0.0);
1444 glRotatef(y * 360, 0.0, 1.0, 0.0);
1445 glRotatef(z * 360, 0.0, 0.0, 1.0);
1450 glCallList(lc->box);
1453 case LAMENT_STAR_OUT:
1454 case LAMENT_STAR_ROT:
1455 case LAMENT_STAR_ROT_IN:
1456 case LAMENT_STAR_ROT_OUT:
1457 case LAMENT_STAR_UNROT:
1458 case LAMENT_STAR_IN:
1459 glTranslatef(0.0, 0.0, lc->anim_z/2);
1460 glRotatef(lc->anim_r/2, 0.0, 0.0, 1.0);
1461 glCallList(lc->star1);
1463 glTranslatef(0.0, 0.0, -lc->anim_z);
1464 glRotatef(-lc->anim_r, 0.0, 0.0, 1.0);
1465 glCallList(lc->star2);
1468 case LAMENT_TETRA_UNE:
1469 case LAMENT_TETRA_USW:
1470 case LAMENT_TETRA_DWN:
1471 case LAMENT_TETRA_DSE:
1476 case LAMENT_TETRA_UNE: magic = lc->tetra_une;
1477 x = 1.0; y = 1.0; z = 1.0; break;
1478 case LAMENT_TETRA_USW: magic = lc->tetra_usw;
1479 x = 1.0; y = 1.0; z = -1.0; break;
1480 case LAMENT_TETRA_DWN: magic = lc->tetra_dwn;
1481 x = 1.0; y = -1.0; z = 1.0; break;
1482 case LAMENT_TETRA_DSE: magic = lc->tetra_dse;
1483 x = -1.0; y = 1.0; z = 1.0; break;
1484 default: abort(); break;
1486 glCallList(lc->tetra_mid);
1487 if (magic != lc->tetra_une) glCallList(lc->tetra_une);
1488 if (magic != lc->tetra_usw) glCallList(lc->tetra_usw);
1489 if (magic != lc->tetra_dwn) glCallList(lc->tetra_dwn);
1490 if (magic != lc->tetra_dse) glCallList(lc->tetra_dse);
1491 glRotatef(lc->anim_r, x, y, z);
1496 case LAMENT_LID_OPEN:
1497 case LAMENT_LID_CLOSE:
1498 case LAMENT_LID_ZOOM:
1502 glTranslatef(lc->anim_z, 0.0, 0.0);
1504 glCallList(lc->lid_0);
1507 glTranslatef(-0.5, -d, 0.0);
1508 glRotatef(-lc->anim_r, 0.0, -1.0, -1.0);
1509 glTranslatef( 0.5, d, 0.0);
1510 glCallList(lc->lid_1);
1513 glTranslatef(-0.5, -d, 0.0);
1514 glRotatef( lc->anim_r, 0.0, -1.0, 1.0);
1515 glTranslatef( 0.5, d, 0.0);
1516 glCallList(lc->lid_2);
1519 glTranslatef(-0.5, d, 0.0);
1520 glRotatef( lc->anim_r, 0.0, -1.0, -1.0);
1521 glTranslatef( 0.5, -d, 0.0);
1522 glCallList(lc->lid_3);
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_4);
1533 case LAMENT_TASER_OUT:
1534 case LAMENT_TASER_SLIDE:
1535 case LAMENT_TASER_SLIDE_IN:
1536 case LAMENT_TASER_IN:
1538 glTranslatef(-lc->anim_z/2, 0.0, 0.0);
1539 glCallList(lc->taser_base);
1541 glTranslatef(lc->anim_z, 0.0, 0.0);
1542 glCallList(lc->taser_lifter);
1544 glTranslatef(0.0, 0.0, lc->anim_y);
1545 glCallList(lc->taser_slider);
1561 animate(ModeInfo *mi)
1563 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1565 /* int pause2 = 60;*/
1572 /* Rather than just picking states randomly, pick an ordering randomly,
1573 do it, and then re-randomize. That way one can be assured of seeing
1574 all states in a short time period, though not always in the same
1575 order (it's frustrating to see it pick the same state 5x in a row.)
1577 static lament_type states[] = {
1578 LAMENT_STAR_OUT, LAMENT_STAR_OUT,
1579 LAMENT_TETRA_UNE, LAMENT_TETRA_USW,
1580 LAMENT_TETRA_DWN, LAMENT_TETRA_DSE,
1581 LAMENT_LID_OPEN, LAMENT_LID_OPEN, LAMENT_LID_OPEN,
1582 LAMENT_TASER_OUT, LAMENT_TASER_OUT,
1583 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1584 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1586 static int state = countof(states);
1588 if (state < countof(states))
1590 lc->type = states[state++];
1596 for (i = 0; i < countof(states); i++)
1598 int a = random() % countof(states);
1599 lament_type swap = states[a];
1600 states[a] = states[i];
1605 if (lc->type == LAMENT_BOX)
1606 lc->anim_pause = pause3;
1614 /* -------------------------------------------------------------- */
1616 case LAMENT_STAR_OUT:
1618 if (lc->anim_z >= 1.0)
1621 lc->type = LAMENT_STAR_ROT;
1622 lc->anim_pause = pause;
1626 case LAMENT_STAR_ROT:
1628 if (lc->anim_r >= 45.0)
1631 lc->type = LAMENT_STAR_ROT_IN;
1632 lc->anim_pause = pause;
1636 case LAMENT_STAR_ROT_IN:
1638 if (lc->anim_z <= 0.0)
1641 lc->type = LAMENT_STAR_ROT_OUT;
1642 lc->anim_pause = pause3 * (1 + (random() % 4) + (random() % 4));
1646 case LAMENT_STAR_ROT_OUT:
1648 if (lc->anim_z >= 1.0)
1651 lc->type = LAMENT_STAR_UNROT;
1652 lc->anim_pause = pause;
1656 case LAMENT_STAR_UNROT:
1658 if (lc->anim_r <= 0.0)
1661 lc->type = LAMENT_STAR_IN;
1662 lc->anim_pause = pause;
1666 case LAMENT_STAR_IN:
1668 if (lc->anim_z <= 0.0)
1671 lc->type = LAMENT_BOX;
1672 lc->anim_pause = pause3;
1676 /* -------------------------------------------------------------- */
1678 case LAMENT_TETRA_UNE:
1679 case LAMENT_TETRA_USW:
1680 case LAMENT_TETRA_DWN:
1681 case LAMENT_TETRA_DSE:
1684 if (lc->anim_r >= 360.0)
1687 lc->type = LAMENT_BOX;
1688 lc->anim_pause = pause3;
1690 else if (lc->anim_r > 119.0 && lc->anim_r <= 120.0)
1693 lc->anim_pause = pause;
1695 else if (lc->anim_r > 239.0 && lc->anim_r <= 240.0)
1698 lc->anim_pause = pause;
1702 /* -------------------------------------------------------------- */
1704 case LAMENT_LID_OPEN:
1707 if (lc->anim_r >= 112.0)
1709 GLfloat hysteresis = 0.05;
1713 lc->anim_pause = pause3;
1715 if (lc->rotx >= -hysteresis &&
1716 lc->rotx <= hysteresis &&
1717 ((lc->rotz >= (0.25 - hysteresis) &&
1718 lc->rotz <= (0.25 + hysteresis)) ||
1719 (lc->rotz >= (-0.25 - hysteresis) &&
1720 lc->rotz <= (-0.25 + hysteresis))))
1722 lc->type = LAMENT_LID_ZOOM;
1724 lc->rotz = (lc->rotz < 0 ? -0.25 : 0.25);
1728 lc->type = LAMENT_LID_CLOSE;
1733 case LAMENT_LID_CLOSE:
1735 if (lc->anim_r <= 0.0)
1738 lc->type = LAMENT_BOX;
1739 lc->anim_pause = pause3;
1743 case LAMENT_LID_ZOOM:
1745 if (lc->anim_z < -50.0)
1749 lc->rotx = frand(1.0) * RANDSIGN();
1750 lc->roty = frand(1.0) * RANDSIGN();
1751 lc->rotz = frand(1.0) * RANDSIGN();
1752 lc->type = LAMENT_BOX;
1756 /* -------------------------------------------------------------- */
1758 case LAMENT_TASER_OUT:
1759 lc->anim_z += 0.0025;
1760 if (lc->anim_z >= 0.25)
1763 lc->type = LAMENT_TASER_SLIDE;
1764 lc->anim_pause = pause * (1 + (random() % 5) + (random() % 5));
1768 case LAMENT_TASER_SLIDE:
1769 lc->anim_y += 0.0025;
1770 if (lc->anim_y >= 0.23)
1773 lc->type = LAMENT_TASER_SLIDE_IN;
1774 lc->anim_pause = pause3 * (1 + (random() % 5) + (random() % 5));
1778 case LAMENT_TASER_SLIDE_IN:
1779 lc->anim_y -= 0.0025;
1780 if (lc->anim_y <= 0.0)
1783 lc->type = LAMENT_TASER_IN;
1784 lc->anim_pause = pause;
1788 case LAMENT_TASER_IN:
1789 lc->anim_z -= 0.0025;
1790 if (lc->anim_z <= 0.0)
1793 lc->type = LAMENT_BOX;
1794 lc->anim_pause = pause3;
1806 rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v)
1812 ppos = -(ppos + *v);
1821 if (ppos < 0) abort();
1822 if (ppos > 1.0) abort();
1823 *pos = (*pos > 0 ? ppos : -ppos);
1828 /* clamp velocity */
1829 if (*v > max_v || *v < -max_v)
1833 /* If it stops, start it going in the other direction. */
1840 /* keep going in the same direction */
1855 /* Alter direction of rotational acceleration randomly. */
1856 if (! (random() % 120))
1859 /* Change acceleration very occasionally. */
1860 if (! (random() % 200))
1864 else if (random() & 1)
1873 /* Window management, etc
1877 reshape_lament(ModeInfo *mi, int width, int height)
1879 int target_size = 180;
1880 int win_size = (width > height ? height : width);
1881 GLfloat h = (GLfloat) height / (GLfloat) width;
1883 glViewport(0, 0, (GLint) width, (GLint) height);
1885 /* glViewport(-600, -600, 1800, 1800); */
1887 glMatrixMode(GL_PROJECTION);
1889 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
1890 glMatrixMode(GL_MODELVIEW);
1892 glTranslatef(0.0, 0.0, -40.0);
1894 /* This scale makes the box take up most of the window */
1895 glScalef(2.0, 2.0, 2.0);
1897 /* But if the window is more than a little larger than our target size,
1898 scale the object back down, so that the bits drawn on the screen end
1899 up rougly target_size across (actually it ends up a little larger.)
1900 Note that the image-map bits we have are 128x128. Therefore, if the
1901 image is magnified a lot, it looks pretty blocky. So it's better to
1902 have a 128x128 animation on a 1280x1024 screen that looks good, than
1903 a 1024x1024 animation that looks really pixellated.
1905 if (win_size > target_size * 1.5)
1907 GLfloat ratio = ((GLfloat) target_size / (GLfloat) win_size);
1909 glScalef(ratio, ratio, ratio);
1912 /* The depth buffer will be cleared, if needed, before the
1913 * next frame. Right now we just want to black the screen.
1915 glClear(GL_COLOR_BUFFER_BIT);
1920 gl_init(ModeInfo *mi)
1922 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1923 Bool wire = MI_IS_WIREFRAME(mi);
1930 static GLfloat pos0[] = { -4.0, 2.0, 5.0, 1.0 };
1931 static GLfloat pos1[] = { 12.0, 5.0, 1.0, 1.0 };
1932 static GLfloat local[] = { 0.0 };
1933 static GLfloat ambient[] = { 0.3, 0.3, 0.3, 1.0 };
1934 static GLfloat spec[] = { 1.0, 1.0, 1.0, 1.0 };
1935 static GLfloat shine[] = { 100.0 };
1937 glLightfv(GL_LIGHT0, GL_POSITION, pos0);
1938 glLightfv(GL_LIGHT1, GL_POSITION, pos1);
1940 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
1941 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
1943 glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
1944 glLightfv(GL_LIGHT1, GL_SPECULAR, spec);
1946 glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local);
1947 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1948 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
1949 glMaterialfv(GL_FRONT, GL_SHININESS, shine);
1951 glEnable(GL_LIGHTING);
1952 glEnable(GL_LIGHT0);
1953 glEnable(GL_LIGHT1);
1954 glDisable(GL_LIGHT1);
1956 glEnable(GL_DEPTH_TEST);
1957 glEnable(GL_TEXTURE_2D);
1958 glEnable(GL_NORMALIZE);
1959 glEnable(GL_CULL_FACE);
1964 #ifdef HAVE_GLBINDTEXTURE
1966 for (i = 0; i < 6; i++)
1967 glGenTextures(1, &lc->texids[i]);
1969 parse_image_data(mi);
1971 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1972 glPixelStorei(GL_UNPACK_ROW_LENGTH, lc->texture->width);
1974 for (i = 0; i < 6; i++)
1976 int height = lc->texture->width; /* assume square */
1977 glBindTexture(GL_TEXTURE_2D, lc->texids[i]);
1978 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1981 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
1982 lc->texture->width, height, 0,
1983 GL_RGBA, GL_UNSIGNED_BYTE,
1984 (lc->texture->data +
1985 (lc->texture->bytes_per_line * height * i)));
1986 check_gl_error("texture");
1988 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1989 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1990 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1991 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1992 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1993 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1996 #else /* !HAVE_GLBINDTEXTURE */
1998 "%s: this version of GL doesn't support multiple texture maps.\n"
1999 "\tGet OpenGL 1.1.\n",
2002 #endif /* !HAVE_GLBINDTEXTURE */
2005 lc->box = glGenLists(16);
2006 lc->star1 = lc->box+1;
2007 lc->star2 = lc->box+2;
2008 lc->tetra_une = lc->box+3;
2009 lc->tetra_usw = lc->box+4;
2010 lc->tetra_dwn = lc->box+5;
2011 lc->tetra_dse = lc->box+6;
2012 lc->tetra_mid = lc->box+7;
2013 lc->lid_0 = lc->box+8;
2014 lc->lid_1 = lc->box+9;
2015 lc->lid_2 = lc->box+10;
2016 lc->lid_3 = lc->box+11;
2017 lc->lid_4 = lc->box+12;
2018 lc->taser_base = lc->box+13;
2019 lc->taser_lifter = lc->box+14;
2020 lc->taser_slider = lc->box+15;
2023 star(mi, True, wire);
2024 star(mi, False, wire);
2031 # ifdef HAVE_MESA_GL
2033 # include <signal.h>
2036 lament_signal_kludge (int sig)
2038 signal (sig, SIG_DFL);
2041 "%s: dying with signal %d (%s).\n"
2043 "\tThis is almost certainly a bug in the MesaGL library,\n"
2044 "\tespecially if the stack trace in the core file mentions\n"
2045 "\t`lambda_textured_triangle' or `render_quad'.\n"
2047 "\tI encourage you to report this to the Mesa maintainers\n"
2048 "\tat <http://www.mesa3d.org/>. I reported this bug more\n"
2049 "\tthan a year ago, and it is trivially reproducible.\n"
2050 "\tI do not know a workaround.\n"
2054 (sig == SIGILL ? "SIGILL" :
2055 sig == SIGFPE ? "SIGFPE" :
2056 sig == SIGBUS ? "SIGBUS" :
2057 sig == SIGSEGV ? "SIGSEGV" : "???"));
2059 kill (getpid (), sig);
2063 handle_signals (void)
2065 signal (SIGILL, lament_signal_kludge);
2066 signal (SIGFPE, lament_signal_kludge);
2067 signal (SIGBUS, lament_signal_kludge);
2068 signal (SIGSEGV, lament_signal_kludge);
2070 # endif /* HAVE_MESA_GL */
2074 init_lament(ModeInfo *mi)
2076 lament_configuration *lc;
2079 lcs = (lament_configuration *)
2080 calloc(MI_NUM_SCREENS(mi), sizeof (lament_configuration));
2083 fprintf(stderr, "%s: out of memory\n", progname);
2088 lc = &lcs[MI_SCREEN(mi)];
2090 lc->rotx = frand(1.0) * RANDSIGN();
2091 lc->roty = frand(1.0) * RANDSIGN();
2092 lc->rotz = frand(1.0) * RANDSIGN();
2094 /* bell curve from 0-1.5 degrees, avg 0.75 */
2095 lc->dx = (frand(1) + frand(1) + frand(1)) / (360*2);
2096 lc->dy = (frand(1) + frand(1) + frand(1)) / (360*2);
2097 lc->dz = (frand(1) + frand(1) + frand(1)) / (360*2);
2099 lc->d_max = lc->dx * 2;
2101 lc->ddx = 0.00006 + frand(0.00003);
2102 lc->ddy = 0.00006 + frand(0.00003);
2103 lc->ddz = 0.00006 + frand(0.00003);
2105 lc->type = LAMENT_BOX;
2106 lc->anim_pause = 300 + (random() % 100);
2108 if ((lc->glx_context = init_GL(mi)) != NULL)
2110 reshape_lament(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
2114 # ifdef HAVE_MESA_GL
2116 # endif /* HAVE_MESA_GL */
2121 draw_lament(ModeInfo *mi)
2123 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
2124 Display *dpy = MI_DISPLAY(mi);
2125 Window window = MI_WINDOW(mi);
2127 if (!lc->glx_context)
2130 glDrawBuffer(GL_BACK);
2132 glXMakeCurrent(dpy, window, *(lc->glx_context));
2134 if (mi->fps_p) do_fps (mi);
2137 glXSwapBuffers(dpy, window);
2139 if (lc->type != LAMENT_LID_ZOOM)
2141 rotate(&lc->rotx, &lc->dx, &lc->ddx, lc->d_max);
2142 rotate(&lc->roty, &lc->dy, &lc->ddy, lc->d_max);
2143 rotate(&lc->rotz, &lc->dz, &lc->ddz, lc->d_max);