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" \
19 "*wallFacets: 360 \n" \
20 "*tubeFacets: 90 \n" \
21 "*clockwise: False \n" \
23 "*turnSpacing: 2.40 \n" \
24 "*barSpacing: 0.30 \n" \
25 "*wallHeight: 0.4 \n" \
26 "*wallThickness: 0.1 \n" \
27 "*tubeThickness: 0.075 \n" \
28 "*wallTaper: 1.047 \n" \
29 "*gasketSize: 2.15 \n" \
30 "*gasketDepth: 0.15 \n" \
31 "*gasketThickness: 0.4 \n" \
33 ".foreground: #00AA00 \n" \
35 # define refresh_logo 0
36 # define release_logo 0
38 #define countof(x) (sizeof((x))/sizeof((*x)))
40 #include "xlockmore.h"
44 #include "gltrackball.h"
46 #ifdef USE_GL /* whole file */
50 GLfloat position; /* 0.0 - 1.0 */
51 GLfloat speed; /* how far along the path (may be negative) */
52 GLfloat probability; /* relative likelyhood to start spinning */
56 GLXContext *glx_context;
58 GLuint helix_list, helix_list_wire, helix_list_facetted;
59 GLuint gasket_list, gasket_list_wire;
70 GLfloat wall_thickness;
71 GLfloat tube_thickness;
76 GLfloat gasket_thickness;
80 spinner gasket_spinnerx, gasket_spinnery, gasket_spinnerz;
81 spinner scene_spinnerx, scene_spinnery;
82 spinner helix_spinnerz;
84 trackball_state *trackball;
87 int wire_overlay; /* frame countdown */
91 static logo_configuration *dcs = NULL;
93 static XrmOptionDescRec opts[] = {
94 { "-speed", ".speed", XrmoptionSepArg, 0 },
97 ENTRYPOINT ModeSpecOpt logo_opts = {countof(opts), opts, 0, NULL, NULL};
99 #define PROBABILITY_SCALE 600
103 /* Calculate the angle (in degrees) between two vectors.
106 vector_angle (double ax, double ay, double az,
107 double bx, double by, double bz)
109 double La = sqrt (ax*ax + ay*ay + az*az);
110 double Lb = sqrt (bx*bx + by*by + bz*bz);
113 if (La == 0 || Lb == 0) return 0;
114 if (ax == bx && ay == by && az == bz) return 0;
116 /* dot product of two vectors is defined as:
117 La * Lb * cos(angle between vectors)
118 and is also defined as:
119 ax*bx + ay*by + az*bz
121 La * Lb * cos(angle) = ax*bx + ay*by + az*bz
122 cos(angle) = (ax*bx + ay*by + az*bz) / (La * Lb)
123 angle = acos ((ax*bx + ay*by + az*bz) / (La * Lb));
125 cc = (ax*bx + ay*by + az*bz) / (La * Lb);
126 if (cc > 1) cc = 1; /* avoid fp rounding error (1.000001 => sqrt error) */
129 return (angle * M_PI / 180);
137 make_helix (logo_configuration *dc, int facetted, int wire)
139 int wall_facets = dc->wall_facets / (facetted ? 15 : 1);
141 GLfloat max_th = M_PI * 2 * dc->turns;
142 GLfloat th_inc = M_PI * 2 / wall_facets;
144 GLfloat x1=0, y1=0, x2=0, y2=0;
145 GLfloat x1b=0, y1b=0, x2b=0, y2b=0;
148 GLfloat h1off=0, h2off=0;
149 GLfloat z_inc = dc->turn_spacing / wall_facets;
154 x1b = 1 - dc->wall_thickness;
157 z1 = -(dc->turn_spacing * dc->turns / 2);
159 h1 = (dc->wall_taper > 0 ? 0 : dc->wall_height / 2);
160 h1off = (dc->wall_taper > 0 ? -dc->wall_height / 2 : 0);
163 z1 = -z1, z_inc = -z_inc, h1off = -h1off;
172 nx = cos (th + M_PI/2);
173 ny = sin (th + M_PI/2);
174 glNormal3f(nx, ny, 0);
175 glVertex3f( x1, y1, z1 - h1 + h1off);
176 glVertex3f( x1, y1, z1 + h1 + h1off);
177 glVertex3f(x1b, y1b, z1 + h1 + h1off);
178 glVertex3f(x1b, y1b, z1 - h1 + h1off);
182 while (th + th_inc <= max_th)
189 x2b = x2 * (1 - dc->wall_thickness);
190 y2b = y2 * (1 - dc->wall_thickness);
195 if (dc->wall_taper > 0)
198 if (th < dc->wall_taper)
200 h2 = dc->wall_height/2 * cos (M_PI / 2
201 * (1 - (th / dc->wall_taper)));
203 h2off = h2 - dc->wall_height/2;
205 h2off = dc->wall_height/2 - h2;
207 else if (th >= max_th - dc->wall_taper)
209 if (th + th_inc > max_th) /* edge case: always come to a point */
212 h2 = dc->wall_height/2 * cos (M_PI / 2
213 * (1 - ((max_th - th)
216 h2off = dc->wall_height/2 - h2;
218 h2off = h2 - dc->wall_height/2;
225 glBegin(wire ? GL_LINES : GL_QUADS);
226 glNormal3f(x1, y1, 0);
227 glVertex3f(x1, y1, z1 - h1 + h1off);
228 glVertex3f(x1, y1, z1 + h1 + h1off);
229 glNormal3f(x2, y2, 0);
230 glVertex3f(x2, y2, z2 + h2 + h2off);
231 glVertex3f(x2, y2, z2 - h2 + h2off);
237 glBegin(wire ? GL_LINES : GL_QUADS);
238 glNormal3f(-x1b, -y1b, 0);
239 glVertex3f( x1b, y1b, z1 - h1 + h1off);
240 glVertex3f( x1b, y1b, z1 + h1 + h1off);
241 glNormal3f(-x2b, -y2b, 0);
242 glVertex3f( x2b, y2b, z2 + h2 + h2off);
243 glVertex3f( x2b, y2b, z2 - h2 + h2off);
249 /* glNormal3f(0, 0, 1);*/
250 do_normal (x2, y2, z2 + h2 + h2off,
251 x2b, y2b, z2 + h2 + h2off,
252 x1b, y1b, z1 + h1 + h1off);
253 glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
254 glVertex3f( x2, y2, z2 + h2 + h2off);
255 glVertex3f( x2b, y2b, z2 + h2 + h2off);
256 glVertex3f( x1b, y1b, z1 + h1 + h1off);
257 glVertex3f( x1, y1, z1 + h1 + h1off);
264 do_normal ( x1, y1, z1 - h1 + h1off,
265 x1b, y1b, z1 - h1 + h1off,
266 x2b, y2b, z2 - h2 + h2off);
267 glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
268 glNormal3f(0, 0, -1);
269 glVertex3f( x1, y1, z1 - h1 + h1off);
270 glVertex3f( x1b, y1b, z1 - h1 + h1off);
271 glVertex3f( x2b, y2b, z2 - h2 + h2off);
272 glVertex3f( x2, y2, z2 - h2 + h2off);
291 nx = cos (th + M_PI/2);
292 ny = sin (th + M_PI/2);
293 glNormal3f(nx, ny, 0);
294 glVertex3f(x2, y2, z1 - h2 + h2off);
295 glVertex3f(x2, y2, z1 + h2 + h2off);
296 glVertex3f(x2b, y2b, z1 + h2 + h2off);
297 glVertex3f(x2b, y2b, z1 - h2 + h2off);
304 make_ladder (logo_configuration *dc, int facetted, int wire)
307 GLfloat max_th = dc->turns * M_PI * 2;
308 GLfloat max_z = dc->turns * dc->turn_spacing;
309 GLfloat z_inc = dc->bar_spacing;
310 GLfloat th_inc = M_PI * 2 * (dc->bar_spacing / dc->turn_spacing);
313 /* skip forward to center the bars in the helix... */
315 GLfloat usable_th = max_th - dc->wall_taper;
316 GLfloat usable_z = max_z / (max_th / usable_th);
317 int nbars = usable_z / dc->bar_spacing;
318 GLfloat used_z = (nbars - 1) * dc->bar_spacing;
319 GLfloat pad_z = max_z - used_z;
320 GLfloat pad_ratio = pad_z / max_z;
322 th = (max_th * pad_ratio/2);
323 z = -(max_z / 2) + (max_z * pad_ratio/2);
326 z = -z, z_inc = -z_inc;
328 for (i = 0; i < nbars; i++)
330 int facets = dc->tube_facets / (facetted ? 14 : 1);
331 if (facets <= 3) facets = 3;
332 x = cos (th) * (1 - dc->wall_thickness);
333 y = sin (th) * (1 - dc->wall_thickness);
336 dc->tube_thickness, 0, facets,
350 make_gasket (logo_configuration *dc, int wire)
357 GLfloat d2r = M_PI / 180;
359 GLfloat thick2 = (dc->gasket_thickness / dc->gasket_size) / 2;
361 GLfloat *pointsx0, *pointsy0, *pointsx1, *pointsy1, *normals;
363 GLfloat r0 = 0.780; /* 395 */
364 GLfloat r1a = 0.855; /* top of wall below upper left hole */
365 GLfloat r1b = 0.890; /* center of upper left hole */
366 GLfloat r1c = 0.922; /* bottom of wall above hole */
367 GLfloat r1 = 0.928; /* 471 */
368 GLfloat r2 = 0.966; /* 490 */
369 GLfloat r3 = 0.984; /* 499 */
370 GLfloat r4 = 1.000; /* 507 */
371 GLfloat r5 = 1.090; /* 553 */
373 GLfloat ctrl_r[100], ctrl_th[100];
377 # define POINT(r,th) \
378 ctrl_r [nctrls] = r, \
379 ctrl_th[nctrls] = (th * d2r), \
382 POINT (0.829, 0); /* top indentation, right half */
390 POINT (r4, 4.0); /* moving clockwise... */
411 POINT (r4, 316.8); /* upper left indentation */
412 POINT (0.990, 326.87);
413 POINT (0.880, 327.21);
414 POINT (0.872, 327.45);
415 POINT (0.869, 327.80);
416 POINT (0.867, 328.10);
418 POINT (0.867, 328.85);
419 POINT (0.869, 329.15);
420 POINT (0.872, 329.50);
421 POINT (0.880, 329.74);
422 POINT (0.990, 330.08);
427 POINT (r1a, 339.0); /* cut-out disc */
433 POINT (0.872, 356.05); /* top indentation, left half */
434 POINT (0.862, 356.19);
435 POINT (0.851, 356.70);
436 POINT (0.841, 357.35);
437 POINT (0.835, 358.19);
438 POINT (0.831, 359.15);
442 points_size = res + (nctrls * 2);
443 pointsx0 = (GLfloat *) malloc (points_size * sizeof(GLfloat));
444 pointsy0 = (GLfloat *) malloc (points_size * sizeof(GLfloat));
445 pointsx1 = (GLfloat *) malloc (points_size * sizeof(GLfloat));
446 pointsy1 = (GLfloat *) malloc (points_size * sizeof(GLfloat));
447 normals = (GLfloat *) malloc (points_size * sizeof(GLfloat) * 2);
450 for (i = 1; i < nctrls; i++)
452 GLfloat from_r = ctrl_r [i-1];
453 GLfloat from_th = ctrl_th[i-1];
454 GLfloat to_r = ctrl_r [i];
455 GLfloat to_th = ctrl_th[i];
457 GLfloat step = 2*M_PI / res;
458 int nsteps = 1 + ((to_th - from_th) / step);
461 for (j = 0; j < nsteps + (i == nctrls-1); j++)
463 GLfloat r = from_r + (j * (to_r - from_r) / nsteps);
464 GLfloat th = from_th + (j * (to_th - from_th) / nsteps);
466 GLfloat cth = cos(th) * dc->gasket_size;
467 GLfloat sth = sin(th) * dc->gasket_size;
469 pointsx0[npoints] = r0 * cth; /* inner ring */
470 pointsy0[npoints] = r0 * sth;
471 pointsx1[npoints] = r * cth; /* outer ring */
472 pointsy1[npoints] = r * sth;
475 if (npoints >= points_size) abort();
479 /* normals for the outer ring */
480 for (i = 1; i < npoints; i++)
491 n = calc_normal (a, b, c);
492 normals[(i-1)*2 ] = n.x;
493 normals[(i-1)*2+1] = n.y;
496 glRotatef(-90, 0, 1, 0);
497 glRotatef(180, 0, 0, 1);
502 for (z = -thick2; z <= thick2; z += thick2*2)
506 glBegin (GL_LINE_LOOP);
507 for (i = 0; i < npoints; i++)
508 glVertex3f (pointsx0[i], pointsy0[i], z);
512 glBegin (GL_LINE_LOOP);
513 for (i = 0; i < npoints; i++)
514 glVertex3f (pointsx1[i], pointsy1[i], z);
517 for (i = 1; i < npoints; i++)
519 glBegin (GL_LINE_STRIP);
520 glVertex3f (pointsx0[i-1], pointsy0[i-1], z);
521 glVertex3f (pointsx0[i ], pointsy0[i ], z);
522 glVertex3f (pointsx1[i ], pointsy1[i ], z);
523 glVertex3f (pointsx1[i-1], pointsy1[i-1], z);
530 for (i = 0; i < npoints; i++)
533 glVertex3f (pointsx0[i], pointsy0[i], -thick2);
534 glVertex3f (pointsx0[i], pointsy0[i], thick2);
536 glVertex3f (pointsx1[i], pointsy1[i], -thick2);
537 glVertex3f (pointsx1[i], pointsy1[i], thick2);
546 glNormal3f(0, 0, -1);
547 glBegin (GL_QUAD_STRIP);
548 for (i = 0; i < npoints; i++)
550 glVertex3f (pointsx0[i], pointsy0[i], -thick2);
551 glVertex3f (pointsx1[i], pointsy1[i], -thick2);
558 glBegin (GL_QUAD_STRIP);
559 for (i = 0; i < npoints; i++)
561 glVertex3f (pointsx0[i], pointsy0[i], thick2);
562 glVertex3f (pointsx1[i], pointsy1[i], thick2);
568 glBegin (GL_QUAD_STRIP);
569 for (i = 0; i < npoints; i++)
571 glNormal3f (-pointsx0[i], -pointsy0[i], 0);
572 glVertex3f ( pointsx0[i], pointsy0[i], thick2);
573 glVertex3f ( pointsx0[i], pointsy0[i], -thick2);
581 for (i = 0; i < npoints-1; i++)
583 int ia = (i == 0 ? npoints-2 : i-1);
584 int iz = (i == npoints-2 ? 0 : i+1);
585 GLfloat x = pointsx1[i];
586 GLfloat y = pointsy1[i];
587 GLfloat xz = pointsx1[iz];
588 GLfloat yz = pointsy1[iz];
590 GLfloat nxa = normals[ia*2]; /* normal of [i-1 - i] face */
591 GLfloat nya = normals[ia*2+1];
592 GLfloat nx = normals[i*2]; /* normal of [i - i+1] face */
593 GLfloat ny = normals[i*2+1];
594 GLfloat nxz = normals[iz*2]; /* normal of [i+1 - i+2] face */
595 GLfloat nyz = normals[iz*2+1];
597 GLfloat anglea = vector_angle (nx, ny, 0, nxa, nya, 0);
598 GLfloat anglez = vector_angle (nx, ny, 0, nxz, nyz, 0);
599 GLfloat pointy = 0.005;
603 glNormal3f (nx, ny, 0);
604 glVertex3f (x, y, thick2);
605 glVertex3f (x, y, -thick2);
609 glNormal3f ((nxa + nx) / 2, (nya + ny) / 2, 0);
610 glVertex3f (x, y, thick2);
611 glVertex3f (x, y, -thick2);
616 glNormal3f (nx, ny, 0);
617 glVertex3f (xz, yz, -thick2);
618 glVertex3f (xz, yz, thick2);
622 glNormal3f ((nx + nxz) / 2, (ny + nyz) / 2, 0);
623 glVertex3f (xz, yz, -thick2);
624 glVertex3f (xz, yz, thick2);
631 /* Fill in the upper left hole...
638 pointsx0[npoints] = r1c * cos(th) * dc->gasket_size;
639 pointsy0[npoints] = r1c * sin(th) * dc->gasket_size;
641 pointsx0[npoints] = r4 * cos(th) * dc->gasket_size;
642 pointsy0[npoints] = r4 * sin(th) * dc->gasket_size;
646 pointsx0[npoints] = r1c * cos(th) * dc->gasket_size;
647 pointsy0[npoints] = r1c * sin(th) * dc->gasket_size;
649 pointsx0[npoints] = r4 * cos(th) * dc->gasket_size;
650 pointsy0[npoints] = r4 * sin(th) * dc->gasket_size;
656 glNormal3f (0, 0, -1);
658 glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
659 glVertex3f (pointsx0[0], pointsy0[0], -thick2);
660 glVertex3f (pointsx0[1], pointsy0[1], -thick2);
661 glVertex3f (pointsx0[3], pointsy0[3], -thick2);
662 glVertex3f (pointsx0[2], pointsy0[2], -thick2);
666 glNormal3f (0, 0, 1);
668 glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
669 glVertex3f (pointsx0[0], pointsy0[0], thick2);
670 glVertex3f (pointsx0[1], pointsy0[1], thick2);
671 glVertex3f (pointsx0[3], pointsy0[3], thick2);
672 glVertex3f (pointsx0[2], pointsy0[2], thick2);
678 glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
679 glNormal3f (pointsx0[1], pointsy0[1], 0);
680 glVertex3f (pointsx0[1], pointsy0[1], thick2);
681 glNormal3f (pointsx0[3], pointsy0[3], 0);
682 glVertex3f (pointsx0[3], pointsy0[3], thick2);
683 glVertex3f (pointsx0[3], pointsy0[3], -thick2);
684 glNormal3f (pointsx0[1], pointsy0[1], 0);
685 glVertex3f (pointsx0[1], pointsy0[1], -thick2);
695 GLfloat th, cth, sth;
699 th = ((339.0 + 343.0) / 2) * d2r;
701 glTranslatef (r1b * cos(th) * dc->gasket_size,
702 r1b * sin(th) * dc->gasket_size,
706 for (i = 0; i < nsteps; i++)
708 th = 2 * M_PI * i / nsteps;
709 cth = cos (th) * dc->gasket_size;
710 sth = sin (th) * dc->gasket_size;
711 pointsx0[npoints] = r0 * cth;
712 pointsy0[npoints] = r0 * sth;
713 pointsx1[npoints] = r1 * cth;
714 pointsy1[npoints] = r1 * sth;
718 pointsx0[npoints] = pointsx0[0];
719 pointsy0[npoints] = pointsy0[0];
720 pointsx1[npoints] = pointsx1[0];
721 pointsy1[npoints] = pointsy1[0];
726 glBegin (GL_LINE_LOOP);
727 for (i = 0; i < npoints; i++)
728 glVertex3f (pointsx0[i], pointsy0[i], -thick2);
730 glBegin (GL_LINE_LOOP);
731 for (i = 0; i < npoints; i++)
732 glVertex3f (pointsx0[i], pointsy0[i], thick2);
735 glBegin (GL_LINE_LOOP);
736 for (i = 0; i < npoints; i++)
737 glVertex3f (pointsx1[i], pointsy1[i], -thick2);
739 glBegin (GL_LINE_LOOP);
740 for (i = 0; i < npoints; i++)
741 glVertex3f (pointsx1[i], pointsy1[i], thick2);
749 glNormal3f(0, 0, -1);
750 glBegin (GL_QUAD_STRIP);
751 for (i = 0; i < npoints; i++)
753 glVertex3f (pointsx0[i], pointsy0[i], -thick2);
754 glVertex3f (pointsx1[i], pointsy1[i], -thick2);
761 glBegin (GL_QUAD_STRIP);
762 for (i = 0; i < npoints; i++)
764 glVertex3f (pointsx0[i], pointsy0[i], thick2);
765 glVertex3f (pointsx1[i], pointsy1[i], thick2);
772 glBegin (wire ? GL_LINES : GL_QUAD_STRIP);
773 for (i = 0; i < npoints; i++)
775 glNormal3f (-pointsx0[i], -pointsy0[i], 0);
776 glVertex3f ( pointsx0[i], pointsy0[i], thick2);
777 glVertex3f ( pointsx0[i], pointsy0[i], -thick2);
786 /* Attach the bottom-right dingus...
793 glRotatef (50, 0, 0, 1);
794 glScalef (dc->gasket_size, dc->gasket_size, 1);
795 glTranslatef (0, (r0+r1)/2, 0);
801 glBegin (wire ? GL_LINE_STRIP : GL_QUADS);
802 glNormal3f (0, 0, -1);
803 glVertex3f (-w/2, -h/2, -thick2); glVertex3f (-w/2, h/2, -thick2);
804 glVertex3f ( w/2, h/2, -thick2); glVertex3f ( w/2, -h/2, -thick2);
805 glNormal3f (1, 0, 0);
806 glVertex3f ( w/2, -h/2, -thick2); glVertex3f ( w/2, h/2, -thick2);
807 glVertex3f ( w/2, h/2, thick2); glVertex3f ( w/2, -h/2, thick2);
808 glNormal3f (0, 0, 1);
809 glVertex3f ( w/2, -h/2, thick2); glVertex3f ( w/2, h/2, thick2);
810 glVertex3f (-w/2, h/2, thick2); glVertex3f (-w/2, -h/2, thick2);
811 glNormal3f (-1, 0, 0);
812 glVertex3f (-w/2, -h/2, thick2); glVertex3f (-w/2, h/2, thick2);
813 glVertex3f (-w/2, h/2, -thick2); glVertex3f (-w/2, -h/2, -thick2);
818 for (th = 0; th < M_PI; th += (M_PI / 6))
820 pointsx0[npoints] = w/2 * cos(th);
821 pointsy0[npoints] = w/2 * sin(th);
825 /* front inside curve */
826 glNormal3f (0, 0, -1);
828 glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN);
829 if (! wire) glVertex3f (0, h/2, -thick2);
830 for (i = 0; i < npoints; i++)
831 glVertex3f (pointsx0[i], h/2 + pointsy0[i], -thick2);
834 /* front outside curve */
836 glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN);
837 if (! wire) glVertex3f (0, -h/2, -thick2);
838 for (i = 0; i < npoints; i++)
839 glVertex3f (pointsx0[i], -h/2 - pointsy0[i], -thick2);
842 /* back 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 /* back 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);
861 glBegin (wire ? GL_LINES : GL_QUAD_STRIP);
862 for (i = 0; i < npoints; i++)
864 glNormal3f (pointsx0[i], pointsy0[i], 0);
865 glVertex3f (pointsx0[i], h/2 + pointsy0[i], thick2);
866 glVertex3f (pointsx0[i], h/2 + pointsy0[i], -thick2);
872 glBegin (wire ? GL_LINES : GL_QUAD_STRIP);
873 for (i = 0; i < npoints; i++)
875 glNormal3f (pointsx0[i], -pointsy0[i], 0);
876 glVertex3f (pointsx0[i], -h/2 - pointsy0[i], thick2);
877 glVertex3f (pointsx0[i], -h/2 - pointsy0[i], -thick2);
892 /* Window management, etc
895 reshape_logo (ModeInfo *mi, int width, int height)
897 GLfloat h = (GLfloat) height / (GLfloat) width;
899 glViewport (0, 0, (GLint) width, (GLint) height);
901 glMatrixMode(GL_PROJECTION);
903 gluPerspective (30.0, 1/h, 1.0, 100.0);
905 glMatrixMode(GL_MODELVIEW);
907 gluLookAt( 0.0, 0.0, 30.0,
911 glClear(GL_COLOR_BUFFER_BIT);
916 gl_init (ModeInfo *mi)
918 /* logo_configuration *dc = &dcs[MI_SCREEN(mi)]; */
919 int wire = MI_IS_WIREFRAME(mi);
921 GLfloat position[] = {0, 0, 0, 0};
922 GLfloat direction[] = {3, -1, -3};
924 position[0] = -direction[0];
925 position[1] = -direction[1];
926 position[2] = -direction[2];
930 glLightfv(GL_LIGHT0, GL_POSITION, position);
931 glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, direction);
932 glShadeModel(GL_SMOOTH);
933 glEnable(GL_NORMALIZE);
934 glEnable(GL_CULL_FACE);
935 glEnable(GL_LIGHTING);
937 glEnable(GL_DEPTH_TEST);
943 init_logo (ModeInfo *mi)
945 logo_configuration *dc;
946 int do_gasket = get_boolean_resource(mi->dpy, "doGasket", "Boolean");
947 int do_helix = get_boolean_resource(mi->dpy, "doHelix", "Boolean");
948 int do_ladder = do_helix && get_boolean_resource(mi->dpy, "doLadder", "Boolean");
950 if (!do_gasket && !do_helix)
952 fprintf (stderr, "%s: no helix or gasket?\n", progname);
957 dcs = (logo_configuration *)
958 calloc (MI_NUM_SCREENS(mi), sizeof (logo_configuration));
960 fprintf(stderr, "%s: out of memory\n", progname);
965 dc = &dcs[MI_SCREEN(mi)];
967 if ((dc->glx_context = init_GL(mi)) != NULL) {
969 reshape_logo (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
972 dc->wall_facets = get_integer_resource(mi->dpy, "wallFacets", "Integer");
973 dc->tube_facets = get_integer_resource(mi->dpy, "tubeFacets", "Integer");
974 dc->clockwise = get_boolean_resource(mi->dpy, "clockwise", "Boolean");
975 dc->turns = get_float_resource(mi->dpy, "turns", "Float");
976 dc->turn_spacing = get_float_resource(mi->dpy, "turnSpacing", "Float");
977 dc->bar_spacing = get_float_resource(mi->dpy, "barSpacing", "Float");
978 dc->wall_height = get_float_resource(mi->dpy, "wallHeight", "Float");
979 dc->wall_thickness = get_float_resource(mi->dpy, "wallThickness", "Float");
980 dc->tube_thickness = get_float_resource(mi->dpy, "tubeThickness", "Float");
981 dc->wall_taper = get_float_resource(mi->dpy, "wallTaper", "Float");
983 dc->gasket_size = get_float_resource(mi->dpy, "gasketSize", "Float");
984 dc->gasket_depth = get_float_resource(mi->dpy, "gasketDepth", "Float");
985 dc->gasket_thickness = get_float_resource(mi->dpy, "gasketThickness", "Float");
987 dc->speed = get_float_resource(mi->dpy, "speed", "Float");
992 char *color_name = get_string_resource (mi->dpy, "foreground", "Foreground");
994 for (s2 = color_name + strlen(color_name) - 1; s2 > color_name; s2--)
995 if (*s2 == ' ' || *s2 == '\t')
1000 if (! XParseColor (MI_DISPLAY(mi), mi->xgwa.colormap, color_name, &xcolor))
1002 fprintf (stderr, "%s: can't parse color %s\n", progname, color_name);
1006 dc->color[0] = xcolor.red / 65535.0;
1007 dc->color[1] = xcolor.green / 65535.0;
1008 dc->color[2] = xcolor.blue / 65535.0;
1012 dc->trackball = gltrackball_init ();
1014 dc->gasket_spinnery.probability = 0.1;
1015 dc->gasket_spinnerx.probability = 0.1;
1016 dc->gasket_spinnerz.probability = 1.0;
1017 dc->helix_spinnerz.probability = 0.6;
1018 dc->scene_spinnerx.probability = 0.1;
1019 dc->scene_spinnery.probability = 0.0;
1021 if (dc->speed > 0) /* start off with the gasket in motion */
1023 dc->gasket_spinnerz.spinning_p = True;
1024 dc->gasket_spinnerz.speed = (0.002
1025 * ((random() & 1) ? 1 : -1)
1030 dc->helix_list = glGenLists (1);
1031 glNewList (dc->helix_list, GL_COMPILE);
1032 glRotatef(126, 0, 0, 1);
1033 if (do_ladder) make_ladder (dc, 0, 0);
1034 if (do_helix) make_helix (dc, 0, 0);
1035 glRotatef(180, 0, 0, 1);
1036 if (do_helix) make_helix (dc, 0, 0);
1041 dc->helix_list_wire = glGenLists (1);
1042 glNewList (dc->helix_list_wire, GL_COMPILE);
1043 /* glRotatef(126, 0, 0, 1); wtf? */
1044 if (do_ladder) make_ladder (dc, 1, 1);
1045 if (do_helix) make_helix (dc, 1, 1);
1046 glRotatef(180, 0, 0, 1);
1047 if (do_helix) make_helix (dc, 1, 1);
1052 dc->helix_list_facetted = glGenLists (1);
1053 glNewList (dc->helix_list_facetted, GL_COMPILE);
1054 glRotatef(126, 0, 0, 1);
1055 if (do_ladder) make_ladder (dc, 1, 0);
1056 if (do_helix) make_helix (dc, 1, 0);
1057 glRotatef(180, 0, 0, 1);
1058 if (do_helix) make_helix (dc, 1, 0);
1062 dc->gasket_list = glGenLists (1);
1063 glNewList (dc->gasket_list, GL_COMPILE);
1064 if (do_gasket) make_gasket (dc, 0);
1067 dc->gasket_list_wire = glGenLists (1);
1068 glNewList (dc->gasket_list_wire, GL_COMPILE);
1069 if (do_gasket) make_gasket (dc, 1);
1072 /* When drawing both solid and wireframe objects,
1073 make sure the wireframe actually shows up! */
1074 glEnable (GL_POLYGON_OFFSET_FILL);
1075 glPolygonOffset (1.0, 1.0);
1080 logo_handle_event (ModeInfo *mi, XEvent *event)
1082 logo_configuration *dc = &dcs[MI_SCREEN(mi)];
1084 if (event->xany.type == ButtonPress &&
1085 event->xbutton.button == Button1)
1087 dc->button_down_p = True;
1088 gltrackball_start (dc->trackball,
1089 event->xbutton.x, event->xbutton.y,
1090 MI_WIDTH (mi), MI_HEIGHT (mi));
1093 else if (event->xany.type == ButtonRelease &&
1094 event->xbutton.button == Button1)
1096 dc->button_down_p = False;
1099 else if (event->xany.type == ButtonPress &&
1100 (event->xbutton.button == Button4 ||
1101 event->xbutton.button == Button5 ||
1102 event->xbutton.button == Button6 ||
1103 event->xbutton.button == Button7))
1105 gltrackball_mousewheel (dc->trackball, event->xbutton.button, 10,
1106 !!event->xbutton.state);
1109 else if (event->xany.type == MotionNotify &&
1112 gltrackball_track (dc->trackball,
1113 event->xmotion.x, event->xmotion.y,
1114 MI_WIDTH (mi), MI_HEIGHT (mi));
1123 tick_spinner (ModeInfo *mi, spinner *s)
1125 logo_configuration *dc = &dcs[MI_SCREEN(mi)];
1127 if (dc->speed == 0) return;
1128 if (dc->button_down_p) return;
1132 s->position += s->speed;
1133 if (s->position >= 1.0 || s->position <= -1.0)
1137 s->spinning_p = False;
1140 else if (s->probability &&
1141 (random() % (int) (PROBABILITY_SCALE / s->probability)) == 0)
1144 s->spinning_p = True;
1147 s->speed = dc->speed * (frand(ss/3) + frand(ss/3) + frand(ss/3));
1148 } while (s->speed <= 0);
1150 s->speed = -s->speed;
1156 link_spinners (ModeInfo *mi, spinner *s0, spinner *s1)
1158 if (s0->spinning_p && !s1->spinning_p)
1160 GLfloat op = s1->probability;
1161 s1->probability = PROBABILITY_SCALE;
1162 tick_spinner (mi, s1);
1163 s1->probability = op;
1169 draw_logo (ModeInfo *mi)
1171 logo_configuration *dc = &dcs[MI_SCREEN(mi)];
1172 Display *dpy = MI_DISPLAY(mi);
1173 Window window = MI_WINDOW(mi);
1174 int wire = MI_IS_WIREFRAME(mi);
1176 GLfloat specular[] = {0.8, 0.8, 0.8, 1.0};
1177 GLfloat shininess = 50.0;
1179 if (!dc->glx_context)
1182 glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(dc->glx_context));
1184 if (dc->wire_overlay == 0 &&
1185 (random() % (int) (PROBABILITY_SCALE / 0.2)) == 0)
1186 dc->wire_overlay = ((random() % 200) +
1190 tick_spinner (mi, &dc->gasket_spinnerx);
1191 tick_spinner (mi, &dc->gasket_spinnery);
1192 tick_spinner (mi, &dc->gasket_spinnerz);
1193 tick_spinner (mi, &dc->helix_spinnerz);
1194 tick_spinner (mi, &dc->scene_spinnerx);
1195 tick_spinner (mi, &dc->scene_spinnery);
1196 link_spinners (mi, &dc->scene_spinnerx, &dc->scene_spinnery);
1198 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1202 glScalef(3.3, 3.3, 3.3);
1204 gltrackball_rotate (dc->trackball);
1206 glRotatef(90, 1, 0, 0);
1207 glRotatef(90, 0, 0, 1);
1209 glColor3f(dc->color[0], dc->color[1], dc->color[2]);
1211 glRotatef (360 * sin (M_PI/2 * dc->scene_spinnerx.position), 0, 1, 0);
1212 glRotatef (360 * sin (M_PI/2 * dc->scene_spinnery.position), 0, 0, 1);
1216 glRotatef (360 * sin (M_PI/2 * dc->gasket_spinnerx.position), 0, 1, 0);
1217 glRotatef (360 * sin (M_PI/2 * dc->gasket_spinnery.position), 0, 0, 1);
1218 glRotatef (360 * sin (M_PI/2 * dc->gasket_spinnerz.position), 1, 0, 0);
1220 memcpy (gcolor, dc->color, sizeof (dc->color));
1221 if (dc->wire_overlay != 0)
1223 gcolor[0] = gcolor[1] = gcolor[2] = 0;
1224 specular[0] = specular[1] = specular[2] = 0;
1227 glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, gcolor);
1228 glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular);
1229 glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shininess);
1232 glCallList (dc->gasket_list_wire);
1233 else if (dc->wire_overlay != 0)
1235 glCallList (dc->gasket_list);
1236 glDisable (GL_LIGHTING);
1237 glCallList (dc->gasket_list_wire);
1238 if (!wire) glEnable (GL_LIGHTING);
1241 glCallList (dc->gasket_list);
1245 glRotatef (360 * sin (M_PI/2 * dc->helix_spinnerz.position), 0, 0, 1);
1248 glCallList (dc->helix_list_wire);
1249 else if (dc->wire_overlay != 0)
1251 glCallList (dc->helix_list_facetted);
1252 glDisable (GL_LIGHTING);
1253 glCallList (dc->helix_list_wire);
1254 if (!wire) glEnable (GL_LIGHTING);
1257 glCallList (dc->helix_list);
1261 if (dc->wire_overlay > 0)
1264 if (mi->fps_p) do_fps (mi);
1267 glXSwapBuffers(dpy, window);
1270 XSCREENSAVER_MODULE_2 ("DNAlogo", dnalogo, logo)