http://packetstormsecurity.org/UNIX/admin/xscreensaver-3.32.tar.gz
[xscreensaver] / hacks / glx / atlantis.c
index 00853dc6a09b81b86192bb1b9a39493795b58630..f1844a5b212abb7b30c20288578c297a4fdb8abf 100644 (file)
@@ -36,6 +36,11 @@ static const char sccsid[] = "@(#)atlantis.c 1.3 98/06/18 xlockmore";
  *
  * REVISION HISTORY:
  * 
+ * Jamie Zawinski, 2-Apr-01:  - The fishies were inside out!  The back faces
+ *                              were being drawn, not the front faces.
+ *                            - Added a texture to simulate light from the
+ *                              surface, like in the SGI version.
+ *
  * David A. Bagley - 98/06/17 : Add whalespeed option. Global options to
  *                              initialize local variables are now:
  *                              XLock.atlantis.cycles: 100      ! SharkSpeed
@@ -109,6 +114,7 @@ static const char sccsid[] = "@(#)atlantis.c        1.3 98/06/18 xlockmore";
                         "*showFPS:    False \n" \
                         "*cycles:       100 \n" \
                         "*size:        6000 \n" \
+                        "*wireframe:  False \n" \
                         "*whalespeed:   250 \n"
 # include "xlockmore.h"                /* from the xscreensaver distribution */
 #else  /* !STANDALONE */
@@ -122,21 +128,28 @@ static const char sccsid[] = "@(#)atlantis.c      1.3 98/06/18 xlockmore";
 #include <GL/glu.h>
 
 
+#define DEF_TEXTURE "True"
+
 #define DEF_WHALESPEED  "250"
 static int  whalespeed;
+static int do_texture;
 static XrmOptionDescRec opts[] =
 {
-     {"-whalespeed", ".atlantis.whalespeed", XrmoptionSepArg, (caddr_t) NULL}
+     {"-whalespeed", ".atlantis.whalespeed", XrmoptionSepArg, (caddr_t) NULL},
+     {"-texture",    ".atlantis.texture",    XrmoptionNoArg, (caddr_t)"true"},
+     {"+texture",    ".atlantis.texture",    XrmoptionNoArg, (caddr_t)"false"},
 };
 
 static argtype vars[] =
 {
-{(caddr_t *) & whalespeed, "whalespeed", "WhaleSpeed", DEF_WHALESPEED, t_Int}
+ {(caddr_t *) & whalespeed, "whalespeed", "WhaleSpeed", DEF_WHALESPEED, t_Int},
+ {(caddr_t *) &do_texture,  "texture",    "Texture",    DEF_TEXTURE,   t_Bool},
 };
 
 static OptionStruct desc[] =
 {
-       {"-whalespeed num", "speed of whales and the dolphin"}
+       {"-whalespeed num", "speed of whales and the dolphin"},
+       {"-texture num",    "whether to introduce water-like distortion"}
 };
 
 ModeSpecOpt atlantis_opts =
@@ -153,6 +166,19 @@ ModStruct   atlantis_description =
 
 static atlantisstruct *atlantis = NULL;
 
+#include "xpm-ximage.h"
+#include "../images/sea-texture.xpm"
+
+static void
+parse_image_data(ModeInfo *mi)
+{
+  atlantisstruct *ap = &atlantis[MI_SCREEN(mi)];
+  ap->texture = xpm_to_ximage (mi->dpy,
+                              mi->xgwa.visual,
+                              mi->xgwa.colormap,
+                              sea_texture);
+}
+
 static void
 InitFishs(atlantisstruct * ap)
 {
@@ -192,8 +218,10 @@ InitFishs(atlantisstruct * ap)
 }
 
 static void
-Init(atlantisstruct * ap)
+Init(ModeInfo *mi)
 {
+       atlantisstruct *ap = &atlantis[MI_SCREEN(mi)];
+
        static float ambient[] =
        {0.1, 0.1, 0.1, 1.0};
        static float diffuse[] =
@@ -214,23 +242,78 @@ Init(atlantisstruct * ap)
        {0.0};
        float       fblue = 0.0, fgreen;
 
-       glFrontFace(GL_CW);
-
-       glDepthFunc(GL_LEQUAL);
-       glEnable(GL_DEPTH_TEST);
-
-       glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
-       glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
-       glLightfv(GL_LIGHT0, GL_POSITION, position);
-       glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
-       glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_localviewer);
-       glEnable(GL_LIGHTING);
-       glEnable(GL_LIGHT0);
-
-       glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
-       glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
-       glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
-       glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
+       glFrontFace(GL_CCW);
+
+        if (ap->wire)
+          {
+            glDisable(GL_DEPTH_TEST);
+            glDisable(GL_CULL_FACE);
+            glDisable(GL_LIGHTING);
+            glDisable(GL_NORMALIZE);
+          }
+        else
+          {
+            glDepthFunc(GL_LEQUAL);
+            glEnable(GL_DEPTH_TEST);
+            glEnable(GL_CULL_FACE);
+            glEnable(GL_NORMALIZE);
+            glShadeModel(GL_SMOOTH);
+
+            glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+            glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+            glLightfv(GL_LIGHT0, GL_POSITION, position);
+            glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+            glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_localviewer);
+            glEnable(GL_LIGHTING);
+            glEnable(GL_LIGHT0);
+
+            glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
+            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
+            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
+            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
+          }
+
+        if (ap->wire || !do_texture)
+          {
+            glDisable(GL_TEXTURE_2D);
+          }
+        else
+          {
+            GLfloat s_plane[] = { 1, 0, 0, 0 };
+            GLfloat t_plane[] = { 0, 0, 1, 0 };
+            GLfloat scale = 0.0005;
+
+            if (!ap->texture)
+              parse_image_data (mi);
+
+            clear_gl_error();
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+                         ap->texture->width, ap->texture->height, 0,
+                         GL_RGBA, GL_UNSIGNED_BYTE,
+                         ap->texture->data);
+            check_gl_error("texture");
+
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+            glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+            glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+            glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
+            glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
+
+            glEnable(GL_TEXTURE_GEN_S);
+            glEnable(GL_TEXTURE_GEN_T);
+            glEnable(GL_TEXTURE_2D);
+
+            glMatrixMode(GL_TEXTURE);
+            glLoadIdentity();
+            glScalef(scale, scale, 1);
+            glMatrixMode(GL_MODELVIEW);
+          }
 
        InitFishs(ap);
 
@@ -361,7 +444,7 @@ init_atlantis(ModeInfo * mi)
 
                reshape_atlantis(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
                glDrawBuffer(GL_BACK);
-               Init(ap);
+               Init(mi);
                AllDisplay(ap);
                glXSwapBuffers(display, window);
 
@@ -392,12 +475,8 @@ draw_atlantis(ModeInfo * mi)
 
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
-       glPushMatrix();
-
-       AllDisplay(ap);
-       Animate(ap);
-
-        glPopMatrix();
+        AllDisplay(ap);
+        Animate(ap);
 
         if (mi->fps_p) do_fps (mi);
        glXSwapBuffers(display, window);
@@ -444,7 +523,7 @@ change_atlantis(ModeInfo * mi)
                return;
 
        glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(ap->glx_context));
-       Init(ap);
+       Init(mi);
 }
 
 #endif /* USE_GL */