1 /* DNA Logo, Copyright (c) 2001, 2002, 2003 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 #define DEFAULTS __extension__ \
14 "*showFPS: False \n" \
15 "*wireframe: False \n" \
16 "*doGasket: True \n" \
18 "*doLadder: True \n" \
20 "*wallFacets: 360 \n" \
22 "*clockwise: False \n" \
24 "*turnSpacing: 2.2 \n" \
25 "*barSpacing: 0.24 \n" \
26 "*wallHeight: 0.45 \n" \
27 "*wallThickness: 0.12 \n" \
28 "*barThickness: 0.058 \n" \
29 "*wallTaper: 0.95 \n" \
30 "*gasketSize: 1.88 \n" \
31 "*gasketDepth: 0.15 \n" \
32 "*gasketThickness: 0.4 \n" \
33 "*frameSize: 1.20 \n" \
34 "*frameDepth: 0.01 \n" \
35 "*frameThickness: 0.03 \n" \
36 "*triangleSize: 0.045 \n" \
38 ".foreground: #00AA00 \n" \
39 "*geometry: =640x640\n" \
41 # define refresh_logo 0
42 # define release_logo 0
44 #define countof(x) (sizeof((x))/sizeof((*x)))
46 #include "xlockmore.h"
50 #include "gltrackball.h"
52 #ifdef USE_GL /* whole file */
56 GLfloat position; /* 0.0 - 1.0 */
57 GLfloat speed; /* how far along the path (may be negative) */
58 GLfloat probability; /* relative likelyhood to start spinning */
62 GLXContext *glx_context;
64 GLuint helix_list, helix_list_wire, helix_list_facetted;
65 GLuint gasket_list, gasket_list_wire;
66 GLuint frame_list, frame_list_wire;
77 GLfloat wall_thickness;
78 GLfloat bar_thickness;
83 GLfloat gasket_thickness;
87 GLfloat frame_thickness;
88 GLfloat triangle_size;
92 spinner gasket_spinnerx, gasket_spinnery, gasket_spinnerz;
93 spinner scene_spinnerx, scene_spinnery;
94 spinner helix_spinnerz;
95 spinner frame_spinner;
97 trackball_state *trackball;
100 int wire_overlay; /* frame countdown */
102 } logo_configuration;
104 static logo_configuration *dcs = NULL;
106 static XrmOptionDescRec opts[] = {
107 { "-speed", ".speed", XrmoptionSepArg, 0 },
110 ENTRYPOINT ModeSpecOpt logo_opts = {countof(opts), opts, 0, NULL, NULL};
112 #define PROBABILITY_SCALE 600
116 /* Calculate the angle (in degrees) between two vectors.
119 vector_angle (double ax, double ay, double az,
120 double bx, double by, double bz)
122 double La = sqrt (ax*ax + ay*ay + az*az);
123 double Lb = sqrt (bx*bx + by*by + bz*bz);
126 if (La == 0 || Lb == 0) return 0;
127 if (ax == bx && ay == by && az == bz) return 0;
129 /* dot product of two vectors is defined as:
130 La * Lb * cos(angle between vectors)
131 and is also defined as:
132 ax*bx + ay*by + az*bz
134 La * Lb * cos(angle) = ax*bx + ay*by + az*bz
135 cos(angle) = (ax*bx + ay*by + az*bz) / (La * Lb)
136 angle = acos ((ax*bx + ay*by + az*bz) / (La * Lb));
138 cc = (ax*bx + ay*by + az*bz) / (La * Lb);
139 if (cc > 1) cc = 1; /* avoid fp rounding error (1.000001 => sqrt error) */
142 return (angle * M_PI / 180);
150 make_helix (logo_configuration *dc, int facetted, int wire)
152 int wall_facets = dc->wall_facets / (facetted ? 10 : 1);
154 GLfloat max_th = M_PI * 2 * dc->turns;
155 GLfloat th_inc = M_PI * 2 / wall_facets;
157 GLfloat x1=0, y1=0, x2=0, y2=0;
158 GLfloat x1b=0, y1b=0, x2b=0, y2b=0;
161 GLfloat h1off=0, h2off=0;
162 GLfloat z_inc = dc->turn_spacing / wall_facets;
167 x1b = 1 - dc->wall_thickness;
170 z1 = -(dc->turn_spacing * dc->turns / 2);
172 h1 = (dc->wall_taper > 0 ? 0 : dc->wall_height / 2);
173 h1off = (dc->wall_taper > 0 ? -dc->wall_height / 2 : 0);
176 z1 = -z1, z_inc = -z_inc, h1off = -h1off;
185 nx = cos (th + M_PI/2);
186 ny = sin (th + M_PI/2);
187 glNormal3f(nx, ny, 0);
188 glVertex3f( x1, y1, z1 - h1 + h1off);
189 glVertex3f( x1, y1, z1 + h1 + h1off);
190 glVertex3f(x1b, y1b, z1 + h1 + h1off);
191 glVertex3f(x1b, y1b, z1 - h1 + h1off);
195 while (th + th_inc <= max_th)
202 x2b = x2 * (1 - dc->wall_thickness);
203 y2b = y2 * (1 - dc->wall_thickness);
208 if (dc->wall_taper > 0)
211 if (th < dc->wall_taper)
213 h2 = dc->wall_height/2 * cos (M_PI / 2
214 * (1 - (th / dc->wall_taper)));
216 h2off = h2 - dc->wall_height/2;
218 h2off = dc->wall_height/2 - h2;
220 else if (th >= max_th - dc->wall_taper)
222 if (th + th_inc > max_th) /* edge case: always come to a point */
225 h2 = dc->wall_height/2 * cos (M_PI / 2
226 * (1 - ((max_th - th)
229 h2off = dc->wall_height/2 - h2;
231 h2off = h2 - dc->wall_height/2;
238 glBegin(wire ? GL_LINES : GL_QUADS);
239 glNormal3f(x1, y1, 0);
240 glVertex3f(x1, y1, z1 - h1 + h1off);
241 glVertex3f(x1, y1, z1 + h1 + h1off);
242 glNormal3f(x2, y2, 0);
243 glVertex3f(x2, y2, z2 + h2 + h2off);
244 glVertex3f(x2, y2, z2 - h2 + h2off);
250 glBegin(wire ? GL_LINES : GL_QUADS);
251 glNormal3f(-x1b, -y1b, 0);
252 glVertex3f( x1b, y1b, z1 - h1 + h1off);
253 glVertex3f( x1b, y1b, z1 + h1 + h1off);
254 glNormal3f(-x2b, -y2b, 0);
255 glVertex3f( x2b, y2b, z2 + h2 + h2off);
256 glVertex3f( x2b, y2b, z2 - h2 + h2off);
262 /* glNormal3f(0, 0, 1);*/
263 do_normal (x2, y2, z2 + h2 + h2off,
264 x2b, y2b, z2 + h2 + h2off,
265 x1b, y1b, z1 + h1 + h1off);
266 glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
267 glVertex3f( x2, y2, z2 + h2 + h2off);
268 glVertex3f( x2b, y2b, z2 + h2 + h2off);
269 glVertex3f( x1b, y1b, z1 + h1 + h1off);
270 glVertex3f( x1, y1, z1 + h1 + h1off);
277 do_normal ( x1, y1, z1 - h1 + h1off,
278 x1b, y1b, z1 - h1 + h1off,
279 x2b, y2b, z2 - h2 + h2off);
280 glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
281 glNormal3f(0, 0, -1);
282 glVertex3f( x1, y1, z1 - h1 + h1off);
283 glVertex3f( x1b, y1b, z1 - h1 + h1off);
284 glVertex3f( x2b, y2b, z2 - h2 + h2off);
285 glVertex3f( x2, y2, z2 - h2 + h2off);
304 nx = cos (th + M_PI/2);
305 ny = sin (th + M_PI/2);
306 glNormal3f(nx, ny, 0);
307 glVertex3f(x2, y2, z1 - h2 + h2off);
308 glVertex3f(x2, y2, z1 + h2 + h2off);
309 glVertex3f(x2b, y2b, z1 + h2 + h2off);
310 glVertex3f(x2b, y2b, z1 - h2 + h2off);
317 make_ladder (logo_configuration *dc, int facetted, int wire)
320 GLfloat max_th = dc->turns * M_PI * 2;
321 GLfloat max_z = dc->turns * dc->turn_spacing;
322 GLfloat z_inc = dc->bar_spacing;
323 GLfloat th_inc = M_PI * 2 * (dc->bar_spacing / dc->turn_spacing);
326 /* skip forward to center the bars in the helix... */
328 GLfloat usable_th = max_th - dc->wall_taper;
329 GLfloat usable_z = max_z / (max_th / usable_th);
330 int nbars = usable_z / dc->bar_spacing;
331 GLfloat used_z, pad_z, pad_ratio;
333 if (! (nbars & 1)) nbars--; /* always an odd number of bars */
335 used_z = (nbars - 1) * dc->bar_spacing;
336 pad_z = max_z - used_z;
337 pad_ratio = pad_z / max_z;
339 th = (max_th * pad_ratio/2);
340 z = -(max_z / 2) + (max_z * pad_ratio/2);
343 z = -z, z_inc = -z_inc;
345 for (i = 0; i < nbars; i++)
347 int facets = dc->bar_facets / (facetted ? 14 : 1);
348 if (facets <= 3) facets = 3;
349 x = cos (th) * (1 - dc->wall_thickness);
350 y = sin (th) * (1 - dc->wall_thickness);
353 dc->bar_thickness, 0, facets,
367 make_gasket (logo_configuration *dc, int wire)
374 GLfloat d2r = M_PI / 180;
376 GLfloat thick2 = (dc->gasket_thickness / dc->gasket_size) / 2;
378 GLfloat *pointsx0, *pointsy0, *pointsx1, *pointsy1, *normals;
380 GLfloat r0 = 0.750; /* 395 */
381 GLfloat r1a = 0.825; /* bottom of wall below upper left hole */
382 GLfloat r1b = 0.867; /* center of upper left hole */
383 GLfloat r1c = 0.909; /* top of wall above hole */
384 GLfloat r1 = 0.916; /* 471 */
385 GLfloat r2 = 0.963; /* 490 */
386 GLfloat r3 = 0.960; /* 499 */
387 GLfloat r4 = 1.000; /* 507 */
388 GLfloat r5 = 1.080; /* 553 */
390 GLfloat ctrl_r[100], ctrl_th[100];
394 # define POINT(r,th) \
395 ctrl_r [nctrls] = r, \
396 ctrl_th[nctrls] = (th * d2r), \
399 POINT (0.829, 0); /* top indentation, right half */
407 POINT (r4, 4.0); /* moving clockwise... */
428 POINT (r4, 316.8); /* upper left indentation */
429 POINT (0.990, 316.87);
430 POINT (0.880, 317.21);
431 POINT (0.872, 317.45);
432 POINT (0.869, 317.80);
433 POINT (0.867, 318.10);
435 POINT (0.867, 318.85);
436 POINT (0.869, 319.15);
437 POINT (0.872, 319.50);
438 POINT (0.880, 319.74);
439 POINT (0.990, 320.08);
444 POINT (r1a, 338.5); /* cut-out disc */
450 POINT (0.872, 356.05); /* top indentation, left half */
451 POINT (0.862, 356.19);
452 POINT (0.851, 356.70);
453 POINT (0.841, 357.35);
454 POINT (0.835, 358.19);
455 POINT (0.831, 359.15);
459 points_size = res + (nctrls * 2);
460 pointsx0 = (GLfloat *) malloc (points_size * sizeof(GLfloat));
461 pointsy0 = (GLfloat *) malloc (points_size * sizeof(GLfloat));
462 pointsx1 = (GLfloat *) malloc (points_size * sizeof(GLfloat));
463 pointsy1 = (GLfloat *) malloc (points_size * sizeof(GLfloat));
464 normals = (GLfloat *) malloc (points_size * sizeof(GLfloat) * 2);
467 for (i = 1; i < nctrls; i++)
469 GLfloat from_r = ctrl_r [i-1];
470 GLfloat from_th = ctrl_th[i-1];
471 GLfloat to_r = ctrl_r [i];
472 GLfloat to_th = ctrl_th[i];
474 GLfloat step = 2*M_PI / res;
475 int nsteps = 1 + ((to_th - from_th) / step);
478 for (j = 0; j < nsteps + (i == nctrls-1); j++)
480 GLfloat r = from_r + (j * (to_r - from_r) / nsteps);
481 GLfloat th = from_th + (j * (to_th - from_th) / nsteps);
483 GLfloat cth = cos(th) * dc->gasket_size;
484 GLfloat sth = sin(th) * dc->gasket_size;
486 pointsx0[npoints] = r0 * cth; /* inner ring */
487 pointsy0[npoints] = r0 * sth;
488 pointsx1[npoints] = r * cth; /* outer ring */
489 pointsy1[npoints] = r * sth;
492 if (npoints >= points_size) abort();
496 /* normals for the outer ring */
497 for (i = 1; i < npoints; i++)
508 n = calc_normal (a, b, c);
509 normals[(i-1)*2 ] = n.x;
510 normals[(i-1)*2+1] = n.y;
513 glRotatef(-90, 0, 1, 0);
514 glRotatef(180, 0, 0, 1);
519 for (z = -thick2; z <= thick2; z += thick2*2)
523 glBegin (GL_LINE_LOOP);
524 for (i = 0; i < npoints; i++)
525 glVertex3f (pointsx0[i], pointsy0[i], z);
529 glBegin (GL_LINE_LOOP);
530 for (i = 0; i < npoints; i++)
531 glVertex3f (pointsx1[i], pointsy1[i], z);
534 for (i = 1; i < npoints; i++)
536 glBegin (GL_LINE_STRIP);
537 glVertex3f (pointsx0[i-1], pointsy0[i-1], z);
538 glVertex3f (pointsx0[i ], pointsy0[i ], z);
539 glVertex3f (pointsx1[i ], pointsy1[i ], z);
540 glVertex3f (pointsx1[i-1], pointsy1[i-1], z);
547 for (i = 0; i < npoints; i++)
550 glVertex3f (pointsx0[i], pointsy0[i], -thick2);
551 glVertex3f (pointsx0[i], pointsy0[i], thick2);
553 glVertex3f (pointsx1[i], pointsy1[i], -thick2);
554 glVertex3f (pointsx1[i], pointsy1[i], thick2);
563 glNormal3f(0, 0, -1);
564 glBegin (GL_QUAD_STRIP);
565 for (i = 0; i < npoints; i++)
567 glVertex3f (pointsx0[i], pointsy0[i], -thick2);
568 glVertex3f (pointsx1[i], pointsy1[i], -thick2);
575 glBegin (GL_QUAD_STRIP);
576 for (i = 0; i < npoints; i++)
578 glVertex3f (pointsx0[i], pointsy0[i], thick2);
579 glVertex3f (pointsx1[i], pointsy1[i], thick2);
585 glBegin (GL_QUAD_STRIP);
586 for (i = 0; i < npoints; i++)
588 glNormal3f (-pointsx0[i], -pointsy0[i], 0);
589 glVertex3f ( pointsx0[i], pointsy0[i], thick2);
590 glVertex3f ( pointsx0[i], pointsy0[i], -thick2);
598 for (i = 0; i < npoints-1; i++)
600 int ia = (i == 0 ? npoints-2 : i-1);
601 int iz = (i == npoints-2 ? 0 : i+1);
602 GLfloat x = pointsx1[i];
603 GLfloat y = pointsy1[i];
604 GLfloat xz = pointsx1[iz];
605 GLfloat yz = pointsy1[iz];
607 GLfloat nxa = normals[ia*2]; /* normal of [i-1 - i] face */
608 GLfloat nya = normals[ia*2+1];
609 GLfloat nx = normals[i*2]; /* normal of [i - i+1] face */
610 GLfloat ny = normals[i*2+1];
611 GLfloat nxz = normals[iz*2]; /* normal of [i+1 - i+2] face */
612 GLfloat nyz = normals[iz*2+1];
614 GLfloat anglea = vector_angle (nx, ny, 0, nxa, nya, 0);
615 GLfloat anglez = vector_angle (nx, ny, 0, nxz, nyz, 0);
616 GLfloat pointy = 0.005;
620 glNormal3f (nx, ny, 0);
621 glVertex3f (x, y, thick2);
622 glVertex3f (x, y, -thick2);
626 glNormal3f ((nxa + nx) / 2, (nya + ny) / 2, 0);
627 glVertex3f (x, y, thick2);
628 glVertex3f (x, y, -thick2);
633 glNormal3f (nx, ny, 0);
634 glVertex3f (xz, yz, -thick2);
635 glVertex3f (xz, yz, thick2);
639 glNormal3f ((nx + nxz) / 2, (ny + nyz) / 2, 0);
640 glVertex3f (xz, yz, -thick2);
641 glVertex3f (xz, yz, thick2);
648 /* Fill in the upper left hole...
655 pointsx0[npoints] = r1c * cos(th) * dc->gasket_size;
656 pointsy0[npoints] = r1c * sin(th) * dc->gasket_size;
658 pointsx0[npoints] = r4 * cos(th) * dc->gasket_size;
659 pointsy0[npoints] = r4 * sin(th) * dc->gasket_size;
663 pointsx0[npoints] = r1c * cos(th) * dc->gasket_size;
664 pointsy0[npoints] = r1c * sin(th) * dc->gasket_size;
666 pointsx0[npoints] = r4 * cos(th) * dc->gasket_size;
667 pointsy0[npoints] = r4 * sin(th) * dc->gasket_size;
673 glNormal3f (0, 0, -1);
675 glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
676 glVertex3f (pointsx0[0], pointsy0[0], -thick2);
677 glVertex3f (pointsx0[1], pointsy0[1], -thick2);
678 glVertex3f (pointsx0[3], pointsy0[3], -thick2);
679 glVertex3f (pointsx0[2], pointsy0[2], -thick2);
683 glNormal3f (0, 0, 1);
685 glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
686 glVertex3f (pointsx0[0], pointsy0[0], thick2);
687 glVertex3f (pointsx0[1], pointsy0[1], thick2);
688 glVertex3f (pointsx0[3], pointsy0[3], thick2);
689 glVertex3f (pointsx0[2], pointsy0[2], thick2);
695 glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
696 glNormal3f (pointsx0[1], pointsy0[1], 0);
697 glVertex3f (pointsx0[1], pointsy0[1], thick2);
698 glNormal3f (pointsx0[3], pointsy0[3], 0);
699 glVertex3f (pointsx0[3], pointsy0[3], thick2);
700 glVertex3f (pointsx0[3], pointsy0[3], -thick2);
701 glNormal3f (pointsx0[1], pointsy0[1], 0);
702 glVertex3f (pointsx0[1], pointsy0[1], -thick2);
712 GLfloat th, cth, sth;
716 th = ((339.0 + 343.0) / 2) * d2r;
718 glTranslatef (r1b * cos(th) * dc->gasket_size,
719 r1b * sin(th) * dc->gasket_size,
723 for (i = 0; i < nsteps; i++)
725 th = 2 * M_PI * i / nsteps;
726 cth = cos (th) * dc->gasket_size;
727 sth = sin (th) * dc->gasket_size;
728 pointsx0[npoints] = r0 * cth;
729 pointsy0[npoints] = r0 * sth;
730 pointsx1[npoints] = r1 * cth;
731 pointsy1[npoints] = r1 * sth;
735 pointsx0[npoints] = pointsx0[0];
736 pointsy0[npoints] = pointsy0[0];
737 pointsx1[npoints] = pointsx1[0];
738 pointsy1[npoints] = pointsy1[0];
743 glBegin (GL_LINE_LOOP);
744 for (i = 0; i < npoints; i++)
745 glVertex3f (pointsx0[i], pointsy0[i], -thick2);
747 glBegin (GL_LINE_LOOP);
748 for (i = 0; i < npoints; i++)
749 glVertex3f (pointsx0[i], pointsy0[i], thick2);
752 glBegin (GL_LINE_LOOP);
753 for (i = 0; i < npoints; i++)
754 glVertex3f (pointsx1[i], pointsy1[i], -thick2);
756 glBegin (GL_LINE_LOOP);
757 for (i = 0; i < npoints; i++)
758 glVertex3f (pointsx1[i], pointsy1[i], thick2);
766 glNormal3f(0, 0, -1);
767 glBegin (GL_QUAD_STRIP);
768 for (i = 0; i < npoints; i++)
770 glVertex3f (pointsx0[i], pointsy0[i], -thick2);
771 glVertex3f (pointsx1[i], pointsy1[i], -thick2);
778 glBegin (GL_QUAD_STRIP);
779 for (i = 0; i < npoints; i++)
781 glVertex3f (pointsx0[i], pointsy0[i], thick2);
782 glVertex3f (pointsx1[i], pointsy1[i], thick2);
789 glBegin (wire ? GL_LINES : GL_QUAD_STRIP);
790 for (i = 0; i < npoints; i++)
792 glNormal3f (-pointsx0[i], -pointsy0[i], 0);
793 glVertex3f ( pointsx0[i], pointsy0[i], thick2);
794 glVertex3f ( pointsx0[i], pointsy0[i], -thick2);
803 /* Attach the bottom-right dingus...
810 glRotatef (49.5, 0, 0, 1);
811 glScalef (dc->gasket_size, dc->gasket_size, 1);
812 glTranslatef (0, (r0+r1)/2, 0);
818 glBegin (wire ? GL_LINE_STRIP : GL_QUADS);
819 glNormal3f (0, 0, -1);
820 glVertex3f (-w/2, -h/2, -thick2); glVertex3f (-w/2, h/2, -thick2);
821 glVertex3f ( w/2, h/2, -thick2); glVertex3f ( w/2, -h/2, -thick2);
822 glNormal3f (1, 0, 0);
823 glVertex3f ( w/2, -h/2, -thick2); glVertex3f ( w/2, h/2, -thick2);
824 glVertex3f ( w/2, h/2, thick2); glVertex3f ( w/2, -h/2, thick2);
825 glNormal3f (0, 0, 1);
826 glVertex3f ( w/2, -h/2, thick2); glVertex3f ( w/2, h/2, thick2);
827 glVertex3f (-w/2, h/2, thick2); glVertex3f (-w/2, -h/2, thick2);
828 glNormal3f (-1, 0, 0);
829 glVertex3f (-w/2, -h/2, thick2); glVertex3f (-w/2, h/2, thick2);
830 glVertex3f (-w/2, h/2, -thick2); glVertex3f (-w/2, -h/2, -thick2);
835 for (th = 0; th < M_PI; th += (M_PI / 6))
837 pointsx0[npoints] = w/2 * cos(th);
838 pointsy0[npoints] = w/2 * sin(th);
842 /* front inside curve */
843 glNormal3f (0, 0, -1);
845 glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN);
846 if (! wire) glVertex3f (0, h/2, -thick2);
847 for (i = 0; i < npoints; i++)
848 glVertex3f (pointsx0[i], h/2 + pointsy0[i], -thick2);
851 /* front outside curve */
853 glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN);
854 if (! wire) glVertex3f (0, -h/2, -thick2);
855 for (i = 0; i < npoints; i++)
856 glVertex3f (pointsx0[i], -h/2 - pointsy0[i], -thick2);
859 /* back inside curve */
860 glNormal3f (0, 0, 1);
862 glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN);
863 if (! wire) glVertex3f (0, h/2, thick2);
864 for (i = 0; i < npoints; i++)
865 glVertex3f (pointsx0[i], h/2 + pointsy0[i], thick2);
868 /* back outside curve */
870 glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN);
871 if (! wire) glVertex3f (0, -h/2, thick2);
872 for (i = 0; i < npoints; i++)
873 glVertex3f (pointsx0[i], -h/2 - pointsy0[i], thick2);
878 glBegin (wire ? GL_LINES : GL_QUAD_STRIP);
879 for (i = 0; i < npoints; i++)
881 glNormal3f (pointsx0[i], pointsy0[i], 0);
882 glVertex3f (pointsx0[i], h/2 + pointsy0[i], thick2);
883 glVertex3f (pointsx0[i], h/2 + pointsy0[i], -thick2);
889 glBegin (wire ? GL_LINES : GL_QUAD_STRIP);
890 for (i = 0; i < npoints; i++)
892 glNormal3f (pointsx0[i], -pointsy0[i], 0);
893 glVertex3f (pointsx0[i], -h/2 - pointsy0[i], thick2);
894 glVertex3f (pointsx0[i], -h/2 - pointsy0[i], -thick2);
909 make_frame (logo_configuration *dc, int wire)
912 GLfloat x[20], y[20];
913 GLfloat corner_cut = 0.5;
916 glRotatef (90, 0, 1, 0);
917 glScalef (4 * dc->frame_size,
921 x[0] = -dc->frame_thickness;
922 x[1] = -dc->frame_thickness * corner_cut;
924 x[3] = 0.5 - dc->triangle_size;
926 x[5] = 0.5 + dc->triangle_size;
928 x[7] = 1 + dc->frame_thickness * corner_cut;
929 x[8] = 1 + dc->frame_thickness;
931 y[0] = -dc->frame_thickness;
932 y[1] = -dc->frame_thickness * corner_cut;
934 y[3] = dc->triangle_size;
938 glTranslatef (-0.5, -0.5, dc->frame_depth / 4);
940 for (j = 0; j <= 1; j++)
942 if (j) glTranslatef (0, 0, -dc->frame_depth / 2);
943 glFrontFace (j ? GL_CCW : GL_CW);
944 for (i = 0; i < 4; i++)
946 glNormal3f (0, 0, (j ? -1 : 1));
947 glBegin (wire ? GL_LINES : GL_QUAD_STRIP);
948 glVertex3f (x[0], y[1], 0); glVertex3f (x[0], y[2], 0);
949 glVertex3f (x[1], y[0], 0); glVertex3f (x[1], y[2], 0);
950 glVertex3f (x[3], y[0], 0); glVertex3f (x[3], y[2], 0);
951 glVertex3f (x[4], y[0], 0); glVertex3f (x[4], y[3], 0);
952 glVertex3f (x[5], y[0], 0); glVertex3f (x[5], y[2], 0);
953 glVertex3f (x[7], y[0], 0); glVertex3f (x[7], y[2], 0);
954 glVertex3f (x[8], y[1], 0); glVertex3f (x[8], y[2], 0);
956 glTranslatef (0.5, 0.5, 0);
957 glRotatef (90, 0, 0, 1);
958 glTranslatef (-0.5, -0.5, 0);
964 glFrontFace (GL_CCW);
965 for (i = 0; i < 4; i++)
967 glNormal3f (0, 1, 0);
968 glBegin (wire ? GL_LINES : GL_QUAD_STRIP);
969 glVertex3f (x[2], y[2], 0); glVertex3f (x[2], y[2], dc->frame_depth/2);
970 glVertex3f (x[3], y[2], 0); glVertex3f (x[3], y[2], dc->frame_depth/2);
971 glVertex3f (x[4], y[3], 0); glVertex3f (x[4], y[3], dc->frame_depth/2);
972 glVertex3f (x[5], y[2], 0); glVertex3f (x[5], y[2], dc->frame_depth/2);
973 glVertex3f (x[6], y[2], 0); glVertex3f (x[6], y[2], dc->frame_depth/2);
976 glNormal3f (0, -1, 0);
977 glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
978 glVertex3f (x[7], y[0], 0);
979 glVertex3f (x[7], y[0], dc->frame_depth/2);
980 glVertex3f (x[1], y[0], dc->frame_depth/2);
981 glVertex3f (x[1], y[0], 0);
984 glNormal3f (1, -1, 0);
985 glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
986 glVertex3f (x[8], y[1], 0);
987 glVertex3f (x[8], y[1], dc->frame_depth/2);
988 glVertex3f (x[7], y[0], dc->frame_depth/2);
989 glVertex3f (x[7], y[0], 0);
994 glNormal3f (0, 1, 0);
995 for (j = 0; j <= 1; j++)
997 glBegin (GL_LINE_STRIP);
998 glVertex3f (x[2], y[2], j*dc->frame_depth/2);
999 glVertex3f (x[3], y[2], j*dc->frame_depth/2);
1000 glVertex3f (x[4], y[3], j*dc->frame_depth/2);
1001 glVertex3f (x[5], y[2], j*dc->frame_depth/2);
1002 glVertex3f (x[6], y[2], j*dc->frame_depth/2);
1007 glTranslatef (0.5, 0.5, 0);
1008 glRotatef (90, 0, 0, 1);
1009 glTranslatef (-0.5, -0.5, 0);
1017 /* Window management, etc
1020 reshape_logo (ModeInfo *mi, int width, int height)
1022 GLfloat h = (GLfloat) height / (GLfloat) width;
1024 glViewport (0, 0, (GLint) width, (GLint) height);
1026 glMatrixMode(GL_PROJECTION);
1028 gluPerspective (30.0, 1/h, 1.0, 100.0);
1030 glMatrixMode(GL_MODELVIEW);
1032 gluLookAt( 0.0, 0.0, 30.0,
1036 glClear(GL_COLOR_BUFFER_BIT);
1041 gl_init (ModeInfo *mi)
1043 /* logo_configuration *dc = &dcs[MI_SCREEN(mi)]; */
1044 int wire = MI_IS_WIREFRAME(mi);
1046 GLfloat position[] = {0, 0, 0, 0};
1047 GLfloat direction[] = {3, -1, -3};
1049 position[0] = -direction[0];
1050 position[1] = -direction[1];
1051 position[2] = -direction[2];
1055 glLightfv(GL_LIGHT0, GL_POSITION, position);
1056 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, direction);
1057 glShadeModel(GL_SMOOTH);
1058 glEnable(GL_NORMALIZE);
1059 glEnable(GL_CULL_FACE);
1060 glEnable(GL_LIGHTING);
1061 glEnable(GL_LIGHT0);
1062 glEnable(GL_DEPTH_TEST);
1068 init_logo (ModeInfo *mi)
1070 logo_configuration *dc;
1071 int do_gasket = get_boolean_resource(mi->dpy, "doGasket", "Boolean");
1072 int do_helix = get_boolean_resource(mi->dpy, "doHelix", "Boolean");
1073 int do_ladder = (do_helix &&
1074 get_boolean_resource(mi->dpy, "doLadder", "Boolean"));
1075 int do_frame = get_boolean_resource(mi->dpy, "doFrame", "Boolean");
1076 GLfloat helix_rot = 147.0;
1078 if (!do_gasket && !do_helix)
1080 fprintf (stderr, "%s: no helix or gasket?\n", progname);
1085 dcs = (logo_configuration *)
1086 calloc (MI_NUM_SCREENS(mi), sizeof (logo_configuration));
1088 fprintf(stderr, "%s: out of memory\n", progname);
1093 dc = &dcs[MI_SCREEN(mi)];
1095 if ((dc->glx_context = init_GL(mi)) != NULL) {
1097 reshape_logo (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
1100 dc->wall_facets = get_integer_resource(mi->dpy, "wallFacets", "Integer");
1101 dc->bar_facets = get_integer_resource(mi->dpy, "barFacets", "Integer");
1102 dc->clockwise = get_boolean_resource(mi->dpy, "clockwise", "Boolean");
1103 dc->turns = get_float_resource(mi->dpy, "turns", "Float");
1104 dc->turn_spacing = get_float_resource(mi->dpy, "turnSpacing", "Float");
1105 dc->bar_spacing = get_float_resource(mi->dpy, "barSpacing", "Float");
1106 dc->wall_height = get_float_resource(mi->dpy, "wallHeight", "Float");
1107 dc->wall_thickness = get_float_resource(mi->dpy, "wallThickness", "Float");
1108 dc->bar_thickness = get_float_resource(mi->dpy, "barThickness", "Float");
1109 dc->wall_taper = get_float_resource(mi->dpy, "wallTaper", "Float");
1111 dc->gasket_size = get_float_resource(mi->dpy,"gasketSize", "Float");
1112 dc->gasket_depth = get_float_resource(mi->dpy,"gasketDepth", "Float");
1113 dc->gasket_thickness = get_float_resource(mi->dpy,"gasketThickness","Float");
1115 dc->frame_size = get_float_resource(mi->dpy, "frameSize", "Float");
1116 dc->frame_depth = get_float_resource(mi->dpy, "frameDepth", "Float");
1117 dc->frame_thickness = get_float_resource(mi->dpy, "frameThickness", "Float");
1118 dc->triangle_size = get_float_resource(mi->dpy, "triangleSize", "Float");
1120 dc->speed = get_float_resource(mi->dpy, "speed", "Float");
1125 char *color_name = get_string_resource (mi->dpy, "foreground", "Foreground");
1127 for (s2 = color_name + strlen(color_name) - 1; s2 > color_name; s2--)
1128 if (*s2 == ' ' || *s2 == '\t')
1133 if (! XParseColor (MI_DISPLAY(mi), mi->xgwa.colormap, color_name, &xcolor))
1135 fprintf (stderr, "%s: can't parse color %s\n", progname, color_name);
1139 dc->color[0] = xcolor.red / 65535.0;
1140 dc->color[1] = xcolor.green / 65535.0;
1141 dc->color[2] = xcolor.blue / 65535.0;
1145 dc->trackball = gltrackball_init ();
1147 dc->gasket_spinnery.probability = 0.1;
1148 dc->gasket_spinnerx.probability = 0.1;
1149 dc->gasket_spinnerz.probability = 1.0;
1150 dc->helix_spinnerz.probability = 0.6;
1151 dc->scene_spinnerx.probability = 0.1;
1152 dc->scene_spinnery.probability = 0.0;
1153 dc->frame_spinner.probability = 5.0;
1155 /* start the frame off-screen */
1156 dc->frame_spinner.spinning_p = True;
1157 dc->frame_spinner.position = 0.3;
1158 dc->frame_spinner.speed = 0.001;
1160 if (dc->speed > 0) /* start off with the gasket in motion */
1162 dc->gasket_spinnerz.spinning_p = True;
1163 dc->gasket_spinnerz.speed = (0.002
1164 * ((random() & 1) ? 1 : -1)
1169 dc->helix_list = glGenLists (1);
1170 glNewList (dc->helix_list, GL_COMPILE);
1171 glRotatef(helix_rot, 0, 0, 1);
1172 if (do_ladder) make_ladder (dc, 0, 0);
1173 if (do_helix) make_helix (dc, 0, 0);
1174 glRotatef(180, 0, 0, 1);
1175 if (do_helix) make_helix (dc, 0, 0);
1180 dc->helix_list_wire = glGenLists (1);
1181 glNewList (dc->helix_list_wire, GL_COMPILE);
1182 /* glRotatef(helix_rot, 0, 0, 1); wtf? */
1183 if (do_ladder) make_ladder (dc, 1, 1);
1184 if (do_helix) make_helix (dc, 1, 1);
1185 glRotatef(180, 0, 0, 1);
1186 if (do_helix) make_helix (dc, 1, 1);
1191 dc->helix_list_facetted = glGenLists (1);
1192 glNewList (dc->helix_list_facetted, GL_COMPILE);
1193 glRotatef(helix_rot, 0, 0, 1);
1194 if (do_ladder) make_ladder (dc, 1, 0);
1195 if (do_helix) make_helix (dc, 1, 0);
1196 glRotatef(180, 0, 0, 1);
1197 if (do_helix) make_helix (dc, 1, 0);
1201 dc->gasket_list = glGenLists (1);
1202 glNewList (dc->gasket_list, GL_COMPILE);
1203 if (do_gasket) make_gasket (dc, 0);
1206 dc->gasket_list_wire = glGenLists (1);
1207 glNewList (dc->gasket_list_wire, GL_COMPILE);
1208 if (do_gasket) make_gasket (dc, 1);
1211 dc->frame_list = glGenLists (1);
1212 glNewList (dc->frame_list, GL_COMPILE);
1213 if (do_frame) make_frame (dc, 0);
1216 dc->frame_list_wire = glGenLists (1);
1217 glNewList (dc->frame_list_wire, GL_COMPILE);
1218 if (do_frame) make_frame (dc, 1);
1221 /* When drawing both solid and wireframe objects,
1222 make sure the wireframe actually shows up! */
1223 glEnable (GL_POLYGON_OFFSET_FILL);
1224 glPolygonOffset (1.0, 1.0);
1229 logo_handle_event (ModeInfo *mi, XEvent *event)
1231 logo_configuration *dc = &dcs[MI_SCREEN(mi)];
1233 if (event->xany.type == ButtonPress &&
1234 event->xbutton.button == Button1)
1236 dc->button_down_p = True;
1237 gltrackball_start (dc->trackball,
1238 event->xbutton.x, event->xbutton.y,
1239 MI_WIDTH (mi), MI_HEIGHT (mi));
1242 else if (event->xany.type == ButtonRelease &&
1243 event->xbutton.button == Button1)
1245 dc->button_down_p = False;
1248 else if (event->xany.type == ButtonPress &&
1249 (event->xbutton.button == Button4 ||
1250 event->xbutton.button == Button5 ||
1251 event->xbutton.button == Button6 ||
1252 event->xbutton.button == Button7))
1254 gltrackball_mousewheel (dc->trackball, event->xbutton.button, 10,
1255 !!event->xbutton.state);
1258 else if (event->xany.type == MotionNotify &&
1261 gltrackball_track (dc->trackball,
1262 event->xmotion.x, event->xmotion.y,
1263 MI_WIDTH (mi), MI_HEIGHT (mi));
1272 tick_spinner (ModeInfo *mi, spinner *s)
1274 logo_configuration *dc = &dcs[MI_SCREEN(mi)];
1276 if (dc->speed == 0) return;
1277 if (dc->button_down_p) return;
1281 s->position += s->speed;
1282 if (s->position >= 1.0 || s->position <= -1.0)
1286 s->spinning_p = False;
1289 else if (s->probability &&
1290 (random() % (int) (PROBABILITY_SCALE / s->probability)) == 0)
1293 s->spinning_p = True;
1296 s->speed = dc->speed * (frand(ss/3) + frand(ss/3) + frand(ss/3));
1297 } while (s->speed <= 0);
1299 s->speed = -s->speed;
1305 link_spinners (ModeInfo *mi, spinner *s0, spinner *s1)
1307 if (s0->spinning_p && !s1->spinning_p)
1309 GLfloat op = s1->probability;
1310 s1->probability = PROBABILITY_SCALE;
1311 tick_spinner (mi, s1);
1312 s1->probability = op;
1318 draw_logo (ModeInfo *mi)
1320 logo_configuration *dc = &dcs[MI_SCREEN(mi)];
1321 Display *dpy = MI_DISPLAY(mi);
1322 Window window = MI_WINDOW(mi);
1323 int wire = MI_IS_WIREFRAME(mi);
1325 GLfloat specular[] = {0.8, 0.8, 0.8, 1.0};
1326 GLfloat shininess = 50.0;
1328 if (!dc->glx_context)
1331 glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(dc->glx_context));
1333 if (dc->wire_overlay == 0 &&
1334 (random() % (int) (PROBABILITY_SCALE / 0.2)) == 0)
1335 dc->wire_overlay = ((random() % 200) +
1339 tick_spinner (mi, &dc->gasket_spinnerx);
1340 tick_spinner (mi, &dc->gasket_spinnery);
1341 tick_spinner (mi, &dc->gasket_spinnerz);
1342 tick_spinner (mi, &dc->helix_spinnerz);
1343 tick_spinner (mi, &dc->scene_spinnerx);
1344 tick_spinner (mi, &dc->scene_spinnery);
1345 tick_spinner (mi, &dc->frame_spinner);
1346 link_spinners (mi, &dc->scene_spinnerx, &dc->scene_spinnery);
1348 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1354 glColor3f(dc->color[0], dc->color[1], dc->color[2]);
1356 /* Draw frame before trackball rotation */
1358 GLfloat p = (dc->frame_spinner.position >= 0
1359 ? dc->frame_spinner.position
1360 : -dc->frame_spinner.position);
1361 GLfloat size = (p > 0.5 ? 1-p : p);
1362 GLfloat scale = 1 + (size * 10);
1364 /* gltrackball_rotate (dc->trackball); */
1365 glRotatef(90, 1, 0, 0);
1366 glRotatef(90, 0, 0, 1);
1368 glScalef (1, scale, scale);
1370 glCallList (dc->frame_list_wire);
1371 else if (dc->wire_overlay != 0)
1373 glCallList (dc->frame_list);
1374 glDisable (GL_LIGHTING);
1375 glCallList (dc->frame_list_wire);
1376 if (!wire) glEnable (GL_LIGHTING);
1379 glCallList (dc->frame_list);
1383 gltrackball_rotate (dc->trackball);
1385 glRotatef(90, 1, 0, 0);
1386 glRotatef(90, 0, 0, 1);
1388 glRotatef (360 * sin (M_PI/2 * dc->scene_spinnerx.position), 0, 1, 0);
1389 glRotatef (360 * sin (M_PI/2 * dc->scene_spinnery.position), 0, 0, 1);
1393 glRotatef (360 * sin (M_PI/2 * dc->gasket_spinnerx.position), 0, 1, 0);
1394 glRotatef (360 * sin (M_PI/2 * dc->gasket_spinnery.position), 0, 0, 1);
1395 glRotatef (360 * sin (M_PI/2 * dc->gasket_spinnerz.position), 1, 0, 0);
1397 memcpy (gcolor, dc->color, sizeof (dc->color));
1398 if (dc->wire_overlay != 0)
1400 gcolor[0] = gcolor[1] = gcolor[2] = 0;
1401 specular[0] = specular[1] = specular[2] = 0;
1404 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, gcolor);
1405 glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular);
1406 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shininess);
1409 glCallList (dc->gasket_list_wire);
1410 else if (dc->wire_overlay != 0)
1412 glCallList (dc->gasket_list);
1413 glDisable (GL_LIGHTING);
1414 glCallList (dc->gasket_list_wire);
1415 if (!wire) glEnable (GL_LIGHTING);
1418 glCallList (dc->gasket_list);
1422 glRotatef (360 * sin (M_PI/2 * dc->helix_spinnerz.position), 0, 0, 1);
1425 glCallList (dc->helix_list_wire);
1426 else if (dc->wire_overlay != 0)
1428 glCallList (dc->helix_list_facetted);
1429 glDisable (GL_LIGHTING);
1430 glCallList (dc->helix_list_wire);
1431 if (!wire) glEnable (GL_LIGHTING);
1434 glCallList (dc->helix_list);
1438 if (dc->wire_overlay > 0)
1441 if (mi->fps_p) do_fps (mi);
1444 glXSwapBuffers(dpy, window);
1447 XSCREENSAVER_MODULE_2 ("DNAlogo", dnalogo, logo)