http://packetstormsecurity.org/UNIX/admin/xscreensaver-4.02.tar.gz
[xscreensaver] / hacks / glx / dangerball.c
index 2dca4e0303a371816b6175b941c16953a742b157..746b7b2415edeef6909a2d8b2454b0d306ebe5f8 100644 (file)
@@ -1,4 +1,4 @@
-/* dangerball, Copyright (c) 2001 Jamie Zawinski <jwz@jwz.org>
+/* dangerball, Copyright (c) 2001, 2002 Jamie Zawinski <jwz@jwz.org>
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -32,32 +32,24 @@ extern XtAppContext app;
                        "*wander:     " DEF_WANDER "\n" \
 
 
+#define SPIKE_FACES   12  /* how densely to render spikes */
+#define SMOOTH_SPIKES True
 #define SPHERE_SLICES 32  /* how densely to render spheres */
 #define SPHERE_STACKS 16
 
 
-#define SPIKE_FACES  12   /* how densely to render spikes */
-
-
 #undef countof
 #define countof(x) (sizeof((x))/sizeof((*x)))
 
 #include "xlockmore.h"
 #include "colors.h"
+#include "sphere.h"
+#include "tube.h"
 #include <ctype.h>
 
 #ifdef USE_GL /* whole file */
 
-#ifdef HAVE_UNAME
-# include <sys/utsname.h>
-#endif /* HAVE_UNAME */
-
-
 #include <GL/glu.h>
-#include "glutstroke.h"
-#include "glut_roman.h"
-#define GLUT_FONT (&glutStrokeRoman)
-
 
 typedef struct {
   GLXContext *glx_context;
@@ -103,112 +95,6 @@ static argtype vars[] = {
 ModeSpecOpt sws_opts = {countof(opts), opts, countof(vars), vars, NULL};
 
 
-
-static void
-unit_spike (Bool wire)
-{
-  int i;
-  int faces = SPIKE_FACES;
-  GLfloat step = M_PI * 2 / faces;
-  GLfloat th;
-
-  glFrontFace(GL_CW);
-  glBegin(wire ? GL_LINE_STRIP : GL_TRIANGLE_FAN);
-
-  glNormal3f(0, 1, 0);
-  glVertex3f(0, 1, 0);
-  for (i = 0, th = 0; i <= faces; i++)
-    {
-      GLfloat x = cos (th);
-      GLfloat y = sin (th);
-      glNormal3f(x, 0, y);
-      glVertex3f(x, 0, y);
-      if (wire) glVertex3f(0, 1, 0);
-      th += step;
-    }
-  glEnd();
-}
-
-
-/* lifted from glplanet */
-/* Function for determining points on the surface of the sphere */
-static void
-parametric_sphere (float theta, float rho, GLfloat *vector)
-{
-  vector[0] = -sin(theta) * sin(rho);
-  vector[1] = cos(theta) * sin(rho);
-  vector[2] = cos(rho);
-}
-
-/* lifted from glplanet */
-static void
-unit_sphere (Bool wire)
-{
-  int stacks = SPHERE_STACKS;
-  int slices = SPHERE_SLICES;
-
-  int i, j;
-  float drho, dtheta;
-  float rho, theta;
-  GLfloat vector[3];
-  GLfloat ds, dt, t, s;
-
-  if (!wire)
-    glShadeModel(GL_SMOOTH);
-
-  /* Generate a sphere with quadrilaterals.
-   * Quad vertices are determined using a parametric sphere function.
-   * For fun, you could generate practically any parameteric surface and
-   * map an image onto it. 
-   */
-  drho = M_PI / stacks;
-  dtheta = 2.0 * M_PI / slices;
-  ds = 1.0 / slices;
-  dt = 1.0 / stacks;
-
-  glFrontFace(GL_CCW);
-  glBegin( wire ? GL_LINE_LOOP : GL_QUADS );
-
-  t = 0.0;
-  for (i=0; i < stacks; i++) {
-    rho = i * drho;
-    s = 0.0;
-    for (j=0; j < slices; j++) {
-      theta = j * dtheta;
-
-      glTexCoord2f (s,t);
-      parametric_sphere (theta, rho, vector);
-      glNormal3fv (vector);
-      parametric_sphere (theta, rho, vector);
-      glVertex3f (vector[0], vector[1], vector[2]);
-
-      glTexCoord2f (s,t+dt);
-      parametric_sphere (theta, rho+drho, vector);
-      glNormal3fv (vector);
-      parametric_sphere (theta, rho+drho, vector);
-      glVertex3f (vector[0], vector[1], vector[2]);
-
-      glTexCoord2f (s+ds,t+dt);
-      parametric_sphere (theta + dtheta, rho+drho, vector);
-      glNormal3fv (vector);
-      parametric_sphere (theta + dtheta, rho+drho, vector);
-      glVertex3f (vector[0], vector[1], vector[2]);
-
-      glTexCoord2f (s+ds, t);
-      parametric_sphere (theta + dtheta, rho, vector);
-      glNormal3fv (vector);
-      parametric_sphere (theta + dtheta, rho, vector);
-      glVertex3f (vector[0], vector[1], vector[2]);
-
-      s = s + ds;
-    }
-    t = t + dt;
-  }
-  glEnd();
-}
-
-
-
 /* Window management, etc
  */
 void
@@ -233,25 +119,6 @@ reshape_ball (ModeInfo *mi, int width, int height)
 }
 
 
-static void
-gl_init (ModeInfo *mi)
-{
-/*  ball_configuration *bp = &bps[MI_SCREEN(mi)]; */
-  int wire = MI_IS_WIREFRAME(mi);
-
-  static GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0};
-
-  if (!wire)
-    {
-      glLightfv(GL_LIGHT0, GL_POSITION, pos);
-      glEnable(GL_CULL_FACE);
-      glEnable(GL_LIGHTING);
-      glEnable(GL_LIGHT0);
-      glEnable(GL_DEPTH_TEST);
-    }
-}
-
-
 /* lifted from lament.c */
 #define RAND(n) ((long) ((random() & 0x7fffffff) % ((long) (n))))
 #define RANDSIGN() ((random() & 1) ? 1 : -1)
