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);
719 glNewList(lc->tetra_mid, GL_COMPILE);
721 face3(0, interior_color, wire,
722 0.0, 0.0, 0.5, -0.5, 0.5,
723 0.0, 0.0, 0.5, 0.5, -0.5,
724 0.0, 0.0, -0.5, 0.5, 0.5);
726 face3(0, interior_color, wire,
727 0.0, 0.0, -0.5, 0.5, 0.5,
728 0.0, 0.0, -0.5, -0.5, -0.5,
729 0.0, 0.0, 0.5, -0.5, 0.5);
731 face3(0, interior_color, wire,
732 0.0, 0.0, -0.5, 0.5, 0.5,
733 0.0, 0.0, 0.5, 0.5, -0.5,
734 0.0, 0.0, -0.5, -0.5, -0.5);
736 face3(0, interior_color, wire,
737 0.0, 0.0, 0.5, 0.5, -0.5,
738 0.0, 0.0, 0.5, -0.5, 0.5,
739 0.0, 0.0, -0.5, -0.5, -0.5);
741 face3(0, interior_color, wire,
742 0.0, 0.0, 0.5, -0.5, 0.5,
743 0.0, 0.0, 0.5, 0.5, -0.5,
744 0.0, 0.0, -0.5, -0.5, -0.5);
751 lid(ModeInfo *mi, Bool wire)
753 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
757 { 128, 20 },{ 21, 129 },{ 0, 129 },{ 0, 0 },{ 128, 0 }, /* L1 */
758 { 21, 129 },{ 127, 234 },{ 127, 255 },{ 0, 255 },{ 0, 129 }, /* L2 */
759 { 127, 234 },{ 233, 127 },{ 255, 127 },{ 255, 255 },{ 127, 255 }, /* R2 */
760 { 233, 127 },{ 128, 20 },{ 128, 0 },{ 255, 0 },{ 255, 127 }, /* R1 */
763 for (i = 0; i < countof(points); i++)
764 points[i][1] = 255-points[i][1];
766 glNewList(lc->lid_0, GL_COMPILE);
767 glShadeModel(GL_SMOOTH);
770 face4(lc->texids[FACE_N], exterior_color, wire,
771 0.0, 0.0, -0.5, 0.5, 0.5,
772 1.0, 0.0, 0.5, 0.5, 0.5,
773 1.0, 1.0, 0.5, 0.5, -0.5,
774 0.0, 1.0, -0.5, 0.5, -0.5);
777 face4(lc->texids[FACE_S], exterior_color, wire,
778 0.0, 0.0, -0.5, -0.5, -0.5,
779 1.0, 0.0, 0.5, -0.5, -0.5,
780 1.0, 1.0, 0.5, -0.5, 0.5,
781 0.0, 1.0, -0.5, -0.5, 0.5);
784 face4(lc->texids[FACE_E], exterior_color, wire,
785 0.0, 0.0, 0.5, -0.5, -0.5,
786 1.0, 0.0, 0.5, 0.5, -0.5,
787 1.0, 1.0, 0.5, 0.5, 0.5,
788 0.0, 1.0, 0.5, -0.5, 0.5);
791 face4(lc->texids[FACE_U], exterior_color, wire,
792 1.0, 0.0, 0.5, -0.5, 0.5,
793 1.0, 1.0, 0.5, 0.5, 0.5,
794 0.0, 1.0, -0.5, 0.5, 0.5,
795 0.0, 0.0, -0.5, -0.5, 0.5);
798 face4(lc->texids[FACE_D], exterior_color, wire,
799 0.0, 1.0, -0.5, -0.5, -0.5,
800 0.0, 0.0, -0.5, 0.5, -0.5,
801 1.0, 0.0, 0.5, 0.5, -0.5,
802 1.0, 1.0, 0.5, -0.5, -0.5);
805 for (i = 0; i < countof(points)/5; i++)
808 GLfloat s[5], t[5], x[5], y[5], z[5];
809 for (j = 0; j < 5; j++)
811 GLfloat xx = points[(i*5)+j][0] / 255.0L;
812 GLfloat yy = points[(i*5)+j][1] / 255.0L;
819 face5(lc->texids[FACE_W], exterior_color, wire,
820 s[0], t[0], x[0], y[0], z[0],
821 s[1], t[1], x[1], y[1], z[1],
822 s[2], t[2], x[2], y[2], z[2],
823 s[3], t[3], x[3], y[3], z[3],
824 s[4], t[4], x[4], y[4], z[4]);
829 /* W -- lid_1 through lid_4 */
830 for (i = 0; i < 4; i++)
832 GLfloat x1, y1, x2, y2, x3, y3;
834 glNewList(lc->lid_1 + i, GL_COMPILE);
835 glShadeModel(GL_SMOOTH);
837 x1 = points[(i*5)+1][0] / 255.0L;
838 y1 = points[(i*5)+1][1] / 255.0L;
839 x2 = points[(i*5)][0] / 255.0L;
840 y2 = points[(i*5)][1] / 255.0L;
845 face3(lc->texids[FACE_W], exterior_color, wire,
846 1.0-x1, y1, -0.5, x1-0.5, y1-0.5,
847 1.0-x2, y2, -0.5, x2-0.5, y2-0.5,
848 1.0-x3, y3, -0.5, x3-0.5, y3-0.5);
851 face3(0, interior_color, wire,
852 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
853 0.0, 0.0, -0.48, x1-0.5, y1-0.5,
854 0.0, 0.0, -0.48, x3-0.5, y3-0.5);
857 face4(0, interior_color, wire,
858 0.0, 0.0, -0.5, x1-0.5, y1-0.5,
859 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
860 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
861 0.0, 0.0, -0.48, x1-0.5, y1-0.5);
864 face4(0, interior_color, wire,
865 0.0, 0.0, -0.48, x2-0.5, y2-0.5,
866 0.0, 0.0, -0.48, x3-0.5, y3-0.5,
867 0.0, 0.0, -0.5, x3-0.5, y3-0.5,
868 0.0, 0.0, -0.5, x2-0.5, y2-0.5);
875 taser(ModeInfo *mi, Bool wire)
877 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
880 int slider_face_points[][2] = {
881 { 86, 58 },{ 38, 106 },{ 70, 106 },{ 118, 58 },{ -1, -1 }, /* a */
882 { 136, 58 },{ 184, 106 },{ 216, 106 },{ 168, 58 },{ -1, -1 }, /* b */
883 { 38, 106 },{ 0, 144 },{ 0, 190 },{ 60, 190 },{ 108, 106 }, /* c */
884 { 144, 106 },{ 194, 190 },{ 254, 190 },{ 254, 144 },{ 216, 106 }, /* d */
885 { 98, 124 },{ 60, 190 },{ 92, 190 },{ 126, 158 },{ 126, 124 }, /* e */
886 { 126, 124 },{ 126, 158 },{ 160, 190 },{ 194, 190 },{ 154, 124 }, /* f */
887 { 22, 190 },{ 22, 254 },{ 60, 254 },{ 60, 190 },{ -1, -1 }, /* g */
888 { 194, 190 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ -1, -1 }, /* h */
889 { 60, 190 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ -1, -1 }, /* i */
890 { 160, 190 },{ 160, 210 },{ 194, 210 },{ 194, 190 },{ -1, -1 }, /* j */
891 { 110, 172 },{ 92, 190 },{ 110, 190 },{ -1, -1 },{ -1, -1 }, /* k */
892 { 140, 172 },{ 140, 190 },{ 160, 190 },{ -1, -1 },{ -1, -1 }, /* l */
893 { 110, 172 },{ 140, 172 },{ 126, 156 },{ -1, -1 },{ -1, -1 }, /* m */
896 int body_face_points[][2] = {
897 { 0, 0 },{ 0, 58 },{ 254, 58 },{ 254, 0 },{ -1, -1 }, /* A */
898 { 0, 58 },{ 0, 144 },{ 86, 58 },{ -1, -1 },{ -1, -1 }, /* B */
899 { 168, 58 },{ 254, 144 },{ 254, 58 },{ -1, -1 },{ -1, -1 }, /* C */
900 { 118, 58 },{ 70, 106 },{ 184, 106 },{ 136, 58 },{ -1, -1 }, /* F */
901 { 108, 106 },{ 98, 124 },{ 154, 124 },{ 144, 106 },{ -1, -1 }, /* G */
904 int lifter_face_points[][2] = {
905 { 0, 190 },{ 0, 254 },{ 22, 254 },{ 22, 190 },{ -1, -1 }, /* D */
906 { 230, 190 },{ 230, 254 },{ 254, 254 },{ 254, 190 },{ -1, -1 }, /* E */
907 { 60, 210 },{ 60, 254 },{ 194, 254 },{ 194, 210 },{ -1, -1 }, /* H */
908 { 92, 190 },{ 92, 210 },{ 160, 210 },{ 160, 190 },{ -1, -1 }, /* I */
909 { 110, 172 },{ 110, 190 },{ 140, 190 },{ 140, 172 },{ -1, -1 }, /* J */
912 int body_perimiter_points[][2] = {
913 { 0, 144 },{ 86, 59 },{ 119, 58 },{ 71, 107 },
914 { 108, 107 },{ 98, 124 },{ 155, 124 },{ 144, 107 },
915 { 185, 106 },{ 136, 59 },{ 169, 59 },{ 255, 145 },
919 int slider_perimiter_points[][2] = {
920 { 86, 58 },{ 0, 144 },{ 0, 190 },{ 22, 190 },{ 22, 254 },
921 { 60, 254 },{ 60, 210 },{ 92, 210 },{ 92, 190 },{ 110, 190 },
922 { 110, 172 },{ 140, 172 },{ 140, 190 },{ 160, 190 },{ 160, 210 },
923 { 194, 210 },{ 194, 254 },{ 230, 254 },{ 230, 190 },{ 254, 190 },
924 { 254, 144 },{ 168, 58 },{ 136, 58 },{ 184, 106 },{ 144, 106 },
925 { 154, 124 },{ 98, 124 },{ 108, 106 },{ 70, 106 },{ 118, 58 },
928 int lifter_perimiter_points_1[][2] = {
929 { 0, 189 },{ 0, 254 },{ 22, 255 },{ 23, 190 },
932 int lifter_perimiter_points_2[][2] = {
933 { 230, 254 },{ 255, 255 },{ 254, 190 },{ 230, 190 },
936 int lifter_perimiter_points_3[][2] = {
937 { 60, 254 },{ 194, 254 },{ 194, 211 },{ 160, 210 },
938 { 160, 190 },{ 140, 191 },{ 141, 172 },{ 111, 172 },
939 { 110, 190 },{ 93, 190 },{ 92, 210 },{ 60, 211 },
942 for (i = 0; i < countof(slider_face_points); i++)
943 slider_face_points[i][1] = 255-slider_face_points[i][1];
944 for (i = 0; i < countof(body_face_points); i++)
945 body_face_points[i][1] = 255-body_face_points[i][1];
946 for (i = 0; i < countof(lifter_face_points); i++)
947 lifter_face_points[i][1] = 255-lifter_face_points[i][1];
948 for (i = 0; i < countof(body_perimiter_points); i++)
949 body_perimiter_points[i][1] = 255-body_perimiter_points[i][1];
950 for (i = 0; i < countof(slider_perimiter_points); i++)
951 slider_perimiter_points[i][1] = 255-slider_perimiter_points[i][1];
952 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
953 lifter_perimiter_points_1[i][1] = 255-lifter_perimiter_points_1[i][1];
954 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
955 lifter_perimiter_points_2[i][1] = 255-lifter_perimiter_points_2[i][1];
956 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
957 lifter_perimiter_points_3[i][1] = 255-lifter_perimiter_points_3[i][1];
959 /* -------------------------------------------------------------------- */
961 glNewList(lc->taser_base, GL_COMPILE);
962 glShadeModel(GL_SMOOTH);
965 face4(lc->texids[FACE_N], exterior_color, wire,
966 0.0, 0.0, -0.5, 0.5, 0.5,
967 0.75, 0.0, 0.25, 0.5, 0.5,
968 0.75, 0.75, 0.25, 0.5, -0.25,
969 0.0, 0.75, -0.5, 0.5, -0.25);
972 face4(lc->texids[FACE_S], exterior_color, wire,
973 0.0, 0.25, -0.5, -0.5, -0.25,
974 0.75, 0.25, 0.25, -0.5, -0.25,
975 0.75, 1.0, 0.25, -0.5, 0.5,
976 0.0, 1.0, -0.5, -0.5, 0.5);
979 face4(0, interior_color, wire,
980 0.0, 0.0, 0.25, -0.5, -0.25,
981 1.0, 0.0, 0.25, 0.5, -0.25,
982 1.0, 1.0, 0.25, 0.5, 0.5,
983 0.0, 1.0, 0.25, -0.5, 0.5);
986 face4(lc->texids[FACE_W], exterior_color, wire,
987 1.0, 1.0, -0.5, -0.5, 0.5,
988 0.0, 1.0, -0.5, 0.5, 0.5,
989 0.0, 0.25, -0.5, 0.5, -0.25,
990 1.0, 0.25, -0.5, -0.5, -0.25);
993 face4(lc->texids[FACE_U], exterior_color, wire,
994 0.75, 0.0, 0.25, -0.5, 0.5,
995 0.75, 1.0, 0.25, 0.5, 0.5,
996 0.0, 1.0, -0.5, 0.5, 0.5,
997 0.0, 0.0, -0.5, -0.5, 0.5);
1000 face4(0, interior_color, wire,
1001 0.0, 1.0, -0.5, -0.5, -0.25,
1002 0.0, 0.0, -0.5, 0.5, -0.25,
1003 1.0, 0.0, 0.25, 0.5, -0.25,
1004 1.0, 1.0, 0.25, -0.5, -0.25);
1007 for (i = 0; i < countof(body_face_points)/5; i++)
1010 #ifdef HAVE_GLBINDTEXTURE
1011 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1012 #endif /* HAVE_GLBINDTEXTURE */
1013 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1015 do_normal(0, body_face_points[(i*5)+0][0], body_face_points[(i*5)+0][1],
1016 0, body_face_points[(i*5)+1][0], body_face_points[(i*5)+1][1],
1017 0, body_face_points[(i*5)+2][0], body_face_points[(i*5)+2][1]
1019 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1020 for (j = 0; j < 5; j++)
1022 int ix = body_face_points[(i*5)+j][0];
1023 int iy = body_face_points[(i*5)+j][1];
1025 if (ix == -1) /* these are padding: ignore them */
1030 glVertex3f(0.5, x-0.5, y-0.5);
1036 for (i = 0; i < countof(body_perimiter_points); i++)
1038 int j = (i+1 >= countof(body_perimiter_points) ? 0 : i+1);
1039 GLfloat x1 = body_perimiter_points[i][0] / 255.0;
1040 GLfloat y1 = body_perimiter_points[i][1] / 255.0;
1041 GLfloat x2 = body_perimiter_points[j][0] / 255.0;
1042 GLfloat y2 = body_perimiter_points[j][1] / 255.0;
1044 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1048 texture = lc->texids[FACE_N];
1050 s2 = 1.0; t2 = 0.568;
1051 s3 = 0.75, t3 = 0.568;
1052 s4 = 0.75; t4 = 0.0;
1056 texture = lc->texids[FACE_U];
1059 s3 = 0.75, t3 = 1.0;
1060 s4 = 0.75; t4 = 0.0;
1064 texture = lc->texids[FACE_S];
1065 s1 = 1.0; t1 = 0.437;
1067 s3 = 0.75; t3 = 1.0;
1068 s4 = 0.75; t4 = 0.437;
1071 face4((texture == -1 ? 0 : texture),
1072 (texture == -1 ? interior_color : exterior_color),
1074 s1, t1, 0.5, x2-0.5, y2-0.5,
1075 s2, t2, 0.5, x1-0.5, y1-0.5,
1076 s3, t3, 0.25, x1-0.5, y1-0.5,
1077 s4, t4, 0.25, x2-0.5, y2-0.5);
1082 /* -------------------------------------------------------------------- */
1084 glNewList(lc->taser_lifter, GL_COMPILE);
1085 glShadeModel(GL_SMOOTH);
1088 face4(lc->texids[FACE_N], exterior_color, wire,
1089 0.0, 0.75, -0.5, 0.5, -0.25,
1090 0.75, 0.75, 0.25, 0.5, -0.25,
1091 0.75, 1.0, 0.25, 0.5, -0.5,
1092 0.0, 1.0, -0.5, 0.5, -0.5);
1095 face4(lc->texids[FACE_S], exterior_color, wire,
1096 0.0, 0.0, -0.5, -0.5, -0.5,
1097 0.75, 0.0, 0.25, -0.5, -0.5,
1098 0.75, 0.25, 0.25, -0.5, -0.25,
1099 0.0, 0.25, -0.5, -0.5, -0.25);
1102 face4(0, interior_color, wire,
1103 0.0, 1.0, 0.25, -0.5, -0.5,
1104 1.0, 1.0, 0.25, 0.5, -0.5,
1105 1.0, 0.0, 0.25, 0.5, -0.25,
1106 0.0, 0.0, 0.25, -0.5, -0.25);
1109 face4(lc->texids[FACE_W], exterior_color, wire,
1110 1.0, 0.25, -0.5, -0.5, -0.25,
1111 0.0, 0.25, -0.5, 0.5, -0.25,
1112 0.0, 0.0, -0.5, 0.5, -0.5,
1113 1.0, 0.0, -0.5, -0.5, -0.5);
1116 face4(0, interior_color, wire,
1117 1.0, 0.0, 0.25, -0.5, -0.25,
1118 1.0, 1.0, 0.25, 0.5, -0.25,
1119 0.0, 1.0, -0.5, 0.5, -0.25,
1120 0.0, 0.0, -0.5, -0.5, -0.25);
1123 face4(lc->texids[FACE_D], exterior_color, wire,
1124 0.0, 1.0, -0.5, -0.5, -0.5,
1125 0.0, 0.0, -0.5, 0.5, -0.5,
1126 0.75, 0.0, 0.25, 0.5, -0.5,
1127 0.75, 1.0, 0.25, -0.5, -0.5);
1131 for (i = 0; i < countof(lifter_face_points)/5; i++)
1135 #ifdef HAVE_GLBINDTEXTURE
1136 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1137 #endif /* HAVE_GLBINDTEXTURE */
1138 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1141 0, lifter_face_points[(i*5)+0][0], lifter_face_points[(i*5)+0][1],
1142 0, lifter_face_points[(i*5)+1][0], lifter_face_points[(i*5)+1][1],
1143 0, lifter_face_points[(i*5)+2][0], lifter_face_points[(i*5)+2][1]);
1145 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1146 for (j = 0; j < 5; j++)
1148 int ix = lifter_face_points[(i*5)+j][0];
1149 int iy = lifter_face_points[(i*5)+j][1];
1151 if (ix == -1) /* these are padding: ignore them */
1156 glVertex3f(0.5, x-0.5, y-0.5);
1162 for (i = 0; i < countof(lifter_perimiter_points_1); i++)
1164 int j = (i+1 >= countof(lifter_perimiter_points_1) ? 0 : i+1);
1165 GLfloat x1 = lifter_perimiter_points_1[i][0] / 255.0;
1166 GLfloat y1 = lifter_perimiter_points_1[i][1] / 255.0;
1167 GLfloat x2 = lifter_perimiter_points_1[j][0] / 255.0;
1168 GLfloat y2 = lifter_perimiter_points_1[j][1] / 255.0;
1170 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1174 texture = lc->texids[FACE_S];
1176 s2 = 1.0; t2 = 0.26;
1177 s3 = 0.75, t3 = 0.26;
1178 s4 = 0.75; t4 = 0.0;
1182 texture = lc->texids[FACE_D];
1183 s1 = 1.0; t1 = 0.914;
1185 s3 = 0.75; t3 = 1.0;
1186 s4 = 0.75; t4 = 0.914;
1189 face4((texture == -1 ? 0 : texture),
1190 (texture == -1 ? interior_color : exterior_color),
1192 s1, t1, 0.5, x2-0.5, y2-0.5,
1193 s2, t2, 0.5, x1-0.5, y1-0.5,
1194 s3, t3, 0.25, x1-0.5, y1-0.5,
1195 s4, t4, 0.25, x2-0.5, y2-0.5);
1198 for (i = 0; i < countof(lifter_perimiter_points_2); i++)
1200 int j = (i+1 >= countof(lifter_perimiter_points_2) ? 0 : i+1);
1201 GLfloat x1 = lifter_perimiter_points_2[i][0] / 255.0;
1202 GLfloat y1 = lifter_perimiter_points_2[i][1] / 255.0;
1203 GLfloat x2 = lifter_perimiter_points_2[j][0] / 255.0;
1204 GLfloat y2 = lifter_perimiter_points_2[j][1] / 255.0;
1206 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1210 texture = lc->texids[FACE_D];
1212 s2 = 1.0; t2 = 0.095;
1213 s3 = 0.75; t3 = 0.095;
1214 s4 = 0.75; t4 = 0.0;
1218 texture = lc->texids[FACE_N];
1219 s1 = 1.0; t1 = 0.745;
1221 s3 = 0.75; t3 = 1.0;
1222 s4 = 0.75; t4 = 0.745;
1225 face4((texture == -1 ? 0 : texture),
1226 (texture == -1 ? interior_color : exterior_color),
1228 s1, t1, 0.5, x2-0.5, y2-0.5,
1229 s2, t2, 0.5, x1-0.5, y1-0.5,
1230 s3, t3, 0.25, x1-0.5, y1-0.5,
1231 s4, t4, 0.25, x2-0.5, y2-0.5);
1234 for (i = 0; i < countof(lifter_perimiter_points_3); i++)
1236 int j = (i+1 >= countof(lifter_perimiter_points_3) ? 0 : i+1);
1237 GLfloat x1 = lifter_perimiter_points_3[i][0] / 255.0;
1238 GLfloat y1 = lifter_perimiter_points_3[i][1] / 255.0;
1239 GLfloat x2 = lifter_perimiter_points_3[j][0] / 255.0;
1240 GLfloat y2 = lifter_perimiter_points_3[j][1] / 255.0;
1242 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1246 texture = lc->texids[FACE_D];
1247 s1 = 1.0; t1 = 0.235;
1248 s2 = 1.0; t2 = 0.765;
1249 s3 = 0.75; t3 = 0.765;
1250 s4 = 0.75; t4 = 0.235;
1253 face4((texture == -1 ? 0 : texture),
1254 (texture == -1 ? interior_color : exterior_color),
1256 s1, t1, 0.5, x2-0.5, y2-0.5,
1257 s2, t2, 0.5, x1-0.5, y1-0.5,
1258 s3, t3, 0.25, x1-0.5, y1-0.5,
1259 s4, t4, 0.25, x2-0.5, y2-0.5);
1264 /* -------------------------------------------------------------------- */
1266 glNewList(lc->taser_slider, GL_COMPILE);
1267 glShadeModel(GL_SMOOTH);
1270 for (i = 0; i < countof(slider_face_points)/5; i++)
1273 #ifdef HAVE_GLBINDTEXTURE
1274 glBindTexture(GL_TEXTURE_2D, lc->texids[FACE_E]);
1275 #endif /* HAVE_GLBINDTEXTURE */
1276 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1279 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1],
1280 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1281 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1]);
1282 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1283 for (j = 0; j < 5; j++)
1285 int ix = slider_face_points[(i*5)+j][0];
1286 int iy = slider_face_points[(i*5)+j][1];
1288 if (ix == -1) /* these are padding: ignore them */
1293 glVertex3f(0.5, x-0.5, y-0.5);
1299 for (i = countof(slider_face_points)/5 - 1; i >= 0; i--)
1302 #ifdef HAVE_GLBINDTEXTURE
1303 glBindTexture(GL_TEXTURE_2D, 0);
1304 #endif /* HAVE_GLBINDTEXTURE */
1305 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, interior_color);
1308 0, slider_face_points[(i*5)+2][0], slider_face_points[(i*5)+2][1],
1309 0, slider_face_points[(i*5)+1][0], slider_face_points[(i*5)+1][1],
1310 0, slider_face_points[(i*5)+0][0], slider_face_points[(i*5)+0][1]);
1311 glBegin(wire ? GL_LINE_LOOP : GL_POLYGON);
1312 for (j = 4; j >= 0; j--)
1314 int ix = slider_face_points[(i*5)+j][0];
1315 int iy = slider_face_points[(i*5)+j][1];
1317 if (ix == -1) /* these are padding: ignore them */
1322 glVertex3f(0.25, x-0.5, y-0.5);
1328 for (i = 0; i < countof(slider_perimiter_points); i++)
1330 int j = (i+1 >= countof(slider_perimiter_points) ? 0 : i+1);
1331 GLfloat x1 = slider_perimiter_points[i][0] / 255.0;
1332 GLfloat y1 = slider_perimiter_points[i][1] / 255.0;
1333 GLfloat x2 = slider_perimiter_points[j][0] / 255.0;
1334 GLfloat y2 = slider_perimiter_points[j][1] / 255.0;
1336 GLfloat s1=0, t1=0, s2=0, t2=0, s3=0, t3=0, s4=0, t4=0;
1340 texture = lc->texids[FACE_S];
1341 s1 = 1.0; t1 = 0.255;
1342 s2 = 1.0; t2 = 0.435;
1343 s3 = 0.75; t3 = 0.435;
1344 s4 = 0.75; t4 = 0.255;
1348 texture = lc->texids[FACE_D];
1349 s1 = 1.0; t1 = 0.758;
1350 s2 = 1.0; t2 = 0.915;
1351 s3 = 0.75; t3 = 0.915;
1352 s4 = 0.75; t4 = 0.758;
1356 texture = lc->texids[FACE_D];
1357 s1 = 1.0; t1 = 0.095;
1358 s2 = 1.0; t2 = 0.24;
1359 s3 = 0.75; t3 = 0.24;
1360 s4 = 0.75; t4 = 0.095;
1364 texture = lc->texids[FACE_N];
1365 s1 = 1.0; t1 = 0.568;
1366 s2 = 1.0; t2 = 0.742;
1367 s3 = 0.75; t3 = 0.742;
1368 s4 = 0.75; t4 = 0.568;
1371 face4((texture == -1 ? 0 : texture),
1372 (texture == -1 ? interior_color : exterior_color),
1374 s1, t1, 0.5, x2-0.5, y2-0.5,
1375 s2, t2, 0.5, x1-0.5, y1-0.5,
1376 s3, t3, 0.25, x1-0.5, y1-0.5,
1377 s4, t4, 0.25, x2-0.5, y2-0.5);
1385 /* Rendering and animating object models
1391 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1392 Bool wire = MI_IS_WIREFRAME(mi);
1395 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1397 glClear(GL_COLOR_BUFFER_BIT);
1401 GLfloat x = lc->rotx;
1402 GLfloat y = lc->roty;
1403 GLfloat z = lc->rotz;
1409 if (x < 0) x = 1 - (x + 1);
1410 if (y < 0) y = 1 - (y + 1);
1411 if (z < 0) z = 1 - (z + 1);
1413 /* Make into the screen be +Y right be +X, and up be +Z. */
1414 glRotatef(-90.0, 1.0, 0.0, 0.0);
1417 glScalef(4.0, 4.0, 4.0);
1422 /* Shift to the upper left, and draw the vanilla box. */
1423 glTranslatef(-0.6, 0.0, 0.6);
1425 /* Apply rotation to the object. */
1426 glRotatef(x * 360, 1.0, 0.0, 0.0);
1427 glRotatef(y * 360, 0.0, 1.0, 0.0);
1428 glRotatef(z * 360, 0.0, 0.0, 1.0);
1431 glCallList(lc->box);
1435 /* Shift to the lower right, and draw the animated object. */
1436 glTranslatef(0.6, 0.0, -0.6);
1442 /* Apply rotation to the object. */
1443 glRotatef(x * 360, 1.0, 0.0, 0.0);
1444 glRotatef(y * 360, 0.0, 1.0, 0.0);
1445 glRotatef(z * 360, 0.0, 0.0, 1.0);
1450 glCallList(lc->box);
1453 case LAMENT_STAR_OUT:
1454 case LAMENT_STAR_ROT:
1455 case LAMENT_STAR_ROT_IN:
1456 case LAMENT_STAR_ROT_OUT:
1457 case LAMENT_STAR_UNROT:
1458 case LAMENT_STAR_IN:
1459 glTranslatef(0.0, 0.0, lc->anim_z/2);
1460 glRotatef(lc->anim_r/2, 0.0, 0.0, 1.0);
1461 glCallList(lc->star1);
1463 glTranslatef(0.0, 0.0, -lc->anim_z);
1464 glRotatef(-lc->anim_r, 0.0, 0.0, 1.0);
1465 glCallList(lc->star2);
1468 case LAMENT_TETRA_UNE:
1469 case LAMENT_TETRA_USW:
1470 case LAMENT_TETRA_DWN:
1471 case LAMENT_TETRA_DSE:
1476 case LAMENT_TETRA_UNE: magic = lc->tetra_une;
1477 x = 1.0; y = 1.0; z = 1.0; break;
1478 case LAMENT_TETRA_USW: magic = lc->tetra_usw;
1479 x = 1.0; y = 1.0; z = -1.0; break;
1480 case LAMENT_TETRA_DWN: magic = lc->tetra_dwn;
1481 x = 1.0; y = -1.0; z = 1.0; break;
1482 case LAMENT_TETRA_DSE: magic = lc->tetra_dse;
1483 x = -1.0; y = 1.0; z = 1.0; break;
1484 default: abort(); break;
1486 glCallList(lc->tetra_mid);
1487 if (magic != lc->tetra_une) glCallList(lc->tetra_une);
1488 if (magic != lc->tetra_usw) glCallList(lc->tetra_usw);
1489 if (magic != lc->tetra_dwn) glCallList(lc->tetra_dwn);
1490 if (magic != lc->tetra_dse) glCallList(lc->tetra_dse);
1491 glRotatef(lc->anim_r, x, y, z);
1496 case LAMENT_LID_OPEN:
1497 case LAMENT_LID_CLOSE:
1498 case LAMENT_LID_ZOOM:
1502 glTranslatef(lc->anim_z, 0.0, 0.0);
1504 glCallList(lc->lid_0);
1507 glTranslatef(-0.5, -d, 0.0);
1508 glRotatef(-lc->anim_r, 0.0, -1.0, -1.0);
1509 glTranslatef( 0.5, d, 0.0);
1510 glCallList(lc->lid_1);
1513 glTranslatef(-0.5, -d, 0.0);
1514 glRotatef( lc->anim_r, 0.0, -1.0, 1.0);
1515 glTranslatef( 0.5, d, 0.0);
1516 glCallList(lc->lid_2);
1519 glTranslatef(-0.5, d, 0.0);
1520 glRotatef( lc->anim_r, 0.0, -1.0, -1.0);
1521 glTranslatef( 0.5, -d, 0.0);
1522 glCallList(lc->lid_3);
1525 glTranslatef(-0.5, d, 0.0);
1526 glRotatef(-lc->anim_r, 0.0, -1.0, 1.0);
1527 glTranslatef( 0.5, -d, 0.0);
1528 glCallList(lc->lid_4);
1533 case LAMENT_TASER_OUT:
1534 case LAMENT_TASER_SLIDE:
1535 case LAMENT_TASER_SLIDE_IN:
1536 case LAMENT_TASER_IN:
1538 glTranslatef(-lc->anim_z/2, 0.0, 0.0);
1539 glCallList(lc->taser_base);
1541 glTranslatef(lc->anim_z, 0.0, 0.0);
1542 glCallList(lc->taser_lifter);
1544 glTranslatef(0.0, 0.0, lc->anim_y);
1545 glCallList(lc->taser_slider);
1561 animate(ModeInfo *mi)
1563 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1565 /* int pause2 = 60;*/
1572 /* Rather than just picking states randomly, pick an ordering randomly,
1573 do it, and then re-randomize. That way one can be assured of seeing
1574 all states in a short time period, though not always in the same
1575 order (it's frustrating to see it pick the same state 5x in a row.)
1577 static lament_type states[] = {
1578 LAMENT_STAR_OUT, LAMENT_STAR_OUT,
1579 LAMENT_TETRA_UNE, LAMENT_TETRA_USW,
1580 LAMENT_TETRA_DWN, LAMENT_TETRA_DSE,
1581 LAMENT_LID_OPEN, LAMENT_LID_OPEN, LAMENT_LID_OPEN,
1582 LAMENT_TASER_OUT, LAMENT_TASER_OUT,
1583 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1584 LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX, LAMENT_BOX,
1586 static int state = countof(states);
1588 if (state < countof(states))
1590 lc->type = states[state++];
1596 for (i = 0; i < countof(states); i++)
1598 int a = random() % countof(states);
1599 lament_type swap = states[a];
1600 states[a] = states[i];
1605 if (lc->type == LAMENT_BOX)
1606 lc->anim_pause = pause3;
1614 /* -------------------------------------------------------------- */
1616 case LAMENT_STAR_OUT:
1618 if (lc->anim_z >= 1.0)
1621 lc->type = LAMENT_STAR_ROT;
1622 lc->anim_pause = pause;
1626 case LAMENT_STAR_ROT:
1628 if (lc->anim_r >= 45.0)
1631 lc->type = LAMENT_STAR_ROT_IN;
1632 lc->anim_pause = pause;
1636 case LAMENT_STAR_ROT_IN:
1638 if (lc->anim_z <= 0.0)
1641 lc->type = LAMENT_STAR_ROT_OUT;
1642 lc->anim_pause = pause3 * (1 + (random() % 4) + (random() % 4));
1646 case LAMENT_STAR_ROT_OUT:
1648 if (lc->anim_z >= 1.0)
1651 lc->type = LAMENT_STAR_UNROT;
1652 lc->anim_pause = pause;
1656 case LAMENT_STAR_UNROT:
1658 if (lc->anim_r <= 0.0)
1661 lc->type = LAMENT_STAR_IN;
1662 lc->anim_pause = pause;
1666 case LAMENT_STAR_IN:
1668 if (lc->anim_z <= 0.0)
1671 lc->type = LAMENT_BOX;
1672 lc->anim_pause = pause3;
1676 /* -------------------------------------------------------------- */
1678 case LAMENT_TETRA_UNE:
1679 case LAMENT_TETRA_USW:
1680 case LAMENT_TETRA_DWN:
1681 case LAMENT_TETRA_DSE:
1684 if (lc->anim_r >= 360.0)
1687 lc->type = LAMENT_BOX;
1688 lc->anim_pause = pause3;
1690 else if (lc->anim_r > 119.0 && lc->anim_r <= 120.0)
1693 lc->anim_pause = pause;
1695 else if (lc->anim_r > 239.0 && lc->anim_r <= 240.0)
1698 lc->anim_pause = pause;
1702 /* -------------------------------------------------------------- */
1704 case LAMENT_LID_OPEN:
1707 if (lc->anim_r >= 112.0)
1709 GLfloat hysteresis = 0.05;
1713 lc->anim_pause = pause3;
1715 if (lc->rotx >= -hysteresis &&
1716 lc->rotx <= hysteresis &&
1717 ((lc->rotz >= (0.25 - hysteresis) &&
1718 lc->rotz <= (0.25 + hysteresis)) ||
1719 (lc->rotz >= (-0.25 - hysteresis) &&
1720 lc->rotz <= (-0.25 + hysteresis))))
1722 lc->type = LAMENT_LID_ZOOM;
1724 lc->rotz = (lc->rotz < 0 ? -0.25 : 0.25);
1728 lc->type = LAMENT_LID_CLOSE;
1733 case LAMENT_LID_CLOSE:
1735 if (lc->anim_r <= 0.0)
1738 lc->type = LAMENT_BOX;
1739 lc->anim_pause = pause3;
1743 case LAMENT_LID_ZOOM:
1745 if (lc->anim_z < -50.0)
1749 lc->rotx = frand(1.0) * RANDSIGN();
1750 lc->roty = frand(1.0) * RANDSIGN();
1751 lc->rotz = frand(1.0) * RANDSIGN();
1752 lc->type = LAMENT_BOX;
1756 /* -------------------------------------------------------------- */
1758 case LAMENT_TASER_OUT:
1759 lc->anim_z += 0.0025;
1760 if (lc->anim_z >= 0.25)
1763 lc->type = LAMENT_TASER_SLIDE;
1764 lc->anim_pause = pause * (1 + (random() % 5) + (random() % 5));
1768 case LAMENT_TASER_SLIDE:
1769 lc->anim_y += 0.0025;
1770 if (lc->anim_y >= 0.23)
1773 lc->type = LAMENT_TASER_SLIDE_IN;
1774 lc->anim_pause = pause3 * (1 + (random() % 5) + (random() % 5));
1778 case LAMENT_TASER_SLIDE_IN:
1779 lc->anim_y -= 0.0025;
1780 if (lc->anim_y <= 0.0)
1783 lc->type = LAMENT_TASER_IN;
1784 lc->anim_pause = pause;
1788 case LAMENT_TASER_IN:
1789 lc->anim_z -= 0.0025;
1790 if (lc->anim_z <= 0.0)
1793 lc->type = LAMENT_BOX;
1794 lc->anim_pause = pause3;
1806 rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v)
1812 ppos = -(ppos + *v);
1821 if (ppos < 0) abort();
1822 if (ppos > 1.0) abort();
1823 *pos = (*pos > 0 ? ppos : -ppos);
1828 /* clamp velocity */
1829 if (*v > max_v || *v < -max_v)
1833 /* If it stops, start it going in the other direction. */
1840 /* keep going in the same direction */
1855 /* Alter direction of rotational acceleration randomly. */
1856 if (! (random() % 120))
1859 /* Change acceleration very occasionally. */
1860 if (! (random() % 200))
1864 else if (random() & 1)
1873 /* Window management, etc
1877 reshape(int width, int height)
1879 int target_size = 180;
1880 int win_size = (width > height ? height : width);
1881 GLfloat h = (GLfloat) height / (GLfloat) width;
1883 glViewport(0, 0, (GLint) width, (GLint) height);
1885 /* glViewport(-600, -600, 1800, 1800); */
1887 glMatrixMode(GL_PROJECTION);
1889 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
1890 glMatrixMode(GL_MODELVIEW);
1892 glTranslatef(0.0, 0.0, -40.0);
1894 /* This scale makes the box take up most of the window */
1895 glScalef(2.0, 2.0, 2.0);
1897 /* But if the window is more than a little larger than our target size,
1898 scale the object back down, so that the bits drawn on the screen end
1899 up rougly target_size across (actually it ends up a little larger.)
1900 Note that the image-map bits we have are 128x128. Therefore, if the
1901 image is magnified a lot, it looks pretty blocky. So it's better to
1902 have a 128x128 animation on a 1280x1024 screen that looks good, than
1903 a 1024x1024 animation that looks really pixellated.
1905 if (win_size > target_size * 1.5)
1907 GLfloat ratio = ((GLfloat) target_size / (GLfloat) win_size);
1909 glScalef(ratio, ratio, ratio);
1912 /* The depth buffer will be cleared, if needed, before the
1913 * next frame. Right now we just want to black the screen.
1915 glClear(GL_COLOR_BUFFER_BIT);
1920 gl_init(ModeInfo *mi)
1922 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
1923 Bool wire = MI_IS_WIREFRAME(mi);
1930 static GLfloat pos0[] = { -4.0, 2.0, 5.0, 1.0 };
1931 static GLfloat pos1[] = { 12.0, 5.0, 1.0, 1.0 };
1932 static GLfloat local[] = { 0.0 };
1933 static GLfloat ambient[] = { 0.3, 0.3, 0.3, 1.0 };
1934 static GLfloat spec[] = { 1.0, 1.0, 1.0, 1.0 };
1935 static GLfloat shine[] = { 100.0 };
1937 glLightfv(GL_LIGHT0, GL_POSITION, pos0);
1938 glLightfv(GL_LIGHT1, GL_POSITION, pos1);
1940 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
1941 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
1943 glLightfv(GL_LIGHT0, GL_SPECULAR, spec);
1944 glLightfv(GL_LIGHT1, GL_SPECULAR, spec);
1946 glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local);
1947 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1948 glMaterialfv(GL_FRONT, GL_SPECULAR, spec);
1949 glMaterialfv(GL_FRONT, GL_SHININESS, shine);
1951 glEnable(GL_LIGHTING);
1952 glEnable(GL_LIGHT0);
1953 glEnable(GL_LIGHT1);
1954 glDisable(GL_LIGHT1);
1956 glEnable(GL_DEPTH_TEST);
1957 glEnable(GL_TEXTURE_2D);
1958 glEnable(GL_NORMALIZE);
1959 glEnable(GL_CULL_FACE);
1964 #ifdef HAVE_GLBINDTEXTURE
1966 for (i = 0; i < 6; i++)
1967 glGenTextures(1, &lc->texids[i]);
1969 parse_image_data(mi);
1971 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1972 glPixelStorei(GL_UNPACK_ROW_LENGTH, lc->texture->width);
1974 for (i = 0; i < 6; i++)
1976 int height = lc->texture->width; /* assume square */
1977 glBindTexture(GL_TEXTURE_2D, lc->texids[i]);
1978 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, exterior_color);
1979 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
1980 lc->texture->width, height, 0,
1981 GL_RGBA, GL_UNSIGNED_BYTE,
1982 (lc->texture->data +
1983 (lc->texture->bytes_per_line * height * i)));
1985 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1986 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1987 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1988 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1989 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1990 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
1993 #else /* !HAVE_GLBINDTEXTURE */
1995 "%s: this version of GL doesn't support multiple texture maps.\n"
1996 "\tGet OpenGL 1.1.\n",
1999 #endif /* !HAVE_GLBINDTEXTURE */
2002 lc->box = glGenLists(16);
2003 lc->star1 = lc->box+1;
2004 lc->star2 = lc->box+2;
2005 lc->tetra_une = lc->box+3;
2006 lc->tetra_usw = lc->box+4;
2007 lc->tetra_dwn = lc->box+5;
2008 lc->tetra_dse = lc->box+6;
2009 lc->tetra_mid = lc->box+7;
2010 lc->lid_0 = lc->box+8;
2011 lc->lid_1 = lc->box+9;
2012 lc->lid_2 = lc->box+10;
2013 lc->lid_3 = lc->box+11;
2014 lc->lid_4 = lc->box+12;
2015 lc->taser_base = lc->box+13;
2016 lc->taser_lifter = lc->box+14;
2017 lc->taser_slider = lc->box+15;
2020 star(mi, True, wire);
2021 star(mi, False, wire);
2029 init_lament(ModeInfo *mi)
2031 lament_configuration *lc;
2034 lcs = (lament_configuration *)
2035 calloc(MI_NUM_SCREENS(mi), sizeof (lament_configuration));
2038 fprintf(stderr, "%s: out of memory\n", progname);
2043 lc = &lcs[MI_SCREEN(mi)];
2045 lc->rotx = frand(1.0) * RANDSIGN();
2046 lc->roty = frand(1.0) * RANDSIGN();
2047 lc->rotz = frand(1.0) * RANDSIGN();
2049 /* bell curve from 0-1.5 degrees, avg 0.75 */
2050 lc->dx = (frand(1) + frand(1) + frand(1)) / (360*2);
2051 lc->dy = (frand(1) + frand(1) + frand(1)) / (360*2);
2052 lc->dz = (frand(1) + frand(1) + frand(1)) / (360*2);
2054 lc->d_max = lc->dx * 2;
2056 lc->ddx = 0.00006 + frand(0.00003);
2057 lc->ddy = 0.00006 + frand(0.00003);
2058 lc->ddz = 0.00006 + frand(0.00003);
2064 lc->type = LAMENT_BOX;
2065 lc->anim_pause = 300 + (random() % 100);
2067 if ((lc->glx_context = init_GL(mi)) != NULL)
2069 reshape(MI_WIDTH(mi), MI_HEIGHT(mi));
2076 draw_lament(ModeInfo *mi)
2078 static int tick = 0;
2079 lament_configuration *lc = &lcs[MI_SCREEN(mi)];
2080 Display *dpy = MI_DISPLAY(mi);
2081 Window window = MI_WINDOW(mi);
2083 if (!lc->glx_context)
2086 glDrawBuffer(GL_BACK);
2088 glXMakeCurrent(dpy, window, *(lc->glx_context));
2091 glXSwapBuffers(dpy, window);
2093 if (lc->type != LAMENT_LID_ZOOM)
2095 rotate(&lc->rotx, &lc->dx, &lc->ddx, lc->d_max);
2096 rotate(&lc->roty, &lc->dy, &lc->ddy, lc->d_max);
2097 rotate(&lc->rotz, &lc->dz, &lc->ddz, lc->d_max);
2108 reshape(MI_WIDTH(mi), MI_HEIGHT(mi));