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"
113 #include "../images/lament.xpm"
115 #define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n))))
116 #define RANDSIGN() ((random() & 1) ? 1 : -1)
139 LAMENT_TASER_SLIDE_IN,
144 static GLfloat exterior_color[] = { 0.33, 0.22, 0.03, 1.00, /* ambient */
145 0.78, 0.57, 0.11, 1.00, /* specular */
146 0.99, 0.91, 0.81, 1.00, /* diffuse */
147 27.80 /* shininess */
149 static GLfloat interior_color[] = { 0.20, 0.20, 0.15, 1.00, /* ambient */
150 0.40, 0.40, 0.32, 1.00, /* specular */
151 0.99, 0.99, 0.81, 1.00, /* diffuse */
152 50.80 /* shininess */
157 GLXContext *glx_context;
159 GLuint box; /* display list IDs */
161 GLuint tetra_une, tetra_usw, tetra_dwn, tetra_dse, tetra_mid;
162 GLuint lid_0, lid_1, lid_2, lid_3, lid_4;
163 GLuint taser_base, taser_lifter, taser_slider;
165 GLfloat rotx, roty, rotz; /* current object rotation */
166 GLfloat dx, dy, dz; /* current rotational velocity */
167 GLfloat ddx, ddy, ddz; /* current rotational acceleration */
168 GLfloat d_max; /* max velocity */
169 XImage *texture; /* image bits */
170 GLuint texids[6]; /* texture map IDs */
171 lament_type type; /* which mode of the object is current */
173 int anim_pause; /* countdown before animating again */
174 GLfloat anim_r, anim_y, anim_z; /* relative position during anims */
176 } lament_configuration;
178 static lament_configuration *lcs = NULL;
188 parse_image_data(ModeInfo *mi)
190 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
191 lc->texture = xpm_to_ximage (mi->dpy,
198 /* Computing normal vectors (thanks to Nat Friedman <ndf@mit.edu>)
201 typedef struct vector {
205 typedef struct plane {
210 vector_set(vector *v, GLfloat x, GLfloat y, GLfloat z)
218 vector_cross(vector v1, vector v2, vector *v3)
220 v3->x = (v1.y * v2.z) - (v1.z * v2.y);
221 v3->y = (v1.z * v2.x) - (v1.x * v2.z);
222 v3->z = (v1.x * v2.y) - (v1.y * v2.x);
226 vector_subtract(vector v1, vector v2, vector *res)
228 res->x = v1.x - v2.x;
229 res->y = v1.y - v2.y;
230 res->z = v1.z - v2.z;
234 plane_normal(plane p, vector *n)
237 vector_subtract(p.p1, p.p2, &v1);
238 vector_subtract(p.p1, p.p3, &v2);
239 vector_cross(v2, v1, n);
243 do_normal(GLfloat x1, GLfloat y1, GLfloat z1,
244 GLfloat x2, GLfloat y2, GLfloat z2,
245 GLfloat x3, GLfloat y3, GLfloat z3)
249 vector_set(&plane.p1, x1, y1, z1);
250 vector_set(&plane.p2, x2, y2, z2);
251 vector_set(&plane.p3, x3, y3, z3);
252 plane_normal(plane, &n);
253 n.x = -n.x; n.y = -n.y; n.z = -n.z;
255 glNormal3f(n.x, n.y, n.z);
258 /* Draw a line in the direction of this face's normal. */
260 GLfloat ax = n.x > 0 ? n.x : -n.x;
261 GLfloat ay = n.y > 0 ? n.y : -n.y;
262 GLfloat az = n.z > 0 ? n.z : -n.z;
263 GLfloat mx = (x1 + x2 + x3) / 3;
264 GLfloat my = (y1 + y2 + y3) / 3;
265 GLfloat mz = (z1 + z2 + z3) / 3;
268 GLfloat max = ax > ay ? ax : ay;
269 if (az > max) max = az;
275 glBegin(GL_LINE_LOOP);
276 glVertex3f(mx, my, mz);
277 glVertex3f(mx+xx, my+yy, mz+zz);
285 /* Shorthand utilities for making faces, with proper normals.
289 set_colors (GLfloat *color)
291 glMaterialfv(GL_FRONT, GL_AMBIENT, color+0);
292 glMaterialfv(GL_FRONT, GL_DIFFUSE, color+4);
293 glMaterialfv(GL_FRONT, GL_SPECULAR, color+8);
294 glMaterialfv(GL_FRONT, GL_SHININESS, color+12);
298 face3(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)
303 #ifdef HAVE_GLBINDTEXTURE
304 glBindTexture(GL_TEXTURE_2D, texture);
305 #endif /* HAVE_GLBINDTEXTURE */
308 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
309 glBegin(wire ? GL_LINE_LOOP : GL_TRIANGLES);
310 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
311 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
312 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
317 face4(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)
323 #ifdef HAVE_GLBINDTEXTURE
324 glBindTexture(GL_TEXTURE_2D, texture);
325 #endif /* HAVE_GLBINDTEXTURE */
327 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
328 glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
329 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
330 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
331 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
332 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
337 face5(GLint texture, GLfloat *color, Bool wire,
338 GLfloat s1, GLfloat t1, GLfloat x1, GLfloat y1, GLfloat z1,
339 GLfloat s2, GLfloat t2, GLfloat x2, GLfloat y2, GLfloat z2,
340 GLfloat s3, GLfloat t3, GLfloat x3, GLfloat y3, GLfloat z3,
341 GLfloat s4, GLfloat t4, GLfloat x4, GLfloat y4, GLfloat z4,
342 GLfloat s5, GLfloat t5, GLfloat x5, GLfloat y5, GLfloat z5)
344 #ifdef HAVE_GLBINDTEXTURE
345 glBindTexture(GL_TEXTURE_2D, texture);
346 #endif /* HAVE_GLBINDTEXTURE */
348 do_normal(x1, y1, z1, x2, y2, z2, x3, y3, z3);
349 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
350 glTexCoord2f(s1, t1); glVertex3f(x1, y1, z1);
351 glTexCoord2f(s2, t2); glVertex3f(x2, y2, z2);
352 glTexCoord2f(s3, t3); glVertex3f(x3, y3, z3);
353 glTexCoord2f(s4, t4); glVertex3f(x4, y4, z4);
354 glTexCoord2f(s5, t5); glVertex3f(x5, y5, z5);
360 /* Creating object models
364 box(ModeInfo *mi, Bool wire)
366 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
368 glNewList(lc->box, GL_COMPILE);
369 glShadeModel(GL_SMOOTH);
372 face4(lc->texids[FACE_N], exterior_color, wire,
373 0.0, 0.0, -0.5, 0.5, 0.5,
374 1.0, 0.0, 0.5, 0.5, 0.5,
375 1.0, 1.0, 0.5, 0.5, -0.5,
376 0.0, 1.0, -0.5, 0.5, -0.5);
379 face4(lc->texids[FACE_S], exterior_color, wire,
380 0.0, 0.0, -0.5, -0.5, -0.5,
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);
386 face4(lc->texids[FACE_E], exterior_color, wire,
387 0.0, 0.0, 0.5, -0.5, -0.5,
388 1.0, 0.0, 0.5, 0.5, -0.5,
389 1.0, 1.0, 0.5, 0.5, 0.5,
390 0.0, 1.0, 0.5, -0.5, 0.5);
393 face4(lc->texids[FACE_W], exterior_color, wire,
394 1.0, 1.0, -0.5, -0.5, 0.5,
395 0.0, 1.0, -0.5, 0.5, 0.5,
396 0.0, 0.0, -0.5, 0.5, -0.5,
397 1.0, 0.0, -0.5, -0.5, -0.5);
400 face4(lc->texids[FACE_U], exterior_color, wire,
401 1.0, 0.0, 0.5, -0.5, 0.5,
402 1.0, 1.0, 0.5, 0.5, 0.5,
403 0.0, 1.0, -0.5, 0.5, 0.5,
404 0.0, 0.0, -0.5, -0.5, 0.5);
407 face4(lc->texids[FACE_D], exterior_color, wire,
408 0.0, 1.0, -0.5, -0.5, -0.5,
409 0.0, 0.0, -0.5, 0.5, -0.5,
410 1.0, 0.0, 0.5, 0.5, -0.5,
411 1.0, 1.0, 0.5, -0.5, -0.5);
418 star(ModeInfo *mi, Bool top, Bool wire)
420 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
424 { 77, 74 }, { 60, 98 }, { 0, 71 }, { 0, 0 }, /* L1 */
425 { 60, 98 }, { 55, 127 }, { 0, 127 }, { 0, 71 }, /* L2 */
426 { 55, 127 }, { 60, 154 }, { 0, 179 }, { 0, 127 }, /* L3 */
427 { 60, 154 }, { 76, 176 }, { 0, 255 }, { 0, 179 }, /* L4 */
428 { 76, 176 }, { 100, 193 }, { 74, 255 }, { 0, 255 }, /* B1 */
429 { 100, 193 }, { 127, 198 }, { 127, 255 }, { 74, 255 }, /* B2 */
430 { 127, 198 }, { 151, 193 }, { 180, 255 }, { 127, 255 }, /* B3 */
431 { 151, 193 }, { 178, 177 }, { 255, 255 }, { 180, 255 }, /* B4 */
432 { 178, 177 }, { 193, 155 }, { 255, 181 }, { 255, 255 }, /* R4 */
433 { 193, 155 }, { 199, 127 }, { 255, 127 }, { 255, 181 }, /* R3 */
434 { 199, 127 }, { 194, 99 }, { 255, 74 }, { 255, 127 }, /* R2 */
435 { 194, 99 }, { 179, 76 }, { 255, 0 }, { 255, 74 }, /* R1 */
436 { 179, 76 }, { 155, 60 }, { 180, 0 }, { 255, 0 }, /* T4 */
437 { 155, 60 }, { 126, 55 }, { 126, 0 }, { 180, 0 }, /* T3 */
438 { 126, 55 }, { 100, 60 }, { 75, 0 }, { 126, 0 }, /* T2 */
439 { 100, 60 }, { 77, 74 }, { 0, 0 }, { 75, 0 }, /* T1 */
442 for (i = 0; i < countof(points); i++)
443 points[i][1] = 255-points[i][1];
446 glNewList(lc->star1, GL_COMPILE);
448 glNewList(lc->star2, GL_COMPILE);
451 glRotatef(-180.0, 1.0, 0.0, 0.0);
453 for (i = 0; i < countof(points)/4; i += 2)
460 GLfloat s[4], t[4], x[4], y[4], z[4];
461 for (j = 3, k = 0; j >= 0; j--, k++)
463 GLfloat xx = points[(i*4)+j][0] / 255.0L;
464 GLfloat yy = points[(i*4)+j][1] / 255.0L;
471 face4(lc->texids[top ? FACE_U : FACE_D], exterior_color, wire,
472 s[0], t[0], x[0], y[0], z[0],
473 s[1], t[1], x[1], y[1], z[1],
474 s[2], t[2], x[2], y[2], z[2],
475 s[3], t[3], x[3], y[3], z[3]);
479 for (j = 0, k = 0; j < 4; j++, k++)
481 GLfloat xx = points[(i*4)+j][0] / 255.0L;
482 GLfloat yy = points[(i*4)+j][1] / 255.0L;
489 face4(lc->texids[top ? FACE_U : FACE_D], exterior_color, wire,
490 s[0], t[0], x[0], y[0], z[0],
491 s[1], t[1], x[1], y[1], z[1],
492 s[2], t[2], x[2], y[2], z[2],
493 s[3], t[3], x[3], y[3], z[3]);
497 for (j = 3; j >= 0; j--)
499 int k = (j == 0 ? 3 : j-1);
500 Bool front_p = (j == 3);
501 GLfloat x1 = points[(i*4)+j][0] / 255.0L;
502 GLfloat y1 = points[(i*4)+j][1] / 255.0L;
503 GLfloat x2 = points[(i*4)+k][0] / 255.0L;
504 GLfloat y2 = points[(i*4)+k][1] / 255.0L;
506 GLfloat tx1=0.0, tx2=1.0, ty1=0.0, ty2=1.0;
510 facing = (facing + j + 5) % 4;
516 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
517 ty1 = 0.0; ty2 = 1.0;
520 ty1 = 1.0; ty2 = 0.0;
524 texture = top ? FACE_S : FACE_N;
526 ty1 = 0.0; ty2 = 1.0;
532 ty1 = 0.0; ty2 = 1.0;
534 tx1 = 1.0 - y1; tx2 = 1.0 - y2;
535 ty1 = 1.0; ty2 = 0.0;
539 texture = top ? FACE_N : FACE_S;
541 ty1 = 1.0; ty2 = 0.0;
545 x1 -= 0.5; x2 -= 0.5;
546 y1 -= 0.5; y2 -= 0.5;
548 face4(front_p ? lc->texids[texture] : 0,
549 front_p ? exterior_color : interior_color,
551 tx1, ty2, x1, y1, 0.5,
552 tx1, ty1, x1, y1, -0.5,
553 tx2, ty1, x2, y2, -0.5,
554 tx2, ty2, x2, y2, 0.5);
559 /* Central core top cap.
561 #ifdef HAVE_GLBINDTEXTURE
562 glBindTexture(GL_TEXTURE_2D, lc->texids[top ? FACE_U : FACE_D]);
563 #endif /* HAVE_GLBINDTEXTURE */
564 set_colors(exterior_color);
567 do_normal(points[i+0][0], points[i+0][1], 0,
568 points[i+4][0], points[i+4][1], 0,
569 points[i+8][0], points[i+8][1], 0);
570 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
571 for (i = 1; i < countof(points); i += 4)
573 GLfloat x = points[i][0] / 255.0L;
574 GLfloat y = points[i][1] / 255.0L;
576 glVertex3f(x-0.5, y-0.5, 0.5);
581 /* Central core bottom cap.
583 #ifdef HAVE_GLBINDTEXTURE
584 glBindTexture(GL_TEXTURE_2D, 0);
585 #endif /* HAVE_GLBINDTEXTURE */
586 set_colors(interior_color);
588 i = countof(points) - 9;
589 do_normal(points[i+0][0], points[i+0][1], 0,
590 points[i+4][0], points[i+4][1], 0,
591 points[i+8][0], points[i+8][1], 0);
593 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
594 for (i = countof(points) - 3; i >= 0; i -= 4)
596 GLfloat x = points[i][0] / 255.0L;
597 GLfloat y = points[i][1] / 255.0L;
598 glVertex3f(x-0.5, y-0.5, 0);
603 /* Central core walls.
605 for (i = 1; i < countof(points); i += 4)
608 GLfloat x1 = points[i-1][0] / 255.0L;
609 GLfloat y1 = points[i-1][1] / 255.0L;
610 GLfloat x2 = points[i][0] / 255.0L;
611 GLfloat y2 = points[i][1] / 255.0L;
612 face4(0, interior_color, wire,
613 0.0, 0.0, x1-0.5, y1-0.5, 0.5,
614 0.0, 0.0, x1-0.5, y1-0.5, 0.0,
615 0.0, 0.0, x2-0.5, y2-0.5, 0.0,
616 0.0, 0.0, x2-0.5, y2-0.5, 0.5);
624 tetra(ModeInfo *mi, Bool wire)
626 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
628 glNewList(lc->tetra_une, GL_COMPILE);
630 glShadeModel(GL_SMOOTH);
633 face3(lc->texids[FACE_U], exterior_color, wire,
634 1.0, 0.0, 0.5, -0.5, 0.5,
635 1.0, 1.0, 0.5, 0.5, 0.5,
636 0.0, 1.0, -0.5, 0.5, 0.5);
639 face3(lc->texids[FACE_N], exterior_color, wire,
640 0.0, 0.0, -0.5, 0.5, 0.5,
641 1.0, 0.0, 0.5, 0.5, 0.5,
642 1.0, 1.0, 0.5, 0.5, -0.5);
645 face3(lc->texids[FACE_E], exterior_color, wire,
646 1.0, 0.0, 0.5, 0.5, -0.5,
647 1.0, 1.0, 0.5, 0.5, 0.5,
648 0.0, 1.0, 0.5, -0.5, 0.5);
650 face3(0, interior_color, wire,
651 0.0, 0.0, 0.5, 0.5, -0.5,
652 0.0, 0.0, 0.5, -0.5, 0.5,
653 0.0, 0.0, -0.5, 0.5, 0.5);
657 glNewList(lc->tetra_usw, GL_COMPILE);
660 face3(lc->texids[FACE_U], exterior_color, wire,
661 0.0, 1.0, -0.5, 0.5, 0.5,
662 0.0, 0.0, -0.5, -0.5, 0.5,
663 1.0, 0.0, 0.5, -0.5, 0.5);
666 face3(lc->texids[FACE_S], exterior_color, wire,
667 1.0, 1.0, 0.5, -0.5, 0.5,
668 0.0, 1.0, -0.5, -0.5, 0.5,
669 0.0, 0.0, -0.5, -0.5, -0.5);
672 face3(lc->texids[FACE_W], exterior_color, wire,
673 1.0, 0.0, -0.5, -0.5, -0.5,
674 1.0, 1.0, -0.5, -0.5, 0.5,
675 0.0, 1.0, -0.5, 0.5, 0.5);
677 face3(0, interior_color, wire,
678 0.0,0.0, -0.5, -0.5, -0.5,
679 0.0,0.0, -0.5, 0.5, 0.5,
680 0.0,0.0, 0.5, -0.5, 0.5);
684 glNewList(lc->tetra_dwn, GL_COMPILE);
687 face3(lc->texids[FACE_D], exterior_color, wire,
688 0.0, 1.0, -0.5, -0.5, -0.5,
689 0.0, 0.0, -0.5, 0.5, -0.5,
690 1.0, 0.0, 0.5, 0.5, -0.5);
693 face3(lc->texids[FACE_W], exterior_color, wire,
694 0.0, 1.0, -0.5, 0.5, 0.5,
695 0.0, 0.0, -0.5, 0.5, -0.5,
696 1.0, 0.0, -0.5, -0.5, -0.5);
699 face3(lc->texids[FACE_N], exterior_color, wire,
700 1.0, 1.0, 0.5, 0.5, -0.5,
701 0.0, 1.0, -0.5, 0.5, -0.5,
702 0.0, 0.0, -0.5, 0.5, 0.5);
704 face3(0, interior_color, wire,
705 0.0, 0.0, 0.5, 0.5, -0.5,
706 0.0, 0.0, -0.5, 0.5, 0.5,
707 0.0, 0.0, -0.5, -0.5, -0.5);
711 glNewList(lc->tetra_dse, GL_COMPILE);
714 face3(lc->texids[FACE_S], exterior_color, wire,
715 0.0, 0.0, -0.5, -0.5, -0.5,
716 1.0, 0.0, 0.5, -0.5, -0.5,
717 1.0, 1.0, 0.5, -0.5, 0.5);
720 face3(lc->texids[FACE_E], exterior_color, wire,
721 0.0, 1.0, 0.5, -0.5, 0.5,
722 0.0, 0.0, 0.5, -0.5, -0.5,
723 1.0, 0.0, 0.5, 0.5, -0.5);
726 face3(lc->texids[FACE_D], exterior_color, wire,
727 1.0, 0.0, 0.5, 0.5, -0.5,
728 1.0, 1.0, 0.5, -0.5, -0.5,
729 0.0, 1.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);
738 glNewList(lc->tetra_mid, GL_COMPILE);
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);
745 face3(0, interior_color, wire,
746 0.0, 0.0, -0.5, 0.5, 0.5,
747 0.0, 0.0, -0.5, -0.5, -0.5,
748 0.0, 0.0, 0.5, -0.5, 0.5);
750 face3(0, interior_color, wire,
751 0.0, 0.0, -0.5, 0.5, 0.5,
752 0.0, 0.0, 0.5, 0.5, -0.5,
753 0.0, 0.0, -0.5, -0.5, -0.5);
755 face3(0, interior_color, wire,
756 0.0, 0.0, 0.5, 0.5, -0.5,
757 0.0, 0.0, 0.5, -0.5, 0.5,
758 0.0, 0.0, -0.5, -0.5, -0.5);
760 face3(0, interior_color, wire,
761 0.0, 0.0, 0.5, -0.5, 0.5,
762 0.0, 0.0, 0.5, 0.5, -0.5,
763 0.0, 0.0, -0.5, -0.5, -0.5);
770 lid(ModeInfo *mi, Bool wire)
772 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
776 { 128, 20 },{ 21, 129 },{ 0, 129 },{ 0, 0 },{ 128, 0 }, /* L1 */
777 { 21, 129 },{ 127, 234 },{ 127, 255 },{ 0, 255 },{ 0, 129 }, /* L2 */
778 { 127, 234 },{ 233, 127 },{ 255, 127 },{ 255, 255 },{ 127, 255 }, /* R2 */
779 { 233, 127 },{ 128, 20 },{ 128, 0 },{ 255, 0 },{ 255, 127 }, /* R1 */
782 for (i = 0; i < countof(points); i++)
783 points[i][1] = 255-points[i][1];
785 glNewList(lc->lid_0, GL_COMPILE);
786 glShadeModel(GL_SMOOTH);
789 face4(lc->texids[FACE_N], exterior_color, wire,
790 0.0, 0.0, -0.5, 0.5, 0.5,
791 1.0, 0.0, 0.5, 0.5, 0.5,
792 1.0, 1.0, 0.5, 0.5, -0.5,
793 0.0, 1.0, -0.5, 0.5, -0.5);
796 face4(lc->texids[FACE_S], exterior_color, wire,
797 0.0, 0.0, -0.5, -0.5, -0.5,
798 1.0, 0.0, 0.5, -0.5, -0.5,
799 1.0, 1.0, 0.5, -0.5, 0.5,
800 0.0, 1.0, -0.5, -0.5, 0.5);
803 face4(lc->texids[FACE_E], exterior_color, wire,
804 0.0, 0.0, 0.5, -0.5, -0.5,
805 1.0, 0.0, 0.5, 0.5, -0.5,
806 1.0, 1.0, 0.5, 0.5, 0.5,
807 0.0, 1.0, 0.5, -0.5, 0.5);
810 face4(lc->texids[FACE_U], exterior_color, wire,
811 1.0, 0.0, 0.5, -0.5, 0.5,
812 1.0, 1.0, 0.5, 0.5, 0.5,
813 0.0, 1.0, -0.5, 0.5, 0.5,
814 0.0, 0.0, -0.5, -0.5, 0.5);
817 face4(lc->texids[FACE_D], exterior_color, wire,
818 0.0, 1.0, -0.5, -0.5, -0.5,
819 0.0, 0.0, -0.5, 0.5, -0.5,
820 1.0, 0.0, 0.5, 0.5, -0.5,
821 1.0, 1.0, 0.5, -0.5, -0.5);
824 for (i = 0; i < countof(points)/5; i++)
827 GLfloat s[5], t[5], x[5], y[5], z[5];
828 for (j = 0; j < 5; j++)
830 GLfloat xx = points[(i*5)+j][0] / 255.0L;
831 GLfloat yy = points[(i*5)+j][1] / 255.0L;
838 face5(lc->texids[FACE_W], exterior_color, wire,
839 s[0], t[0], x[0], y[0], z[0],
840 s[1], t[1], x[1], y[1], z[1],
841 s[2], t[2], x[2], y[2], z[2],
842 s[3], t[3], x[3], y[3], z[3],
843 s[4], t[4], x[4], y[4], z[4]);
848 /* W -- lid_1 through lid_4 */
849 for (i = 0; i < 4; i++)
851 GLfloat x1, y1, x2, y2, x3, y3;
853 glNewList(lc->lid_1 + i, GL_COMPILE);
854 glShadeModel(GL_SMOOTH);
856 x1 = points[(i*5)+1][0] / 255.0L;
857 y1 = points[(i*5)+1][1] / 255.0L;
858 x2 = points[(i*5)][0] / 255.0L;
859 y2 = points[(i*5)][1] / 255.0L;
864 face3(lc->texids[FACE_W], exterior_color, wire,
865 1.0-x1, y1, -0.5, x1-0.5, y1-0.5,
866 1.0-x2, y2, -0.5, x2-0.5, y2-0.5,
867 1.0-x3, y3, -0.5, x3-0.5, y3-0.5);
870 face3(0, interior_color, wire,
871 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
872 0.0, 0.0, -0.48, x1-0.5, y1-0.5,
873 0.0, 0.0, -0.48, x3-0.5, y3-0.5);
876 face4(0, interior_color, wire,
877 0.0, 0.0, -0.5, x1-0.5, y1-0.5,
878 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
879 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
880 0.0, 0.0, -0.48, x1-0.5, y1-0.5);
883 face4(0, interior_color, wire,
884 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
885 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
886 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
887 0.0, 0.0, -0.5, x2-0.5, y2-0.5);
894 taser(ModeInfo *mi, Bool wire)
896 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
899 int slider_face_points[][2] = {
900 { 86, 58 },{ 38, 106 },{ 70, 106 },{ 118, 58 },{ -1, -1 }, /* a */
901 { 136, 58 },{ 184, 106 },{ 216, 106 },{ 168, 58 },{ -1, -1 }, /* b */
902 { 38, 106 },{ 0, 144 },{ 0, 190 },{ 60, 190 },{ 108, 106 }, /* c */
903 { 144, 106 },{ 194, 190 },{ 254, 190 },{ 254, 144 },{ 216, 106 }, /* d */
904 { 98, 124 },{ 60, 190 },{ 92, 190 },{ 126, 158 },{ 126, 124 }, /* e */
905 { 126, 124 },{ 126, 158 },{ 160, 190 },{ 194, 190 },{ 154, 124 }, /* f */
906 { 22, 190 },{ 22, 254 },{ 60, 254 },{ 60, 190 },{ -1, -1 }, /* g */
907 { 194, 190 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ -1, -1 }, /* h */
908 { 60, 190 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ -1, -1 }, /* i */
909 { 160, 190 },{ 160, 210 },{ 194, 210 },{ 194, 190 },{ -1, -1 }, /* j */
910 { 110, 172 },{ 92, 190 },{ 110, 190 },{ -1, -1 },{ -1, -1 }, /* k */
911 { 140, 172 },{ 140, 190 },{ 160, 190 },{ -1, -1 },{ -1, -1 }, /* l */
912 { 110, 172 },{ 140, 172 },{ 126, 156 },{ -1, -1 },{ -1, -1 }, /* m */
915 int body_face_points[][2] = {
916 { 0, 0 },{ 0, 58 },{ 254, 58 },{ 254, 0 },{ -1, -1 }, /* A */
917 { 0, 58 },{ 0, 144 },{ 86, 58 },{ -1, -1 },{ -1, -1 }, /* B */
918 { 168, 58 },{ 254, 144 },{ 254, 58 },{ -1, -1 },{ -1, -1 }, /* C */
919 { 118, 58 },{ 70, 106 },{ 184, 106 },{ 136, 58 },{ -1, -1 }, /* F */
920 { 108, 106 },{ 98, 124 },{ 154, 124 },{ 144, 106 },{ -1, -1 }, /* G */
923 int lifter_face_points[][2] = {
924 { 0, 190 },{ 0, 254 },{ 22, 254 },{ 22, 190 },{ -1, -1 }, /* D */
925 { 230, 190 },{ 230, 254 },{ 254, 254 },{ 254, 190 },{ -1, -1 }, /* E */
926 { 60, 210 },{ 60, 254 },{ 194, 254 },{ 194, 210 },{ -1, -1 }, /* H */
927 { 92, 190 },{ 92, 210 },{ 160, 210 },{ 160, 190 },{ -1, -1 }, /* I */
928 { 110, 172 },{ 110, 190 },{ 140, 190 },{ 140, 172 },{ -1, -1 }, /* J */
931 int body_perimiter_points[][2] = {
932 { 0, 144 },{ 86, 59 },{ 119, 58 },{ 71, 107 },
933 { 108, 107 },{ 98, 124 },{ 155, 124 },{ 144, 107 },
934 { 185, 106 },{ 136, 59 },{ 169, 59 },{ 255, 145 },
938 int slider_perimiter_points[][2] = {
939 { 86, 58 },{ 0, 144 },{ 0, 190 },{ 22, 190 },{ 22, 254 },
940 { 60, 254 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ 110, 190 },
941 { 110, 172 },{ 140, 172 },{ 140, 190 },{ 160, 190 },{ 160, 210 },
942 { 194, 210 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ 254, 190 },
943 { 254, 144 },{ 168, 58 },{ 136, 58 },{ 184, 106 },{ 144, 106 },
944 { 154, 124 },{ 98, 124 },{ 108, 106 },{ 70, 106 },{ 118, 58 },
947 int lifter_perimiter_points_1[][2] = {
948 { 0, 189 },{ 0, 254 },{ 22, 255 },{ 23, 190 },
951 int lifter_perimiter_points_2[][2] = {
952 { 230, 254 },{ 255, 255 },{ 254, 190 },{ 230, 190 },
955 int lifter_perimiter_points_3[][2] = {
956 { 60, 254 },{ 194, 254 },{ 194, 211 },{ 160, 210 },
957 { 160, 190 },{ 140, 191 },{ 141, 172 },{ 111, 172 },
958 { 110, 190 },{ 93, 190 },{ 92, 210 },{ 60, 211 },
961 for (i = 0; i < countof(slider_face_points); i++)
962 slider_face_points[i][1] = 255-slider_face_points[i][1];
963 for (i = 0; i < countof(body_face_points); i++)
964 body_face_points[i][1] = 255-body_face_points[i][1];
965 for (i = 0; i < countof(lifter_face_points); i++)
966 lifter_face_points[i][1] = 255-lifter_face_points[i][1];
967 for (i = 0; i < countof(body_perimiter_points); i++)
968 body_perimiter_points[i][1] = 255-body_perimiter_points[i][1];
969 for (i = 0; i < countof(slider_perimiter_points); i++)
970 slider_perimiter_points[i][1] = 255-slider_perimiter_points[i][1];
971 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
972 lifter_perimiter_points_1[i][1] = 255-lifter_perimiter_points_1[i][1];
973 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
974 lifter_perimiter_points_2[i][1] = 255-lifter_perimiter_points_2[i][1];
975 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
976 lifter_perimiter_points_3[i][1] = 255-lifter_perimiter_points_3[i][1];
978 /* -------------------------------------------------------------------- */
980 glNewList(lc->taser_base, GL_COMPILE);
981 glShadeModel(GL_SMOOTH);
984 face4(lc->texids[FACE_N], exterior_color, wire,
985 0.0, 0.0, -0.5, 0.5, 0.5,
986 0.75, 0.0, 0.25, 0.5, 0.5,
987 0.75, 0.75, 0.25, 0.5, -0.25,
988 0.0, 0.75, -0.5, 0.5, -0.25);
991 face4(lc->texids[FACE_S], exterior_color, wire,
992 0.0, 0.25, -0.5, -0.5, -0.25,
993 0.75, 0.25, 0.25, -0.5, -0.25,
994 0.75, 1.0, 0.25, -0.5, 0.5,
995 0.0, 1.0, -0.5, -0.5, 0.5);
998 face4(0, interior_color, wire,
999 0.0, 0.0, 0.25, -0.5, -0.25,
1000 1.0, 0.0, 0.25, 0.5, -0.25,
1001 1.0, 1.0, 0.25, 0.5, 0.5,
1002 0.0, 1.0, 0.25, -0.5, 0.5);
1005 face4(lc->texids[FACE_W], exterior_color, wire,
1006 1.0, 1.0, -0.5, -0.5, 0.5,
1007 0.0, 1.0, -0.5, 0.5, 0.5,
1008 0.0, 0.25, -0.5, 0.5, -0.25,
1009 1.0, 0.25, -0.5, -0.5, -0.25);
1012 face4(lc->texids[FACE_U], exterior_color, wire,
1013 0.75, 0.0, 0.25, -0.5, 0.5,
1014 0.75, 1.0, 0.25, 0.5, 0.5,
1015 0.0, 1.0, -0.5, 0.5, 0.5,
1016 0.0, 0.0, -0.5, -0.5, 0.5);
1019 face4(0, interior_color, wire,
1020 0.0, 1.0, -0.5, -0.5, -0.25,
1021 0.0, 0.0, -0.5, 0.5, -0.25,
1022 1.0, 0.0, 0.25, 0.5, -0.25,
1023 1.0, 1.0, 0.25, -0.5, -0.25);
1026 for (i = 0; i < countof(body_face_points)/5; i++)
1029 #ifdef HAVE_GLBINDTEXTURE
1030 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1031 #endif /* HAVE_GLBINDTEXTURE */
1032 set_colors(exterior_color);
1034 do_normal(0, body_face_points[(i*5)+0][0], body_face_points[(i*5)+0][1],
1035 0, body_face_points[(i*5)+1][0], body_face_points[(i*5)+1][1],
1036 0, body_face_points[(i*5)+2][0], body_face_points[(i*5)+2][1]
1038 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1039 for (j = 0; j < 5; j++)
1041 int ix = body_face_points[(i*5)+j][0];
1042 int iy = body_face_points[(i*5)+j][1];
1044 if (ix == -1) /* these are padding: ignore them */
1049 glVertex3f(0.5, x-0.5, y-0.5);
1055 for (i = 0; i < countof(body_perimiter_points); i++)
1057 int j = (i+1 >= countof(body_perimiter_points) ? 0 : i+1);
1058 GLfloat x1 = body_perimiter_points[i][0] / 255.0;
1059 GLfloat y1 = body_perimiter_points[i][1] / 255.0;
1060 GLfloat x2 = body_perimiter_points[j][0] / 255.0;
1061 GLfloat y2 = body_perimiter_points[j][1] / 255.0;
1063 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1067 texture = lc->texids[FACE_N];
1069 s2 = 1.0; t2 = 0.568;
1070 s3 = 0.75, t3 = 0.568;
1071 s4 = 0.75; t4 = 0.0;
1075 texture = lc->texids[FACE_U];
1078 s3 = 0.75, t3 = 1.0;
1079 s4 = 0.75; t4 = 0.0;
1083 texture = lc->texids[FACE_S];
1084 s1 = 1.0; t1 = 0.437;
1086 s3 = 0.75; t3 = 1.0;
1087 s4 = 0.75; t4 = 0.437;
1090 face4((texture == -1 ? 0 : texture),
1091 (texture == -1 ? interior_color : exterior_color),
1093 s1, t1, 0.5, x2-0.5, y2-0.5,
1094 s2, t2, 0.5, x1-0.5, y1-0.5,
1095 s3, t3, 0.25, x1-0.5, y1-0.5,
1096 s4, t4, 0.25, x2-0.5, y2-0.5);
1101 /* -------------------------------------------------------------------- */
1103 glNewList(lc->taser_lifter, GL_COMPILE);
1104 glShadeModel(GL_SMOOTH);
1107 face4(lc->texids[FACE_N], exterior_color, wire,
1108 0.0, 0.75, -0.5, 0.5, -0.25,
1109 0.75, 0.75, 0.25, 0.5, -0.25,
1110 0.75, 1.0, 0.25, 0.5, -0.5,
1111 0.0, 1.0, -0.5, 0.5, -0.5);
1114 face4(lc->texids[FACE_S], exterior_color, wire,
1115 0.0, 0.0, -0.5, -0.5, -0.5,
1116 0.75, 0.0, 0.25, -0.5, -0.5,
1117 0.75, 0.25, 0.25, -0.5, -0.25,
1118 0.0, 0.25, -0.5, -0.5, -0.25);
1121 face4(0, interior_color, wire,
1122 0.0, 1.0, 0.25, -0.5, -0.5,
1123 1.0, 1.0, 0.25, 0.5, -0.5,
1124 1.0, 0.0, 0.25, 0.5, -0.25,
1125 0.0, 0.0, 0.25, -0.5, -0.25);
1128 face4(lc->texids[FACE_W], exterior_color, wire,
1129 1.0, 0.25, -0.5, -0.5, -0.25,
1130 0.0, 0.25, -0.5, 0.5, -0.25,
1131 0.0, 0.0, -0.5, 0.5, -0.5,
1132 1.0, 0.0, -0.5, -0.5, -0.5);
1135 face4(0, interior_color, wire,
1136 1.0, 0.0, 0.25, -0.5, -0.25,
1137 1.0, 1.0, 0.25, 0.5, -0.25,
1138 0.0, 1.0, -0.5, 0.5, -0.25,
1139 0.0, 0.0, -0.5, -0.5, -0.25);
1142 face4(lc->texids[FACE_D], exterior_color, wire,
1143 0.0, 1.0, -0.5, -0.5, -0.5,
1144 0.0, 0.0, -0.5, 0.5, -0.5,
1145 0.75, 0.0, 0.25, 0.5, -0.5,
1146 0.75, 1.0, 0.25, -0.5, -0.5);
1150 for (i = 0; i < countof(lifter_face_points)/5; i++)
1154 #ifdef HAVE_GLBINDTEXTURE
1155 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1156 #endif /* HAVE_GLBINDTEXTURE */
1157 set_colors(exterior_color);
1160 0, lifter_face_points[(i*5)+0][0], lifter_face_points[(i*5)+0][1],
1161 0, lifter_face_points[(i*5)+1][0], lifter_face_points[(i*5)+1][1],
1162 0, lifter_face_points[(i*5)+2][0], lifter_face_points[(i*5)+2][1]);
1164 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1165 for (j = 0; j < 5; j++)
1167 int ix = lifter_face_points[(i*5)+j][0];
1168 int iy = lifter_face_points[(i*5)+j][1];
1170 if (ix == -1) /* these are padding: ignore them */
1175 glVertex3f(0.5, x-0.5, y-0.5);
1181 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
1183 int j = (i+1 >= countof(lifter_perimiter_points_1) ? 0 : i+1);
1184 GLfloat x1 = lifter_perimiter_points_1[i][0] / 255.0;
1185 GLfloat y1 = lifter_perimiter_points_1[i][1] / 255.0;
1186 GLfloat x2 = lifter_perimiter_points_1[j][0] / 255.0;
1187 GLfloat y2 = lifter_perimiter_points_1[j][1] / 255.0;
1189 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1193 texture = lc->texids[FACE_S];
1195 s2 = 1.0; t2 = 0.26;
1196 s3 = 0.75, t3 = 0.26;
1197 s4 = 0.75; t4 = 0.0;
1201 texture = lc->texids[FACE_D];
1202 s1 = 1.0; t1 = 0.914;
1204 s3 = 0.75; t3 = 1.0;
1205 s4 = 0.75; t4 = 0.914;
1208 face4((texture == -1 ? 0 : texture),
1209 (texture == -1 ? interior_color : exterior_color),
1211 s1, t1, 0.5, x2-0.5, y2-0.5,
1212 s2, t2, 0.5, x1-0.5, y1-0.5,
1213 s3, t3, 0.25, x1-0.5, y1-0.5,
1214 s4, t4, 0.25, x2-0.5, y2-0.5);
1217 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
1219 int j = (i+1 >= countof(lifter_perimiter_points_2) ? 0 : i+1);
1220 GLfloat x1 = lifter_perimiter_points_2[i][0] / 255.0;
1221 GLfloat y1 = lifter_perimiter_points_2[i][1] / 255.0;
1222 GLfloat x2 = lifter_perimiter_points_2[j][0] / 255.0;
1223 GLfloat y2 = lifter_perimiter_points_2[j][1] / 255.0;
1225 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1229 texture = lc->texids[FACE_D];
1231 s2 = 1.0; t2 = 0.095;
1232 s3 = 0.75; t3 = 0.095;
1233 s4 = 0.75; t4 = 0.0;
1237 texture = lc->texids[FACE_N];
1238 s1 = 1.0; t1 = 0.745;
1240 s3 = 0.75; t3 = 1.0;
1241 s4 = 0.75; t4 = 0.745;
1244 face4((texture == -1 ? 0 : texture),
1245 (texture == -1 ? interior_color : exterior_color),
1247 s1, t1, 0.5, x2-0.5, y2-0.5,
1248 s2, t2, 0.5, x1-0.5, y1-0.5,
1249 s3, t3, 0.25, x1-0.5, y1-0.5,
1250 s4, t4, 0.25, x2-0.5, y2-0.5);
1253 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
1255 int j = (i+1 >= countof(lifter_perimiter_points_3) ? 0 : i+1);
1256 GLfloat x1 = lifter_perimiter_points_3[i][0] / 255.0;
1257 GLfloat y1 = lifter_perimiter_points_3[i][1] / 255.0;
1258 GLfloat x2 = lifter_perimiter_points_3[j][0] / 255.0;
1259 GLfloat y2 = lifter_perimiter_points_3[j][1] / 255.0;
1261 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1265 texture = lc->texids[FACE_D];
1266 s1 = 1.0; t1 = 0.235;
1267 s2 = 1.0; t2 = 0.765;
1268 s3 = 0.75; t3 = 0.765;
1269 s4 = 0.75; t4 = 0.235;
1272 face4((texture == -1 ? 0 : texture),
1273 (texture == -1 ? interior_color : exterior_color),
1275 s1, t1, 0.5, x2-0.5, y2-0.5,
1276 s2, t2, 0.5, x1-0.5, y1-0.5,
1277 s3, t3, 0.25, x1-0.5, y1-0.5,
1278 s4, t4, 0.25, x2-0.5, y2-0.5);
1283 /* -------------------------------------------------------------------- */
1285 glNewList(lc->taser_slider, GL_COMPILE);
1286 glShadeModel(GL_SMOOTH);
1289 for (i = 0; i < countof(slider_face_points)/5; i++)
1292 #ifdef HAVE_GLBINDTEXTURE
1293 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1294 #endif /* HAVE_GLBINDTEXTURE */
1295 set_colors(exterior_color);
1298 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1],
1299 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1300 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1]);
1301 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1302 for (j = 0; j < 5; j++)
1304 int ix = slider_face_points[(i*5)+j][0];
1305 int iy = slider_face_points[(i*5)+j][1];
1307 if (ix == -1) /* these are padding: ignore them */
1312 glVertex3f(0.5, x-0.5, y-0.5);
1318 for (i = countof(slider_face_points)/5 - 1; i >= 0; i--)
1321 #ifdef HAVE_GLBINDTEXTURE
1322 glBindTexture(GL_TEXTURE_2D, 0);
1323 #endif /* HAVE_GLBINDTEXTURE */
1324 set_colors(interior_color);
1327 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1],
1328 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1329 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1]);
1330 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1331 for (j = 4; j >= 0; j--)
1333 int ix = slider_face_points[(i*5)+j][0];
1334 int iy = slider_face_points[(i*5)+j][1];
1336 if (ix == -1) /* these are padding: ignore them */
1341 glVertex3f(0.25, x-0.5, y-0.5);
1347 for (i = 0; i < countof(slider_perimiter_points); i++)
1349 int j = (i+1 >= countof(slider_perimiter_points) ? 0 : i+1);
1350 GLfloat x1 = slider_perimiter_points[i][0] / 255.0;
1351 GLfloat y1 = slider_perimiter_points[i][1] / 255.0;
1352 GLfloat x2 = slider_perimiter_points[j][0] / 255.0;
1353 GLfloat y2 = slider_perimiter_points[j][1] / 255.0;
1355 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1359 texture = lc->texids[FACE_S];
1360 s1 = 1.0; t1 = 0.255;
1361 s2 = 1.0; t2 = 0.435;
1362 s3 = 0.75; t3 = 0.435;
1363 s4 = 0.75; t4 = 0.255;
1367 texture = lc->texids[FACE_D];
1368 s1 = 1.0; t1 = 0.758;
1369 s2 = 1.0; t2 = 0.915;
1370 s3 = 0.75; t3 = 0.915;
1371 s4 = 0.75; t4 = 0.758;
1375 texture = lc->texids[FACE_D];
1376 s1 = 1.0; t1 = 0.095;
1377 s2 = 1.0; t2 = 0.24;
1378 s3 = 0.75; t3 = 0.24;
1379 s4 = 0.75; t4 = 0.095;
1383 texture = lc->texids[FACE_N];
1384 s1 = 1.0; t1 = 0.568;
1385 s2 = 1.0; t2 = 0.742;
1386 s3 = 0.75; t3 = 0.742;
1387 s4 = 0.75; t4 = 0.568;
1390 face4((texture == -1 ? 0 : texture),
1391 (texture == -1 ? interior_color : exterior_color),
1393 s1, t1, 0.5, x2-0.5, y2-0.5,
1394 s2, t2, 0.5, x1-0.5, y1-0.5,
1395 s3, t3, 0.25, x1-0.5, y1-0.5,
1396 s4, t4, 0.25, x2-0.5, y2-0.5);
1404 /* Rendering and animating object models
1410 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1411 Bool wire = MI_IS_WIREFRAME(mi);
1414 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1416 glClear(GL_COLOR_BUFFER_BIT);
1420 GLfloat x = lc->rotx;
1421 GLfloat y = lc->roty;
1422 GLfloat z = lc->rotz;
1428 if (x < 0) x = 1 - (x + 1);
1429 if (y < 0) y = 1 - (y + 1);
1430 if (z < 0) z = 1 - (z + 1);
1432 /* Make into the screen be +Y right be +X, and up be +Z. */
1433 glRotatef(-90.0, 1.0, 0.0, 0.0);
1436 glScalef(4.0, 4.0, 4.0);
1441 /* Shift to the upper left, and draw the vanilla box. */
1442 glTranslatef(-0.6, 0.0, 0.6);
1444 /* Apply rotation to the object. */
1445 glRotatef(x * 360, 1.0, 0.0, 0.0);
1446 glRotatef(y * 360, 0.0, 1.0, 0.0);
1447 glRotatef(z * 360, 0.0, 0.0, 1.0);
1450 glCallList(lc->box);
1454 /* Shift to the lower right, and draw the animated object. */
1455 glTranslatef(0.6, 0.0, -0.6);
1461 /* Apply rotation to the object. */
1462 glRotatef(x * 360, 1.0, 0.0, 0.0);
1463 glRotatef(y * 360, 0.0, 1.0, 0.0);
1464 glRotatef(z * 360, 0.0, 0.0, 1.0);
1469 glCallList(lc->box);
1472 case LAMENT_STAR_OUT:
1473 case LAMENT_STAR_ROT:
1474 case LAMENT_STAR_ROT_IN:
1475 case LAMENT_STAR_ROT_OUT:
1476 case LAMENT_STAR_UNROT:
1477 case LAMENT_STAR_IN:
1478 glTranslatef(0.0, 0.0, lc->anim_z/2);
1479 glRotatef(lc->anim_r/2, 0.0, 0.0, 1.0);
1480 glCallList(lc->star1);
1482 glTranslatef(0.0, 0.0, -lc->anim_z);
1483 glRotatef(-lc->anim_r, 0.0, 0.0, 1.0);
1484 glCallList(lc->star2);
1487 case LAMENT_TETRA_UNE:
1488 case LAMENT_TETRA_USW:
1489 case LAMENT_TETRA_DWN:
1490 case LAMENT_TETRA_DSE:
1495 case LAMENT_TETRA_UNE: magic = lc->tetra_une;
1496 x = 1.0; y = 1.0; z = 1.0; break;
1497 case LAMENT_TETRA_USW: magic = lc->tetra_usw;
1498 x = 1.0; y = 1.0; z = -1.0; break;
1499 case LAMENT_TETRA_DWN: magic = lc->tetra_dwn;
1500 x = 1.0; y = -1.0; z = 1.0; break;
1501 case LAMENT_TETRA_DSE: magic = lc->tetra_dse;
1502 x = -1.0; y = 1.0; z = 1.0; break;
1503 default: abort(); break;
1505 glCallList(lc->tetra_mid);
1506 if (magic != lc->tetra_une) glCallList(lc->tetra_une);
1507 if (magic != lc->tetra_usw) glCallList(lc->tetra_usw);
1508 if (magic != lc->tetra_dwn) glCallList(lc->tetra_dwn);
1509 if (magic != lc->tetra_dse) glCallList(lc->tetra_dse);
1510 glRotatef(lc->anim_r, x, y, z);
1515 case LAMENT_LID_OPEN:
1516 case LAMENT_LID_CLOSE:
1517 case LAMENT_LID_ZOOM:
1521 glTranslatef(lc->anim_z, 0.0, 0.0);
1523 glCallList(lc->lid_0);
1526 glTranslatef(-0.5, -d, 0.0);
1527 glRotatef(-lc->anim_r, 0.0, -1.0, -1.0);
1528 glTranslatef( 0.5, d, 0.0);
1529 glCallList(lc->lid_1);
1532 glTranslatef(-0.5, -d, 0.0);
1533 glRotatef( lc->anim_r, 0.0, -1.0, 1.0);
1534 glTranslatef( 0.5, d, 0.0);
1535 glCallList(lc->lid_2);
1538 glTranslatef(-0.5, d, 0.0);
1539 glRotatef( lc->anim_r, 0.0, -1.0, -1.0);
1540 glTranslatef( 0.5, -d, 0.0);
1541 glCallList(lc->lid_3);
1544 glTranslatef(-0.5, d, 0.0);
1545 glRotatef(-lc->anim_r, 0.0, -1.0, 1.0);
1546 glTranslatef( 0.5, -d, 0.0);
1547 glCallList(lc->lid_4);
1552 case LAMENT_TASER_OUT:
1553 case LAMENT_TASER_SLIDE:
1554 case LAMENT_TASER_SLIDE_IN:
1555 case LAMENT_TASER_IN:
1557 glTranslatef(-lc->anim_z/2, 0.0, 0.0);
1558 glCallList(lc->taser_base);
1560 glTranslatef(lc->anim_z, 0.0, 0.0);
1561 glCallList(lc->taser_lifter);
1563 glTranslatef(0.0, 0.0, lc->anim_y);
1564 glCallList(lc->taser_slider);
1580 animate(ModeInfo *mi)
1582 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1584 /* int pause2 = 60;*/
1591 /* Rather than just picking states randomly, pick an ordering randomly,
1592 do it, and then re-randomize. That way one can be assured of seeing
1593 all states in a short time period, though not always in the same
1594 order (it's frustrating to see it pick the same state 5x in a row.)
1596 static lament_type states[] = {
1597 LAMENT_STAR_OUT, LAMENT_STAR_OUT,
1598 LAMENT_TETRA_UNE, LAMENT_TETRA_USW,
1599 LAMENT_TETRA_DWN, LAMENT_TETRA_DSE,
1600 LAMENT_LID_OPEN, LAMENT_LID_OPEN, LAMENT_LID_OPEN,
1601 LAMENT_TASER_OUT, LAMENT_TASER_OUT,
1602 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1603 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1605 static int state = countof(states);
1607 if (state < countof(states))
1609 lc->type = states[state++];
1615 for (i = 0; i < countof(states); i++)
1617 int a = random() % countof(states);
1618 lament_type swap = states[a];
1619 states[a] = states[i];
1624 if (lc->type == LAMENT_BOX)
1625 lc->anim_pause = pause3;
1633 /* -------------------------------------------------------------- */
1635 case LAMENT_STAR_OUT:
1637 if (lc->anim_z >= 1.0)
1640 lc->type = LAMENT_STAR_ROT;
1641 lc->anim_pause = pause;
1645 case LAMENT_STAR_ROT:
1647 if (lc->anim_r >= 45.0)
1650 lc->type = LAMENT_STAR_ROT_IN;
1651 lc->anim_pause = pause;
1655 case LAMENT_STAR_ROT_IN:
1657 if (lc->anim_z <= 0.0)
1660 lc->type = LAMENT_STAR_ROT_OUT;
1661 lc->anim_pause = pause3 * (1 + (random() % 4) + (random() % 4));
1665 case LAMENT_STAR_ROT_OUT:
1667 if (lc->anim_z >= 1.0)
1670 lc->type = LAMENT_STAR_UNROT;
1671 lc->anim_pause = pause;
1675 case LAMENT_STAR_UNROT:
1677 if (lc->anim_r <= 0.0)
1680 lc->type = LAMENT_STAR_IN;
1681 lc->anim_pause = pause;
1685 case LAMENT_STAR_IN:
1687 if (lc->anim_z <= 0.0)
1690 lc->type = LAMENT_BOX;
1691 lc->anim_pause = pause3;
1695 /* -------------------------------------------------------------- */
1697 case LAMENT_TETRA_UNE:
1698 case LAMENT_TETRA_USW:
1699 case LAMENT_TETRA_DWN:
1700 case LAMENT_TETRA_DSE:
1703 if (lc->anim_r >= 360.0)
1706 lc->type = LAMENT_BOX;
1707 lc->anim_pause = pause3;
1709 else if (lc->anim_r > 119.0 && lc->anim_r <= 120.0)
1712 lc->anim_pause = pause;
1714 else if (lc->anim_r > 239.0 && lc->anim_r <= 240.0)
1717 lc->anim_pause = pause;
1721 /* -------------------------------------------------------------- */
1723 case LAMENT_LID_OPEN:
1726 if (lc->anim_r >= 112.0)
1728 GLfloat hysteresis = 0.05;
1732 lc->anim_pause = pause3;
1734 if (lc->rotx >= -hysteresis &&
1735 lc->rotx <= hysteresis &&
1736 ((lc->rotz >= (0.25 - hysteresis) &&
1737 lc->rotz <= (0.25 + hysteresis)) ||
1738 (lc->rotz >= (-0.25 - hysteresis) &&
1739 lc->rotz <= (-0.25 + hysteresis))))
1741 lc->type = LAMENT_LID_ZOOM;
1743 lc->rotz = (lc->rotz < 0 ? -0.25 : 0.25);
1747 lc->type = LAMENT_LID_CLOSE;
1752 case LAMENT_LID_CLOSE:
1754 if (lc->anim_r <= 0.0)
1757 lc->type = LAMENT_BOX;
1758 lc->anim_pause = pause3;
1762 case LAMENT_LID_ZOOM:
1764 if (lc->anim_z < -50.0)
1768 lc->rotx = frand(1.0) * RANDSIGN();
1769 lc->roty = frand(1.0) * RANDSIGN();
1770 lc->rotz = frand(1.0) * RANDSIGN();
1771 lc->type = LAMENT_BOX;
1775 /* -------------------------------------------------------------- */
1777 case LAMENT_TASER_OUT:
1778 lc->anim_z += 0.0025;
1779 if (lc->anim_z >= 0.25)
1782 lc->type = LAMENT_TASER_SLIDE;
1783 lc->anim_pause = pause * (1 + (random() % 5) + (random() % 5));
1787 case LAMENT_TASER_SLIDE:
1788 lc->anim_y += 0.0025;
1789 if (lc->anim_y >= 0.23)
1792 lc->type = LAMENT_TASER_SLIDE_IN;
1793 lc->anim_pause = pause3 * (1 + (random() % 5) + (random() % 5));
1797 case LAMENT_TASER_SLIDE_IN:
1798 lc->anim_y -= 0.0025;
1799 if (lc->anim_y <= 0.0)
1802 lc->type = LAMENT_TASER_IN;
1803 lc->anim_pause = pause;
1807 case LAMENT_TASER_IN:
1808 lc->anim_z -= 0.0025;
1809 if (lc->anim_z <= 0.0)
1812 lc->type = LAMENT_BOX;
1813 lc->anim_pause = pause3;
1825 rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v)
1831 ppos = -(ppos + *v);
1840 if (ppos < 0) abort();
1841 if (ppos > 1.0) abort();
1842 *pos = (*pos > 0 ? ppos : -ppos);
1847 /* clamp velocity */
1848 if (*v > max_v || *v < -max_v)
1852 /* If it stops, start it going in the other direction. */
1859 /* keep going in the same direction */
1874 /* Alter direction of rotational acceleration randomly. */
1875 if (! (random() % 120))
1878 /* Change acceleration very occasionally. */
1879 if (! (random() % 200))
1883 else if (random() & 1)
1892 /* Window management, etc
1896 reshape_lament(ModeInfo *mi, int width, int height)
1898 int target_size = 180;
1899 int win_size = (width > height ? height : width);
1900 GLfloat h = (GLfloat) height / (GLfloat) width;
1902 glViewport(0, 0, (GLint) width, (GLint) height);
1904 /* glViewport(-600, -600, 1800, 1800); */
1906 glMatrixMode(GL_PROJECTION);
1908 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
1909 glMatrixMode(GL_MODELVIEW);
1911 glTranslatef(0.0, 0.0, -40.0);
1913 /* This scale makes the box take up most of the window */
1914 glScalef(2.0, 2.0, 2.0);
1916 /* But if the window is more than a little larger than our target size,
1917 scale the object back down, so that the bits drawn on the screen end
1918 up rougly target_size across (actually it ends up a little larger.)
1919 Note that the image-map bits we have are 128x128. Therefore, if the
1920 image is magnified a lot, it looks pretty blocky. So it's better to
1921 have a 128x128 animation on a 1280x1024 screen that looks good, than
1922 a 1024x1024 animation that looks really pixellated.
1924 if (win_size > target_size * 1.5)
1926 GLfloat ratio = ((GLfloat) target_size / (GLfloat) win_size);
1928 glScalef(ratio, ratio, ratio);
1931 /* The depth buffer will be cleared, if needed, before the
1932 * next frame. Right now we just want to black the screen.
1934 glClear(GL_COLOR_BUFFER_BIT);
1939 gl_init(ModeInfo *mi)
1941 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1942 Bool wire = MI_IS_WIREFRAME(mi);
1949 static GLfloat pos0[] = { -4.0, 2.0, 5.0, 1.0 };
1950 static GLfloat pos1[] = { 6.0, -1.0, 3.0, 1.0 };
1952 static GLfloat amb0[] = { 0.7, 0.7, 0.7, 1.0 };
1953 /* static GLfloat amb1[] = { 0.7, 0.0, 0.0, 1.0 }; */
1954 static GLfloat dif0[] = { 1.0, 1.0, 1.0, 1.0 };
1955 static GLfloat dif1[] = { 0.3, 0.1, 0.1, 1.0 };
1957 glLightfv(GL_LIGHT0, GL_POSITION, pos0);
1958 glLightfv(GL_LIGHT1, GL_POSITION, pos1);
1960 glLightfv(GL_LIGHT0, GL_AMBIENT, amb0);
1961 /* glLightfv(GL_LIGHT1, GL_AMBIENT, amb1); */
1962 glLightfv(GL_LIGHT0, GL_DIFFUSE, dif0);
1963 glLightfv(GL_LIGHT1, GL_DIFFUSE, dif1);
1964 set_colors(exterior_color);
1966 glEnable(GL_LIGHTING);
1967 glEnable(GL_LIGHT0);
1968 /* glEnable(GL_LIGHT1); */
1970 glEnable(GL_DEPTH_TEST);
1971 glEnable(GL_TEXTURE_2D);
1972 glEnable(GL_NORMALIZE);
1973 glEnable(GL_CULL_FACE);
1978 #ifdef HAVE_GLBINDTEXTURE
1980 for (i = 0; i < 6; i++)
1981 glGenTextures(1, &lc->texids[i]);
1983 parse_image_data(mi);
1985 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1986 glPixelStorei(GL_UNPACK_ROW_LENGTH, lc->texture->width);
1988 for (i = 0; i < 6; i++)
1990 int height = lc->texture->width; /* assume square */
1991 glBindTexture(GL_TEXTURE_2D, lc->texids[i]);
1992 set_colors(exterior_color);
1995 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
1996 lc->texture->width, height, 0,
1997 GL_RGBA, GL_UNSIGNED_BYTE,
1998 (lc->texture->data +
1999 (lc->texture->bytes_per_line * height * i)));
2000 check_gl_error("texture");
2002 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2003 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2004 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2005 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2006 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
2007 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
2010 #else /* !HAVE_GLBINDTEXTURE */
2012 "%s: this version of GL doesn't support multiple texture maps.\n"
2013 "\tGet OpenGL 1.1.\n",
2016 #endif /* !HAVE_GLBINDTEXTURE */
2019 lc->box = glGenLists(16);
2020 lc->star1 = lc->box+1;
2021 lc->star2 = lc->box+2;
2022 lc->tetra_une = lc->box+3;
2023 lc->tetra_usw = lc->box+4;
2024 lc->tetra_dwn = lc->box+5;
2025 lc->tetra_dse = lc->box+6;
2026 lc->tetra_mid = lc->box+7;
2027 lc->lid_0 = lc->box+8;
2028 lc->lid_1 = lc->box+9;
2029 lc->lid_2 = lc->box+10;
2030 lc->lid_3 = lc->box+11;
2031 lc->lid_4 = lc->box+12;
2032 lc->taser_base = lc->box+13;
2033 lc->taser_lifter = lc->box+14;
2034 lc->taser_slider = lc->box+15;
2037 star(mi, True, wire);
2038 star(mi, False, wire);
2045 # ifdef HAVE_MESA_GL
2047 # include <signal.h>
2050 lament_signal_kludge (int sig)
2052 signal (sig, SIG_DFL);
2055 "%s: dying with signal %d (%s).\n"
2057 "\tThis is almost certainly a bug in the Mesa GL library,\n"
2058 "\tespecially if the stack trace in the core file mentions\n"
2059 "\t`lambda_textured_triangle' or `render_quad'.\n"
2061 "\tFirst make sure that you have the latest version of Mesa.\n"
2062 "\tIf that doesn't fix it, then I encourage you to report this\n"
2063 "\tbug to the Mesa maintainers at <http://www.mesa3d.org/>.\n"
2067 (sig == SIGILL ? "SIGILL" :
2068 sig == SIGFPE ? "SIGFPE" :
2069 sig == SIGBUS ? "SIGBUS" :
2070 sig == SIGSEGV ? "SIGSEGV" : "???"));
2072 kill (getpid (), sig);
2076 handle_signals (void)
2078 signal (SIGILL, lament_signal_kludge);
2079 signal (SIGFPE, lament_signal_kludge);
2080 signal (SIGBUS, lament_signal_kludge);
2081 signal (SIGSEGV, lament_signal_kludge);
2083 # endif /* HAVE_MESA_GL */
2087 init_lament(ModeInfo *mi)
2089 lament_configuration *lc;
2092 lcs = (lament_configuration *)
2093 calloc(MI_NUM_SCREENS(mi), sizeof (lament_configuration));
2096 fprintf(stderr, "%s: out of memory\n", progname);
2101 lc = &lcs[MI_SCREEN(mi)];
2103 lc->rotx = frand(1.0) * RANDSIGN();
2104 lc->roty = frand(1.0) * RANDSIGN();
2105 lc->rotz = frand(1.0) * RANDSIGN();
2107 /* bell curve from 0-1.5 degrees, avg 0.75 */
2108 lc->dx = (frand(1) + frand(1) + frand(1)) / (360*2);
2109 lc->dy = (frand(1) + frand(1) + frand(1)) / (360*2);
2110 lc->dz = (frand(1) + frand(1) + frand(1)) / (360*2);
2112 lc->d_max = lc->dx * 2;
2114 lc->ddx = 0.00006 + frand(0.00003);
2115 lc->ddy = 0.00006 + frand(0.00003);
2116 lc->ddz = 0.00006 + frand(0.00003);
2118 lc->type = LAMENT_BOX;
2119 lc->anim_pause = 300 + (random() % 100);
2121 if ((lc->glx_context = init_GL(mi)) != NULL)
2123 reshape_lament(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
2127 # ifdef HAVE_MESA_GL
2129 # endif /* HAVE_MESA_GL */
2134 draw_lament(ModeInfo *mi)
2136 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
2137 Display *dpy = MI_DISPLAY(mi);
2138 Window window = MI_WINDOW(mi);
2140 if (!lc->glx_context)
2143 glDrawBuffer(GL_BACK);
2145 glXMakeCurrent(dpy, window, *(lc->glx_context));
2147 if (mi->fps_p) do_fps (mi);
2150 glXSwapBuffers(dpy, window);
2152 if (lc->type != LAMENT_LID_ZOOM)
2154 rotate(&lc->rotx, &lc->dx, &lc->ddx, lc->d_max);
2155 rotate(&lc->roty, &lc->dy, &lc->ddy, lc->d_max);
2156 rotate(&lc->rotz, &lc->dz, &lc->ddz, lc->d_max);