@@ -410,10 +277,27 @@ init_ball (ModeInfo *mi)
 
   bp = &bps[MI_SCREEN(mi)];
 
-  if ((bp->glx_context = init_GL(mi)) != NULL) {
-    gl_init(mi);
-    reshape_ball (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
-  }
+  bp->glx_context = init_GL(mi);
+
+  reshape_ball (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+
+  if (!wire)
+    {
+      GLfloat pos[4] = {1.0, 1.0, 1.0, 0.0};
+      GLfloat amb[4] = {0.0, 0.0, 0.0, 1.0};
+      GLfloat dif[4] = {1.0, 1.0, 1.0, 1.0};
+      GLfloat spc[4] = {0.0, 1.0, 1.0, 1.0};
+
+      glEnable(GL_LIGHTING);
+      glEnable(GL_LIGHT0);
+      glEnable(GL_DEPTH_TEST);
+      glEnable(GL_CULL_FACE);
+
+      glLightfv(GL_LIGHT0, GL_POSITION, pos);
+      glLightfv(GL_LIGHT0, GL_AMBIENT,  amb);
+      glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
+      glLightfv(GL_LIGHT0, GL_SPECULAR, spc);
+    }
 
   bp->rotx = frand(1.0) * RANDSIGN();
   bp->roty = frand(1.0) * RANDSIGN();
@@ -442,11 +326,13 @@ init_ball (ModeInfo *mi)
   bp->spike_list = glGenLists (1);
 
   glNewList (bp->ball_list, GL_COMPILE);
-  unit_sphere (wire);
+  unit_sphere (SPHERE_STACKS, SPHERE_SLICES, wire);
   glEndList ();
 
   glNewList (bp->spike_list, GL_COMPILE);
-  unit_spike (wire);
+  cone (0, 0, 0,
+        0, 1, 0,
+        1, 0, SPIKE_FACES, SMOOTH_SPIKES, wire);
   glEndList ();
 
   randomize_spikes (mi);
@@ -461,8 +347,16 @@ draw_ball (ModeInfo *mi)
   Window window = MI_WINDOW(mi);
   int c2;
 
-  static GLfloat color1[4] = {0.0, 0.0, 0.0, 1.0};
-  static GLfloat color2[4] = {0.0, 0.0, 0.0, 1.0};
+  /* #### I'm not getting specular reflections on the ball,
+          and I can't figure out why.
+   */
+
+  static GLfloat bcolor[4] = {0.0, 0.0, 0.0, 1.0};
+  static GLfloat scolor[4] = {0.0, 0.0, 0.0, 1.0};
+  static GLfloat bspec[4]  = {1.0, 1.0, 1.0, 1.0};
+  static GLfloat sspec[4]  = {0.0, 0.0, 0.0, 1.0};
+  static GLfloat bshiny    = 128.0;
+  static GLfloat sshiny    = 0.0;
 
   if (!bp->glx_context)
     return;
@@ -515,14 +409,14 @@ draw_ball (ModeInfo *mi)
       }
   }
 
-  color1[0] = bp->colors[bp->ccolor].red   / 65536.0;
-  color1[1] = bp->colors[bp->ccolor].green / 65536.0;
-  color1[2] = bp->colors[bp->ccolor].blue  / 65536.0;
+  bcolor[0] = bp->colors[bp->ccolor].red   / 65536.0;
+  bcolor[1] = bp->colors[bp->ccolor].green / 65536.0;
+  bcolor[2] = bp->colors[bp->ccolor].blue  / 65536.0;
 
   c2 = (bp->ccolor + bp->color_shift) % bp->ncolors;
-  color2[0] = bp->colors[c2].red   / 65536.0;
-  color2[1] = bp->colors[c2].green / 65536.0;
-  color2[2] = bp->colors[c2].blue  / 65536.0;
+  scolor[0] = bp->colors[c2].red   / 65536.0;
+  scolor[1] = bp->colors[c2].green / 65536.0;
+  scolor[2] = bp->colors[c2].blue  / 65536.0;
 
   bp->ccolor++;
   if (bp->ccolor >= bp->ncolors) bp->ccolor = 0;
@@ -531,10 +425,14 @@ draw_ball (ModeInfo *mi)
 
   move_spikes (mi);
 
-  glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color1);
+  glMaterialfv (GL_FRONT, GL_SPECULAR,            bspec);
+  glMateriali  (GL_FRONT, GL_SHININESS,           bshiny);
+  glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, bcolor);
   glCallList (bp->ball_list);
 
-  glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color2);
+  glMaterialfv (GL_FRONT, GL_SPECULAR,            sspec);
+  glMaterialf  (GL_FRONT, GL_SHININESS,           sshiny);
+  glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, scolor);
   draw_spikes (mi);
   glPopMatrix ();