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,
188 /* Computing normal vectors (thanks to Nat Friedman <ndf@mit.edu>)
191 typedef struct vector {
195 typedef struct plane {
200 vector_set(vector *v, GLfloat x, GLfloat y, GLfloat z)
208 vector_cross(vector v1, vector v2, vector *v3)
210 v3->x = (v1.y * v2.z) - (v1.z * v2.y);
211 v3->y = (v1.z * v2.x) - (v1.x * v2.z);
212 v3->z = (v1.x * v2.y) - (v1.y * v2.x);
216 vector_subtract(vector v1, vector v2, vector *res)
218 res->x = v1.x - v2.x;
219 res->y = v1.y - v2.y;
220 res->z = v1.z - v2.z;
224 plane_normal(plane p, vector *n)
227 vector_subtract(p.p1, p.p2, &v1);
228 vector_subtract(p.p1, p.p3, &v2);
229 vector_cross(v2, v1, n);
233 do_normal(GLfloat x1, GLfloat y1, GLfloat z1,
234 GLfloat x2, GLfloat y2, GLfloat z2,
235 GLfloat x3, GLfloat y3, GLfloat z3)
239 vector_set(&plane.p1, x1, y1, z1);
240 vector_set(&plane.p2, x2, y2, z2);
241 vector_set(&plane.p3, x3, y3, z3);
242 plane_normal(plane, &n);
243 n.x = -n.x; n.y = -n.y; n.z = -n.z;
245 glNormal3f(n.x, n.y, n.z);
248 /* Draw a line in the direction of this face's normal. */
250 GLfloat ax = n.x > 0 ? n.x : -n.x;
251 GLfloat ay = n.y > 0 ? n.y : -n.y;
252 GLfloat az = n.z > 0 ? n.z : -n.z;
253 GLfloat mx = (x1 + x2 + x3) / 3;
254 GLfloat my = (y1 + y2 + y3) / 3;
255 GLfloat mz = (z1 + z2 + z3) / 3;
258 GLfloat max = ax > ay ? ax : ay;
259 if (az > max) max = az;
265 glBegin(GL_LINE_LOOP);
266 glVertex3f(mx, my, mz);
267 glVertex3f(mx+xx, my+yy, mz+zz);
275 /* Shorthand utilities for making faces, with proper normals.
279 face3(GLint texture, GLfloat *color, Bool wire,
280 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
281 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
282 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3)
284 #ifdef HAVE_GLBINDTEXTURE
285 glBindTexture(GL_TEXTURE_2D, texture);
286 #endif /* HAVE_GLBINDTEXTURE */
287 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
288 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
289 glBegin(wire ? GL_LINE_LOOP : GL_TRIANGLES);
290 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
291 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
292 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
297 face4(GLint texture, GLfloat *color, Bool wire,
298 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
299 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
300 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3,
301 GLfloat s4, GLfloat t4, GLfloat x4, GLfloat y4, GLfloat z4)
303 #ifdef HAVE_GLBINDTEXTURE
304 glBindTexture(GL_TEXTURE_2D, texture);
305 #endif /* HAVE_GLBINDTEXTURE */
306 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
307 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
308 glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
309 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
310 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
311 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
312 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
317 face5(GLint texture, GLfloat *color, Bool wire,
318 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
319 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
320 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3,
321 GLfloat s4, GLfloat t4, GLfloat x4, GLfloat y4, GLfloat z4,
322 GLfloat s5, GLfloat t5, GLfloat x5, GLfloat y5, GLfloat z5)
324 #ifdef HAVE_GLBINDTEXTURE
325 glBindTexture(GL_TEXTURE_2D, texture);
326 #endif /* HAVE_GLBINDTEXTURE */
327 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
328 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
329 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
330 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
331 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
332 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
333 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
334 glTexCoord2f(s5, t5); glVertex3f(x5, y5, z5);
340 /* Creating object models
344 box(ModeInfo *mi, Bool wire)
346 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
348 glNewList(lc->box, GL_COMPILE);
349 glShadeModel(GL_SMOOTH);
352 face4(lc->texids[FACE_N], exterior_color, wire,
353 0.0, 0.0, -0.5, 0.5, 0.5,
354 1.0, 0.0, 0.5, 0.5, 0.5,
355 1.0, 1.0, 0.5, 0.5, -0.5,
356 0.0, 1.0, -0.5, 0.5, -0.5);
359 face4(lc->texids[FACE_S], exterior_color, wire,
360 0.0, 0.0, -0.5, -0.5, -0.5,
361 1.0, 0.0, 0.5, -0.5, -0.5,
362 1.0, 1.0, 0.5, -0.5, 0.5,
363 0.0, 1.0, -0.5, -0.5, 0.5);
366 face4(lc->texids[FACE_E], exterior_color, wire,
367 0.0, 0.0, 0.5, -0.5, -0.5,
368 1.0, 0.0, 0.5, 0.5, -0.5,
369 1.0, 1.0, 0.5, 0.5, 0.5,
370 0.0, 1.0, 0.5, -0.5, 0.5);
373 face4(lc->texids[FACE_W], exterior_color, wire,
374 1.0, 1.0, -0.5, -0.5, 0.5,
375 0.0, 1.0, -0.5, 0.5, 0.5,
376 0.0, 0.0, -0.5, 0.5, -0.5,
377 1.0, 0.0, -0.5, -0.5, -0.5);
380 face4(lc->texids[FACE_U], exterior_color, wire,
381 1.0, 0.0, 0.5, -0.5, 0.5,
382 1.0, 1.0, 0.5, 0.5, 0.5,
383 0.0, 1.0, -0.5, 0.5, 0.5,
384 0.0, 0.0, -0.5, -0.5, 0.5);
387 face4(lc->texids[FACE_D], exterior_color, wire,
388 0.0, 1.0, -0.5, -0.5, -0.5,
389 0.0, 0.0, -0.5, 0.5, -0.5,
390 1.0, 0.0, 0.5, 0.5, -0.5,
391 1.0, 1.0, 0.5, -0.5, -0.5);
398 star(ModeInfo *mi, Bool top, Bool wire)
400 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
404 { 77, 74 }, { 60, 98 }, { 0, 71 }, { 0, 0 }, /* L1 */
405 { 60, 98 }, { 55, 127 }, { 0, 127 }, { 0, 71 }, /* L2 */
406 { 55, 127 }, { 60, 154 }, { 0, 179 }, { 0, 127 }, /* L3 */
407 { 60, 154 }, { 76, 176 }, { 0, 255 }, { 0, 179 }, /* L4 */
408 { 76, 176 }, { 100, 193 }, { 74, 255 }, { 0, 255 }, /* B1 */
409 { 100, 193 }, { 127, 198 }, { 127, 255 }, { 74, 255 }, /* B2 */
410 { 127, 198 }, { 151, 193 }, { 180, 255 }, { 127, 255 }, /* B3 */
411 { 151, 193 }, { 178, 177 }, { 255, 255 }, { 180, 255 }, /* B4 */
412 { 178, 177 }, { 193, 155 }, { 255, 181 }, { 255, 255 }, /* R4 */
413 { 193, 155 }, { 199, 127 }, { 255, 127 }, { 255, 181 }, /* R3 */
414 { 199, 127 }, { 194, 99 }, { 255, 74 }, { 255, 127 }, /* R2 */
415 { 194, 99 }, { 179, 76 }, { 255, 0 }, { 255, 74 }, /* R1 */
416 { 179, 76 }, { 155, 60 }, { 180, 0 }, { 255, 0 }, /* T4 */
417 { 155, 60 }, { 126, 55 }, { 126, 0 }, { 180, 0 }, /* T3 */
418 { 126, 55 }, { 100, 60 }, { 75, 0 }, { 126, 0 }, /* T2 */
419 { 100, 60 }, { 77, 74 }, { 0, 0 }, { 75, 0 }, /* T1 */
422 for (i = 0; i < countof(points); i++)
423 points[i][1] = 255-points[i][1];
426 glNewList(lc->star1, GL_COMPILE);
428 glNewList(lc->star2, GL_COMPILE);
431 glRotatef(-180.0, 1.0, 0.0, 0.0);
433 for (i = 0; i < countof(points)/4; i += 2)
440 GLfloat s[4], t[4], x[4], y[4], z[4];
441 for (j = 3, k = 0; j >= 0; j--, k++)
443 GLfloat xx = points[(i*4)+j][0] / 255.0L;
444 GLfloat yy = points[(i*4)+j][1] / 255.0L;
451 face4(lc->texids[top ? FACE_U : FACE_D], exterior_color, wire,
452 s[0], t[0], x[0], y[0], z[0],
453 s[1], t[1], x[1], y[1], z[1],
454 s[2], t[2], x[2], y[2], z[2],
455 s[3], t[3], x[3], y[3], z[3]);
459 for (j = 0, k = 0; j < 4; j++, k++)
461 GLfloat xx = points[(i*4)+j][0] / 255.0L;
462 GLfloat yy = points[(i*4)+j][1] / 255.0L;
469 face4(lc->texids[top ? FACE_U : FACE_D], exterior_color, wire,
470 s[0], t[0], x[0], y[0], z[0],
471 s[1], t[1], x[1], y[1], z[1],
472 s[2], t[2], x[2], y[2], z[2],
473 s[3], t[3], x[3], y[3], z[3]);
477 for (j = 3; j >= 0; j--)
479 int k = (j == 0 ? 3 : j-1);
480 Bool front_p = (j == 3);
481 GLfloat x1 = points[(i*4)+j][0] / 255.0L;
482 GLfloat y1 = points[(i*4)+j][1] / 255.0L;
483 GLfloat x2 = points[(i*4)+k][0] / 255.0L;
484 GLfloat y2 = points[(i*4)+k][1] / 255.0L;
486 GLfloat tx1=0.0, tx2=1.0, ty1=0.0, ty2=1.0;
490 facing = (facing + j + 5) % 4;
496 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
497 ty1 = 0.0; ty2 = 1.0;
500 ty1 = 1.0; ty2 = 0.0;
504 texture = top ? FACE_S : FACE_N;
506 ty1 = 0.0; ty2 = 1.0;
512 ty1 = 0.0; ty2 = 1.0;
514 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
515 ty1 = 1.0; ty2 = 0.0;
519 texture = top ? FACE_N : FACE_S;
521 ty1 = 1.0; ty2 = 0.0;
525 x1 -= 0.5; x2 -= 0.5;
526 y1 -= 0.5; y2 -= 0.5;
528 face4(front_p ? lc->texids[texture] : 0,
529 front_p ? exterior_color : interior_color,
531 tx1, ty2, x1, y1, 0.5,
532 tx1, ty1, x1, y1, -0.5,
533 tx2, ty1, x2, y2, -0.5,
534 tx2, ty2, x2, y2, 0.5);
539 /* Central core top cap.
541 #ifdef HAVE_GLBINDTEXTURE
542 glBindTexture(GL_TEXTURE_2D, lc->texids[top ? FACE_U : FACE_D]);
543 #endif /* HAVE_GLBINDTEXTURE */
544 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
547 do_normal(points[i+0][0], points[i+0][1], 0,
548 points[i+4][0], points[i+4][1], 0,
549 points[i+8][0], points[i+8][1], 0);
550 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
551 for (i = 1; i < countof(points); i += 4)
553 GLfloat x = points[i][0] / 255.0L;
554 GLfloat y = points[i][1] / 255.0L;
556 glVertex3f(x-0.5, y-0.5, 0.5);
561 /* Central core bottom cap.
563 #ifdef HAVE_GLBINDTEXTURE
564 glBindTexture(GL_TEXTURE_2D, 0);
565 #endif /* HAVE_GLBINDTEXTURE */
566 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color);
568 i = countof(points) - 9;
569 do_normal(points[i+0][0], points[i+0][1], 0,
570 points[i+4][0], points[i+4][1], 0,
571 points[i+8][0], points[i+8][1], 0);
573 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
574 for (i = countof(points) - 3; i >= 0; i -= 4)
576 GLfloat x = points[i][0] / 255.0L;
577 GLfloat y = points[i][1] / 255.0L;
578 glVertex3f(x-0.5, y-0.5, 0);
583 /* Central core walls.
585 for (i = 1; i < countof(points); i += 4)
588 GLfloat x1 = points[i-1][0] / 255.0L;
589 GLfloat y1 = points[i-1][1] / 255.0L;
590 GLfloat x2 = points[i][0] / 255.0L;
591 GLfloat y2 = points[i][1] / 255.0L;
592 face4(0, interior_color, wire,
593 0.0, 0.0, x1-0.5, y1-0.5, 0.5,
594 0.0, 0.0, x1-0.5, y1-0.5, 0.0,
595 0.0, 0.0, x2-0.5, y2-0.5, 0.0,
596 0.0, 0.0, x2-0.5, y2-0.5, 0.5);
604 tetra(ModeInfo *mi, Bool wire)
606 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
608 glNewList(lc->tetra_une, GL_COMPILE);
610 glShadeModel(GL_SMOOTH);
613 face3(lc->texids[FACE_U], exterior_color, wire,
614 1.0, 0.0, 0.5, -0.5, 0.5,
615 1.0, 1.0, 0.5, 0.5, 0.5,
616 0.0, 1.0, -0.5, 0.5, 0.5);
619 face3(lc->texids[FACE_N], exterior_color, wire,
620 0.0, 0.0, -0.5, 0.5, 0.5,
621 1.0, 0.0, 0.5, 0.5, 0.5,
622 1.0, 1.0, 0.5, 0.5, -0.5);
625 face3(lc->texids[FACE_E], exterior_color, wire,
626 1.0, 0.0, 0.5, 0.5, -0.5,
627 1.0, 1.0, 0.5, 0.5, 0.5,
628 0.0, 1.0, 0.5, -0.5, 0.5);
630 face3(0, interior_color, wire,
631 0.0, 0.0, 0.5, 0.5, -0.5,
632 0.0, 0.0, 0.5, -0.5, 0.5,
633 0.0, 0.0, -0.5, 0.5, 0.5);
637 glNewList(lc->tetra_usw, GL_COMPILE);
640 face3(lc->texids[FACE_U], exterior_color, wire,
641 0.0, 1.0, -0.5, 0.5, 0.5,
642 0.0, 0.0, -0.5, -0.5, 0.5,
643 1.0, 0.0, 0.5, -0.5, 0.5);
646 face3(lc->texids[FACE_S], exterior_color, wire,
647 1.0, 1.0, 0.5, -0.5, 0.5,
648 0.0, 1.0, -0.5, -0.5, 0.5,
649 0.0, 0.0, -0.5, -0.5, -0.5);
652 face3(lc->texids[FACE_W], exterior_color, wire,
653 1.0, 0.0, -0.5, -0.5, -0.5,
654 1.0, 1.0, -0.5, -0.5, 0.5,
655 0.0, 1.0, -0.5, 0.5, 0.5);
657 face3(0, interior_color, wire,
658 0.0,0.0, -0.5, -0.5, -0.5,
659 0.0,0.0, -0.5, 0.5, 0.5,
660 0.0,0.0, 0.5, -0.5, 0.5);
664 glNewList(lc->tetra_dwn, GL_COMPILE);
667 face3(lc->texids[FACE_D], exterior_color, wire,
668 0.0, 1.0, -0.5, -0.5, -0.5,
669 0.0, 0.0, -0.5, 0.5, -0.5,
670 1.0, 0.0, 0.5, 0.5, -0.5);
673 face3(lc->texids[FACE_W], exterior_color, wire,
674 0.0, 1.0, -0.5, 0.5, 0.5,
675 0.0, 0.0, -0.5, 0.5, -0.5,
676 1.0, 0.0, -0.5, -0.5, -0.5);
679 face3(lc->texids[FACE_N], exterior_color, wire,
680 1.0, 1.0, 0.5, 0.5, -0.5,
681 0.0, 1.0, -0.5, 0.5, -0.5,
682 0.0, 0.0, -0.5, 0.5, 0.5);
684 face3(0, interior_color, wire,
685 0.0, 0.0, 0.5, 0.5, -0.5,
686 0.0, 0.0, -0.5, 0.5, 0.5,
687 0.0, 0.0, -0.5, -0.5, -0.5);
691 glNewList(lc->tetra_dse, GL_COMPILE);
694 face3(lc->texids[FACE_S], exterior_color, wire,
695 0.0, 0.0, -0.5, -0.5, -0.5,
696 1.0, 0.0, 0.5, -0.5, -0.5,
697 1.0, 1.0, 0.5, -0.5, 0.5);
700 face3(lc->texids[FACE_E], exterior_color, wire,
701 0.0, 1.0, 0.5, -0.5, 0.5,
702 0.0, 0.0, 0.5, -0.5, -0.5,
703 1.0, 0.0, 0.5, 0.5, -0.5);
706 face3(lc->texids[FACE_D], exterior_color, wire,
707 1.0, 0.0, 0.5, 0.5, -0.5,
708 1.0, 1.0, 0.5, -0.5, -0.5,
709 0.0, 1.0, -0.5, -0.5, -0.5);
711 face3(0, interior_color, wire,
712 0.0, 0.0, 0.5, -0.5, 0.5,
713 0.0, 0.0, 0.5, 0.5, -0.5,
714 0.0, 0.0, -0.5, -0.5, -0.5);
718 glNewList(lc->tetra_mid, GL_COMPILE);
720 face3(0, interior_color, wire,
721 0.0, 0.0, 0.5, -0.5, 0.5,
722 0.0, 0.0, 0.5, 0.5, -0.5,
723 0.0, 0.0, -0.5, 0.5, 0.5);
725 face3(0, interior_color, wire,
726 0.0, 0.0, -0.5, 0.5, 0.5,
727 0.0, 0.0, -0.5, -0.5, -0.5,
728 0.0, 0.0, 0.5, -0.5, 0.5);
730 face3(0, interior_color, wire,
731 0.0, 0.0, -0.5, 0.5, 0.5,
732 0.0, 0.0, 0.5, 0.5, -0.5,
733 0.0, 0.0, -0.5, -0.5, -0.5);
735 face3(0, interior_color, wire,
736 0.0, 0.0, 0.5, 0.5, -0.5,
737 0.0, 0.0, 0.5, -0.5, 0.5,
738 0.0, 0.0, -0.5, -0.5, -0.5);
740 face3(0, interior_color, wire,
741 0.0, 0.0, 0.5, -0.5, 0.5,
742 0.0, 0.0, 0.5, 0.5, -0.5,
743 0.0, 0.0, -0.5, -0.5, -0.5);
750 lid(ModeInfo *mi, Bool wire)
752 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
756 { 128, 20 },{ 21, 129 },{ 0, 129 },{ 0, 0 },{ 128, 0 }, /* L1 */
757 { 21, 129 },{ 127, 234 },{ 127, 255 },{ 0, 255 },{ 0, 129 }, /* L2 */
758 { 127, 234 },{ 233, 127 },{ 255, 127 },{ 255, 255 },{ 127, 255 }, /* R2 */
759 { 233, 127 },{ 128, 20 },{ 128, 0 },{ 255, 0 },{ 255, 127 }, /* R1 */
762 for (i = 0; i < countof(points); i++)
763 points[i][1] = 255-points[i][1];
765 glNewList(lc->lid_0, GL_COMPILE);
766 glShadeModel(GL_SMOOTH);
769 face4(lc->texids[FACE_N], exterior_color, wire,
770 0.0, 0.0, -0.5, 0.5, 0.5,
771 1.0, 0.0, 0.5, 0.5, 0.5,
772 1.0, 1.0, 0.5, 0.5, -0.5,
773 0.0, 1.0, -0.5, 0.5, -0.5);
776 face4(lc->texids[FACE_S], exterior_color, wire,
777 0.0, 0.0, -0.5, -0.5, -0.5,
778 1.0, 0.0, 0.5, -0.5, -0.5,
779 1.0, 1.0, 0.5, -0.5, 0.5,
780 0.0, 1.0, -0.5, -0.5, 0.5);
783 face4(lc->texids[FACE_E], exterior_color, wire,
784 0.0, 0.0, 0.5, -0.5, -0.5,
785 1.0, 0.0, 0.5, 0.5, -0.5,
786 1.0, 1.0, 0.5, 0.5, 0.5,
787 0.0, 1.0, 0.5, -0.5, 0.5);
790 face4(lc->texids[FACE_U], exterior_color, wire,
791 1.0, 0.0, 0.5, -0.5, 0.5,
792 1.0, 1.0, 0.5, 0.5, 0.5,
793 0.0, 1.0, -0.5, 0.5, 0.5,
794 0.0, 0.0, -0.5, -0.5, 0.5);
797 face4(lc->texids[FACE_D], exterior_color, wire,
798 0.0, 1.0, -0.5, -0.5, -0.5,
799 0.0, 0.0, -0.5, 0.5, -0.5,
800 1.0, 0.0, 0.5, 0.5, -0.5,
801 1.0, 1.0, 0.5, -0.5, -0.5);
804 for (i = 0; i < countof(points)/5; i++)
807 GLfloat s[5], t[5], x[5], y[5], z[5];
808 for (j = 0; j < 5; j++)
810 GLfloat xx = points[(i*5)+j][0] / 255.0L;
811 GLfloat yy = points[(i*5)+j][1] / 255.0L;
818 face5(lc->texids[FACE_W], exterior_color, wire,
819 s[0], t[0], x[0], y[0], z[0],
820 s[1], t[1], x[1], y[1], z[1],
821 s[2], t[2], x[2], y[2], z[2],
822 s[3], t[3], x[3], y[3], z[3],
823 s[4], t[4], x[4], y[4], z[4]);
828 /* W -- lid_1 through lid_4 */
829 for (i = 0; i < 4; i++)
831 GLfloat x1, y1, x2, y2, x3, y3;
833 glNewList(lc->lid_1 + i, GL_COMPILE);
834 glShadeModel(GL_SMOOTH);
836 x1 = points[(i*5)+1][0] / 255.0L;
837 y1 = points[(i*5)+1][1] / 255.0L;
838 x2 = points[(i*5)][0] / 255.0L;
839 y2 = points[(i*5)][1] / 255.0L;
844 face3(lc->texids[FACE_W], exterior_color, wire,
845 1.0-x1, y1, -0.5, x1-0.5, y1-0.5,
846 1.0-x2, y2, -0.5, x2-0.5, y2-0.5,
847 1.0-x3, y3, -0.5, x3-0.5, y3-0.5);
850 face3(0, interior_color, wire,
851 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
852 0.0, 0.0, -0.48, x1-0.5, y1-0.5,
853 0.0, 0.0, -0.48, x3-0.5, y3-0.5);
856 face4(0, interior_color, wire,
857 0.0, 0.0, -0.5, x1-0.5, y1-0.5,
858 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
859 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
860 0.0, 0.0, -0.48, x1-0.5, y1-0.5);
863 face4(0, interior_color, wire,
864 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
865 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
866 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
867 0.0, 0.0, -0.5, x2-0.5, y2-0.5);
874 taser(ModeInfo *mi, Bool wire)
876 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
879 int slider_face_points[][2] = {
880 { 86, 58 },{ 38, 106 },{ 70, 106 },{ 118, 58 },{ -1, -1 }, /* a */
881 { 136, 58 },{ 184, 106 },{ 216, 106 },{ 168, 58 },{ -1, -1 }, /* b */
882 { 38, 106 },{ 0, 144 },{ 0, 190 },{ 60, 190 },{ 108, 106 }, /* c */
883 { 144, 106 },{ 194, 190 },{ 254, 190 },{ 254, 144 },{ 216, 106 }, /* d */
884 { 98, 124 },{ 60, 190 },{ 92, 190 },{ 126, 158 },{ 126, 124 }, /* e */
885 { 126, 124 },{ 126, 158 },{ 160, 190 },{ 194, 190 },{ 154, 124 }, /* f */
886 { 22, 190 },{ 22, 254 },{ 60, 254 },{ 60, 190 },{ -1, -1 }, /* g */
887 { 194, 190 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ -1, -1 }, /* h */
888 { 60, 190 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ -1, -1 }, /* i */
889 { 160, 190 },{ 160, 210 },{ 194, 210 },{ 194, 190 },{ -1, -1 }, /* j */
890 { 110, 172 },{ 92, 190 },{ 110, 190 },{ -1, -1 },{ -1, -1 }, /* k */
891 { 140, 172 },{ 140, 190 },{ 160, 190 },{ -1, -1 },{ -1, -1 }, /* l */
892 { 110, 172 },{ 140, 172 },{ 126, 156 },{ -1, -1 },{ -1, -1 }, /* m */
895 int body_face_points[][2] = {
896 { 0, 0 },{ 0, 58 },{ 254, 58 },{ 254, 0 },{ -1, -1 }, /* A */
897 { 0, 58 },{ 0, 144 },{ 86, 58 },{ -1, -1 },{ -1, -1 }, /* B */
898 { 168, 58 },{ 254, 144 },{ 254, 58 },{ -1, -1 },{ -1, -1 }, /* C */
899 { 118, 58 },{ 70, 106 },{ 184, 106 },{ 136, 58 },{ -1, -1 }, /* F */
900 { 108, 106 },{ 98, 124 },{ 154, 124 },{ 144, 106 },{ -1, -1 }, /* G */
903 int lifter_face_points[][2] = {
904 { 0, 190 },{ 0, 254 },{ 22, 254 },{ 22, 190 },{ -1, -1 }, /* D */
905 { 230, 190 },{ 230, 254 },{ 254, 254 },{ 254, 190 },{ -1, -1 }, /* E */
906 { 60, 210 },{ 60, 254 },{ 194, 254 },{ 194, 210 },{ -1, -1 }, /* H */
907 { 92, 190 },{ 92, 210 },{ 160, 210 },{ 160, 190 },{ -1, -1 }, /* I */
908 { 110, 172 },{ 110, 190 },{ 140, 190 },{ 140, 172 },{ -1, -1 }, /* J */
911 int body_perimiter_points[][2] = {
912 { 0, 144 },{ 86, 59 },{ 119, 58 },{ 71, 107 },
913 { 108, 107 },{ 98, 124 },{ 155, 124 },{ 144, 107 },
914 { 185, 106 },{ 136, 59 },{ 169, 59 },{ 255, 145 },
918 int slider_perimiter_points[][2] = {
919 { 86, 58 },{ 0, 144 },{ 0, 190 },{ 22, 190 },{ 22, 254 },
920 { 60, 254 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ 110, 190 },
921 { 110, 172 },{ 140, 172 },{ 140, 190 },{ 160, 190 },{ 160, 210 },
922 { 194, 210 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ 254, 190 },
923 { 254, 144 },{ 168, 58 },{ 136, 58 },{ 184, 106 },{ 144, 106 },
924 { 154, 124 },{ 98, 124 },{ 108, 106 },{ 70, 106 },{ 118, 58 },
927 int lifter_perimiter_points_1[][2] = {
928 { 0, 189 },{ 0, 254 },{ 22, 255 },{ 23, 190 },
931 int lifter_perimiter_points_2[][2] = {
932 { 230, 254 },{ 255, 255 },{ 254, 190 },{ 230, 190 },
935 int lifter_perimiter_points_3[][2] = {
936 { 60, 254 },{ 194, 254 },{ 194, 211 },{ 160, 210 },
937 { 160, 190 },{ 140, 191 },{ 141, 172 },{ 111, 172 },
938 { 110, 190 },{ 93, 190 },{ 92, 210 },{ 60, 211 },
941 for (i = 0; i < countof(slider_face_points); i++)
942 slider_face_points[i][1] = 255-slider_face_points[i][1];
943 for (i = 0; i < countof(body_face_points); i++)
944 body_face_points[i][1] = 255-body_face_points[i][1];
945 for (i = 0; i < countof(lifter_face_points); i++)
946 lifter_face_points[i][1] = 255-lifter_face_points[i][1];
947 for (i = 0; i < countof(body_perimiter_points); i++)
948 body_perimiter_points[i][1] = 255-body_perimiter_points[i][1];
949 for (i = 0; i < countof(slider_perimiter_points); i++)
950 slider_perimiter_points[i][1] = 255-slider_perimiter_points[i][1];
951 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
952 lifter_perimiter_points_1[i][1] = 255-lifter_perimiter_points_1[i][1];
953 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
954 lifter_perimiter_points_2[i][1] = 255-lifter_perimiter_points_2[i][1];
955 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
956 lifter_perimiter_points_3[i][1] = 255-lifter_perimiter_points_3[i][1];
958 /* -------------------------------------------------------------------- */
960 glNewList(lc->taser_base, GL_COMPILE);
961 glShadeModel(GL_SMOOTH);
964 face4(lc->texids[FACE_N], exterior_color, wire,
965 0.0, 0.0, -0.5, 0.5, 0.5,
966 0.75, 0.0, 0.25, 0.5, 0.5,
967 0.75, 0.75, 0.25, 0.5, -0.25,
968 0.0, 0.75, -0.5, 0.5, -0.25);
971 face4(lc->texids[FACE_S], exterior_color, wire,
972 0.0, 0.25, -0.5, -0.5, -0.25,
973 0.75, 0.25, 0.25, -0.5, -0.25,
974 0.75, 1.0, 0.25, -0.5, 0.5,
975 0.0, 1.0, -0.5, -0.5, 0.5);
978 face4(0, interior_color, wire,
979 0.0, 0.0, 0.25, -0.5, -0.25,
980 1.0, 0.0, 0.25, 0.5, -0.25,
981 1.0, 1.0, 0.25, 0.5, 0.5,
982 0.0, 1.0, 0.25, -0.5, 0.5);
985 face4(lc->texids[FACE_W], exterior_color, wire,
986 1.0, 1.0, -0.5, -0.5, 0.5,
987 0.0, 1.0, -0.5, 0.5, 0.5,
988 0.0, 0.25, -0.5, 0.5, -0.25,
989 1.0, 0.25, -0.5, -0.5, -0.25);
992 face4(lc->texids[FACE_U], exterior_color, wire,
993 0.75, 0.0, 0.25, -0.5, 0.5,
994 0.75, 1.0, 0.25, 0.5, 0.5,
995 0.0, 1.0, -0.5, 0.5, 0.5,
996 0.0, 0.0, -0.5, -0.5, 0.5);
999 face4(0, interior_color, wire,
1000 0.0, 1.0, -0.5, -0.5, -0.25,
1001 0.0, 0.0, -0.5, 0.5, -0.25,
1002 1.0, 0.0, 0.25, 0.5, -0.25,
1003 1.0, 1.0, 0.25, -0.5, -0.25);
1006 for (i = 0; i < countof(body_face_points)/5; i++)
1009 #ifdef HAVE_GLBINDTEXTURE
1010 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1011 #endif /* HAVE_GLBINDTEXTURE */
1012 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1014 do_normal(0, body_face_points[(i*5)+0][0], body_face_points[(i*5)+0][1],
1015 0, body_face_points[(i*5)+1][0], body_face_points[(i*5)+1][1],
1016 0, body_face_points[(i*5)+2][0], body_face_points[(i*5)+2][1]
1018 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1019 for (j = 0; j < 5; j++)
1021 int ix = body_face_points[(i*5)+j][0];
1022 int iy = body_face_points[(i*5)+j][1];
1024 if (ix == -1) /* these are padding: ignore them */
1029 glVertex3f(0.5, x-0.5, y-0.5);
1035 for (i = 0; i < countof(body_perimiter_points); i++)
1037 int j = (i+1 >= countof(body_perimiter_points) ? 0 : i+1);
1038 GLfloat x1 = body_perimiter_points[i][0] / 255.0;
1039 GLfloat y1 = body_perimiter_points[i][1] / 255.0;
1040 GLfloat x2 = body_perimiter_points[j][0] / 255.0;
1041 GLfloat y2 = body_perimiter_points[j][1] / 255.0;
1043 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1047 texture = lc->texids[FACE_N];
1049 s2 = 1.0; t2 = 0.568;
1050 s3 = 0.75, t3 = 0.568;
1051 s4 = 0.75; t4 = 0.0;
1055 texture = lc->texids[FACE_U];
1058 s3 = 0.75, t3 = 1.0;
1059 s4 = 0.75; t4 = 0.0;
1063 texture = lc->texids[FACE_S];
1064 s1 = 1.0; t1 = 0.437;
1066 s3 = 0.75; t3 = 1.0;
1067 s4 = 0.75; t4 = 0.437;
1070 face4((texture == -1 ? 0 : texture),
1071 (texture == -1 ? interior_color : exterior_color),
1073 s1, t1, 0.5, x2-0.5, y2-0.5,
1074 s2, t2, 0.5, x1-0.5, y1-0.5,
1075 s3, t3, 0.25, x1-0.5, y1-0.5,
1076 s4, t4, 0.25, x2-0.5, y2-0.5);
1081 /* -------------------------------------------------------------------- */
1083 glNewList(lc->taser_lifter, GL_COMPILE);
1084 glShadeModel(GL_SMOOTH);
1087 face4(lc->texids[FACE_N], exterior_color, wire,
1088 0.0, 0.75, -0.5, 0.5, -0.25,
1089 0.75, 0.75, 0.25, 0.5, -0.25,
1090 0.75, 1.0, 0.25, 0.5, -0.5,
1091 0.0, 1.0, -0.5, 0.5, -0.5);
1094 face4(lc->texids[FACE_S], exterior_color, wire,
1095 0.0, 0.0, -0.5, -0.5, -0.5,
1096 0.75, 0.0, 0.25, -0.5, -0.5,
1097 0.75, 0.25, 0.25, -0.5, -0.25,
1098 0.0, 0.25, -0.5, -0.5, -0.25);
1101 face4(0, interior_color, wire,
1102 0.0, 1.0, 0.25, -0.5, -0.5,
1103 1.0, 1.0, 0.25, 0.5, -0.5,
1104 1.0, 0.0, 0.25, 0.5, -0.25,
1105 0.0, 0.0, 0.25, -0.5, -0.25);
1108 face4(lc->texids[FACE_W], exterior_color, wire,
1109 1.0, 0.25, -0.5, -0.5, -0.25,
1110 0.0, 0.25, -0.5, 0.5, -0.25,
1111 0.0, 0.0, -0.5, 0.5, -0.5,
1112 1.0, 0.0, -0.5, -0.5, -0.5);
1115 face4(0, interior_color, wire,
1116 1.0, 0.0, 0.25, -0.5, -0.25,
1117 1.0, 1.0, 0.25, 0.5, -0.25,
1118 0.0, 1.0, -0.5, 0.5, -0.25,
1119 0.0, 0.0, -0.5, -0.5, -0.25);
1122 face4(lc->texids[FACE_D], exterior_color, wire,
1123 0.0, 1.0, -0.5, -0.5, -0.5,
1124 0.0, 0.0, -0.5, 0.5, -0.5,
1125 0.75, 0.0, 0.25, 0.5, -0.5,
1126 0.75, 1.0, 0.25, -0.5, -0.5);
1130 for (i = 0; i < countof(lifter_face_points)/5; i++)
1134 #ifdef HAVE_GLBINDTEXTURE
1135 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1136 #endif /* HAVE_GLBINDTEXTURE */
1137 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1140 0, lifter_face_points[(i*5)+0][0], lifter_face_points[(i*5)+0][1],
1141 0, lifter_face_points[(i*5)+1][0], lifter_face_points[(i*5)+1][1],
1142 0, lifter_face_points[(i*5)+2][0], lifter_face_points[(i*5)+2][1]);
1144 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1145 for (j = 0; j < 5; j++)
1147 int ix = lifter_face_points[(i*5)+j][0];
1148 int iy = lifter_face_points[(i*5)+j][1];
1150 if (ix == -1) /* these are padding: ignore them */
1155 glVertex3f(0.5, x-0.5, y-0.5);
1161 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
1163 int j = (i+1 >= countof(lifter_perimiter_points_1) ? 0 : i+1);
1164 GLfloat x1 = lifter_perimiter_points_1[i][0] / 255.0;
1165 GLfloat y1 = lifter_perimiter_points_1[i][1] / 255.0;
1166 GLfloat x2 = lifter_perimiter_points_1[j][0] / 255.0;
1167 GLfloat y2 = lifter_perimiter_points_1[j][1] / 255.0;
1169 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1173 texture = lc->texids[FACE_S];
1175 s2 = 1.0; t2 = 0.26;
1176 s3 = 0.75, t3 = 0.26;
1177 s4 = 0.75; t4 = 0.0;
1181 texture = lc->texids[FACE_D];
1182 s1 = 1.0; t1 = 0.914;
1184 s3 = 0.75; t3 = 1.0;
1185 s4 = 0.75; t4 = 0.914;
1188 face4((texture == -1 ? 0 : texture),
1189 (texture == -1 ? interior_color : exterior_color),
1191 s1, t1, 0.5, x2-0.5, y2-0.5,
1192 s2, t2, 0.5, x1-0.5, y1-0.5,
1193 s3, t3, 0.25, x1-0.5, y1-0.5,
1194 s4, t4, 0.25, x2-0.5, y2-0.5);
1197 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
1199 int j = (i+1 >= countof(lifter_perimiter_points_2) ? 0 : i+1);
1200 GLfloat x1 = lifter_perimiter_points_2[i][0] / 255.0;
1201 GLfloat y1 = lifter_perimiter_points_2[i][1] / 255.0;
1202 GLfloat x2 = lifter_perimiter_points_2[j][0] / 255.0;
1203 GLfloat y2 = lifter_perimiter_points_2[j][1] / 255.0;
1205 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1209 texture = lc->texids[FACE_D];
1211 s2 = 1.0; t2 = 0.095;
1212 s3 = 0.75; t3 = 0.095;
1213 s4 = 0.75; t4 = 0.0;
1217 texture = lc->texids[FACE_N];
1218 s1 = 1.0; t1 = 0.745;
1220 s3 = 0.75; t3 = 1.0;
1221 s4 = 0.75; t4 = 0.745;
1224 face4((texture == -1 ? 0 : texture),
1225 (texture == -1 ? interior_color : exterior_color),
1227 s1, t1, 0.5, x2-0.5, y2-0.5,
1228 s2, t2, 0.5, x1-0.5, y1-0.5,
1229 s3, t3, 0.25, x1-0.5, y1-0.5,
1230 s4, t4, 0.25, x2-0.5, y2-0.5);
1233 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
1235 int j = (i+1 >= countof(lifter_perimiter_points_3) ? 0 : i+1);
1236 GLfloat x1 = lifter_perimiter_points_3[i][0] / 255.0;
1237 GLfloat y1 = lifter_perimiter_points_3[i][1] / 255.0;
1238 GLfloat x2 = lifter_perimiter_points_3[j][0] / 255.0;
1239 GLfloat y2 = lifter_perimiter_points_3[j][1] / 255.0;
1241 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1245 texture = lc->texids[FACE_D];
1246 s1 = 1.0; t1 = 0.235;
1247 s2 = 1.0; t2 = 0.765;
1248 s3 = 0.75; t3 = 0.765;
1249 s4 = 0.75; t4 = 0.235;
1252 face4((texture == -1 ? 0 : texture),
1253 (texture == -1 ? interior_color : exterior_color),
1255 s1, t1, 0.5, x2-0.5, y2-0.5,
1256 s2, t2, 0.5, x1-0.5, y1-0.5,
1257 s3, t3, 0.25, x1-0.5, y1-0.5,
1258 s4, t4, 0.25, x2-0.5, y2-0.5);
1263 /* -------------------------------------------------------------------- */
1265 glNewList(lc->taser_slider, GL_COMPILE);
1266 glShadeModel(GL_SMOOTH);
1269 for (i = 0; i < countof(slider_face_points)/5; i++)
1272 #ifdef HAVE_GLBINDTEXTURE
1273 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1274 #endif /* HAVE_GLBINDTEXTURE */
1275 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1278 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1],
1279 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1280 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1]);
1281 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1282 for (j = 0; j < 5; j++)
1284 int ix = slider_face_points[(i*5)+j][0];
1285 int iy = slider_face_points[(i*5)+j][1];
1287 if (ix == -1) /* these are padding: ignore them */
1292 glVertex3f(0.5, x-0.5, y-0.5);
1298 for (i = countof(slider_face_points)/5 - 1; i >= 0; i--)
1301 #ifdef HAVE_GLBINDTEXTURE
1302 glBindTexture(GL_TEXTURE_2D, 0);
1303 #endif /* HAVE_GLBINDTEXTURE */
1304 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color);
1307 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1],
1308 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1309 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1]);
1310 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1311 for (j = 4; j >= 0; j--)
1313 int ix = slider_face_points[(i*5)+j][0];
1314 int iy = slider_face_points[(i*5)+j][1];
1316 if (ix == -1) /* these are padding: ignore them */
1321 glVertex3f(0.25, x-0.5, y-0.5);
1327 for (i = 0; i < countof(slider_perimiter_points); i++)
1329 int j = (i+1 >= countof(slider_perimiter_points) ? 0 : i+1);
1330 GLfloat x1 = slider_perimiter_points[i][0] / 255.0;
1331 GLfloat y1 = slider_perimiter_points[i][1] / 255.0;
1332 GLfloat x2 = slider_perimiter_points[j][0] / 255.0;
1333 GLfloat y2 = slider_perimiter_points[j][1] / 255.0;
1335 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1339 texture = lc->texids[FACE_S];
1340 s1 = 1.0; t1 = 0.255;
1341 s2 = 1.0; t2 = 0.435;
1342 s3 = 0.75; t3 = 0.435;
1343 s4 = 0.75; t4 = 0.255;
1347 texture = lc->texids[FACE_D];
1348 s1 = 1.0; t1 = 0.758;
1349 s2 = 1.0; t2 = 0.915;
1350 s3 = 0.75; t3 = 0.915;
1351 s4 = 0.75; t4 = 0.758;
1355 texture = lc->texids[FACE_D];
1356 s1 = 1.0; t1 = 0.095;
1357 s2 = 1.0; t2 = 0.24;
1358 s3 = 0.75; t3 = 0.24;
1359 s4 = 0.75; t4 = 0.095;
1363 texture = lc->texids[FACE_N];
1364 s1 = 1.0; t1 = 0.568;
1365 s2 = 1.0; t2 = 0.742;
1366 s3 = 0.75; t3 = 0.742;
1367 s4 = 0.75; t4 = 0.568;
1370 face4((texture == -1 ? 0 : texture),
1371 (texture == -1 ? interior_color : exterior_color),
1373 s1, t1, 0.5, x2-0.5, y2-0.5,
1374 s2, t2, 0.5, x1-0.5, y1-0.5,
1375 s3, t3, 0.25, x1-0.5, y1-0.5,
1376 s4, t4, 0.25, x2-0.5, y2-0.5);
1384 /* Rendering and animating object models
1390 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1391 Bool wire = MI_IS_WIREFRAME(mi);
1394 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1396 glClear(GL_COLOR_BUFFER_BIT);
1400 GLfloat x = lc->rotx;
1401 GLfloat y = lc->roty;
1402 GLfloat z = lc->rotz;
1408 if (x < 0) x = 1 - (x + 1);
1409 if (y < 0) y = 1 - (y + 1);
1410 if (z < 0) z = 1 - (z + 1);
1412 /* Make into the screen be +Y right be +X, and up be +Z. */
1413 glRotatef(-90.0, 1.0, 0.0, 0.0);
1416 glScalef(4.0, 4.0, 4.0);
1421 /* Shift to the upper left, and draw the vanilla box. */
1422 glTranslatef(-0.6, 0.0, 0.6);
1424 /* Apply rotation to the object. */
1425 glRotatef(x * 360, 1.0, 0.0, 0.0);
1426 glRotatef(y * 360, 0.0, 1.0, 0.0);
1427 glRotatef(z * 360, 0.0, 0.0, 1.0);
1430 glCallList(lc->box);
1434 /* Shift to the lower right, and draw the animated object. */
1435 glTranslatef(0.6, 0.0, -0.6);
1441 /* Apply rotation to the object. */
1442 glRotatef(x * 360, 1.0, 0.0, 0.0);
1443 glRotatef(y * 360, 0.0, 1.0, 0.0);
1444 glRotatef(z * 360, 0.0, 0.0, 1.0);
1449 glCallList(lc->box);
1452 case LAMENT_STAR_OUT:
1453 case LAMENT_STAR_ROT:
1454 case LAMENT_STAR_ROT_IN:
1455 case LAMENT_STAR_ROT_OUT:
1456 case LAMENT_STAR_UNROT:
1457 case LAMENT_STAR_IN:
1458 glTranslatef(0.0, 0.0, lc->anim_z/2);
1459 glRotatef(lc->anim_r/2, 0.0, 0.0, 1.0);
1460 glCallList(lc->star1);
1462 glTranslatef(0.0, 0.0, -lc->anim_z);
1463 glRotatef(-lc->anim_r, 0.0, 0.0, 1.0);
1464 glCallList(lc->star2);
1467 case LAMENT_TETRA_UNE:
1468 case LAMENT_TETRA_USW:
1469 case LAMENT_TETRA_DWN:
1470 case LAMENT_TETRA_DSE:
1475 case LAMENT_TETRA_UNE: magic = lc->tetra_une;
1476 x = 1.0; y = 1.0; z = 1.0; break;
1477 case LAMENT_TETRA_USW: magic = lc->tetra_usw;
1478 x = 1.0; y = 1.0; z = -1.0; break;
1479 case LAMENT_TETRA_DWN: magic = lc->tetra_dwn;
1480 x = 1.0; y = -1.0; z = 1.0; break;
1481 case LAMENT_TETRA_DSE: magic = lc->tetra_dse;
1482 x = -1.0; y = 1.0; z = 1.0; break;
1483 default: abort(); break;
1485 glCallList(lc->tetra_mid);
1486 if (magic != lc->tetra_une) glCallList(lc->tetra_une);
1487 if (magic != lc->tetra_usw) glCallList(lc->tetra_usw);
1488 if (magic != lc->tetra_dwn) glCallList(lc->tetra_dwn);
1489 if (magic != lc->tetra_dse) glCallList(lc->tetra_dse);
1490 glRotatef(lc->anim_r, x, y, z);
1495 case LAMENT_LID_OPEN:
1496 case LAMENT_LID_CLOSE:
1497 case LAMENT_LID_ZOOM:
1501 glTranslatef(lc->anim_z, 0.0, 0.0);
1503 glCallList(lc->lid_0);
1506 glTranslatef(-0.5, -d, 0.0);
1507 glRotatef(-lc->anim_r, 0.0, -1.0, -1.0);
1508 glTranslatef( 0.5, d, 0.0);
1509 glCallList(lc->lid_1);
1512 glTranslatef(-0.5, -d, 0.0);
1513 glRotatef( lc->anim_r, 0.0, -1.0, 1.0);
1514 glTranslatef( 0.5, d, 0.0);
1515 glCallList(lc->lid_2);
1518 glTranslatef(-0.5, d, 0.0);
1519 glRotatef( lc->anim_r, 0.0, -1.0, -1.0);
1520 glTranslatef( 0.5, -d, 0.0);
1521 glCallList(lc->lid_3);
1524 glTranslatef(-0.5, d, 0.0);
1525 glRotatef(-lc->anim_r, 0.0, -1.0, 1.0);
1526 glTranslatef( 0.5, -d, 0.0);
1527 glCallList(lc->lid_4);
1532 case LAMENT_TASER_OUT:
1533 case LAMENT_TASER_SLIDE:
1534 case LAMENT_TASER_SLIDE_IN:
1535 case LAMENT_TASER_IN:
1537 glTranslatef(-lc->anim_z/2, 0.0, 0.0);
1538 glCallList(lc->taser_base);
1540 glTranslatef(lc->anim_z, 0.0, 0.0);
1541 glCallList(lc->taser_lifter);
1543 glTranslatef(0.0, 0.0, lc->anim_y);
1544 glCallList(lc->taser_slider);
1560 animate(ModeInfo *mi)
1562 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1564 /* int pause2 = 60;*/
1571 /* Rather than just picking states randomly, pick an ordering randomly,
1572 do it, and then re-randomize. That way one can be assured of seeing
1573 all states in a short time period, though not always in the same
1574 order (it's frustrating to see it pick the same state 5x in a row.)
1576 static lament_type states[] = {
1577 LAMENT_STAR_OUT, LAMENT_STAR_OUT,
1578 LAMENT_TETRA_UNE, LAMENT_TETRA_USW,
1579 LAMENT_TETRA_DWN, LAMENT_TETRA_DSE,
1580 LAMENT_LID_OPEN, LAMENT_LID_OPEN, LAMENT_LID_OPEN,
1581 LAMENT_TASER_OUT, LAMENT_TASER_OUT,
1582 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1583 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1585 static int state = countof(states);
1587 if (state < countof(states))
1589 lc->type = states[state++];
1595 for (i = 0; i < countof(states); i++)
1597 int a = random() % countof(states);
1598 lament_type swap = states[a];
1599 states[a] = states[i];
1604 if (lc->type == LAMENT_BOX)
1605 lc->anim_pause = pause3;
1613 /* -------------------------------------------------------------- */
1615 case LAMENT_STAR_OUT:
1617 if (lc->anim_z >= 1.0)
1620 lc->type = LAMENT_STAR_ROT;
1621 lc->anim_pause = pause;
1625 case LAMENT_STAR_ROT:
1627 if (lc->anim_r >= 45.0)
1630 lc->type = LAMENT_STAR_ROT_IN;
1631 lc->anim_pause = pause;
1635 case LAMENT_STAR_ROT_IN:
1637 if (lc->anim_z <= 0.0)
1640 lc->type = LAMENT_STAR_ROT_OUT;
1641 lc->anim_pause = pause3 * (1 + (random() % 4) + (random() % 4));
1645 case LAMENT_STAR_ROT_OUT:
1647 if (lc->anim_z >= 1.0)
1650 lc->type = LAMENT_STAR_UNROT;
1651 lc->anim_pause = pause;
1655 case LAMENT_STAR_UNROT:
1657 if (lc->anim_r <= 0.0)
1660 lc->type = LAMENT_STAR_IN;
1661 lc->anim_pause = pause;
1665 case LAMENT_STAR_IN:
1667 if (lc->anim_z <= 0.0)
1670 lc->type = LAMENT_BOX;
1671 lc->anim_pause = pause3;
1675 /* -------------------------------------------------------------- */
1677 case LAMENT_TETRA_UNE:
1678 case LAMENT_TETRA_USW:
1679 case LAMENT_TETRA_DWN:
1680 case LAMENT_TETRA_DSE:
1683 if (lc->anim_r >= 360.0)
1686 lc->type = LAMENT_BOX;
1687 lc->anim_pause = pause3;
1689 else if (lc->anim_r > 119.0 && lc->anim_r <= 120.0)
1692 lc->anim_pause = pause;
1694 else if (lc->anim_r > 239.0 && lc->anim_r <= 240.0)
1697 lc->anim_pause = pause;
1701 /* -------------------------------------------------------------- */
1703 case LAMENT_LID_OPEN:
1706 if (lc->anim_r >= 112.0)
1708 GLfloat hysteresis = 0.05;
1712 lc->anim_pause = pause3;
1714 if (lc->rotx >= -hysteresis &&
1715 lc->rotx <= hysteresis &&
1716 ((lc->rotz >= (0.25 - hysteresis) &&
1717 lc->rotz <= (0.25 + hysteresis)) ||
1718 (lc->rotz >= (-0.25 - hysteresis) &&
1719 lc->rotz <= (-0.25 + hysteresis))))
1721 lc->type = LAMENT_LID_ZOOM;
1723 lc->rotz = (lc->rotz < 0 ? -0.25 : 0.25);
1727 lc->type = LAMENT_LID_CLOSE;
1732 case LAMENT_LID_CLOSE:
1734 if (lc->anim_r <= 0.0)
1737 lc->type = LAMENT_BOX;
1738 lc->anim_pause = pause3;
1742 case LAMENT_LID_ZOOM:
1744 if (lc->anim_z < -50.0)
1748 lc->rotx = frand(1.0) * RANDSIGN();
1749 lc->roty = frand(1.0) * RANDSIGN();
1750 lc->rotz = frand(1.0) * RANDSIGN();
1751 lc->type = LAMENT_BOX;
1755 /* -------------------------------------------------------------- */
1757 case LAMENT_TASER_OUT:
1758 lc->anim_z += 0.0025;
1759 if (lc->anim_z >= 0.25)
1762 lc->type = LAMENT_TASER_SLIDE;
1763 lc->anim_pause = pause * (1 + (random() % 5) + (random() % 5));
1767 case LAMENT_TASER_SLIDE:
1768 lc->anim_y += 0.0025;
1769 if (lc->anim_y >= 0.23)
1772 lc->type = LAMENT_TASER_SLIDE_IN;
1773 lc->anim_pause = pause3 * (1 + (random() % 5) + (random() % 5));
1777 case LAMENT_TASER_SLIDE_IN:
1778 lc->anim_y -= 0.0025;
1779 if (lc->anim_y <= 0.0)
1782 lc->type = LAMENT_TASER_IN;
1783 lc->anim_pause = pause;
1787 case LAMENT_TASER_IN:
1788 lc->anim_z -= 0.0025;
1789 if (lc->anim_z <= 0.0)
1792 lc->type = LAMENT_BOX;
1793 lc->anim_pause = pause3;
1805 rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v)
1811 ppos = -(ppos + *v);
1820 if (ppos < 0) abort();
1821 if (ppos > 1.0) abort();
1822 *pos = (*pos > 0 ? ppos : -ppos);
1827 /* clamp velocity */
1828 if (*v > max_v || *v < -max_v)
1832 /* If it stops, start it going in the other direction. */
1839 /* keep going in the same direction */
1854 /* Alter direction of rotational acceleration randomly. */
1855 if (! (random() % 120))
1858 /* Change acceleration very occasionally. */
1859 if (! (random() % 200))
1863 else if (random() & 1)
1872 /* Window management, etc
1876 reshape(int width, int height)
1878 int target_size = 180;
1879 int win_size = (width > height ? height : width);
1880 GLfloat h = (GLfloat) height / (GLfloat) width;
1882 glViewport(0, 0, (GLint) width, (GLint) height);
1884 /* glViewport(-600, -600, 1800, 1800); */
1886 glMatrixMode(GL_PROJECTION);
1888 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
1889 glMatrixMode(GL_MODELVIEW);
1891 glTranslatef(0.0, 0.0, -40.0);
1893 /* This scale makes the box take up most of the window */
1894 glScalef(2.0, 2.0, 2.0);
1896 /* But if the window is more than a little larger than our target size,
1897 scale the object back down, so that the bits drawn on the screen end
1898 up rougly target_size across (actually it ends up a little larger.)
1899 Note that the image-map bits we have are 128x128. Therefore, if the
1900 image is magnified a lot, it looks pretty blocky. So it's better to
1901 have a 128x128 animation on a 1280x1024 screen that looks good, than
1902 a 1024x1024 animation that looks really pixellated.
1904 if (win_size > target_size * 1.5)
1906 GLfloat ratio = ((GLfloat) target_size / (GLfloat) win_size);
1908 glScalef(ratio, ratio, ratio);
1911 /* The depth buffer will be cleared, if needed, before the
1912 * next frame. Right now we just want to black the screen.
1914 glClear(GL_COLOR_BUFFER_BIT);
1919 gl_init(ModeInfo *mi)
1921 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1922 Bool wire = MI_IS_WIREFRAME(mi);
1929 static GLfloat pos0[] = { -4.0, 2.0, 5.0, 1.0 };
1930 static GLfloat pos1[] = { 12.0, 5.0, 1.0, 1.0 };
1931 static GLfloat local[] = { 0.0 };
1932 static GLfloat ambient[] = { 0.3, 0.3, 0.3, 1.0 };
1933 static GLfloat spec[] = { 1.0, 1.0, 1.0, 1.0 };
1934 static GLfloat shine[] = { 100.0 };
1936 glLightfv(GL_LIGHT0, GL_POSITION, pos0);
1937 glLightfv(GL_LIGHT1, GL_POSITION, pos1);
1939 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
1940 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
1942 glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
1943 glLightfv(GL_LIGHT1, GL_SPECULAR, spec);
1945 glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local);
1946 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1947 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
1948 glMaterialfv(GL_FRONT, GL_SHININESS, shine);
1950 glEnable(GL_LIGHTING);
1951 glEnable(GL_LIGHT0);
1952 glEnable(GL_LIGHT1);
1953 glDisable(GL_LIGHT1);
1955 glEnable(GL_DEPTH_TEST);
1956 glEnable(GL_TEXTURE_2D);
1957 glEnable(GL_NORMALIZE);
1958 glEnable(GL_CULL_FACE);
1963 #ifdef HAVE_GLBINDTEXTURE
1965 for (i = 0; i < 6; i++)
1966 glGenTextures(1, &lc->texids[i]);
1968 parse_image_data(mi);
1970 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1971 glPixelStorei(GL_UNPACK_ROW_LENGTH, lc->texture->width);
1973 for (i = 0; i < 6; i++)
1975 int height = lc->texture->width; /* assume square */
1976 glBindTexture(GL_TEXTURE_2D, lc->texids[i]);
1977 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1978 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
1979 lc->texture->width, height, 0,
1980 GL_RGBA, GL_UNSIGNED_BYTE,
1981 (lc->texture->data +
1982 (lc->texture->bytes_per_line * height * i)));
1984 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1985 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1986 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1987 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1988 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1989 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1992 #else /* !HAVE_GLBINDTEXTURE */
1994 "%s: this version of GL doesn't support multiple texture maps.\n"
1995 "\tGet OpenGL 1.1.\n",
1998 #endif /* !HAVE_GLBINDTEXTURE */
2001 lc->box = glGenLists(16);
2002 lc->star1 = lc->box+1;
2003 lc->star2 = lc->box+2;
2004 lc->tetra_une = lc->box+3;
2005 lc->tetra_usw = lc->box+4;
2006 lc->tetra_dwn = lc->box+5;
2007 lc->tetra_dse = lc->box+6;
2008 lc->tetra_mid = lc->box+7;
2009 lc->lid_0 = lc->box+8;
2010 lc->lid_1 = lc->box+9;
2011 lc->lid_2 = lc->box+10;
2012 lc->lid_3 = lc->box+11;
2013 lc->lid_4 = lc->box+12;
2014 lc->taser_base = lc->box+13;
2015 lc->taser_lifter = lc->box+14;
2016 lc->taser_slider = lc->box+15;
2019 star(mi, True, wire);
2020 star(mi, False, wire);
2027 # ifdef HAVE_MESA_GL
2029 # include <signal.h>
2032 lament_signal_kludge (int sig)
2034 signal (sig, SIG_DFL);
2037 "%s: dying with signal %d (%s).\n"
2039 "\tThis is almost certainly a bug in the MesaGL library,\n"
2040 "\tespecially if the stack trace in the core file mentions\n"
2041 "\t`lambda_textured_triangle' or `render_quad'.\n"
2043 "\tI encourage you to report this to the Mesa maintainers\n"
2044 "\tat <http://www.mesa3d.org/>. I reported this bug more\n"
2045 "\tthan a year ago, and it is trivially reproducible.\n"
2046 "\tI do not know a workaround.\n"
2050 (sig == SIGILL ? "SIGILL" :
2051 sig == SIGFPE ? "SIGFPE" :
2052 sig == SIGBUS ? "SIGBUS" :
2053 sig == SIGSEGV ? "SIGSEGV" : "???"));
2055 kill (getpid (), sig);
2059 handle_signals (void)
2061 signal (SIGILL, lament_signal_kludge);
2062 signal (SIGFPE, lament_signal_kludge);
2063 signal (SIGBUS, lament_signal_kludge);
2064 signal (SIGSEGV, lament_signal_kludge);
2066 # endif /* HAVE_MESA_GL */
2070 init_lament(ModeInfo *mi)
2072 lament_configuration *lc;
2075 lcs = (lament_configuration *)
2076 calloc(MI_NUM_SCREENS(mi), sizeof (lament_configuration));
2079 fprintf(stderr, "%s: out of memory\n", progname);
2084 lc = &lcs[MI_SCREEN(mi)];
2086 lc->rotx = frand(1.0) * RANDSIGN();
2087 lc->roty = frand(1.0) * RANDSIGN();
2088 lc->rotz = frand(1.0) * RANDSIGN();
2090 /* bell curve from 0-1.5 degrees, avg 0.75 */
2091 lc->dx = (frand(1) + frand(1) + frand(1)) / (360*2);
2092 lc->dy = (frand(1) + frand(1) + frand(1)) / (360*2);
2093 lc->dz = (frand(1) + frand(1) + frand(1)) / (360*2);
2095 lc->d_max = lc->dx * 2;
2097 lc->ddx = 0.00006 + frand(0.00003);
2098 lc->ddy = 0.00006 + frand(0.00003);
2099 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(MI_WIDTH(mi), MI_HEIGHT(mi));
2114 # ifdef HAVE_MESA_GL
2116 # endif /* HAVE_MESA_GL */
2121 draw_lament(ModeInfo *mi)
2123 static int tick = 0;
2124 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
2125 Display *dpy = MI_DISPLAY(mi);
2126 Window window = MI_WINDOW(mi);
2128 if (!lc->glx_context)
2131 glDrawBuffer(GL_BACK);
2133 glXMakeCurrent(dpy, window, *(lc->glx_context));
2136 glXSwapBuffers(dpy, window);
2138 if (lc->type != LAMENT_LID_ZOOM)
2140 rotate(&lc->rotx, &lc->dx, &lc->ddx, lc->d_max);
2141 rotate(&lc->roty, &lc->dy, &lc->ddy, lc->d_max);
2142 rotate(&lc->rotz, &lc->dz, &lc->ddz, lc->d_max);
2153 reshape(MI_WIDTH(mi), MI_HEIGHT(mi));