diff options
Diffstat (limited to 'hacks/glx/dnalogo.c')
| -rw-r--r-- | hacks/glx/dnalogo.c | 3656 |
1 files changed, 0 insertions, 3656 deletions
diff --git a/hacks/glx/dnalogo.c b/hacks/glx/dnalogo.c deleted file mode 100644 index bd79c5b..0000000 --- a/hacks/glx/dnalogo.c +++ /dev/null @@ -1,3656 +0,0 @@ -/* DNA Logo, Copyright (c) 2001-2018 Jamie Zawinski <jwz@jwz.org> - * - * DNA Lounge - * - * Restaurant -- Bar -- Nightclub -- Cafe -- Est. 1985. - * - * 375 Eleventh Street - * San Francisco, CA - * 94103 - * - * https://www.dnalounge.com/ - * http://www.dnapizza.com/ - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation. No representations are made about the suitability of this - * software for any purpose. It is provided "as is" without express or - * implied warranty. - */ - -#define DEFAULTS __extension__ \ - "*delay: 25000 \n" \ - "*showFPS: False \n" \ - "*wireframe: False \n" \ - "*doGasket: True \n" \ - "*doHelix: True \n" \ - "*doLadder: True \n" \ - "*doFrame: True \n" \ - "*wallFacets: 360 \n" \ - "*barFacets: 90 \n" \ - "*clockwise: False \n" \ - "*turns: 0.72 \n" \ - "*turnSpacing: 2.3 \n" \ - "*barSpacing: 0.268 \n" \ - "*wallHeight: 0.42 \n" \ - "*wallThickness: 0.12 \n" \ - "*barThickness: 0.058 \n" \ - "*wallTaper: 0.95 \n" \ - "*gasketSize: 2.0 \n" \ - "*gasketDepth: 0.15 \n" \ - "*gasketThickness: 0.4 \n" \ - "*frameSize: 1.28 \n" \ - "*frameDepth: 0.01 \n" \ - "*frameThickness: 0.03 \n" \ - "*triangleSize: 0.045 \n" \ - "*cwFacets: 3 \n" \ - "*cwDiscFacets: 64 \n" \ - "*cwSpread: 0.5 \n" \ - "*cwLineWidth: 0.18 \n" \ - "*cwThickness: 0.15 \n" \ - "*cwCapSize: 0.4 \n" \ - "*text: CODEWORD\n" \ - "*speed: 1.0 \n" \ - "*mode: both" "\n" \ - ".background: #000000\n" \ - ".foreground: #00AA00\n" \ - ".cwForeground: #FCA816\n" \ - ".cwBackground: #943225\n" \ - "*cwFont: " CWFONT "\n" \ - "*geometry: =640x640\n" \ - -#define CWFONT "Yearling 28, OCR A Std 24, Courier 24" - -# define release_logo 0 - -#undef DXF_OUTPUT_HACK - -#ifdef DXF_OUTPUT_HACK /* When this is defined, instead of rendering - to the screen, we write a DXF CAD file to stdout. - This is a kludge of shocking magnitude... - Maybe there's some other way to intercept all - glVertex3f calls than with a #define? */ -# define unit_tube dxf_unit_tube -# define unit_cone dxf_unit_cone -# define tube_1 dxf_tube_1 -# define tube dxf_tube -# define cone dxf_cone -#endif /* DXF_OUTPUT_HACK */ - -#include "xlockmore.h" -#include "normals.h" -#include "tube.h" -#include "sphere.h" -#include "rotator.h" -#include "gltrackball.h" -#include "utf8wc.h" -#include "texfont.h" - -#ifdef USE_GL /* whole file */ - -#ifdef HAVE_JWZGLES -# include "dnapizza.h" -#else -# define HAVE_TESS -#endif - -typedef enum { - HELIX_IN, HELIX, HELIX_OUT, - PIZZA_IN, PIZZA, PIZZA_OUT, - HELIX_AND_PIZZA, -# ifdef CW - CODEWORD_IN, CODEWORD, CODEWORD_OUT, CODEWORD_BLANK -# endif -} glyph_mode; - -typedef struct { - Bool spinning_p; - GLfloat position; /* 0.0 - 1.0 */ - GLfloat position_eased; /* 0.0 - 1.0, eased in and out */ - GLfloat easement; /* portion of path that is eased. <= 0.5 */ - GLfloat speed; /* how far along the path (may be negative) */ - GLfloat probability; /* relative likelyhood to start spinning */ -} spinner; - -typedef struct { - GLXContext *glx_context; - - GLuint helix_list, helix_list_wire, helix_list_facetted; - GLuint pizza_list, pizza_list_wire, pizza_list_facetted; - GLuint gasket_list, gasket_list_wire; - GLuint frame_list, frame_list_wire; - int polys[7]; - - int wall_facets; - int bar_facets; - Bool clockwise; - GLfloat color[4]; - - GLfloat turns; - GLfloat turn_spacing; - GLfloat bar_spacing; - GLfloat wall_height; - GLfloat wall_thickness; - GLfloat bar_thickness; - GLfloat wall_taper; - - GLfloat gasket_size; - GLfloat gasket_depth; - GLfloat gasket_thickness; - - GLfloat frame_size; - GLfloat frame_depth; - GLfloat frame_thickness; - GLfloat triangle_size; - -# ifdef CW - int codeword_facets, codeword_disc_facets; - GLfloat codeword_spread, codeword_line_width, codeword_thickness; - GLfloat codeword_cap_size; - const char *codeword_text; - char *codeword_text_out; - int *codeword_text_points; - XYZ *codeword_path; - int codeword_path_npoints; - int codeword_nguides; - XYZ *codeword_guides; - GLfloat codeword_color[4], codeword_bg[4]; - texture_font_data *font; -# endif - -# ifdef DEBUG - GLfloat persp_off, pos_off; - texture_font_data *label_font; -# endif - - GLfloat speed; - glyph_mode mode; - glyph_mode anim_state; - GLfloat anim_ratio; - - spinner gasket_spinnerx, gasket_spinnery, gasket_spinnerz; - spinner scene_spinnerx, scene_spinnery; /* for DNA */ -# ifdef CW - rotator *scene_rot; /* for Codeword */ -# endif - spinner helix_spinnerz; - spinner pizza_spinnery, pizza_spinnerz; - spinner frame_spinner; - - trackball_state *trackball; - Bool button_down_p; - - int wire_overlay; /* frame countdown */ - -} logo_configuration; - -static logo_configuration *dcs = NULL; - -static XrmOptionDescRec opts[] = { - { "-speed", ".speed", XrmoptionSepArg, 0 }, - { "-mode", ".mode", XrmoptionSepArg, 0 }, - { "-pizza", ".mode", XrmoptionNoArg, "pizza" }, - { "-helix", ".mode", XrmoptionNoArg, "helix" }, - { "-both", ".mode", XrmoptionNoArg, "both" }, -# ifdef CW - { "-codeword", ".mode", XrmoptionNoArg, "codeword" }, - { "-cw", ".mode", XrmoptionNoArg, "codeword" }, - { "-text", ".text", XrmoptionSepArg, 0 }, -# endif -}; - -ENTRYPOINT ModeSpecOpt logo_opts = {countof(opts), opts, 0, NULL, NULL}; - -#define PROBABILITY_SCALE 600 - - -#ifdef DXF_OUTPUT_HACK - -# define glBegin dxf_glBegin -# define glVertex3f dxf_glVertex3f -# define glVertex3dv dxf_glVertex3dv -# define glEnd dxf_glEnd -# define glVertexPointer dxf_glVertexPointer -# define glDrawArrays dxf_glDrawArrays - -static int dxf_type, dxf_point, dxf_point_total, dxf_layer, dxf_color; -static GLfloat dxf_quads[4*4]; - -static void -dxf_glBegin (int type) -{ - dxf_type = type; - dxf_point = 0; - dxf_point_total = 0; -} - -static void -dxf_glVertex3f (GLfloat ox, GLfloat oy, GLfloat oz) -{ - int i = 0; - GLfloat m[4*4]; - GLfloat x, y, z; - - /* Transform the point into modelview space. */ - glGetFloatv (GL_MODELVIEW_MATRIX, m); - x = ox * m[0] + oy * m[4] + oz * m[8] + m[12]; - y = ox * m[1] + oy * m[5] + oz * m[9] + m[13]; - z = ox * m[2] + oy * m[6] + oz * m[10] + m[14]; - - dxf_quads[dxf_point*3+0] = x; - dxf_quads[dxf_point*3+1] = y; - dxf_quads[dxf_point*3+2] = z; - dxf_point++; - dxf_point_total++; - - switch (dxf_type) { - case GL_QUADS: - if (dxf_point < 4) return; - - fprintf (stdout, "0\n3DFACE\n8\n%d\n62\n%d\n", dxf_layer, dxf_color); - fprintf (stdout, "10\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "20\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "30\n%.6f\n", dxf_quads[i++]); - - fprintf (stdout, "11\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "21\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "31\n%.6f\n", dxf_quads[i++]); - - fprintf (stdout, "12\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "22\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "32\n%.6f\n", dxf_quads[i++]); - - fprintf (stdout, "13\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "23\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "33\n%.6f\n", dxf_quads[i++]); - dxf_point = 0; - break; - - case GL_QUAD_STRIP: - if (dxf_point < 4) return; - - fprintf (stdout, "0\n3DFACE\n8\n%d\n62\n%d\n", dxf_layer, dxf_color); - fprintf (stdout, "10\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "20\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "30\n%.6f\n", dxf_quads[i++]); - - fprintf (stdout, "11\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "21\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "31\n%.6f\n", dxf_quads[i++]); - - fprintf (stdout, "12\n%.6f\n", dxf_quads[i+3]); /* funky quad strip */ - fprintf (stdout, "22\n%.6f\n", dxf_quads[i+4]); /* vert order: 1243. */ - fprintf (stdout, "32\n%.6f\n", dxf_quads[i+5]); - - fprintf (stdout, "13\n%.6f\n", dxf_quads[i]); - fprintf (stdout, "23\n%.6f\n", dxf_quads[i+1]); - fprintf (stdout, "33\n%.6f\n", dxf_quads[i+2]); - i += 6; - - dxf_quads[0] = dxf_quads[6]; /* copy point 3 to pos 1 */ - dxf_quads[1] = dxf_quads[7]; - dxf_quads[2] = dxf_quads[8]; - dxf_quads[3] = dxf_quads[9]; /* copy point 4 to pos 2 */ - dxf_quads[4] = dxf_quads[10]; - dxf_quads[5] = dxf_quads[11]; - dxf_point = 2; /* leave those two points in queue */ - break; - - case GL_TRIANGLES: - case GL_TRIANGLE_FAN: - if (dxf_point < 3) return; - - fprintf (stdout, "0\n3DFACE\n8\n%d\n62\n%d\n", dxf_layer, dxf_color); - fprintf (stdout, "10\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "20\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "30\n%.6f\n", dxf_quads[i++]); - - fprintf (stdout, "11\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "21\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "31\n%.6f\n", dxf_quads[i++]); - - fprintf (stdout, "12\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "22\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "32\n%.6f\n", dxf_quads[i++]); - - i -= 3; - fprintf (stdout, "13\n%.6f\n", dxf_quads[i++]); /* dup pt 4 as pt 3. */ - fprintf (stdout, "23\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "33\n%.6f\n", dxf_quads[i++]); - - dxf_point = 0; - if (dxf_type == GL_TRIANGLE_FAN) - { - dxf_quads[3] = dxf_quads[6]; /* copy point 3 to point 2 */ - dxf_quads[4] = dxf_quads[7]; - dxf_quads[5] = dxf_quads[8]; - dxf_point = 2; /* leave two points in queue */ - } - break; - - case GL_TRIANGLE_STRIP: - if (dxf_point < 3) return; - - fprintf (stdout, "0\n3DFACE\n8\n%d\n62\n%d\n", dxf_layer, dxf_color); - - fprintf (stdout, "10\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "20\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "30\n%.6f\n", dxf_quads[i++]); - - fprintf (stdout, "11\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "21\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "31\n%.6f\n", dxf_quads[i++]); - - fprintf (stdout, "12\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "22\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "32\n%.6f\n", dxf_quads[i++]); - - i -= 3; - fprintf (stdout, "13\n%.6f\n", dxf_quads[i++]); /* dup pt 4 as pt 3. */ - fprintf (stdout, "23\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "33\n%.6f\n", dxf_quads[i++]); - - dxf_quads[0] = dxf_quads[3]; /* copy point 2 to pos 1 */ - dxf_quads[1] = dxf_quads[4]; - dxf_quads[2] = dxf_quads[5]; - dxf_quads[3] = dxf_quads[6]; /* copy point 3 to pos 2 */ - dxf_quads[4] = dxf_quads[7]; - dxf_quads[5] = dxf_quads[8]; - dxf_point = 2; /* leave those two points in queue */ - break; - - case GL_LINES: - case GL_LINE_STRIP: - case GL_LINE_LOOP: - - if (dxf_point_total == 1) - { - dxf_quads[6] = ox; - dxf_quads[7] = oy; - dxf_quads[8] = oz; - } - - if (dxf_point < 2) return; - - fprintf (stdout, "0\nLINE\n8\n%d\n62\n%d\n", dxf_layer, dxf_color); - - fprintf (stdout, "10\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "20\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "30\n%.6f\n", dxf_quads[i++]); - - fprintf (stdout, "11\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "21\n%.6f\n", dxf_quads[i++]); - fprintf (stdout, "31\n%.6f\n", dxf_quads[i++]); - - dxf_point = 0; - if (dxf_type != GL_LINES) - { - dxf_quads[0] = dxf_quads[3]; - dxf_quads[1] = dxf_quads[4]; - dxf_quads[2] = dxf_quads[5]; - dxf_point = 1; - } - break; - - default: - abort(); - break; - } -} - - -static void -dxf_glVertex3dv (const GLdouble *v) -{ - glVertex3f (v[0], v[1], v[2]); -} - - -static void -dxf_glEnd(void) -{ - if (dxf_type == GL_LINE_LOOP) /* close loop */ - glVertex3f (dxf_quads[6], dxf_quads[7], dxf_quads[8]); - dxf_type = -1; - dxf_point = 0; - dxf_point_total = 0; -} - - -static void -dxf_start (void) -{ - fprintf (stdout, "0\nSECTION\n2\nHEADER\n0\nENDSEC\n"); - fprintf (stdout, "0\nSECTION\n2\nENTITIES\n"); -} - -static void -dxf_end (void) -{ - fprintf (stdout, "0\nENDSEC\n0\nEOF\n"); - exit (0); -} - - -static const GLvoid *dxf_vp; -static GLsizei dxf_vp_size; -static GLsizei dxf_vp_stride; - -static void -dxf_glVertexPointer (GLint size, GLenum type, GLsizei stride, - const GLvoid *pointer) -{ - if (type != GL_FLOAT) abort(); - if (stride <= 0) abort(); - dxf_vp = pointer; - dxf_vp_size = size; - dxf_vp_stride = stride; -} - -static void -dxf_glDrawArrays (GLenum mode, GLint first, GLsizei count) -{ - int i; - unsigned char *a = (unsigned char *) dxf_vp; - dxf_glBegin (mode); - for (i = first; i < first+count; i++) - { - GLfloat *fa = (GLfloat *) a; - dxf_glVertex3f (fa[0], fa[1], fa[2]); - a += dxf_vp_stride; - } - dxf_glEnd(); -} - - -# define XYZ tube_XYZ /* avoid conflict with normals.h */ -# include "tube.c" /* Yes, I really am including a C file. */ -# undef XYZ -# define XYZ sphere_XYZ -# define unit_sphere unit_sphere_dxf -# define unit_dome unit_dome_dxf -# include "sphere.c" -# undef XYZ - -#endif /* DXF_OUTPUT_HACK */ - - - -/* Calculate the angle (in radians) between two vectors. - */ -static GLfloat -vector_angle (double ax, double ay, double az, - double bx, double by, double bz) -{ - double La = sqrt (ax*ax + ay*ay + az*az); - double Lb = sqrt (bx*bx + by*by + bz*bz); - double cc, angle; - - if (La == 0 || Lb == 0) return 0; - if (ax == bx && ay == by && az == bz) return 0; - - /* dot product of two vectors is defined as: - La * Lb * cos(angle between vectors) - and is also defined as: - ax*bx + ay*by + az*bz - so: - La * Lb * cos(angle) = ax*bx + ay*by + az*bz - cos(angle) = (ax*bx + ay*by + az*bz) / (La * Lb) - angle = acos ((ax*bx + ay*by + az*bz) / (La * Lb)); - */ - cc = (ax*bx + ay*by + az*bz) / (La * Lb); - if (cc > 1) cc = 1; /* avoid fp rounding error (1.000001 => sqrt error) */ - angle = acos (cc); - - return (angle); -} - - -# ifdef CW - -static void -normalize (XYZ *p) -{ - GLfloat d = sqrt (p->x*p->x + p->y*p->y + p->z*p->z); - if (d != 0) - { - p->x /= d; - p->y /= d; - p->z /= d; - } - else - { - p->x = p->y = p->z = 0; - } -} - - -static double -dot (const XYZ u, const XYZ v) -{ - return (u.x * v.x) + (u.y * v.y) + (u.z * v.z); -} - -#endif /* CW */ - - -/* Make the helix - */ - -static int -make_helix (logo_configuration *dc, int facetted, int wire) -{ - int polys = 0; - int wall_facets = dc->wall_facets / (facetted ? 10 : 1); - GLfloat th; - GLfloat max_th = M_PI * 2 * dc->turns; - GLfloat th_inc = M_PI * 2 / wall_facets; - - GLfloat x1=0, y1=0, x2=0, y2=0; - GLfloat x1b=0, y1b=0, x2b=0, y2b=0; - GLfloat z1=0, z2=0; - GLfloat h1=0, h2=0; - GLfloat h1off=0, h2off=0; - GLfloat z_inc = dc->turn_spacing / wall_facets; - - th = 0; - x1 = 1; - y1 = 0; - x1b = 1; - y1b = 0; - - z1 = -(dc->turn_spacing * dc->turns / 2); - - h1 = (dc->wall_taper > 0 ? 0 : dc->wall_height / 2); - h1off = (dc->wall_taper > 0 ? -dc->wall_height / 2 : 0); - - if (!dc->clockwise) - z1 = -z1, z_inc = -z_inc, h1off = -h1off; - - /* Leading end-cap - */ - if (!wire && h1 > 0) - { - GLfloat nx, ny; - glFrontFace(GL_CCW); - glBegin(GL_QUADS); - nx = cos (th + M_PI/2); - ny = sin (th + M_PI/2); - glNormal3f(nx, ny, 0); - glVertex3f( x1, y1, z1 - h1 + h1off); - glVertex3f( x1, y1, z1 + h1 + h1off); - glVertex3f(x1b, y1b, z1 + h1 + h1off); - glVertex3f(x1b, y1b, z1 - h1 + h1off); - polys++; - glEnd(); - } - - while (th + th_inc <= max_th) - { - GLfloat thick = dc->wall_thickness; - - th += th_inc; - - x2 = cos (th); - y2 = sin (th); - z2 = z1 + z_inc; - - h2 = h1; - h2off = h1off; - - if (dc->wall_taper > 0) - { - h2off = 0; - if (th < dc->wall_taper) - { - h2 = dc->wall_height/2 * cos (M_PI / 2 - * (1 - (th / dc->wall_taper))); - if (dc->clockwise) - h2off = h2 - dc->wall_height/2; - else - h2off = dc->wall_height/2 - h2; - - if (th + th_inc <= 0) - thick = 0; - else - thick *= cos (M_PI / 2 * (1 - (th / dc->wall_taper))); - } - else if (th >= max_th - dc->wall_taper) - { - if (th + th_inc > max_th) /* edge case: always come to a point */ - h2 = 0; - else - h2 = dc->wall_height/2 * cos (M_PI / 2 - * (1 - ((max_th - th) - / dc->wall_taper))); - if (dc->clockwise) - h2off = dc->wall_height/2 - h2; - else - h2off = h2 - dc->wall_height/2; - - if (th + th_inc > max_th) - thick = 0; - else - thick *= cos(M_PI / 2 * (1 - ((max_th - th)/dc->wall_taper))); - } - } - - x2b = x2 * (1 - thick); - y2b = y2 * (1 - thick); - - /* outer face - */ - glFrontFace(GL_CW); - glBegin(wire ? GL_LINES : GL_QUADS); - glNormal3f(x1, y1, 0); - glVertex3f(x1, y1, z1 - h1 + h1off); - glVertex3f(x1, y1, z1 + h1 + h1off); - glNormal3f(x2, y2, 0); - glVertex3f(x2, y2, z2 + h2 + h2off); - glVertex3f(x2, y2, z2 - h2 + h2off); - polys++; - glEnd(); - - /* inner face - */ - glFrontFace(GL_CCW); - glBegin(wire ? GL_LINES : GL_QUADS); - glNormal3f(-x1b, -y1b, 0); - glVertex3f( x1b, y1b, z1 - h1 + h1off); - glVertex3f( x1b, y1b, z1 + h1 + h1off); - glNormal3f(-x2b, -y2b, 0); - glVertex3f( x2b, y2b, z2 + h2 + h2off); - glVertex3f( x2b, y2b, z2 - h2 + h2off); - polys++; - glEnd(); - - /* top face - */ - glFrontFace(GL_CCW); - /* glNormal3f(0, 0, 1);*/ - do_normal (x2, y2, z2 + h2 + h2off, - x2b, y2b, z2 + h2 + h2off, - x1b, y1b, z1 + h1 + h1off); - glBegin(wire ? GL_LINE_LOOP : GL_QUADS); - glVertex3f( x2, y2, z2 + h2 + h2off); - glVertex3f( x2b, y2b, z2 + h2 + h2off); - glVertex3f( x1b, y1b, z1 + h1 + h1off); - glVertex3f( x1, y1, z1 + h1 + h1off); - polys++; - glEnd(); - - /* bottom face - */ - glFrontFace(GL_CCW); - do_normal ( x1, y1, z1 - h1 + h1off, - x1b, y1b, z1 - h1 + h1off, - x2b, y2b, z2 - h2 + h2off); - glBegin(wire ? GL_LINE_LOOP : GL_QUADS); - glNormal3f(0, 0, -1); - glVertex3f( x1, y1, z1 - h1 + h1off); - glVertex3f( x1b, y1b, z1 - h1 + h1off); - glVertex3f( x2b, y2b, z2 - h2 + h2off); - glVertex3f( x2, y2, z2 - h2 + h2off); - polys++; - glEnd(); - - x1 = x2; - y1 = y2; - x1b = x2b; - y1b = y2b; - z1 += z_inc; - h1 = h2; - h1off = h2off; - } - - /* Trailing end-cap - */ - if (!wire && h2 > 0) - { - GLfloat nx, ny; - glFrontFace(GL_CW); - glBegin(GL_QUADS); - nx = cos (th + M_PI/2); - ny = sin (th + M_PI/2); - glNormal3f(nx, ny, 0); - glVertex3f(x2, y2, z1 - h2 + h2off); - glVertex3f(x2, y2, z1 + h2 + h2off); - glVertex3f(x2b, y2b, z1 + h2 + h2off); - glVertex3f(x2b, y2b, z1 - h2 + h2off); - polys++; - glEnd(); - } - return polys; -} - - -static int -make_ladder (logo_configuration *dc, int facetted, int wire) -{ - int polys = 0; - GLfloat th; - GLfloat max_th = dc->turns * M_PI * 2; - GLfloat max_z = dc->turns * dc->turn_spacing; - GLfloat z_inc = dc->bar_spacing; - GLfloat th_inc = M_PI * 2 * (dc->bar_spacing / dc->turn_spacing); - GLfloat x, y, z; - - /* skip forward to center the bars in the helix... */ - int i; - GLfloat usable_th = max_th - dc->wall_taper; - GLfloat usable_z = max_z / (max_th / usable_th); - int nbars = usable_z / dc->bar_spacing; - GLfloat used_z, pad_z, pad_ratio; - - if (! (nbars & 1)) nbars--; /* always an odd number of bars */ - - used_z = (nbars - 1) * dc->bar_spacing; - pad_z = max_z - used_z; - pad_ratio = pad_z / max_z; - - th = (max_th * pad_ratio/2); - z = -(max_z / 2) + (max_z * pad_ratio/2); - - /* ##### WHYYYYYY */ - /* The image is not reflected across line y = -x and I don't know why. */ - th += M_PI * -0.035; - z -= 0.08; - - if (!dc->clockwise) - z = -z, z_inc = -z_inc; - - glFrontFace(GL_CCW); - for (i = 0; i < nbars; i++) - { - int facets = dc->bar_facets / (facetted ? 14 : 1); - if (facets <= 3) facets = 3; - x = cos (th) * (1 - dc->wall_thickness); - y = sin (th) * (1 - dc->wall_thickness); - polys += tube ( x, y, z, - -x, -y, z, - dc->bar_thickness, 0, facets, - True, True, wire); - z += z_inc; - th += th_inc; - } - return polys; -} - - - -/* Make the gasket - */ - - -static int -make_gasket (logo_configuration *dc, int wire) -{ - int polys = 0; - int i; - int points_size; - int npoints = 0; - int nctrls = 0; - int res = 360/8; - GLfloat d2r = M_PI / 180; - - GLfloat thick2 = (dc->gasket_thickness / dc->gasket_size) / 2; - - GLfloat *pointsx0, *pointsy0, *pointsx1, *pointsy1, *normals; - - GLfloat r0 = 0.750; /* 395 */ - GLfloat r1a = 0.825; /* bottom of wall below upper left hole */ - GLfloat r1b = 0.867; /* center of upper left hole */ - GLfloat r1c = 0.909; /* top of wall above hole */ - GLfloat r1 = 0.916; /* 471 */ - GLfloat r2 = 0.963; /* 490 */ - GLfloat r3 = 0.960; /* 499 */ - GLfloat r4 = 1.000; /* 507 */ - GLfloat r5 = 1.080; /* 553 */ - - GLfloat ctrl_r[100], ctrl_th[100]; - - glPushMatrix(); - -# ifdef DXF_OUTPUT_HACK - if (! wire) res *= 8; -# endif - -# define POINT(r,th) \ - ctrl_r [nctrls] = r, \ - ctrl_th[nctrls] = (th * d2r), \ - nctrls++ - - POINT (0.829, 0); /* top indentation, right half */ - POINT (0.831, 0.85); - POINT (0.835, 1.81); - POINT (0.841, 2.65); - POINT (0.851, 3.30); - POINT (0.862, 3.81); - POINT (0.872, 3.95); - - POINT (r4, 4.0); /* moving clockwise... */ - POINT (r4, 47.0); - POINT (r1, 47.0); - POINT (r1, 53.0); - POINT (r2, 55.5); - POINT (r2, 72.3); - POINT (r1, 74.0); - POINT (r1, 100.0); - POINT (r3, 102.5); - POINT (r3, 132.0); - POINT (r1, 133.0); - - POINT (r1, 180.7); - POINT (r2, 183.6); - POINT (r2, 210.0); - POINT (r1, 212.0); - POINT (r1, 223.2); - POINT (r5, 223.2); - POINT (r5, 225.0); - POINT (r4, 225.0); - - POINT (r4, 316.8); /* upper left indentation */ - POINT (0.990, 316.87); - POINT (0.880, 317.21); - POINT (0.872, 317.45); - POINT (0.869, 317.80); - POINT (0.867, 318.10); - - POINT (0.867, 318.85); - POINT (0.869, 319.15); - POINT (0.872, 319.50); - POINT (0.880, 319.74); - POINT (0.990, 320.08); - - POINT (r4, 338.0); - if (! wire) - { - POINT (r1a, 338.0); /* cut-out disc */ - POINT (r1a, 344.0); - } - POINT (r4, 344.0); - POINT (r4, 356.0); - - POINT (0.872, 356.05); /* top indentation, left half */ - POINT (0.862, 356.19); - POINT (0.851, 356.70); - POINT (0.841, 357.35); - POINT (0.835, 358.19); - POINT (0.831, 359.15); - POINT (0.829, 360); -# undef POINT - - points_size = res + (nctrls * 2); - pointsx0 = (GLfloat *) malloc (points_size * sizeof(GLfloat)); - pointsy0 = (GLfloat *) malloc (points_size * sizeof(GLfloat)); - pointsx1 = (GLfloat *) malloc (points_size * sizeof(GLfloat)); - pointsy1 = (GLfloat *) malloc (points_size * sizeof(GLfloat)); - normals = (GLfloat *) malloc (points_size * sizeof(GLfloat) * 2); - - npoints = 0; - for (i = 1; i < nctrls; i++) - { - GLfloat from_r = ctrl_r [i-1]; - GLfloat from_th = ctrl_th[i-1]; - GLfloat to_r = ctrl_r [i]; - GLfloat to_th = ctrl_th[i]; - - GLfloat step = 2*M_PI / res; - int nsteps = 1 + ((to_th - from_th) / step); - int j; - - for (j = 0; j < nsteps + (i == nctrls-1); j++) - { - GLfloat r = from_r + (j * (to_r - from_r) / nsteps); - GLfloat th = from_th + (j * (to_th - from_th) / nsteps); - - GLfloat cth = cos(th) * dc->gasket_size; - GLfloat sth = sin(th) * dc->gasket_size; - - pointsx0[npoints] = r0 * cth; /* inner ring */ - pointsy0[npoints] = r0 * sth; - pointsx1[npoints] = r * cth; /* outer ring */ - pointsy1[npoints] = r * sth; - npoints++; - - if (npoints >= points_size) abort(); - } - } - - /* normals for the outer ring */ - for (i = 1; i < npoints; i++) - { - XYZ a, b, c, n; - a.x = pointsx1[i-1]; - a.y = pointsy1[i-1]; - a.z = 0; - b.x = pointsx1[i]; - b.y = pointsy1[i]; - b.z = 0; - c = b; - c.z = 1; - n = calc_normal (a, b, c); - normals[(i-1)*2 ] = n.x; - normals[(i-1)*2+1] = n.y; - } - - glRotatef(-90, 0, 1, 0); - glRotatef(180, 0, 0, 1); - - if (wire) - { - GLfloat z; - for (z = -thick2; z <= thick2; z += thick2*2) - { -# if 1 - /* inside edge */ - glBegin (GL_LINE_LOOP); - for (i = 0; i < npoints; i++) - glVertex3f (pointsx0[i], pointsy0[i], z); - polys += npoints; - glEnd(); - - /* outside edge */ - glBegin (GL_LINE_LOOP); - for (i = 0; i < npoints; i++) - glVertex3f (pointsx1[i], pointsy1[i], z); - polys += npoints; - glEnd(); -# else - for (i = 1; i < npoints; i++) - { - glBegin (GL_LINE_STRIP); - glVertex3f (pointsx0[i-1], pointsy0[i-1], z); - glVertex3f (pointsx0[i ], pointsy0[i ], z); - glVertex3f (pointsx1[i ], pointsy1[i ], z); - glVertex3f (pointsx1[i-1], pointsy1[i-1], z); - glEnd(); - } - polys += npoints; -# endif - } -#if 1 - glBegin (GL_LINES); - for (i = 0; i < npoints; i++) - { - /* inside rim */ - glVertex3f (pointsx0[i], pointsy0[i], -thick2); - glVertex3f (pointsx0[i], pointsy0[i], thick2); - /* outside rim */ - glVertex3f (pointsx1[i], pointsy1[i], -thick2); - glVertex3f (pointsx1[i], pointsy1[i], thick2); - } - polys += npoints; - glEnd(); -#endif - } - else - { - /* top */ - glFrontFace(GL_CW); - glNormal3f(0, 0, -1); - glBegin (GL_QUAD_STRIP); - for (i = 0; i < npoints; i++) - { - glVertex3f (pointsx0[i], pointsy0[i], -thick2); - glVertex3f (pointsx1[i], pointsy1[i], -thick2); - } - polys += npoints; - glEnd(); - - /* bottom */ - glFrontFace(GL_CCW); - glNormal3f(0, 0, 1); - glBegin (GL_QUAD_STRIP); - for (i = 0; i < npoints; i++) - { - glVertex3f (pointsx0[i], pointsy0[i], thick2); - glVertex3f (pointsx1[i], pointsy1[i], thick2); - } - polys += npoints; - glEnd(); - - /* inside edge */ - glFrontFace(GL_CW); - glBegin (GL_QUAD_STRIP); - for (i = 0; i < npoints; i++) - { - glNormal3f (-pointsx0[i], -pointsy0[i], 0); - glVertex3f ( pointsx0[i], pointsy0[i], thick2); - glVertex3f ( pointsx0[i], pointsy0[i], -thick2); - } - polys += npoints; - glEnd(); - - /* outside edge */ - glFrontFace(GL_CCW); - glBegin (GL_QUADS); - { - for (i = 0; i < npoints-1; i++) - { - int ia = (i == 0 ? npoints-2 : i-1); - int iz = (i == npoints-2 ? 0 : i+1); - GLfloat x = pointsx1[i]; - GLfloat y = pointsy1[i]; - GLfloat xz = pointsx1[iz]; - GLfloat yz = pointsy1[iz]; - - GLfloat nxa = normals[ia*2]; /* normal of [i-1 - i] face */ - GLfloat nya = normals[ia*2+1]; - GLfloat nx = normals[i*2]; /* normal of [i - i+1] face */ - GLfloat ny = normals[i*2+1]; - GLfloat nxz = normals[iz*2]; /* normal of [i+1 - i+2] face */ - GLfloat nyz = normals[iz*2+1]; - - GLfloat anglea = vector_angle (nx, ny, 0, nxa, nya, 0); - GLfloat anglez = vector_angle (nx, ny, 0, nxz, nyz, 0); - GLfloat pointy = 0.6; - - if (anglea > pointy) - { - glNormal3f (nx, ny, 0); - glVertex3f (x, y, thick2); - glVertex3f (x, y, -thick2); - } - else - { - glNormal3f ((nxa + nx) / 2, (nya + ny) / 2, 0); - glVertex3f (x, y, thick2); - glVertex3f (x, y, -thick2); - } - - if (anglez > pointy) - { - glNormal3f (nx, ny, 0); - glVertex3f (xz, yz, -thick2); - glVertex3f (xz, yz, thick2); - } - else - { - glNormal3f ((nx + nxz) / 2, (ny + nyz) / 2, 0); - glVertex3f (xz, yz, -thick2); - glVertex3f (xz, yz, thick2); - } - } - polys += npoints; - } - glEnd(); - } - - /* Fill in the upper left hole... - */ - { - GLfloat th; - npoints = 0; - - th = 338.0 * d2r; - pointsx0[npoints] = r1c * cos(th) * dc->gasket_size; - pointsy0[npoints] = r1c * sin(th) * dc->gasket_size; - npoints++; - pointsx0[npoints] = r4 * cos(th) * dc->gasket_size; - pointsy0[npoints] = r4 * sin(th) * dc->gasket_size; - npoints++; - - th = 344.0 * d2r; - pointsx0[npoints] = r1c * cos(th) * dc->gasket_size; - pointsy0[npoints] = r1c * sin(th) * dc->gasket_size; - npoints++; - pointsx0[npoints] = r4 * cos(th) * dc->gasket_size; - pointsy0[npoints] = r4 * sin(th) * dc->gasket_size; - - if (! wire) - { - /* front wall */ - glNormal3f (0, 0, -1); - glFrontFace(GL_CW); - glBegin (wire ? GL_LINE_LOOP : GL_QUADS); - glVertex3f (pointsx0[0], pointsy0[0], -thick2); - glVertex3f (pointsx0[1], pointsy0[1], -thick2); - glVertex3f (pointsx0[3], pointsy0[3], -thick2); - glVertex3f (pointsx0[2], pointsy0[2], -thick2); - glEnd(); - polys++; - - /* back wall */ - glNormal3f (0, 0, 1); - glFrontFace(GL_CCW); - glBegin (wire ? GL_LINE_LOOP : GL_QUADS); - glVertex3f (pointsx0[0], pointsy0[0], thick2); - glVertex3f (pointsx0[1], pointsy0[1], thick2); - glVertex3f (pointsx0[3], pointsy0[3], thick2); - glVertex3f (pointsx0[2], pointsy0[2], thick2); - glEnd(); - polys++; - } - - /* top wall */ - glFrontFace(GL_CW); - glBegin (wire ? GL_LINE_LOOP : GL_QUADS); - glNormal3f (pointsx0[1], pointsy0[1], 0); - glVertex3f (pointsx0[1], pointsy0[1], thick2); - glNormal3f (pointsx0[3], pointsy0[3], 0); - glVertex3f (pointsx0[3], pointsy0[3], thick2); - glVertex3f (pointsx0[3], pointsy0[3], -thick2); - glNormal3f (pointsx0[1], pointsy0[1], 0); - glVertex3f (pointsx0[1], pointsy0[1], -thick2); - glEnd(); - polys++; - - - /* Now make a donut. - */ - { - int nsteps = (wire ? 12 : 64); - GLfloat r0 = 0.04; - GLfloat r1 = 0.070; - GLfloat th, cth, sth; - - glPushMatrix (); - - th = ((339.0 + 343.0) / 2) * d2r; - - glTranslatef (r1b * cos(th) * dc->gasket_size, - r1b * sin(th) * dc->gasket_size, - 0); - - npoints = 0; - for (i = 0; i < nsteps; i++) - { - th = 2 * M_PI * i / nsteps; - cth = cos (th) * dc->gasket_size; - sth = sin (th) * dc->gasket_size; - pointsx0[npoints] = r0 * cth; - pointsy0[npoints] = r0 * sth; - pointsx1[npoints] = r1 * cth; - pointsy1[npoints] = r1 * sth; - npoints++; - polys++; - } - - pointsx0[npoints] = pointsx0[0]; - pointsy0[npoints] = pointsy0[0]; - pointsx1[npoints] = pointsx1[0]; - pointsy1[npoints] = pointsy1[0]; - npoints++; - - if (wire) - { - glBegin (GL_LINE_LOOP); - for (i = 0; i < npoints; i++) - glVertex3f (pointsx0[i], pointsy0[i], -thick2); - polys += npoints; - glEnd(); - glBegin (GL_LINE_LOOP); - for (i = 0; i < npoints; i++) - glVertex3f (pointsx0[i], pointsy0[i], thick2); - polys += npoints; - glEnd(); -# if 0 - glBegin (GL_LINE_LOOP); - for (i = 0; i < npoints; i++) - glVertex3f (pointsx1[i], pointsy1[i], -thick2); - polys += npoints; - glEnd(); - glBegin (GL_LINE_LOOP); - for (i = 0; i < npoints; i++) - glVertex3f (pointsx1[i], pointsy1[i], thick2); - polys += npoints; - glEnd(); -# endif - } - else - { - /* top */ - glFrontFace(GL_CW); - glNormal3f(0, 0, -1); - glBegin (GL_QUAD_STRIP); - for (i = 0; i < npoints; i++) - { - glVertex3f (pointsx0[i], pointsy0[i], -thick2); - glVertex3f (pointsx1[i], pointsy1[i], -thick2); - } - polys += npoints; - glEnd(); - - /* bottom */ - glFrontFace(GL_CCW); - glNormal3f(0, 0, 1); - glBegin (GL_QUAD_STRIP); - for (i = 0; i < npoints; i++) - { - glVertex3f (pointsx0[i], pointsy0[i], thick2); - glVertex3f (pointsx1[i], pointsy1[i], thick2); - } - polys += npoints; - glEnd(); - } - - /* inside edge */ - glFrontFace(GL_CW); - glBegin (wire ? GL_LINES : GL_QUAD_STRIP); - for (i = 0; i < npoints; i++) - { - glNormal3f (-pointsx0[i], -pointsy0[i], 0); - glVertex3f ( pointsx0[i], pointsy0[i], thick2); - glVertex3f ( pointsx0[i], pointsy0[i], -thick2); - } - polys += npoints; - glEnd(); - - glPopMatrix(); - } - } - - - /* Attach the bottom-right dingus... - */ - { - GLfloat w = 0.05; - GLfloat h = 0.19; - GLfloat th; - - glRotatef (49.5, 0, 0, 1); - glScalef (dc->gasket_size, dc->gasket_size, 1); - glTranslatef (0, (r0+r1)/2, 0); - - /* buried box */ - if (! wire) - { - glFrontFace(GL_CCW); - glBegin (wire ? GL_LINE_STRIP : GL_QUADS); - glNormal3f (0, 0, -1); - glVertex3f (-w/2, -h/2, -thick2); glVertex3f (-w/2, h/2, -thick2); - glVertex3f ( w/2, h/2, -thick2); glVertex3f ( w/2, -h/2, -thick2); - glNormal3f (1, 0, 0); - glVertex3f ( w/2, -h/2, -thick2); glVertex3f ( w/2, h/2, -thick2); - glVertex3f ( w/2, h/2, thick2); glVertex3f ( w/2, -h/2, thick2); - glNormal3f (0, 0, 1); - glVertex3f ( w/2, -h/2, thick2); glVertex3f ( w/2, h/2, thick2); - glVertex3f (-w/2, h/2, thick2); glVertex3f (-w/2, -h/2, thick2); - glNormal3f (-1, 0, 0); - glVertex3f (-w/2, -h/2, thick2); glVertex3f (-w/2, h/2, thick2); - glVertex3f (-w/2, h/2, -thick2); glVertex3f (-w/2, -h/2, -thick2); - polys++; - glEnd(); - } - - npoints = 0; - for (th = (wire ? 0 : -0.1); - th <= M_PI + 0.1; - th += (M_PI / (wire ? 5 : 32))) - { - pointsx0[npoints] = w/2 * cos(th); - pointsy0[npoints] = w/2 * sin(th); - npoints++; - polys++; - } - - /* front inside curve */ - glNormal3f (0, 0, -1); - glFrontFace(GL_CW); - glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN); - if (! wire) glVertex3f (0, h/2, -thick2); - for (i = 0; i < npoints; i++) - glVertex3f (pointsx0[i], h/2 + pointsy0[i], -thick2); - polys += npoints; - glEnd(); - - /* front outside curve */ - glFrontFace(GL_CCW); - glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN); - if (! wire) glVertex3f (0, -h/2, -thick2); - for (i = 0; i < npoints; i++) - glVertex3f (pointsx0[i], -h/2 - pointsy0[i], -thick2); - polys += npoints; - glEnd(); - - /* back inside curve */ - glNormal3f (0, 0, 1); - glFrontFace(GL_CCW); - glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN); - if (! wire) glVertex3f (0, h/2, thick2); - for (i = 0; i < npoints; i++) - glVertex3f (pointsx0[i], h/2 + pointsy0[i], thick2); - polys += npoints; - glEnd(); - - /* back outside curve */ - glFrontFace(GL_CW); - glBegin (wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN); - if (! wire) glVertex3f (0, -h/2, thick2); - for (i = 0; i < npoints; i++) - glVertex3f (pointsx0[i], -h/2 - pointsy0[i], thick2); - polys += npoints; - glEnd(); - - /* inside curve */ - glFrontFace(GL_CCW); - glBegin (wire ? GL_LINES : GL_QUAD_STRIP); - for (i = 0; i < npoints; i++) - { - glNormal3f (pointsx0[i], pointsy0[i], 0); - glVertex3f (pointsx0[i], h/2 + pointsy0[i], thick2); - glVertex3f (pointsx0[i], h/2 + pointsy0[i], -thick2); - } - polys += npoints; - glEnd(); - - /* outside curve */ - glFrontFace(GL_CW); - glBegin (wire ? GL_LINES : GL_QUAD_STRIP); - for (i = 0; i < npoints; i++) - { - glNormal3f (pointsx0[i], -pointsy0[i], 0); - glVertex3f (pointsx0[i], -h/2 - pointsy0[i], thick2); - glVertex3f (pointsx0[i], -h/2 - pointsy0[i], -thick2); - } - polys += npoints; - glEnd(); - } - - free (pointsx0); - free (pointsy0); - free (pointsx1); - free (pointsy1); - free (normals); - - glPopMatrix(); - return polys; -} - -static int -make_frame (logo_configuration *dc, int wire) -{ - int polys = 0; - int i, j; - GLfloat x[20], y[20]; - GLfloat corner_cut = 0.5; - - glPushMatrix(); - glRotatef (90, 0, 1, 0); - glScalef (4 * dc->frame_size, - 4 * dc->frame_size, - 4 * dc->frame_size); - - x[0] = -dc->frame_thickness; - x[1] = -dc->frame_thickness * corner_cut; - x[2] = 0; - x[3] = 0.5 - dc->triangle_size; - x[4] = 0.5; - x[5] = 0.5 + dc->triangle_size; - x[6] = 1; - x[7] = 1 + dc->frame_thickness * corner_cut; - x[8] = 1 + dc->frame_thickness; - - y[0] = -dc->frame_thickness; - y[1] = -dc->frame_thickness * corner_cut; - y[2] = 0; - y[3] = dc->triangle_size; - - /* front and back - */ - glTranslatef (-0.5, -0.5, dc->frame_depth / 4); - if (! wire) - for (j = 0; j <= 1; j++) - { - if (j) glTranslatef (0, 0, -dc->frame_depth / 2); - glFrontFace (j ? GL_CCW : GL_CW); - for (i = 0; i < 4; i++) - { - glNormal3f (0, 0, (j ? -1 : 1)); - glBegin (wire ? GL_LINES : GL_QUAD_STRIP); - glVertex3f (x[0], y[1], 0); glVertex3f (x[0], y[2], 0); - glVertex3f (x[1], y[0], 0); glVertex3f (x[1], y[2], 0); - glVertex3f (x[3], y[0], 0); glVertex3f (x[3], y[2], 0); - glVertex3f (x[4], y[0], 0); glVertex3f (x[4], y[3], 0); - glVertex3f (x[5], y[0], 0); glVertex3f (x[5], y[2], 0); - glVertex3f (x[7], y[0], 0); glVertex3f (x[7], y[2], 0); - glVertex3f (x[8], y[1], 0); glVertex3f (x[8], y[2], 0); - polys += 6; - glEnd (); - glTranslatef (0.5, 0.5, 0); - glRotatef (90, 0, 0, 1); - glTranslatef (-0.5, -0.5, 0); - } - } - - /* ledges - */ - glFrontFace (GL_CCW); - for (i = 0; i < 4; i++) - { - glNormal3f (0, 1, 0); - glBegin (wire ? GL_LINES : GL_QUAD_STRIP); - glVertex3f (x[2], y[2], 0); glVertex3f (x[2], y[2], dc->frame_depth/2); - glVertex3f (x[3], y[2], 0); glVertex3f (x[3], y[2], dc->frame_depth/2); - glVertex3f (x[4], y[3], 0); glVertex3f (x[4], y[3], dc->frame_depth/2); - glVertex3f (x[5], y[2], 0); glVertex3f (x[5], y[2], dc->frame_depth/2); - glVertex3f (x[6], y[2], 0); glVertex3f (x[6], y[2], dc->frame_depth/2); - polys += 4; - glEnd (); - - glNormal3f (0, -1, 0); - glBegin (wire ? GL_LINE_LOOP : GL_QUADS); - glVertex3f (x[7], y[0], 0); - glVertex3f (x[7], y[0], dc->frame_depth/2); - glVertex3f (x[1], y[0], dc->frame_depth/2); - glVertex3f (x[1], y[0], 0); - polys++; - glEnd (); - - glNormal3f (1, -1, 0); - glBegin (wire ? GL_LINE_LOOP : GL_QUADS); - glVertex3f (x[8], y[1], 0); - glVertex3f (x[8], y[1], dc->frame_depth/2); - glVertex3f (x[7], y[0], dc->frame_depth/2); - glVertex3f (x[7], y[0], 0); - polys++; - glEnd (); - - if (wire) - { - glNormal3f (0, 1, 0); - for (j = 0; j <= 1; j++) - { - glBegin (GL_LINE_STRIP); - glVertex3f (x[2], y[2], j*dc->frame_depth/2); - glVertex3f (x[3], y[2], j*dc->frame_depth/2); - glVertex3f (x[4], y[3], j*dc->frame_depth/2); - glVertex3f (x[5], y[2], j*dc->frame_depth/2); - glVertex3f (x[6], y[2], j*dc->frame_depth/2); - polys += 4; - glEnd (); - } - } - - glTranslatef (0.5, 0.5, 0); - glRotatef (90, 0, 0, 1); - glTranslatef (-0.5, -0.5, 0); - } - - glPopMatrix(); - return polys; -} - - -/* Make some pizza. - */ - -#ifdef HAVE_TESS - -typedef struct { - GLdouble *points; - int i; -} tess_out; - - -static void -tess_error_cb (GLenum errorCode) -{ - fprintf (stderr, "%s: tesselation error: %s\n", - progname, gluErrorString(errorCode)); - exit (0); -} - -static void -tess_combine_cb (GLdouble coords[3], GLdouble *d[4], GLfloat w[4], - GLdouble **data_out) -{ - GLdouble *new = (GLdouble *) malloc (3 * sizeof(*new)); - new[0] = coords[0]; - new[1] = coords[1]; - new[2] = coords[2]; - *data_out = new; -} - - -#if 0 -static void -tess_vertex_cb (void *vertex_data, void *closure) -{ - tess_out *to = (tess_out *) closure; - GLdouble *v = (GLdouble *) vertex_data; - to->points[to->i++] = v[0]; - to->points[to->i++] = v[1]; - to->points[to->i++] = v[2]; -} -#endif - -static void -tess_begin_cb (GLenum which) -{ - glBegin(which); -} - -static void -tess_end_cb (void) -{ - glEnd(); -} - -#endif /* HAVE_TESS */ - - -static int -make_pizza (logo_configuration *dc, int facetted, int wire) -{ - int polys = 0; - int topfaces = (facetted ? 48 : 120); - int discfaces = (facetted ? 12 : 120); - int npoints = topfaces * 2 + 100; - GLdouble *points = (GLdouble *) calloc (npoints * 3, sizeof(GLdouble)); - int nholes = 3; - GLdouble *holes = (GLdouble *) calloc (topfaces*nholes*3, sizeof(GLdouble)); - - GLfloat step = M_PI * 2 / 6 / topfaces; - GLfloat thick2 = (dc->gasket_thickness / dc->gasket_size) / 4; - GLfloat th, x, y, s; - int i, j, k; - int endpoints; - -# ifdef HAVE_TESS - tess_out TO, *to = &TO; - GLUtesselator *tess = gluNewTess(); - - to->points = (GLdouble *) calloc (topfaces * 20, sizeof(GLdouble)); - to->i = 0; - -# ifndef _GLUfuncptr -# define _GLUfuncptr void(*)(void) -# endif - - gluTessCallback(tess,GLU_TESS_BEGIN, (_GLUfuncptr)tess_begin_cb); - gluTessCallback(tess,GLU_TESS_VERTEX, (_GLUfuncptr)glVertex3dv); - gluTessCallback(tess,GLU_TESS_END, (_GLUfuncptr)tess_end_cb); - gluTessCallback(tess,GLU_TESS_COMBINE, (_GLUfuncptr)tess_combine_cb); - gluTessCallback(tess,GLU_TESS_ERROR, (_GLUfuncptr)tess_error_cb); - - gluTessProperty (tess, GLU_TESS_BOUNDARY_ONLY, wire); - gluTessProperty (tess,GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); - -# endif /* HAVE_TESS */ - - glPushMatrix(); - - s = 1.9; - glRotatef (180, 0, 0, 1); - glScalef (s, s, s); - glRotatef (90, 0, 1, 0); - glTranslatef (-0.53, 0, 0); - glRotatef (-30, 0, 0, 1); - - /* Compute the wedge */ - th = 0; - j = 0; - - /* Edge 1 */ - { - GLfloat edge[] = { - 0.000, 0.000, - 0.000, 0.210, - 0.042, 0.230, - 0.042, 0.616, - 0.000, 0.641, - }; - for (i = 0; i < countof(edge)/2; i++) - { - points[j++] = edge[i*2+1]; - points[j++] = edge[i*2]; - points[j++] = 0; - } - } - - s = 0.798; /* radius of end of slice, before crust gap */ - for (i = 0; i < topfaces; i++) - { - points[j++] = cos(th) * s; - points[j++] = sin(th) * s; - points[j++] = 0; - th += step; - } - - /* Edge 2 */ - { - GLfloat edge[] = { - 0.613, 0.353, - 0.572, 0.376, - 0.455, 0.309, - 0.452, 0.260, - 0.332, 0.192, - 0.293, 0.216, - 0.178, 0.149, - 0.178, 0.102, - }; - for (i = 0; i < countof(edge)/2; i++) - { - points[j++] = edge[i*2+1]; - points[j++] = edge[i*2]; - points[j++] = 0; - } - endpoints = j/3; - } - - - /* Draw the rim of the slice */ - glBegin (wire ? GL_LINES : GL_QUADS); - x = points[0]; - y = points[1]; - for (i = (wire ? 0 : 1); i < endpoints; i++) - { - GLdouble *p = points + (i*3); - - do_normal (p[0], p[1], -thick2, - p[0], p[1], thick2, - x, y, thick2); - if (!wire) - { - glVertex3f (x, y, -thick2); - glVertex3f (x, y, thick2); - } - glVertex3f (p[0], p[1], thick2); - glVertex3f (p[0], p[1], -thick2); - x = p[0]; - y = p[1]; - polys++; - } - - do_normal (points[0], points[1], -thick2, - points[0], points[1], thick2, - x, y, thick2); - glVertex3f (x, y, -thick2); - glVertex3f (x, y, thick2); - glVertex3f (points[0], points[1], thick2); - glVertex3f (points[0], points[1], -thick2); - polys++; - glEnd(); - -# ifndef HAVE_TESS - if (wire) - { - /* Outline of slice */ - glBegin (GL_LINE_LOOP); - for (i = 0; i < endpoints; i++) - glVertex3f (points[i*3], points[i*3+1], -thick2); - glEnd(); - glBegin (GL_LINE_LOOP); - for (i = 0; i < endpoints; i++) - glVertex3f (points[i*3], points[i*3+1], thick2); - glEnd(); - } -# endif /* HAVE_TESS */ - - /* Compute the holes */ - step = M_PI * 2 / discfaces; - for (k = 0; k < nholes; k++) - { - GLdouble *p = holes + (discfaces * 3 * k); - th = 0; - j = 0; - switch (k) { - case 0: x = 0.34; y = 0.17; s = 0.05; break; - case 1: x = 0.54; y = 0.17; s = 0.06; break; - case 2: x = 0.55; y = 0.36; s = 0.06; break; - default: abort(); break; - } - for (i = 0; i < discfaces; i++) - { - p[j++] = x + cos(M_PI*2 - th) * s; - p[j++] = y + sin(M_PI*2 - th) * s; - p[j++] = 0; - th += step; - } - } - - - /* Draw the inside rim of the holes */ - for (k = 0; k < nholes; k++) - { - GLdouble *p = holes + (discfaces * 3 * k); - - glBegin (wire ? GL_LINES : GL_QUAD_STRIP); - for (i = 0; i < discfaces; i++) - { - GLdouble *p2 = p + (i*3); - if (i > 0) - do_normal (p2[0], p2[1], -thick2, - p2[0], p2[1], thick2, - p2[-3], p2[-2], thick2); - glVertex3f (p2[0], p2[1], -thick2); - glVertex3f (p2[0], p2[1], thick2); - polys++; - } - glVertex3f (p[0], p[1], -thick2); - glVertex3f (p[0], p[1], thick2); - polys++; - glEnd(); -# ifndef HAVE_TESS - if (wire) - { - /* Outline of holes */ - glBegin (GL_LINE_LOOP); - for (i = 0; i < discfaces; i++) - glVertex3f (p[i*3], p[i*3+1], -thick2); - glEnd(); - glBegin (GL_LINE_LOOP); - for (i = 0; i < discfaces; i++) - glVertex3f (p[i*3], p[i*3+1], thick2); - glEnd(); - } -# endif /* !HAVE_TESS */ - } - -# ifdef HAVE_TESS - glTranslatef (0, 0, -thick2); - for (y = 0; y <= 1; y++) - { - if (y) glTranslatef (0, 0, thick2*2); - - /* A non-convex polygon */ - gluTessBeginPolygon (tess, to); - - glNormal3f (0, 0, (y > 0 ? 1 : -1)); - gluTessNormal (tess, 0, 0, (y > 0 ? 1 : -1)); - glFrontFace (GL_CCW); - - /* Tess the wedge */ - gluTessBeginContour (tess); - for (i = 0; i < endpoints; i++) - { - GLdouble *p = points + (i*3); - gluTessVertex (tess, p, p); - polys++; - } - gluTessVertex (tess, points, points); - gluTessEndContour (tess); - - /* Tess the holes */ - for (k = 0; k < nholes; k++) - { - GLdouble *p = holes + (discfaces * 3 * k); - gluTessBeginContour (tess); - for (i = 0; i < discfaces; i++) - { - GLdouble *p2 = p + (i*3); - gluTessVertex (tess, p2, p2); - polys++; - } - gluTessEndContour (tess); - } - - gluTessEndPolygon (tess); - } - - glTranslatef (0, 0, -thick2); - -# else /* !HAVE_TESS */ - if (! wire) - { - glTranslatef(0, 0, thick2); - glNormal3f (0, 0, 1); - glFrontFace (GL_CW); - - /* Sadly, jwzgl's glVertexPointer seems not to be recordable inside - display lists. */ -# if 0 - glDisableClientState (GL_COLOR_ARRAY); - glDisableClientState (GL_NORMAL_ARRAY); - glDisableClientState (GL_TEXTURE_COORD_ARRAY); - glEnableClientState (GL_VERTEX_ARRAY); - glVertexPointer (3, GL_FLOAT, 0, dnapizza_triangles); - glDrawArrays (GL_TRIANGLES, 0, countof (dnapizza_triangles) / 3); -# else - glBegin (GL_TRIANGLES); - for (i = 0; i < countof (dnapizza_triangles); i += 3) - glVertex3fv (dnapizza_triangles + i); - glEnd(); -# endif - - glTranslatef(0, 0, -thick2*2); - glNormal3f (0, 0, -1); - glFrontFace (GL_CCW); - -# if 0 - glDrawArrays (GL_TRIANGLES, 0, countof (dnapizza_triangles) / 3); -# else - int i; - glBegin (GL_TRIANGLES); - for (i = 0; i < countof (dnapizza_triangles); i += 3) - glVertex3fv (dnapizza_triangles + i); - glEnd(); -# endif - - glTranslatef(0, 0, thick2); - } -# endif /* !HAVE_TESS */ - - - /* Compute the crust */ - - s = 0.861; /* radius of inside of crust */ - step = M_PI * 2 / 6 / topfaces; - th = 0; - j = 0; - for (i = 0; i < topfaces; i++) - { - points[j++] = cos(th) * s; - points[j++] = sin(th) * s; - points[j++] = 0; - th += step; - } - - s = 1; - for (i = 0; i < topfaces; i++) - { - points[j++] = cos(th) * s; - points[j++] = sin(th) * s; - points[j++] = 0; - th -= step; - } - - /* Draw the rim of the crust */ - glFrontFace (GL_CCW); - glBegin (wire ? GL_LINES : GL_QUAD_STRIP); - for (i = 0; i < topfaces * 2; i++) - { - GLdouble *p = points + (i*3); - if (i == 0 || i == (topfaces*2)-1) - glNormal3f (0, -1, 0); - else if (i == topfaces-1 || i == topfaces) - glNormal3f (0, 1, 0); - else - do_normal (p[-3], p[-2], thick2, - p[0], p[1], thick2, - p[0], p[1], -thick2); - glVertex3f (p[0], p[1], -thick2); - glVertex3f (p[0], p[1], thick2); - polys++; - } - glVertex3f (points[0], points[1], -thick2); - glVertex3f (points[0], points[1], thick2); - polys++; - glEnd(); - - if (wire) - { - glBegin (GL_LINE_STRIP); - for (i = 0; i < topfaces * 2; i++) - { - GLdouble *p = points + (i*3); - glVertex3f (p[0], p[1], -thick2); - polys++; - } - glVertex3f (points[0], points[1], -thick2); - glEnd(); - - glBegin (GL_LINE_STRIP); - for (i = 0; i < topfaces * 2; i++) - { - GLdouble *p = points + (i*3); - glVertex3f (p[0], p[1], thick2); - polys++; - } - glVertex3f (points[0], points[1], thick2); - glEnd(); - } - - /* Draw the top of the crust */ - if (! wire) - { - glFrontFace (GL_CW); - glBegin (wire ? GL_LINE_STRIP : GL_QUAD_STRIP); - glNormal3f (0, 0, -1); - if (!wire) - for (i = 0; i < topfaces; i++) - { - int ii = topfaces + (topfaces - i - 1); - GLdouble *p1 = points + (i*3); - GLdouble *p2 = points + (ii*3); - glVertex3f (p1[0], p1[1], -thick2); - glVertex3f (p2[0], p2[1], -thick2); - polys++; - } - polys++; - glEnd(); - - /* Draw the bottom of the crust */ - glFrontFace (GL_CCW); - glBegin (wire ? GL_LINES : GL_QUAD_STRIP); - glNormal3f (0, 0, 1); - for (i = 0; i < topfaces; i++) - { - int ii = topfaces + (topfaces - i - 1); - GLdouble *p1 = points + (i*3); - GLdouble *p2 = points + (ii*3); - glVertex3f (p1[0], p1[1], thick2); - glVertex3f (p2[0], p2[1], thick2); - polys++; - } - polys++; - glEnd(); - } - -# ifdef HAVE_TESS - gluDeleteTess (tess); - free (to->points); -# endif /* HAVE_TESS */ - - free (points); - free (holes); - - glPopMatrix(); - - return polys; -} - - -# ifdef CW - -/* Upcase string, convert Unicrud to ASCII, remove any non-letters. - */ -static char * -codeword_simplify_text (const char *s0) -{ - char *s1 = utf8_to_latin1 ((s0 ? s0 : ""), True); - int L = strlen(s1); - char *s2 = (char *) malloc (L + 10); - char *s3 = s2; - int i; - for (i = 0; i < L; i++) - { - char c = s1[i]; - if (c >= 'a' && c <= 'z') - c -= 'a'-'A'; - if (c >= 'A' && c <= 'Z') - *s3++ = c; - } - *s3 = 0; - if (! *s2) - strcpy (s2, "CODEWORD"); - return s2; -} - - -static void -make_codeword_path (ModeInfo *mi) -{ - logo_configuration *dc = &dcs[MI_SCREEN(mi)]; - int letters = strlen (dc->codeword_text); - - GLfloat rtick = dc->codeword_spread; - GLfloat iradius = rtick * dc->codeword_cap_size; - - int dial = 0; - int letter; - GLfloat last_r = 0; - - GLfloat inner_circum = M_PI * 2 * (iradius + rtick * 2); - GLfloat outer_circum = M_PI * 2 * (iradius + rtick * (letters + 1)); - GLfloat facet_length = inner_circum / (26 * dc->codeword_facets); - int outer_facets = ceil (outer_circum / facet_length); - - int *histo = (int *) calloc (letters * 26, sizeof(*histo)); - XYZ *points = (XYZ *) calloc (letters * outer_facets, sizeof (*points)); - int npoints = 0; - - for (letter = -1; letter < letters; letter++) - { - if (letter == -1) /* Inner starting point */ - { - points[npoints].x = iradius; - points[npoints].y = 0; - last_r = iradius; - npoints++; - } - else /* Add arc for this letter */ - { - int direction = (letter & 1 ? -1 : 1); - int v = (dc->codeword_text[letter] - 'A' + 1); - int dial1 = dial + v * direction; - - GLfloat th; - GLfloat th0 = M_PI * 2 / 26 * dial; - GLfloat th1 = M_PI * 2 / 26 * dial1; - GLfloat r = iradius + rtick * (letter + 2); - GLfloat circum = M_PI * 2 * r; - GLfloat arc_length = circum * v / 26; - int arc_facets = ceil (fabs (arc_length / facet_length)); - GLfloat facet_th = (th1 - th0) / arc_facets; - - if (arc_facets > outer_facets) abort(); - - /* Let's put some intermediate facets on the crossbars too, - so that the animation doesn't speed up on those. */ - { - GLfloat rr; - for (rr = last_r + facet_length; - rr <= r - facet_length; - rr += facet_length) - { - points[npoints].x = rr * cos (th0); - points[npoints].y = rr * sin (th0); - npoints++; - } - last_r = r; - } - - - for (th = th0; - (th0 < th1 - ? th <= th1 + facet_th - : th >= th1 + facet_th); - th += facet_th) - { - GLfloat th2 = th; - if (th0 < th1 && th > th1) - th2 = th1; - if (th0 > th1 && th < th1) - th2 = th1; - points[npoints].x = r * cos (th2); - points[npoints].y = r * sin (th2); - - /* Ugh, add point only if it differs from prev. - Not sure how this happens. */ - if (npoints == 0 || - points[npoints-1].x != points[npoints].x || - points[npoints-1].y != points[npoints].y) - npoints++; - } - - /* Mark up the histo array to find the outer border. */ - { - int i; - for (i = dial; - (direction > 0 - ? i <= dial1 - : i >= dial1); - i += direction) - { - int x = (i + 26) % 26; - int y; - for (y = 0; y <= letter; y++) - histo[y * 26 + x]++; - } - } - - dc->codeword_text_points[letter] = npoints; - - dial = dial1; - } - } - - if (npoints >= letters * outer_facets) abort(); - -# if 0 - { /* Print histo */ - int x, y; - for (y = 0; y < letters; y++) - { - fprintf (stderr, "%2d: ", y); - for (x = 0; x < 26; x++) - fprintf (stderr, "%x", histo[y * 26 + x]); - fprintf (stderr, "\n"); - } - fprintf (stderr, "\n"); - } -# endif - - - /* Find a gap in the outer edge, to draw guide dots. */ - { - int x, y; - int last_row = letters; - int start_dial = -1, end_dial = -1; - - for (y = letters-1; y >= 0; y--) - { - for (x = 0; x < 26; x++) - { - if (histo[y * 26 + x] == 0) - { - if (last_row != y) - start_dial = end_dial = -1; - last_row = y; - if (start_dial == -1) - start_dial = x; - end_dial = x; - } - } - } - - if (last_row < letters-1 && start_dial >= 0) - { - GLfloat r = iradius + rtick * (last_row + 2); - int i; - - dc->codeword_nguides = 0; - dc->codeword_guides = (XYZ *) - calloc (end_dial - start_dial + 1, sizeof (*dc->codeword_guides)); - for (i = start_dial; i <= end_dial; i++) - { - GLfloat th = i * M_PI * 2 / 26; - GLfloat x = r * cos (th); - GLfloat y = r * sin (th); - dc->codeword_guides[dc->codeword_nguides].x = x; - dc->codeword_guides[dc->codeword_nguides].y = y; - dc->codeword_nguides++; - } - } - free (histo); - histo = 0; - } - - dc->codeword_path_npoints = npoints; - dc->codeword_path = points; -} - - -static int -draw_codeword_cap (ModeInfo *mi) -{ - logo_configuration *dc = &dcs[MI_SCREEN(mi)]; - int wire = MI_IS_WIREFRAME(mi); - int polys = 0; - - int segments = dc->codeword_disc_facets; - GLfloat size = dc->codeword_spread * dc->codeword_cap_size; - GLfloat width = dc->codeword_line_width / 2; - GLfloat thick = dc->codeword_thickness / 2; - GLfloat r1 = size + width/2; - GLfloat r2 = size - width/2; - GLfloat facet, th, z; - - if (wire) segments = 12; - facet = M_PI * 2 / segments; - - glPushMatrix(); - - /* Top and bottom */ - - for (z = -thick; z <= thick; z += thick*2) - { - glNormal3f (0, 0, (z < 0 ? -1 : 1)); - glFrontFace (z < 0 ? GL_CCW : GL_CW); - - glBegin (wire ? GL_LINES : GL_QUAD_STRIP); - for (th = 0; th <= M_PI*2; th += facet) - { - GLfloat x = cos (th); - GLfloat y = sin (th); - glVertex3f (r1 * x, r1 * y, z); - glVertex3f (r2 * x, r2 * y, z); - } - glEnd(); - - if (wire) - { - glBegin (GL_LINE_LOOP); - for (th = 0; th <= M_PI*2; th += facet) - { - GLfloat x = cos (th); - GLfloat y = sin (th); - glVertex3f (r1 * x, r1 * y, z); - } - glEnd(); - glBegin (GL_LINE_LOOP); - for (th = 0; th <= M_PI*2; th += facet) - { - GLfloat x = cos (th); - GLfloat y = sin (th); - glVertex3f (r2 * x, r2 * y, z); - } - glEnd(); - } - } - - /* Inside and outside */ - - for (z = -1; z <= 1; z += 2) - { - glFrontFace (z < 0 ? GL_CCW : GL_CW); - - glBegin (wire ? GL_LINES : GL_QUAD_STRIP); - for (th = 0; th <= M_PI*2; th += facet) - { - GLfloat th1 = th + facet; - GLfloat x0 = cos (th); - GLfloat y0 = sin (th); - GLfloat x1 = cos (th1); - GLfloat y1 = sin (th1); - GLfloat r = z < 0 ? r1 : r2; - - if (z < 0) - do_normal (r * x0, r * y0, thick, - r * x0, r * y0, -thick, - r * x1, r * y1, -thick); - else - do_normal (r * x1, r * y1, thick, - r * x1, r * y1, -thick, - r * x0, r * y0, -thick); - - glVertex3f (r * x0, r * y0, thick); - glVertex3f (r * x0, r * y0, -thick); - } - glEnd(); - } - - glPopMatrix(); - - return polys; -} - - -static int -draw_codeword_guides (ModeInfo *mi, GLfloat anim_ratio) -{ - logo_configuration *dc = &dcs[MI_SCREEN(mi)]; - int wire = MI_IS_WIREFRAME(mi); - int polys = 0; - - int segments = dc->codeword_disc_facets; - GLfloat s = dc->codeword_line_width / 2; - GLfloat each = 1.0 / dc->codeword_nguides; - int i; - - if (wire) segments = 6; - - for (i = 0; i < dc->codeword_nguides; i++) - { - GLfloat ratio; - if (anim_ratio < i*each) ratio = 0; - else if (anim_ratio >= (i+1)*each) ratio = 1; - else ratio = (anim_ratio - i*each) / each; - - if (ratio <= 0) continue; - if (ratio == 0) ratio = 0.001; - - glPushMatrix(); - glTranslatef (dc->codeword_guides[i].x, - dc->codeword_guides[i].y, - dc->codeword_guides[i].z); - - glScalef (ratio, ratio, ratio); - - /* If the line width and thickness are pretty close to each other, - use spheres. Otherwise use tubes. - */ - if (dc->codeword_thickness < dc->codeword_line_width * 1.3 && - dc->codeword_thickness > dc->codeword_line_width / 1.3) - { - glScalef (s, s, s); - glFrontFace (GL_CCW); - polys += unit_sphere (segments, segments, wire); - } - else - { - polys += tube (0, 0, -dc->codeword_thickness / 2, - 0, 0, dc->codeword_thickness / 2, - s, 0, segments, True, True, wire); - } - - glPopMatrix(); - } - - return polys; -} - - -/* Compute the characters at which the cursor is currently pointing, - and render it on the logo. - */ -static void -codeword_text_output (ModeInfo *mi, GLfloat anim_ratio) -{ - logo_configuration *dc = &dcs[MI_SCREEN(mi)]; - int i; - int L = strlen (dc->codeword_text); - int point = dc->codeword_path_npoints * anim_ratio; - Bool hit = False; - - if (dc->anim_state == CODEWORD_BLANK) - point = 0; - - for (i = 0; i < L; i++) - { - if (point >= dc->codeword_text_points[i]) - dc->codeword_text_out[i] = dc->codeword_text[i]; - else if (hit) - dc->codeword_text_out[i] = 0; - else - { - int steps = dc->codeword_text[i] - 'A' + 1; - int last = (i > 0 ? dc->codeword_text_points[i-1] : 0); - double ratio = ((point - last) / - (double) (dc->codeword_text_points[i] - last)); - char chr = 'A' + (ratio * steps); - if (ratio < 0.1) chr = 0; - dc->codeword_text_out[i] = chr; - hit = True; - } - } - dc->codeword_text_out[i] = 0; - - if (*dc->codeword_text_out && - !strcmp (dc->codeword_text, "CODEWORD")) - { - int i; - int L2 = strlen (dc->codeword_text_out); - GLfloat ss = 0.01; - int ascent, descent; - - glPushMatrix(); - glColor4fv (dc->codeword_color); - glRotatef (90, 0, 1, 0); - glRotatef (-90, 0, 0, 1); - - for (i = 0; i < L2; i++) - { - XCharStruct e; - char buf[2]; - glPushMatrix(); - glRotatef ((i + 0.5) * 360 / 26.0, 0, 0, 1); - -# if 0 - { - GLfloat th; - glDisable(GL_LIGHTING); - glBegin(GL_LINES); - glVertex3f(0,0,0); - glVertex3f(0,-4,0); - glEnd(); - glBegin(GL_LINE_STRIP); - for (th = M_PI * 1.45; th < M_PI * 1.55; th += 0.1) - { - GLfloat r = 3.85; - glVertex3f (r * cos(th), r * sin(th), 0); - } - glEnd(); - if (!MI_IS_WIREFRAME(mi)) glEnable(GL_LIGHTING); - } -# endif - - glTranslatef (0, -dc->codeword_spread * (L - 1), 0); - glScalef (ss, ss, ss); - buf[0] = dc->codeword_text_out[i] + ('a' - 'A'); - buf[1] = 0; - texture_string_metrics (dc->font, buf, &e, &ascent, &descent); - - glTranslatef (-e.width * 1.0, - -(ascent + descent + e.descent * 2.4), /* #### WTF */ - 0); - - glScalef (2, 2, 2); - -# if 0 - glDisable(GL_LIGHTING); - glBegin(GL_LINE_LOOP); - glVertex3f(0, 0, 0); - glVertex3f(e.width, 0, 0); - glVertex3f(e.width, e.ascent + e.descent, 0); - glVertex3f(0, e.ascent + e.descent, 0); - glEnd(); - if (!MI_IS_WIREFRAME(mi)) glEnable(GL_LIGHTING); -# endif - - glDisable(GL_CULL_FACE); /* tell texfont.c to draw both sides */ - print_texture_string (dc->font, buf); - glEnable(GL_CULL_FACE); - - glPopMatrix(); - } - glPopMatrix(); - } -} - - -/* Convert the precomputed path to a thick line of polygons. - We could actually precompute all of these polygons too, - but it's fast enough. - */ -static int -draw_codeword_path (ModeInfo *mi) -{ - logo_configuration *dc = &dcs[MI_SCREEN(mi)]; - int wire = MI_IS_WIREFRAME(mi); - int polys = 0; - - GLfloat anim_ratio = (dc->anim_state == CODEWORD_IN ? dc->anim_ratio : - dc->anim_state == CODEWORD_OUT ? 1 - dc->anim_ratio : - dc->anim_state == CODEWORD_BLANK ? 0 : - 1); - int last_anim_point = 0; - - GLfloat width = dc->codeword_line_width / 2; - GLfloat thick = dc->codeword_thickness / 2; - int i, k; - GLfloat j; - - int quad_size = (dc->codeword_path_npoints + 1) * 2; - XYZ *quads = (XYZ *) calloc (quad_size, sizeof(*quads)); - XYZ *norms = (XYZ *) calloc (quad_size, sizeof(*norms)); - int nquads = 0; - - for (i = 0; i < dc->codeword_path_npoints; i++) - { - XYZ p1 = dc->codeword_path[i]; - XYZ p2 = (i < dc->codeword_path_npoints-1 - ? dc->codeword_path[i+1] - : dc->codeword_path[i-1]); - XYZ p1a, p1b; - - XYZ n; /* normal of the first line segment */ - n.x = -(p2.y - p1.y); - n.y = (p2.x - p1.x); - n.z = 0; - normalize (&n); - - if (i == 0) - { - p1a.x = p1.x - width / 2 * n.x; - p1a.y = p1.y - width / 2 * n.y; - p1a.z = 0; - - p1b.x = p1.x + width / 2 * n.x; - p1b.y = p1.y + width / 2 * n.y; - p1b.z = 0; - } - else if (i == dc->codeword_path_npoints - 1) - { - p1b.x = p1.x - width / 2 * n.x; - p1b.y = p1.y - width / 2 * n.y; - p1b.z = 0; - - p1a.x = p1.x + width / 2 * n.x; - p1a.y = p1.y + width / 2 * n.y; - p1a.z = 0; - } - else - { - XYZ p0 = dc->codeword_path[i-1]; - - XYZ t, t0, t1; /* tangent of corner between two line segments */ - XYZ m; /* miter line: normal of tangent */ - GLfloat d; /* length of miter */ - - t0.x = p2.x - p1.x; - t0.y = p2.y - p1.y; - t0.z = p2.z - p1.z; - normalize (&t0); - - t1.x = p1.x - p0.x; - t1.y = p1.y - p0.y; - t1.z = p1.z - p0.z; - normalize (&t1); - - t.x = t0.x + t1.x; - t.y = t0.y + t1.y; - t.z = t0.z + t1.z; - normalize (&t); - - m.x = -t.y; - m.y = t.x; - m.z = 0; - - /* find length of miter by projecting it on one of the normals */ - d = width / 2 / dot (m, n); - - p1a.x = p1.x - d * m.x; - p1a.y = p1.y - d * m.y; - p1a.z = 0; - - p1b.x = p1.x + d * m.x; - p1b.y = p1.y + d * m.y; - p1b.z = 0; - } - - quads[nquads++] = p1a; - quads[nquads++] = p1b; - - if (nquads >= quad_size) abort(); - - if (i / (double) dc->codeword_path_npoints > anim_ratio) - break; - - last_anim_point = i; - } - - - /* Compute normals for each point along the interior edge */ - for (k = 0; k <= 1; k++) - { - for (i = k; i < nquads-2; i += 2) - { - XYZ p1a = quads[i]; - XYZ p2a = quads[i+2]; - XYZ p1b = p1a; - XYZ p2b = p2a; - p1a.z = thick; /* a: top */ - p1b.z = -thick; /* b: bottom */ - p2a.z = thick; - p2b.z = -thick; - - norms[i] = (k == 0 - ? calc_normal (p1a, p1b, p2b) - : calc_normal (p2a, p2b, p1a)); - } - } - - glPushMatrix(); - glColor4fv (dc->codeword_color); - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, dc->codeword_color); - - { - GLfloat s = (MI_WIDTH(mi) < MI_HEIGHT(mi) - ? (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi)) - : 1); - glScalef (s, s, s); - } - - codeword_text_output (mi, anim_ratio); - - glRotatef (90, 1, 0, 0); - glRotatef (90, 0, 1, 0); - glRotatef (-90, 0, 0, 1); - glScalef (0.8, 0.8, 0.8); - - glNormal3f (0, 0, -1); - - if (anim_ratio <= 0) - { - polys += draw_codeword_cap (mi); - goto DONE; - } - -# if 0 - glColor3f (1, 0, 0); - glBegin(GL_LINE_STRIP); - for (i = 0; i < dc->codeword_path_npoints; i++) - { - glVertex3f (dc->codeword_path[i].x, - dc->codeword_path[i].y, - dc->codeword_path[i].z); - polys++; - } - glEnd(); - glColor4fv (dc->codeword_color); -# endif - - if (wire) - { - int k; - GLfloat j; - for (i = 0; i <= 1; i++) - for (j = -thick; j <= thick; j += thick*2) - { - glBegin (GL_LINE_STRIP); - for (k = i; k < nquads; k += 2) - { - glVertex3f (quads[k].x, quads[k].y, j); - polys++; - } - glEnd(); - } - } - - /* Top and bottom */ - - for (j = -thick; j <= thick; j += thick*2) - { - if (j < 0) - { - glNormal3f (0, 0, -1); - glFrontFace (GL_CW); - } - else - { - glNormal3f (0, 0, 1); - glFrontFace (GL_CCW); - } - glBegin (wire ? GL_LINES : GL_QUAD_STRIP); - for (i = 0; i < nquads; i += 2) - { - glVertex3f (quads[i+1].x, quads[i+1].y, j); - glVertex3f (quads[i].x, quads[i].y, j); - polys++; - } - glEnd(); - } - - /* Edges */ - - for (k = 0; k <= 1; k++) - { - if (k > 0) - { - glNormal3f (0, 0, -1); - glFrontFace (GL_CW); - } - else - { - glNormal3f (0, 0, 1); - glFrontFace (GL_CCW); - } - - glBegin (wire ? GL_LINES : GL_QUADS); - for (i = k; i < nquads; i += 2) - { - XYZ p1a = quads[i]; - XYZ p2a = (i < nquads-2) ? quads[i+2] : p1a; - XYZ p1b = p1a; - XYZ p2b = p2a; - - XYZ n1 = norms[i]; - XYZ n2 = (i < nquads-2) ? norms[i+2] : n1; - - /* If the two normals are very similar, smooth the face. - If they are different, it's a sharp turn, and use the - same normal for both edges (not quite right, but close). - */ - GLfloat angle = vector_angle (n1.x, n1.y, n1.z, - n2.x, n2.y, n2.z); - GLfloat pointy = 0.8; - - p1a.z = thick; - p1b.z = -thick; - p2a.z = thick; - p2b.z = -thick; - - glNormal3f (n1.x, n1.y, n1.z); - glVertex3f (p1a.x, p1a.y, p1a.z); - glVertex3f (p1b.x, p1b.y, p1b.z); - - if (angle < pointy) - glNormal3f (n2.x, n2.y, n2.z); - glVertex3f (p2b.x, p2b.y, p2b.z); - glVertex3f (p2a.x, p2a.y, p2a.z); - polys++; - } - glEnd(); - } - - - /* Only draw the guides when the path is almost complete; - fade them in and out based on completeness. */ - { - GLfloat size = 0.95; - GLfloat r = (anim_ratio > size - ? (anim_ratio - size) / (1 - size) - : 0); - polys += draw_codeword_guides (mi, r); - } - - - /* Draw the start and end caps */ - { - int i; - GLfloat x, y, z, x2, y2, z2, X, Y, Z; - GLfloat r = dc->codeword_spread * dc->codeword_cap_size; - - i = 0; - x = dc->codeword_path[i].x; - y = dc->codeword_path[i].y; - z = dc->codeword_path[i].z; - - x -= r; - - glPushMatrix(); - glTranslatef (x, y, z); - polys += draw_codeword_cap (mi); - glPopMatrix(); - - /* end cap */ - - i = last_anim_point + 1; - if (i > dc->codeword_path_npoints - 1) - i = dc->codeword_path_npoints - 1; - - x = dc->codeword_path[i].x; - y = dc->codeword_path[i].y; - z = dc->codeword_path[i].z; - - i--; - x2 = dc->codeword_path[i].x; - y2 = dc->codeword_path[i].y; - z2 = dc->codeword_path[i].z; - - X = (x2 - x); - Y = (y2 - y); - Z = (z2 - z); - - glPushMatrix(); - glTranslatef (x, y, z); - glRotatef (-atan2 (X, Y) * (180 / M_PI), 0, 0, 1); - glRotatef ( atan2 (Z, sqrt(X*X + Y*Y)) * (180 / M_PI), 1, 0, 0); - glTranslatef (0, -r, 0); - polys += draw_codeword_cap (mi); - glPopMatrix(); - } - - DONE: - - glPopMatrix(); - - free (quads); - free (norms); - - return polys; -} - -#endif /* CW */ - - -ENTRYPOINT void -reshape_logo (ModeInfo *mi, int width, int height) -{ -# ifdef DEBUG - logo_configuration *dc = &dcs[MI_SCREEN(mi)]; -# endif - GLfloat h = (GLfloat) height / (GLfloat) width; - GLfloat persp = 64; /* 30 */ - GLfloat pos = 13; /* 30 */ - -# ifdef DEBUG - persp += dc->persp_off; - pos += dc->pos_off; -# endif - - glViewport (0, 0, (GLint) width, (GLint) height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective (persp, 1/h, 1, 100); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt( 0, 0, pos, - 0, 0, 0, - 0, 1, 0); - - { - GLfloat s = (MI_WIDTH(mi) < MI_HEIGHT(mi) - ? (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi)) - : 1); - glScalef (s, s, s); - } - - glClear(GL_COLOR_BUFFER_BIT); -} - - -static void -gl_init (ModeInfo *mi) -{ -/* logo_configuration *dc = &dcs[MI_SCREEN(mi)]; */ - int wire = MI_IS_WIREFRAME(mi); - - GLfloat position[] = {0, 0, 0, 0}; - GLfloat direction[] = {3, -1, -3}; - - position[0] = -direction[0]; - position[1] = -direction[1]; - position[2] = -direction[2]; - - if (!wire) - { - glLightfv(GL_LIGHT0, GL_POSITION, position); - glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, direction); - glShadeModel(GL_SMOOTH); - glEnable(GL_NORMALIZE); - glEnable(GL_CULL_FACE); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_DEPTH_TEST); - } -} - - -ENTRYPOINT void -init_logo (ModeInfo *mi) -{ - logo_configuration *dc; - int do_gasket = get_boolean_resource(mi->dpy, "doGasket", "Boolean"); - int do_helix = get_boolean_resource(mi->dpy, "doHelix", "Boolean"); - int do_ladder = (do_helix && - get_boolean_resource(mi->dpy, "doLadder", "Boolean")); - int do_frame = get_boolean_resource(mi->dpy, "doFrame", "Boolean"); - GLfloat helix_rot = 147.0; - - if (!do_gasket && !do_helix) - { - fprintf (stderr, "%s: no helix or gasket?\n", progname); - exit (1); - } - - MI_INIT (mi, dcs); - - dc = &dcs[MI_SCREEN(mi)]; - - if ((dc->glx_context = init_GL(mi)) != NULL) { - gl_init(mi); - reshape_logo (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - } - - dc->wall_facets = get_integer_resource(mi->dpy, "wallFacets", "Integer"); - dc->bar_facets = get_integer_resource(mi->dpy, "barFacets", "Integer"); - dc->clockwise = get_boolean_resource(mi->dpy, "clockwise", "Boolean"); - dc->turns = get_float_resource(mi->dpy, "turns", "Float"); - dc->turn_spacing = get_float_resource(mi->dpy, "turnSpacing", "Float"); - dc->bar_spacing = get_float_resource(mi->dpy, "barSpacing", "Float"); - dc->wall_height = get_float_resource(mi->dpy, "wallHeight", "Float"); - dc->wall_thickness = get_float_resource(mi->dpy, "wallThickness", "Float"); - dc->bar_thickness = get_float_resource(mi->dpy, "barThickness", "Float"); - dc->wall_taper = get_float_resource(mi->dpy, "wallTaper", "Float"); - - dc->gasket_size = get_float_resource(mi->dpy,"gasketSize", "Float"); - dc->gasket_depth = get_float_resource(mi->dpy,"gasketDepth", "Float"); - dc->gasket_thickness = get_float_resource(mi->dpy,"gasketThickness","Float"); - - dc->frame_size = get_float_resource(mi->dpy, "frameSize", "Float"); - dc->frame_depth = get_float_resource(mi->dpy, "frameDepth", "Float"); - dc->frame_thickness = get_float_resource(mi->dpy, "frameThickness", "Float"); - dc->triangle_size = get_float_resource(mi->dpy, "triangleSize", "Float"); - - dc->speed = get_float_resource(mi->dpy, "speed", "Float"); -# ifdef CW - dc->codeword_text = get_string_resource(mi->dpy, "text", "String"); - dc->codeword_text = codeword_simplify_text (dc->codeword_text); - dc->codeword_text_out = - calloc (strlen(dc->codeword_text) + 1, sizeof(*dc->codeword_text_out)); - dc->codeword_text_points = - (int *) calloc (strlen(dc->codeword_text) + 1, - sizeof(*dc->codeword_text_points)); - - dc->codeword_facets = get_integer_resource(mi->dpy, "cwFacets", "Integer"); - dc->codeword_disc_facets = get_integer_resource(mi->dpy, - "cwDiscFacets", "Integer"); - dc->codeword_spread = get_float_resource(mi->dpy, "cwSpread", "Float"); - dc->codeword_line_width = get_float_resource(mi->dpy, "cwLineWidth", "Float"); - dc->codeword_thickness = get_float_resource(mi->dpy, "cwThickness", "Float"); - dc->codeword_cap_size = get_float_resource(mi->dpy, "cwCapSize", "Float"); -# endif - - { - char *s = get_string_resource (MI_DISPLAY (mi), "mode", "String"); - if (!s || !*s || !strcasecmp (s, "helix")) - dc->mode = HELIX; - else if (!strcasecmp (s, "pizza")) - dc->mode = PIZZA; - else if (!strcasecmp (s, "both")) - dc->mode = HELIX_AND_PIZZA; -# ifdef CW - else if (!strcasecmp (s, "codeword")) - dc->mode = CODEWORD_IN; -# endif - else - { - fprintf (stderr, - "%s: mode must be helix, pizza or both, not \"%s\"\n", - progname, s); - exit (1); - } - if (s) free (s); - - dc->anim_state = (dc->mode == HELIX_AND_PIZZA - ? ((random() & 1) ? HELIX : PIZZA) - : dc->mode); - dc->anim_ratio = 0; - } - -# ifdef CW - if (dc->mode == CODEWORD_IN) - dc->font = load_texture_font (MI_DISPLAY(mi), "cwFont"); -# endif - -# ifdef DEBUG - dc->label_font = load_texture_font (MI_DISPLAY(mi), "fpsFont"); -# endif - - { - XColor xcolor; - - char *color_name = - get_string_resource (mi->dpy, "foreground", "Foreground"); - char *s2; - for (s2 = color_name + strlen(color_name) - 1; s2 > color_name; s2--) - if (*s2 == ' ' || *s2 == '\t') - *s2 = 0; - else - break; - - if (! XParseColor (MI_DISPLAY(mi), mi->xgwa.colormap, color_name, &xcolor)) - { - fprintf (stderr, "%s: can't parse color %s\n", progname, color_name); - exit (1); - } - - dc->color[0] = xcolor.red / 65535.0; - dc->color[1] = xcolor.green / 65535.0; - dc->color[2] = xcolor.blue / 65535.0; - dc->color[3] = 1.0; - - free (color_name); - color_name = get_string_resource (mi->dpy, "cwForeground", "Foreground"); - for (s2 = color_name + strlen(color_name) - 1; s2 > color_name; s2--) - if (*s2 == ' ' || *s2 == '\t') - *s2 = 0; - else - break; - - if (! XParseColor (MI_DISPLAY(mi), mi->xgwa.colormap, color_name, &xcolor)) - { - fprintf (stderr, "%s: can't parse color %s\n", progname, color_name); - exit (1); - } - free (color_name); - -# ifdef CW - dc->codeword_color[0] = xcolor.red / 65535.0; - dc->codeword_color[1] = xcolor.green / 65535.0; - dc->codeword_color[2] = xcolor.blue / 65535.0; - dc->codeword_color[3] = 1.0; - - color_name = get_string_resource (mi->dpy, "cwBackground", "Background"); - for (s2 = color_name + strlen(color_name) - 1; s2 > color_name; s2--) - if (*s2 == ' ' || *s2 == '\t') - *s2 = 0; - else - break; - - if (! XParseColor (MI_DISPLAY(mi), mi->xgwa.colormap, color_name, &xcolor)) - { - fprintf (stderr, "%s: can't parse color %s\n", progname, color_name); - exit (1); - } - free (color_name); - - dc->codeword_bg[0] = xcolor.red / 65535.0; - dc->codeword_bg[1] = xcolor.green / 65535.0; - dc->codeword_bg[2] = xcolor.blue / 65535.0; - dc->codeword_bg[3] = 1.0; -# endif /* CW */ - } - - dc->trackball = gltrackball_init (False); - - dc->gasket_spinnerx.probability = 0.1; - dc->gasket_spinnery.probability = 0.1; - dc->gasket_spinnerz.probability = 1.0; - dc->gasket_spinnerx.easement = 0.08; - dc->gasket_spinnery.easement = 0.08; - dc->gasket_spinnerz.easement = 0.08; - - dc->helix_spinnerz.probability = 0.6; - dc->helix_spinnerz.easement = 0.2; - - dc->pizza_spinnerz.probability = 0.6; - dc->pizza_spinnery.probability = 0.6; - dc->pizza_spinnerz.easement = 0.2; - dc->pizza_spinnery.easement = 0.2; - - dc->frame_spinner.probability = 5.0; - dc->frame_spinner.easement = 0.2; - - dc->scene_spinnerx.probability = 0.1; - dc->scene_spinnery.probability = 0.0; - dc->scene_spinnerx.easement = 0.1; - dc->scene_spinnery.easement = 0.1; - -# ifdef CW - if (dc->mode == CODEWORD_IN) - { - double tilt_speed = 0.003; - dc->scene_rot = make_rotator (0, 0, 0, 0, tilt_speed, True); - } -# endif - - /* start the frame off-screen */ - dc->frame_spinner.spinning_p = True; - dc->frame_spinner.position = 0.3; - dc->frame_spinner.speed = 0.001; - - if (dc->speed > 0) /* start off with the gasket in motion */ - { - dc->gasket_spinnerz.spinning_p = True; - dc->gasket_spinnerz.speed = (0.002 - * ((random() & 1) ? 1 : -1) - * dc->speed); - } - -# ifdef DXF_OUTPUT_HACK - { -# if 0 - dc->frame_depth = dc->gasket_depth; - dxf_layer = 1; - dxf_color = 3; - dxf_start(); - glPushMatrix(); - glRotatef(90, 1, 0, 0); - glRotatef(90, 0, 0, 1); - make_pizza (dc, 0, 0); - - glPushMatrix(); - glRotatef(helix_rot, 0, 0, 1); - make_ladder (dc, 0, 0); - make_helix (dc, 0, 0); - glRotatef (180, 0, 0, 1); - make_helix (dc, 0, 0); - glPopMatrix(); - - dxf_layer++; - make_gasket (dc, 0); - dxf_layer++; - make_frame (dc, 0); - glPopMatrix(); - dxf_end(); -# else - dxf_start(); - glPushMatrix(); - glRotatef(90, 1, 0, 0); - glRotatef(90, 0, 0, 1); - dc->anim_state = CODEWORD; - make_codeword_path (mi); - draw_codeword_path (mi); - glPopMatrix(); - dxf_end(); -# endif - } -# endif - - glPushMatrix(); - dc->helix_list = glGenLists (1); - glNewList (dc->helix_list, GL_COMPILE); - glRotatef(helix_rot, 0, 0, 1); - if (do_ladder) dc->polys[0] += make_ladder (dc, 0, 0); - if (do_helix) dc->polys[0] += make_helix (dc, 0, 0); - glRotatef(180, 0, 0, 1); - if (do_helix) dc->polys[0] += make_helix (dc, 0, 0); - glEndList (); - glPopMatrix(); - - glPushMatrix(); - dc->helix_list_wire = glGenLists (1); - glNewList (dc->helix_list_wire, GL_COMPILE); -/* glRotatef(helix_rot, 0, 0, 1); wtf? */ - if (do_ladder) dc->polys[1] += make_ladder (dc, 1, 1); - if (do_helix) dc->polys[1] += make_helix (dc, 1, 1); - glRotatef(180, 0, 0, 1); - if (do_helix) dc->polys[1] += make_helix (dc, 1, 1); - glEndList (); - glPopMatrix(); - - glPushMatrix(); - dc->helix_list_facetted = glGenLists (1); - glNewList (dc->helix_list_facetted, GL_COMPILE); - glRotatef(helix_rot, 0, 0, 1); - if (do_ladder) dc->polys[2] += make_ladder (dc, 1, 0); - if (do_helix) dc->polys[2] += make_helix (dc, 1, 0); - glRotatef(180, 0, 0, 1); - if (do_helix) dc->polys[2] += make_helix (dc, 1, 0); - glEndList (); - glPopMatrix(); - - dc->pizza_list = glGenLists (1); - glNewList (dc->pizza_list, GL_COMPILE); - if (do_frame) dc->polys[5] += make_pizza (dc, 0, 0); - glEndList (); - - dc->pizza_list_wire = glGenLists (1); - glNewList (dc->pizza_list_wire, GL_COMPILE); - if (do_frame) dc->polys[6] += make_pizza (dc, 1, 1); - glEndList (); - - dc->pizza_list_facetted = glGenLists (1); - glNewList (dc->pizza_list_facetted, GL_COMPILE); - if (do_frame) dc->polys[6] += make_pizza (dc, 1, 0); - glEndList (); - - dc->gasket_list = glGenLists (1); - glNewList (dc->gasket_list, GL_COMPILE); - if (do_gasket) dc->polys[3] += make_gasket (dc, 0); - glEndList (); - - dc->gasket_list_wire = glGenLists (1); - glNewList (dc->gasket_list_wire, GL_COMPILE); - if (do_gasket) dc->polys[4] += make_gasket (dc, 1); - glEndList (); - - dc->frame_list = glGenLists (1); - glNewList (dc->frame_list, GL_COMPILE); - if (do_frame) dc->polys[5] += make_frame (dc, 0); - glEndList (); - - dc->frame_list_wire = glGenLists (1); - glNewList (dc->frame_list_wire, GL_COMPILE); - if (do_frame) dc->polys[6] += make_frame (dc, 1); - glEndList (); - -# ifdef CW - make_codeword_path (mi); -# endif - - /* When drawing both solid and wireframe objects, - make sure the wireframe actually shows up! */ - glEnable (GL_POLYGON_OFFSET_FILL); - glPolygonOffset (1.0, 1.0); -} - - -ENTRYPOINT Bool -logo_handle_event (ModeInfo *mi, XEvent *event) -{ - logo_configuration *dc = &dcs[MI_SCREEN(mi)]; - - if (gltrackball_event_handler (event, dc->trackball, - MI_WIDTH (mi), MI_HEIGHT (mi), - &dc->button_down_p)) - return True; - else if (event->xany.type == KeyPress) - { - KeySym keysym; - char c = 0; - XLookupString (&event->xkey, &c, 1, &keysym, 0); - -# ifdef DEBUG - { - GLfloat step = 0.1; - if (c == 'a') dc->persp_off += step; - else if (c == 'z') dc->persp_off -= step; - else if (c == 's') dc->pos_off += step; - else if (c == 'x') dc->pos_off -= step; - else return False; - - /* dc->pos_off = -dc->persp_off; */ - reshape_logo (mi, MI_WIDTH(mi), MI_HEIGHT(mi)); - return True; - } -# endif - - if (c == ' ' || c == '\t') - { - switch (dc->anim_state) { - case HELIX: - dc->anim_state = HELIX_OUT; - dc->anim_ratio = 0.0; - return True; - case PIZZA: - dc->anim_state = PIZZA_OUT; - dc->anim_ratio = 0.0; - return True; -# ifdef CW - case CODEWORD: - dc->anim_state = CODEWORD_OUT; - dc->anim_ratio = 0.0; - return True; -# endif - default: - break; - } - } - } - - return False; -} - - -static GLfloat -spinner_ease (GLfloat x) -{ - /* Smooth curve up, ending at slope = 1. */ - return cos ((x/2 + 1) * M_PI) + 1; -} - - -static void -tick_spinner (ModeInfo *mi, spinner *s) -{ - logo_configuration *dc = &dcs[MI_SCREEN(mi)]; - - if (dc->speed == 0) return; - if (dc->button_down_p) return; - - if (s->spinning_p) - { - s->position += s->speed; - if (s->position >= 1.0 || s->position <= 0.0) - { - s->position = 0; - s->position_eased = 0; - s->spinning_p = False; - } - else if (s->easement > 0 && s->position <= s->easement) - s->position_eased = (s->easement * - spinner_ease (s->position / s->easement)); - else if (s->easement > 0 && s->position >= 1-s->easement) - s->position_eased = (1 - s->easement * - spinner_ease ((1 - s->position) / s->easement)); - else - s->position_eased = s->position; - } - else if (s->probability && - (random() % (int) (PROBABILITY_SCALE / s->probability)) == 0) - { - GLfloat ss = 0.004; - s->spinning_p = True; - s->position = 0; - do { - s->speed = dc->speed * (frand(ss/3) + frand(ss/3) + frand(ss/3)); - } while (s->speed <= 0); - if (random() & 1) - { - s->speed = -s->speed; - s->position = 1.0; - } - } -} - - -static void -link_spinners (ModeInfo *mi, spinner *s0, spinner *s1) -{ - if (s0->spinning_p && !s1->spinning_p) - { - GLfloat op = s1->probability; - s1->probability = PROBABILITY_SCALE; - tick_spinner (mi, s1); - s1->probability = op; - } -} - - -ENTRYPOINT void -draw_logo (ModeInfo *mi) -{ - logo_configuration *dc = &dcs[MI_SCREEN(mi)]; - Display *dpy = MI_DISPLAY(mi); - Window window = MI_WINDOW(mi); - int wire = MI_IS_WIREFRAME(mi); - GLfloat gcolor[4]; - GLfloat specular[] = {0.8, 0.8, 0.8, 1.0}; - GLfloat shininess = 50.0; - Bool pizza_p; -# ifdef CW - Bool codeword_p; -# endif - - if (!dc->glx_context) - return; - - mi->polygon_count = 0; - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *dc->glx_context); - - if (!wire && - dc->wire_overlay == 0 && - (random() % (int) (PROBABILITY_SCALE / 0.2)) == 0) - dc->wire_overlay = ((random() % 200) + - (random() % 200) + - (random() % 200)); - -# ifndef DEBUG - tick_spinner (mi, &dc->gasket_spinnerx); - tick_spinner (mi, &dc->gasket_spinnery); - tick_spinner (mi, &dc->gasket_spinnerz); - tick_spinner (mi, &dc->helix_spinnerz); - tick_spinner (mi, &dc->pizza_spinnery); - tick_spinner (mi, &dc->pizza_spinnerz); - tick_spinner (mi, &dc->scene_spinnerx); - tick_spinner (mi, &dc->scene_spinnery); - tick_spinner (mi, &dc->frame_spinner); - link_spinners (mi, &dc->scene_spinnerx, &dc->scene_spinnery); -# endif /* DEBUG */ - - switch (dc->anim_state) - { - case HELIX: - if (dc->mode == HELIX_AND_PIZZA && - (random() % (int) (PROBABILITY_SCALE / 0.2)) == 0) - dc->anim_state = HELIX_OUT; - break; - - case HELIX_OUT: - dc->anim_ratio += 0.1 * dc->speed; - if (dc->anim_ratio >= 1.0) - { - dc->anim_ratio = 0.0; - dc->anim_state = PIZZA_IN; - } - break; - - case PIZZA_IN: - dc->anim_ratio += 0.1 * dc->speed; - if (dc->anim_ratio >= 1.0) - { - dc->anim_ratio = 0.0; - dc->anim_state = PIZZA; - } - break; - - case PIZZA: - if (dc->mode == HELIX_AND_PIZZA && - (random() % (int) (PROBABILITY_SCALE / 0.2)) == 0) - dc->anim_state = PIZZA_OUT; - break; - - case PIZZA_OUT: - dc->anim_ratio += 0.1 * dc->speed; - if (dc->anim_ratio >= 1.0) - { - dc->anim_ratio = 0.0; - dc->anim_state = HELIX_IN; - } - break; - - case HELIX_IN: - dc->anim_ratio += 0.1 * dc->speed; - if (dc->anim_ratio >= 1.0) - { - dc->anim_ratio = 0.0; - dc->anim_state = HELIX; - } - break; - - -# ifdef CW - case CODEWORD_IN: - dc->scene_spinnerx.probability = 0.2; - dc->scene_spinnery.probability = 0.05; - if (! dc->button_down_p) - dc->anim_ratio += 0.004 * dc->speed; - if (dc->anim_ratio >= 1.0) - { - dc->anim_state = CODEWORD; - dc->anim_ratio = frand (0.5); - } - break; - - case CODEWORD: - dc->scene_spinnerx.probability = 0.5; - dc->scene_spinnery.probability = 0.2; - if (! dc->button_down_p) - dc->anim_ratio += (0.0005 + frand(0.002)) * dc->speed; - if (dc->anim_ratio >= 1.0) - { - dc->anim_ratio = 0.0; - dc->anim_state = CODEWORD_OUT; - } - break; - - case CODEWORD_OUT: - dc->scene_spinnerx.probability = 0; - dc->scene_spinnery.probability = 0; - if (! dc->button_down_p) - dc->anim_ratio += 0.02 * dc->speed; - if (dc->anim_ratio >= 1.0) - { - dc->anim_ratio = 0.0; - dc->anim_state = CODEWORD_BLANK; - } - break; - - case CODEWORD_BLANK: - dc->scene_spinnerx.probability = 0; - dc->scene_spinnery.probability = 0; - if (! dc->button_down_p) - dc->anim_ratio += 0.01 * dc->speed; - if (dc->anim_ratio >= 1.0) - { - dc->anim_ratio = 0.0; - dc->anim_state = CODEWORD_IN; - } - break; -# endif /* CW */ - - default: - abort(); - break; - } - -# ifdef DEBUG - dc->anim_state = HELIX; - dc->wire_overlay = 0; -# endif - - pizza_p = (dc->anim_state == PIZZA || - dc->anim_state == PIZZA_IN || - dc->anim_state == PIZZA_OUT); - -# ifdef CW - codeword_p = (dc->anim_state == CODEWORD || - dc->anim_state == CODEWORD_IN || - dc->anim_state == CODEWORD_OUT || - dc->anim_state == CODEWORD_BLANK); -# endif - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glPushMatrix (); - glRotatef(current_device_rotation(), 0, 0, 1); - { - GLfloat scale = 1.8; - glScalef(scale, scale, scale); - - glColor3f(dc->color[0], dc->color[1], dc->color[2]); - - - /* Draw frame before trackball rotation */ -# ifdef CW - if (! codeword_p) -# endif - { - GLfloat p = (dc->frame_spinner.position_eased >= 0 - ? dc->frame_spinner.position_eased - : -dc->frame_spinner.position_eased); - GLfloat size = (p > 0.5 ? 1-p : p); - scale = 1 + (size * 10); - glPushMatrix(); - /* gltrackball_rotate (dc->trackball); */ - glRotatef(90, 1, 0, 0); - glRotatef(90, 0, 0, 1); - - glScalef (1, scale, scale); - if (wire) - { - glDisable (GL_LIGHTING); - glCallList (dc->frame_list_wire); - mi->polygon_count += dc->polys[6]; - } - else if (dc->wire_overlay != 0) - { - glCallList (dc->frame_list); - glDisable (GL_LIGHTING); - glColor3fv (dc->color); - glCallList (dc->frame_list_wire); - mi->polygon_count += dc->polys[6]; - if (!wire) glEnable (GL_LIGHTING); - } - else - { - glCallList (dc->frame_list); - mi->polygon_count += dc->polys[5]; - } - glPopMatrix(); - } - - gltrackball_rotate (dc->trackball); - - glRotatef(90, 1, 0, 0); - glRotatef(90, 0, 0, 1); - -# ifdef CW - if (! codeword_p) -# endif - { - glRotatef (360 * dc->scene_spinnerx.position_eased, 0, 1, 0); - glRotatef (360 * dc->scene_spinnery.position_eased, 0, 0, 1); - - glPushMatrix(); - - glRotatef (360 * dc->gasket_spinnerx.position_eased, 0, 1, 0); - glRotatef (360 * dc->gasket_spinnery.position_eased, 0, 0, 1); - glRotatef (360 * dc->gasket_spinnerz.position_eased, 1, 0, 0); - - memcpy (gcolor, dc->color, sizeof (dc->color)); - if (dc->wire_overlay != 0) - { - gcolor[0] = gcolor[1] = gcolor[2] = 0; - specular[0] = specular[1] = specular[2] = 0; - shininess = 0; - } - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, gcolor); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shininess); - - if (wire) - { - glDisable (GL_LIGHTING); - glCallList (dc->gasket_list_wire); - mi->polygon_count += dc->polys[4]; - } - else if (dc->wire_overlay != 0) - { - glCallList (dc->gasket_list); - glDisable (GL_LIGHTING); - glColor3fv (dc->color); - glCallList (dc->gasket_list_wire); - mi->polygon_count += dc->polys[4]; - if (!wire) glEnable (GL_LIGHTING); - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, gcolor); - } - else - { - glCallList (dc->gasket_list); - mi->polygon_count += dc->polys[3]; - } - glPopMatrix(); - - if (pizza_p) - { - glRotatef (360 * dc->pizza_spinnery.position_eased, 1, 0, 0); - glRotatef (360 * dc->pizza_spinnerz.position_eased, 0, 0, 1); - } - else - { - glRotatef (360 * dc->helix_spinnerz.position_eased, 0, 0, 1); - } - - scale = ((dc->anim_state == PIZZA_IN || dc->anim_state == HELIX_IN) - ? dc->anim_ratio - : ((dc->anim_state == PIZZA_OUT || dc->anim_state == HELIX_OUT) - ? 1.0 - dc->anim_ratio - : 1.0)); - if (scale <= 0) scale = 0.001; - glScalef (scale, scale, scale); - - if (wire) - { - glDisable (GL_LIGHTING); - if (pizza_p) - glCallList (dc->pizza_list_wire); - else - glCallList (dc->helix_list_wire); - mi->polygon_count += dc->polys[1]; - } - else if (dc->wire_overlay != 0) - { - if (pizza_p) - glCallList (dc->pizza_list_facetted); - else - glCallList (dc->helix_list_facetted); - - glDisable (GL_LIGHTING); - glColor3fv (dc->color); - - if (pizza_p) - glCallList (dc->pizza_list_wire); - else - glCallList (dc->helix_list_wire); - - mi->polygon_count += dc->polys[2]; - if (!wire) glEnable (GL_LIGHTING); - } - else - { - if (pizza_p) - glCallList (dc->pizza_list); - else - glCallList (dc->helix_list); - mi->polygon_count += dc->polys[0]; - } - } -# ifdef CW - else /* codeword_p */ - { -# if 0 - double max = 70; /* face front */ - double x, y, z; - get_position (dc->scene_rot, &x, &y, &z, !dc->button_down_p); - glRotatef (max/2 - x*max, 0, 0, 1); - glRotatef (max/2 - y*max, 0, 1, 0); - /* glRotatef (max/2 - z*max, 1, 0, 0); */ -# else - glRotatef (360 * dc->scene_spinnerx.position_eased, 0, 1, 0); - glRotatef (360 * dc->scene_spinnery.position_eased, 0, 0, 1); -# endif - - glClearColor (dc->codeword_bg[0], - dc->codeword_bg[1], - dc->codeword_bg[2], - dc->codeword_bg[3]); - mi->polygon_count += draw_codeword_path (mi); - } -# endif /* CW */ - } - glPopMatrix(); - - if (dc->wire_overlay > 0) - dc->wire_overlay--; - -# ifdef DEBUG - { - char s[1024]; - sprintf (s, "a/z, s/x; per = %0.2f pos = %0.2f", - dc->persp_off, dc->pos_off); - glColor3f (1,1,1); - print_texture_label (dpy, dc->label_font, MI_WIDTH(mi), MI_HEIGHT(mi), - 1, s); - } -# endif - - if (mi->fps_p) do_fps (mi); - glFinish(); - - glXSwapBuffers(dpy, window); -} - - -ENTRYPOINT void -free_logo (ModeInfo *mi) -{ - logo_configuration *dc = &dcs[MI_SCREEN(mi)]; - if (!dc->glx_context) return; - glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *dc->glx_context); - if (dc->trackball) gltrackball_free (dc->trackball); -# ifdef CW - if (dc->codeword_text) free (dc->codeword_text); - if (dc->codeword_text_out) free (dc->codeword_text_out); - if (dc->scene_rot) free_rotator (dc->scene_rot); - if (dc->font) free_texture_font (dc->font); -# endif -# ifdef DEBUG - if (dc->label_font) free_texture_font (dc->label_font); -# endif - glDeleteLists(dc->helix_list, 1); - glDeleteLists(dc->helix_list_wire, 1); - glDeleteLists(dc->helix_list_facetted, 1); - glDeleteLists(dc->pizza_list, 1); - glDeleteLists(dc->pizza_list_wire, 1); - glDeleteLists(dc->pizza_list_facetted, 1); - glDeleteLists(dc->gasket_list, 1); - glDeleteLists(dc->gasket_list_wire, 1); - glDeleteLists(dc->frame_list, 1); - glDeleteLists(dc->frame_list_wire, 1); -} - -XSCREENSAVER_MODULE_2 ("DNALogo", dnalogo, logo) - -#endif /* USE_GL */ |
