ftp://ftp.linux.ncsu.edu/mirror/ftp.redhat.com/pub/redhat/linux/enterprise/4/en/os...
[xscreensaver] / hacks / glx / lament.c
index b100a9ce8bf909089c101501bc38f0ba5a09fe4a..fecf80982457d88df0b0b3d26a2d3ee8b05e7365 100644 (file)
@@ -1,4 +1,4 @@
-/* xscreensaver, Copyright (c) 1998 Jamie Zawinski <jwz@jwz.org>
+/* xscreensaver, Copyright (c) 1998-2004 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
@@ -78,7 +78,7 @@
 #define HACK_HANDLE_EVENT lament_handle_event
 #define EVENT_MASK     PointerMotionMask
 #define lament_opts    xlockmore_opts
-#define DEFAULTS       "*delay:        10000   \n"     \
+#define DEFAULTS       "*delay:        20000   \n"     \
                        "*showFPS:      False   \n"     \
                        "*wireframe:    False   \n"     \
                        "*texture:      True    \n"
 
 static int do_texture;
 static XrmOptionDescRec opts[] = {
-  {"-texture", ".lament.texture", XrmoptionNoArg, (caddr_t) "true" },
-  {"+texture", ".lament.texture", XrmoptionNoArg, (caddr_t) "false" },
+  {"-texture", ".lament.texture", XrmoptionNoArg, "true" },
+  {"+texture", ".lament.texture", XrmoptionNoArg, "false" },
 };
 
 static argtype vars[] = {
-  {(caddr_t *) &do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool},
+  {&do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool},
 };
 
 ModeSpecOpt lament_opts = {countof(opts), opts, countof(vars), vars, NULL};
@@ -191,92 +191,83 @@ parse_image_data(ModeInfo *mi)
 }
 
 \f
-/* Computing normal vectors (thanks to Nat Friedman <ndf@mit.edu>)
- */
-
-typedef struct vector {
-  GLfloat x, y, z;
-} vector;
-
-typedef struct plane {
-  vector p1, p2, p3;
-} plane;
-
-static void
-vector_set(vector *v, GLfloat x, GLfloat y, GLfloat z)
-{
-  v->x = x;
-  v->y = y;
-  v->z = z;
-}
+typedef struct {
+  double x,y,z;
+} XYZ;
 
 static void
-vector_cross(vector v1, vector v2, vector *v3)
+normalize (XYZ *p)
 {
-  v3->x = (v1.y * v2.z) - (v1.z * v2.y);
-  v3->y = (v1.z * v2.x) - (v1.x * v2.z);
-  v3->z = (v1.x * v2.y) - (v1.y * v2.x);
+  double length;
+  length = sqrt (p->x * p->x +
+                 p->y * p->y +
+                 p->z * p->z);
+  if (length != 0)
+    {
+      p->x /= length;
+      p->y /= length;
+      p->z /= length;
+    }
+  else
+    {
+      p->x = 0;
+      p->y = 0;
+      p->z = 0;
+    }
 }
 
-static void
-vector_subtract(vector v1, vector v2, vector *res)
+/* Calculate the unit normal at p given two other points p1,p2 on the
+   surface. The normal points in the direction of p1 crossproduct p2
+ */
+static XYZ
+calc_normal (XYZ p, XYZ p1, XYZ p2)
 {
-  res->x = v1.x - v2.x;
-  res->y = v1.y - v2.y;
-  res->z = v1.z - v2.z;
+  XYZ n, pa, pb;
+  pa.x = p1.x - p.x;
+  pa.y = p1.y - p.y;
+  pa.z = p1.z - p.z;
+  pb.x = p2.x - p.x;
+  pb.y = p2.y - p.y;
+  pb.z = p2.z - p.z;
+  n.x = pa.y * pb.z - pa.z * pb.y;
+  n.y = pa.z * pb.x - pa.x * pb.z;
+  n.z = pa.x * pb.y - pa.y * pb.x;
+  normalize (&n);
+  return (n);
 }
 
-static void
-plane_normal(plane p, vector *n)
-{
-  vector v1, v2;
-  vector_subtract(p.p1, p.p2, &v1);
-  vector_subtract(p.p1, p.p3, &v2);
-  vector_cross(v2, v1, n);
-}
 
 static void
 do_normal(GLfloat x1, GLfloat y1, GLfloat z1,
          GLfloat x2, GLfloat y2, GLfloat z2,
          GLfloat x3, GLfloat y3, GLfloat z3)
 {
-  plane plane;
-  vector n;
-  vector_set(&plane.p1, x1, y1, z1);
-  vector_set(&plane.p2, x2, y2, z2);
-  vector_set(&plane.p3, x3, y3, z3);
-  plane_normal(plane, &n);
-  n.x = -n.x; n.y = -n.y; n.z = -n.z;
+  XYZ p1, p2, p3, p;
+  p1.x = x1; p1.y = y1; p1.z = z1;
+  p2.x = x2; p2.y = y2; p2.z = z2;
+  p3.x = x3; p3.y = y3; p3.z = z3;
 
-  glNormal3f(n.x, n.y, n.z);
+  p = calc_normal (p1, p2, p3);
+
+  glNormal3f (p.x, p.y, p.z);
 
 #ifdef DEBUG
   /* Draw a line in the direction of this face's normal. */
   {
-    GLfloat ax = n.x > 0 ? n.x : -n.x;
-    GLfloat ay = n.y > 0 ? n.y : -n.y;
-    GLfloat az = n.z > 0 ? n.z : -n.z;
-    GLfloat mx = (x1 + x2 + x3) / 3;
-    GLfloat my = (y1 + y2 + y3) / 3;
-    GLfloat mz = (z1 + z2 + z3) / 3;
-    GLfloat xx, yy, zz;
-
-    GLfloat max = ax > ay ? ax : ay;
-    if (az > max) max = az;
-    max *= 2;
-    xx = n.x / max;
-    yy = n.y / max;
-    zz = n.z / max;
-
+    glPushMatrix();
+    glTranslatef ((x1 + x2 + x3) / 3,
+                  (y1 + y2 + y3) / 3,
+                  (z1 + z2 + z3) / 3);
+    glScalef (0.5, 0.5, 0.5);
     glBegin(GL_LINE_LOOP);
-    glVertex3f(mx, my, mz);
-    glVertex3f(mx+xx, my+yy, mz+zz);
+    glVertex3f(0, 0, 0);
+    glVertex3f(p.x, p.y, p.z);
     glEnd();
+    glPopMatrix();
   }
 #endif /* DEBUG */
 }
 
-
 \f
 /* Shorthand utilities for making faces, with proper normals.
  */
@@ -1870,7 +1861,7 @@ reshape_lament(ModeInfo *mi, int width, int height)
      Note that the image-map bits we have are 128x128.  Therefore, if the
      image is magnified a lot, it looks pretty blocky.  So it's better to
      have a 128x128 animation on a 1280x1024 screen that looks good, than
-     a 1024x1024 animation that looks really pixellated.
+     a 1024x1024 animation that looks really pixelated.
    */
   if (win_size > target_size * 1.5)
     {
@@ -1945,7 +1936,9 @@ gl_init(ModeInfo *mi)
           clear_gl_error();
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                       lc->texture->width, height, 0,
-                      GL_RGBA, GL_UNSIGNED_BYTE,
+                      GL_RGBA,
+                       /* GL_UNSIGNED_BYTE, */
+                       GL_UNSIGNED_INT_8_8_8_8_REV,
                       (lc->texture->data +
                        (lc->texture->bytes_per_line * height * i)));
           check_gl_error("texture");