From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / glx / lockward.c
index d4081ee969e665860078ef300726ae99b7ecc411..404a49fd561389842e3a1da2f132dffb1b165b34 100644 (file)
@@ -40,6 +40,7 @@
                        "*showFPS:      False   \n"
 
 #define        refresh_lockward        0
+#define        release_lockward        0
 
 
 #define        NUMOF(x)        (sizeof ((x)) / sizeof ((*x)))
 #define        NSPINNERS       4
 #define        NRADII          8
 #define        COLORIDX_SHF    4
+#define        SUBDIV          6
+
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
 
 
 /***************************************************************************
@@ -106,24 +111,33 @@ enum blinktype {
        MAX_BTYPE
 };
 
+typedef struct { GLfloat x,y,z; } XYZ;
+
 typedef struct lockward_context {
        GLXContext      *glx_context;
 
        spinnerstate    spinners[NSPINNERS];
        blinkstate      blink;
 
-       GLuint          blades_outer, blades_inner;
+        /* This used to put vertexes into lists without putting begin/end
+           into the same list!  I didn't even know that worked.  Well, it
+           doesn't work with jwzgles, so I changed it to not do that. */
+     /* GLuint         blades_outer, blades_inner; */
+        XYZ points_outer[NRADII][SUBDIV+1];
+        XYZ points_inner[NRADII][SUBDIV+1];
+
        GLuint          rings;
        Bool            blendmode;
        int             nextblink;
        int             fps;
+
 } lockward_context;
 
 
 /***************************************************************************
  * Prototypes.
  */
-static void free_lockward (lockward_context *ctx);
+static void free_lockward (ModeInfo *mi);
 
 
 /***************************************************************************
@@ -190,16 +204,20 @@ ENTRYPOINT ModeSpecOpt lockward_opts = {
 ENTRYPOINT void
 reshape_lockward (ModeInfo *mi, int width, int height)
 {
+       lockward_context *ctx = &g_ctx[MI_SCREEN (mi)];
        GLfloat h = (GLfloat) height / (GLfloat) width;
 
+       glXMakeCurrent (MI_DISPLAY (mi), MI_WINDOW (mi),
+                       *(ctx->glx_context));
+
        glViewport (0, 0, (GLint) width, (GLint) height);
 
        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
        if (height > width)
-               gluOrtho2D (-8.0, 8.0, -8.0 * h, 8.0 * h);
+               glOrtho (-8.0, 8.0, -8.0 * h, 8.0 * h, -1, 1);
        else
-               gluOrtho2D (-8.0 / h, 8.0 / h, -8.0, 8.0);
+               glOrtho (-8.0 / h, 8.0 / h, -8.0, 8.0, -1, 1);
 
        glMatrixMode (GL_MODELVIEW);
 }
@@ -214,7 +232,7 @@ lockward_handle_event (ModeInfo *mi, XEvent *event)
                char    c = 0;
 
                XLookupString (&event->xkey, &c, 1, &keysym, 0);
-               if (c == 'b') {
+               if (c == ' ' || c == '\t') {
                        ctx->blendmode ^= 1;
                        return True;
                }
@@ -278,7 +296,6 @@ random_blade_rot (lockward_context *ctx, struct spinnerstate *ss)
  * the inner one, or the blade clockwise-ness will be wrong, and become
  * invisible.  Arcs of various radii are compiled.
  */
-#define        SUBDIV          6
 
 static void
 gen_blade_arcs (lockward_context *ctx)
@@ -290,18 +307,25 @@ gen_blade_arcs (lockward_context *ctx)
        there = M_PI * 2.0 / g_blades;
        step = there / SUBDIV;
        here -= SUBDIV * step / 2.0;
-       there -= SUBDIV * step / 2.0;
 
        /*
         * Build outer blade arcs.
         * Start at left side of outer radius.  Strike all its vertices.
         */
        for (n = 0;  n < NRADII;  ++n) {
-               glNewList (ctx->blades_outer + n, GL_COMPILE);
-               for (i = SUBDIV;  i >= 0;  --i)
-                       glVertex3f (cos (here + step * i) * (n + 1.0),
-                                   sin (here + step * i) * (n + 1.0), 0);
-               glEndList ();
+          /* glNewList (ctx->blades_outer + n, GL_COMPILE); */
+          XYZ *a = ctx->points_outer[n];
+          int j = 0;
+          for (i = SUBDIV;  i >= 0;  --i) {
+            /* glVertex3f (cos (here + step * i) * (n + 1.0),
+                           sin (here + step * i) * (n + 1.0), 0); */
+            a[j].x = cos (here + step * i) * (n + 1.0);
+            a[j].y = sin (here + step * i) * (n + 1.0);
+            a[j].z = 0;
+            j++;
+          }
+          if (j != SUBDIV+1) abort();
+          /* glEndList (); */
        }
 
        /*
@@ -309,11 +333,19 @@ gen_blade_arcs (lockward_context *ctx)
         * Move to inner radius, strike all vertices in opposite order.
         */
        for (n = 0;  n < NRADII;  ++n) {
-               glNewList (ctx->blades_inner + n, GL_COMPILE);
-               for (i = 0;  i <= SUBDIV;  ++i)
-                       glVertex3f (cos (here + step * i) * (n + 1.0),
-                                   sin (here + step * i) * (n + 1.0), 0);
-               glEndList ();
+          /* glNewList (ctx->blades_inner + n, GL_COMPILE); */
+          XYZ *a = ctx->points_inner[n];
+          int j = 0;
+          for (i = 0;  i <= SUBDIV;  ++i) {
+            /* glVertex3f (cos (here + step * i) * (n + 1.0),
+                          sin (here + step * i) * (n + 1.0), 0); */
+            a[j].x = cos (here + step * i) * (n + 1.0);
+            a[j].y = sin (here + step * i) * (n + 1.0);
+            a[j].z = 0;
+            j++;
+          }
+          if (j != SUBDIV+1) abort();
+          /* glEndList (); */
        }
 }
 
