X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fdnalogo.c;h=075fb55877e9ad3c5e7c2e6fc2a23f4f1a765aee;hp=0051ca5f635b19df440756c1175f30b5bed689e4;hb=019de959b265701cd0c3fccbb61f2b69f06bf9ee;hpb=50be9bb40dc60130c99ffa568e6677779904ff70 diff --git a/hacks/glx/dnalogo.c b/hacks/glx/dnalogo.c index 0051ca5f..075fb558 100644 --- a/hacks/glx/dnalogo.c +++ b/hacks/glx/dnalogo.c @@ -1,4 +1,15 @@ -/* DNA Logo, Copyright (c) 2001-2010 Jamie Zawinski +/* DNA Logo, Copyright (c) 2001-2011 Jamie Zawinski + * + * DNA Lounge + * + * Restaurant -- Bar -- Nightclub -- Cafe -- Est. 1985. + * + * 375 Eleventh Street + * San Francisco, CA + * 94103 + * + * http://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 @@ -35,6 +46,7 @@ "*frameThickness: 0.03 \n" \ "*triangleSize: 0.045 \n" \ "*speed: 1.0 \n" \ + "*mode: both" "\n" \ ".foreground: #00AA00 \n" \ "*geometry: =640x640\n" \ @@ -43,6 +55,21 @@ #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) +#undef LINEAR +#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" @@ -51,6 +78,18 @@ #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, + BOTH +} glyph_mode; + typedef struct { Bool spinning_p; GLfloat position; /* 0.0 - 1.0 */ @@ -62,6 +101,7 @@ 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]; @@ -89,10 +129,14 @@ typedef struct { GLfloat triangle_size; GLfloat speed; + glyph_mode mode; + glyph_mode anim_state; + GLfloat anim_ratio; spinner gasket_spinnerx, gasket_spinnery, gasket_spinnerz; spinner scene_spinnerx, scene_spinnery; spinner helix_spinnerz; + spinner pizza_spinnery, pizza_spinnerz; spinner frame_spinner; trackball_state *trackball; @@ -105,7 +149,11 @@ typedef struct { static logo_configuration *dcs = NULL; static XrmOptionDescRec opts[] = { - { "-speed", ".speed", XrmoptionSepArg, 0 }, + { "-speed", ".speed", XrmoptionSepArg, 0 }, + { "-mode", ".mode", XrmoptionSepArg, 0 }, + { "-pizza", ".mode", XrmoptionNoArg, "pizza" }, + { "-helix", ".mode", XrmoptionNoArg, "helix" }, + { "-both", ".mode", XrmoptionNoArg, "both" }, }; ENTRYPOINT ModeSpecOpt logo_opts = {countof(opts), opts, 0, NULL, NULL}; @@ -113,16 +161,14 @@ ENTRYPOINT ModeSpecOpt logo_opts = {countof(opts), opts, 0, NULL, NULL}; #define PROBABILITY_SCALE 600 -#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? - */ +#ifdef DXF_OUTPUT_HACK -# define glBegin dxf_glBegin -# define glVertex3f dxf_glVertex3f -# define glEnd dxf_glEnd +# 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]; @@ -198,13 +244,13 @@ dxf_glVertex3f (GLfloat ox, GLfloat oy, GLfloat oz) fprintf (stdout, "33\n%.6f\n", dxf_quads[i+2]); i += 6; - dxf_quads[0] = dxf_quads[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]; + 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; + dxf_point = 2; /* leave those two points in queue */ break; case GL_TRIANGLES: @@ -232,13 +278,44 @@ dxf_glVertex3f (GLfloat ox, GLfloat oy, GLfloat oz) dxf_point = 0; if (dxf_type == GL_TRIANGLE_FAN) { - dxf_quads[3] = dxf_quads[6]; + 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; + 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: @@ -278,6 +355,14 @@ dxf_glVertex3f (GLfloat ox, GLfloat oy, GLfloat oz) } } + +static void +dxf_glVertex3dv (const GLdouble *v) +{ + glVertex3f (v[0], v[1], v[2]); +} + + static void dxf_glEnd(void) { @@ -303,12 +388,41 @@ dxf_end (void) exit (0); } -# 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 -# include "tube.c" + +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 #endif /* DXF_OUTPUT_HACK */ @@ -1264,6 +1378,461 @@ make_frame (logo_configuration *dc, int wire) 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; + int endedge1; + +# 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; + } + endedge1 = i; + } + + 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) + { + glDisableClientState (GL_COLOR_ARRAY); + glDisableClientState (GL_NORMAL_ARRAY); + glDisableClientState (GL_TEXTURE_COORD_ARRAY); + glEnableClientState (GL_VERTEX_ARRAY); + glVertexPointer (3, GL_FLOAT, 0, dnapizza_triangles); + + glTranslatef(0, 0, thick2); + glNormal3f (0, 0, 1); + glFrontFace (GL_CW); + glDrawArrays (GL_TRIANGLES, 0, countof (dnapizza_triangles) / 3); + + glTranslatef(0, 0, -thick2*2); + glNormal3f (0, 0, -1); + glFrontFace (GL_CCW); + glDrawArrays (GL_TRIANGLES, 0, countof (dnapizza_triangles) / 3); + + 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; +} + + /* Window management, etc @@ -1369,7 +1938,29 @@ init_logo (ModeInfo *mi) 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"); + dc->speed = get_float_resource(mi->dpy, "speed", "Float"); + + { + 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 = BOTH; + 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 == BOTH + ? ((random() & 1) ? HELIX : PIZZA) + : dc->mode); + dc->anim_ratio = 0; + } { XColor xcolor; @@ -1396,12 +1987,18 @@ init_logo (ModeInfo *mi) dc->trackball = gltrackball_init (); - dc->gasket_spinnery.probability = 0.1; dc->gasket_spinnerx.probability = 0.1; + dc->gasket_spinnery.probability = 0.1; dc->gasket_spinnerz.probability = 1.0; + dc->helix_spinnerz.probability = 0.6; + + dc->pizza_spinnerz.probability = 0.6; + dc->pizza_spinnery.probability = 0.6; + dc->scene_spinnerx.probability = 0.1; dc->scene_spinnery.probability = 0.0; + dc->frame_spinner.probability = 5.0; /* start the frame off-screen */ @@ -1426,6 +2023,8 @@ init_logo (ModeInfo *mi) 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); @@ -1433,6 +2032,7 @@ init_logo (ModeInfo *mi) glRotatef (180, 0, 0, 1); make_helix (dc, 0, 0); glPopMatrix(); + dxf_layer++; make_gasket (dc, 0); dxf_layer++; @@ -1475,6 +2075,21 @@ init_logo (ModeInfo *mi) 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); @@ -1601,6 +2216,7 @@ draw_logo (ModeInfo *mi) GLfloat gcolor[4]; GLfloat specular[] = {0.8, 0.8, 0.8, 1.0}; GLfloat shininess = 50.0; + Bool pizza_p; if (!dc->glx_context) return; @@ -1608,7 +2224,8 @@ draw_logo (ModeInfo *mi) mi->polygon_count = 0; glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(dc->glx_context)); - if (dc->wire_overlay == 0 && + if (!wire && + dc->wire_overlay == 0 && (random() % (int) (PROBABILITY_SCALE / 0.2)) == 0) dc->wire_overlay = ((random() % 200) + (random() % 200) + @@ -1618,16 +2235,104 @@ draw_logo (ModeInfo *mi) 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); +# ifdef LINEAR + { + static double i = 0.0; + dc->anim_state = HELIX; + dc->wire_overlay = 0; + dc->gasket_spinnerx.spinning_p = 0; + dc->gasket_spinnery.spinning_p = 0; + dc->gasket_spinnerz.spinning_p = 0; + dc->helix_spinnerz.spinning_p = 0; + dc->pizza_spinnery.spinning_p = 0; + dc->pizza_spinnerz.spinning_p = 0; + dc->scene_spinnerx.spinning_p = 0; + dc->scene_spinnery.spinning_p = 0; + dc->frame_spinner.spinning_p = 0; + dc->frame_spinner.position = 0.3; + dc->gasket_spinnerz.position = i; + dc->helix_spinnerz.position = i; + i += 0.005; + if (i > 1) i = 0; + } +# endif /* LINEAR */ + + switch (dc->anim_state) + { + case HELIX: + if (dc->mode == BOTH && + (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 == BOTH && + (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; + + default: + abort(); + break; + } + + pizza_p = (dc->anim_state == PIZZA || + dc->anim_state == PIZZA_IN || + dc->anim_state == PIZZA_OUT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); + glRotatef(current_device_rotation(), 0, 0, 1); { - glScalef(3, 3, 3); + GLfloat scale = 1.8; +# ifdef LINEAR + scale = 3.85; +# endif + glScalef(scale, scale, scale); glColor3f(dc->color[0], dc->color[1], dc->color[2]); @@ -1637,7 +2342,7 @@ draw_logo (ModeInfo *mi) ? dc->frame_spinner.position : -dc->frame_spinner.position); GLfloat size = (p > 0.5 ? 1-p : p); - GLfloat scale = 1 + (size * 10); + scale = 1 + (size * 10); glPushMatrix(); /* gltrackball_rotate (dc->trackball); */ glRotatef(90, 1, 0, 0); @@ -1646,6 +2351,7 @@ draw_logo (ModeInfo *mi) glScalef (1, scale, scale); if (wire) { + glDisable (GL_LIGHTING); glCallList (dc->frame_list_wire); mi->polygon_count += dc->polys[6]; } @@ -1653,6 +2359,7 @@ draw_logo (ModeInfo *mi) { 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); @@ -1670,14 +2377,20 @@ draw_logo (ModeInfo *mi) glRotatef(90, 1, 0, 0); glRotatef(90, 0, 0, 1); - glRotatef (360 * sin (M_PI/2 * dc->scene_spinnerx.position), 0, 1, 0); - glRotatef (360 * sin (M_PI/2 * dc->scene_spinnery.position), 0, 0, 1); +# ifdef LINEAR +# define SINIFY(I) (I) +# else +# define SINIFY(I) sin (M_PI/2 * (I)) +# endif + + glRotatef (360 * SINIFY (dc->scene_spinnerx.position), 0, 1, 0); + glRotatef (360 * SINIFY (dc->scene_spinnery.position), 0, 0, 1); glPushMatrix(); { - glRotatef (360 * sin (M_PI/2 * dc->gasket_spinnerx.position), 0, 1, 0); - glRotatef (360 * sin (M_PI/2 * dc->gasket_spinnery.position), 0, 0, 1); - glRotatef (360 * sin (M_PI/2 * dc->gasket_spinnerz.position), 1, 0, 0); + glRotatef (360 * SINIFY (dc->gasket_spinnerx.position), 0, 1, 0); + glRotatef (360 * SINIFY (dc->gasket_spinnery.position), 0, 0, 1); + glRotatef (360 * SINIFY (dc->gasket_spinnerz.position), 1, 0, 0); memcpy (gcolor, dc->color, sizeof (dc->color)); if (dc->wire_overlay != 0) @@ -1692,6 +2405,7 @@ draw_logo (ModeInfo *mi) if (wire) { + glDisable (GL_LIGHTING); glCallList (dc->gasket_list_wire); mi->polygon_count += dc->polys[4]; } @@ -1699,9 +2413,11 @@ draw_logo (ModeInfo *mi) { 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 { @@ -1711,24 +2427,57 @@ draw_logo (ModeInfo *mi) } glPopMatrix(); - glRotatef (360 * sin (M_PI/2 * dc->helix_spinnerz.position), 0, 0, 1); + if (pizza_p) + { + glRotatef (360 * SINIFY (dc->pizza_spinnery.position), 1, 0, 0); + glRotatef (360 * SINIFY (dc->pizza_spinnerz.position), 0, 0, 1); + } + else + { + glRotatef (360 * SINIFY (dc->helix_spinnerz.position), 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) { - glCallList (dc->helix_list_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) { - glCallList (dc->helix_list_facetted); + if (pizza_p) + glCallList (dc->pizza_list_facetted); + else + glCallList (dc->helix_list_facetted); + glDisable (GL_LIGHTING); - glCallList (dc->helix_list_wire); + 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 { - glCallList (dc->helix_list); + if (pizza_p) + glCallList (dc->pizza_list); + else + glCallList (dc->helix_list); mi->polygon_count += dc->polys[0]; } } @@ -1743,6 +2492,6 @@ draw_logo (ModeInfo *mi) glXSwapBuffers(dpy, window); } -XSCREENSAVER_MODULE_2 ("DNAlogo", dnalogo, logo) +XSCREENSAVER_MODULE_2 ("DNALogo", dnalogo, logo) #endif /* USE_GL */