@@ -368,13 +400,25 @@ set_alpha_by_dwell (struct blinkstate *bs)
                bs->color[3] = bs->dwellcnt > (-bs->dwell >> 2)  ?  1.0  : 0.0;
 }
 
+
 static void
-draw_blink_blade (lockward_context *ctx, int inner, int outer)
+draw_blink_blade (lockward_context *ctx, int inner, int outer,
+                  Bool begin_p)
 {
-       glBegin (GL_TRIANGLE_FAN);
-       glCallList (ctx->blades_outer + outer);
-       glCallList (ctx->blades_inner + inner);
-       glEnd ();
+  int i;
+  if (begin_p) glBegin (GL_TRIANGLE_FAN);
+  /* glCallList (ctx->blades_outer + outer); */
+  for (i = 0; i < countof(*ctx->points_outer); i++)
+    glVertex3f(ctx->points_outer[outer][i].x,
+               ctx->points_outer[outer][i].y,
+               ctx->points_outer[outer][i].z);
+
+  /* glCallList (ctx->blades_inner + inner); */
+  for (i = 0; i < countof(*ctx->points_inner); i++)
+    glVertex3f(ctx->points_inner[inner][i].x,
+               ctx->points_inner[inner][i].y,
+               ctx->points_inner[inner][i].z);
+  if (begin_p) glEnd();
 }
 
 static int
@@ -416,9 +460,9 @@ draw_blink_radial_random (lockward_context *ctx, struct blinkstate *bs)
        glColor4fv (bs->color);
        glRotatef (bs->direction * 360.0 / (GLfloat) g_blades, 0, 0, 1);
        if (bs->radius >= 0)
-               draw_blink_blade (ctx, bs->radius, bs->radius + 1);
+               draw_blink_blade (ctx, bs->radius, bs->radius + 1, True);
        else
-               draw_blink_blade (ctx, 0, NRADII - 1);
+               draw_blink_blade (ctx, 0, NRADII - 1, True);
 
        --bs->dwellcnt;
 
@@ -444,7 +488,7 @@ draw_blink_radial_sequential (lockward_context *ctx, struct blinkstate *bs)
        glRotatef ((bs->counter * bs->direction + (int) bs->val)
                    * 360.0 / (GLfloat) g_blades,
                   0, 0, 1);
-       draw_blink_blade (ctx, 0, NRADII - 1);
+       draw_blink_blade (ctx, 0, NRADII - 1, True);
 
        --bs->dwellcnt;
 
@@ -473,7 +517,7 @@ draw_blink_radial_doubleseq (lockward_context *ctx, struct blinkstate *bs)
        glPushMatrix ();
        glRotatef (((int) bs->val + bs->counter) * 360.0 / (GLfloat) g_blades,
                   0, 0, 1);
-       draw_blink_blade (ctx, 0, NRADII - 1);
+       draw_blink_blade (ctx, 0, NRADII - 1, True);
        glPopMatrix ();
        polys = SUBDIV + SUBDIV;
 
@@ -481,7 +525,7 @@ draw_blink_radial_doubleseq (lockward_context *ctx, struct blinkstate *bs)
                glRotatef (((int) bs->val - bs->counter)
                            * 360.0 / (GLfloat) g_blades,
                           0, 0, 1);
-               draw_blink_blade (ctx, 0, NRADII - 1);
+               draw_blink_blade (ctx, 0, NRADII - 1, True);
                polys += SUBDIV + SUBDIV;
        }
 
@@ -592,7 +636,7 @@ draw_blink_segment_scatter (lockward_context *ctx, struct blinkstate *bs)
 
                        glPushMatrix ();
                        glRotatef (i * 360.0 / (GLfloat) g_blades, 0, 0, 1);
-                       draw_blink_blade (ctx, inner, outer);
+                       draw_blink_blade (ctx, inner, outer, True);
                        glPopMatrix ();
 
                        polys += SUBDIV + SUBDIV;
@@ -712,16 +756,20 @@ draw_lockward (ModeInfo *mi)
                glPushMatrix ();
                glRotatef (ss->rot - ss->rotcount * ss->rotinc, 0, 0, 1);
                for (i = ss->nblades;  --i >= 0; ) {
-                       glPushMatrix ();
-                       glRotatef (360.0 * i / ss->nblades, 0, 0, 1);
-
-                       glBegin (GL_TRIANGLE_FAN);
-                       glCallList (ctx->blades_outer + ss->bladeidx[i].outer);
-                       glCallList (ctx->blades_inner + ss->bladeidx[i].inner);
-                       glEnd ();
-
-                       glPopMatrix ();
-                       mi->polygon_count += SUBDIV + SUBDIV;
+                  glPushMatrix ();
+                  glRotatef (360.0 * i / ss->nblades, 0, 0, 1);
+
+                  glBegin (GL_TRIANGLE_FAN);
+                  /* glCallList (ctx->blades_outer + ss->bladeidx[i].outer); */
+                  /* glCallList (ctx->blades_inner + ss->bladeidx[i].inner); */
+                  draw_blink_blade (ctx,
+                                    ss->bladeidx[i].inner,
+                                    ss->bladeidx[i].outer,
+                                    False);
+                  glEnd ();
+
+                  glPopMatrix ();
+                  mi->polygon_count += SUBDIV + SUBDIV;
                }
                glPopMatrix ();
 
@@ -784,15 +832,7 @@ init_lockward (ModeInfo *mi)
        lockward_context        *ctx;
        int             i, n;
 
-       if (!g_ctx) {
-               g_ctx = (lockward_context *) calloc (MI_NUM_SCREENS (mi),
-                                                  sizeof (lockward_context));
-               if (!g_ctx) {
-                       fprintf (stderr, "%s: can't allocate context.\n",
-                                progname);
-                       exit (1);
-               }
-       }
+       MI_INIT (mi, g_ctx, free_lockward);
        ctx = &g_ctx[MI_SCREEN (mi)];
 
        ctx->glx_context = init_GL (mi);
@@ -806,11 +846,8 @@ init_lockward (ModeInfo *mi)
        glShadeModel (GL_FLAT);
        glFrontFace (GL_CW);
 
-
-       glClearColor (0.0, 0.0, 0.0, 1.0);
-
-       ctx->blades_outer       = glGenLists (NRADII);
-       ctx->blades_inner       = glGenLists (NRADII);
+       /* ctx->blades_outer    = glGenLists (NRADII); */
+       /* ctx->blades_inner    = glGenLists (NRADII); */
        ctx->rings              = glGenLists (NRADII - 1);
        ctx->blendmode          = 0;
        ctx->fps                = 1000000 / MI_DELAY (mi);
@@ -888,18 +925,25 @@ init_lockward (ModeInfo *mi)
 }
 
 static void
-free_lockward (lockward_context *ctx)
+free_lockward (ModeInfo *mi)
 {
+       lockward_context        *ctx = &g_ctx[MI_SCREEN (mi)];
        int i;
 
+       if (!ctx->glx_context)
+               return;
+
+       glXMakeCurrent (MI_DISPLAY (mi), MI_WINDOW (mi),
+                       *(ctx->glx_context));
+
        if (ctx->blink.noise)
                free (ctx->blink.noise);
        if (glIsList (ctx->rings))
                glDeleteLists (ctx->rings, NRADII - 1);
-       if (glIsList (ctx->blades_outer))
+       /* if (glIsList (ctx->blades_outer))
                glDeleteLists (ctx->blades_outer, NRADII);
        if (glIsList (ctx->blades_inner))
-               glDeleteLists (ctx->blades_inner, NRADII);
+               glDeleteLists (ctx->blades_inner, NRADII); */
 
        for (i = NSPINNERS;  --i >= 0; ) {
                spinnerstate *ss = &ctx->spinners[i];
@@ -911,25 +955,6 @@ free_lockward (lockward_context *ctx)
        }
 }
 
-ENTRYPOINT void
-release_lockward (ModeInfo *mi)
-{
-       int i;
-
-       if (!g_ctx)
-               return;
-
-       for (i = MI_NUM_SCREENS (mi);  --i >= 0; ) {
-               if (g_ctx[i].glx_context)
-                       glXMakeCurrent (MI_DISPLAY (mi), MI_WINDOW (mi),
-                                       *(g_ctx[i].glx_context));
-               free_lockward (&g_ctx[i]);
-       }
-
-       FreeAllGL (mi);
-       free (g_ctx);  g_ctx = NULL;
-}
-
 
 XSCREENSAVER_MODULE ("Lockward", lockward)