From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / glx / moebius.c
index 9052f4bcc6c3e83ff08af3e20484ae960bd5ad5e..80a8246381a171d7c2036ce94e9238187d1ae0d2 100644 (file)
@@ -77,67 +77,79 @@ static const char sccsid[] = "@(#)moebius.c 5.01 2001/03/01 xlockmore";
  * In real OpenGL, PseudoColor DO NOT support texture map (as far as I know).
  */
 
-#ifdef VMS
-#include <X11/Intrinsic.h>
-#endif
-
 #ifdef STANDALONE
 # define MODE_moebius
-# define PROGCLASS                     "Moebius"
-# define HACK_INIT                     init_moebius
-# define HACK_DRAW                     draw_moebius
-# define HACK_RESHAPE          reshape_moebius
-# define HACK_HANDLE_EVENT     moebius_handle_event
-# define EVENT_MASK                    PointerMotionMask
-# define moebius_opts          xlockmore_opts
+# define refresh_moebius 0
+# define release_moebius 0
 # define DEFAULTS                      "*delay:                20000   \n"                     \
                                                        "*showFPS:      False   \n"                     \
-                                                       "*wireframe:    False   \n"
+                                                       "*suppressRotationAnimation: True\n" \
+
 # include "xlockmore.h"                /* from the xscreensaver distribution */
 #else /* !STANDALONE */
 # include "xlock.h"            /* from the xlockmore distribution */
-
 #endif /* !STANDALONE */
 
-#ifdef MODE_moebius
+#ifdef HAVE_JWXYZ
+# include "jwxyz.h"
+#else
+# include <X11/Xlib.h>
+# include <GL/gl.h>
+# include <GL/glu.h>
+#endif
 
+#ifdef HAVE_JWZGLES
+# include "jwzgles.h"
+#endif /* HAVE_JWZGLES */
 
-#include <GL/glu.h>
+#ifdef MODE_moebius
+
+#if 0 /* Hey, this never actually used the texture at all! */
+#if 0
 #include "e_textures.h"
+#else
+#include "xpm-ximage.h"
+#include "../images/wood.xpm"
+#endif
+#endif /* 0 */
+
+#include "sphere.h"
+#include "tube.h"
+
 #include "rotator.h"
 #include "gltrackball.h"
 
 #define DEF_SOLIDMOEBIUS  "False"
-#define DEF_NOANTS  "False"
+#define DEF_DRAWANTS  "True"
 
 static int  solidmoebius;
-static int  noants;
+static int  drawants;
 
 static XrmOptionDescRec opts[] =
 {
   {"-solidmoebius", ".moebius.solidmoebius", XrmoptionNoArg, "on"},
   {"+solidmoebius", ".moebius.solidmoebius", XrmoptionNoArg, "off"},
-  {"-noants", ".moebius.noants", XrmoptionNoArg, "on"},
-  {"+noants", ".moebius.noants", XrmoptionNoArg, "off"}
+  {"-ants", ".moebius.drawants", XrmoptionNoArg, "on"},
+  {"+ants", ".moebius.drawants", XrmoptionNoArg, "off"}
 };
 static argtype vars[] =
 {
   {&solidmoebius, "solidmoebius", "Solidmoebius", DEF_SOLIDMOEBIUS, t_Bool},
-  {&noants, "noants", "Noants", DEF_NOANTS, t_Bool}
+  {&drawants, "drawants", "Drawants", DEF_DRAWANTS, t_Bool}
 
 };
 static OptionStruct desc[] =
 {
        {"-/+solidmoebius", "select between a SOLID or a NET Moebius Strip"},
-       {"-/+noants", "turn on/off walking ants"}
+       {"-/+drawants", "turn on/off walking ants"}
 };
 
-ModeSpecOpt moebius_opts =
+ENTRYPOINT ModeSpecOpt moebius_opts =
 {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
 
 #ifdef USE_MODULES
 ModStruct   moebius_description =
-{"moebius", "init_moebius", "draw_moebius", "release_moebius",
+{"moebius", "init_moebius", "draw_moebius", (char *) NULL,
  "draw_moebius", "change_moebius", (char *) NULL, &moebius_opts,
  1000, 1, 1, 1, 4, 1.0, "",
  "Shows Moebius Strip II, an Escher-like GL scene with ants", 0, NULL};
@@ -163,51 +175,33 @@ typedef struct {
        GLint       WindH, WindW;
        GLfloat     step;
        GLfloat     ant_position;
+       float       ant_step;
        GLXContext *glx_context;
     rotator    *rot;
     trackball_state *trackball;
     Bool        button_down_p;
 } moebiusstruct;
 
-static float front_shininess[] =
-{60.0};
-static float front_specular[] =
-{0.7, 0.7, 0.7, 1.0};
-static float ambient[] =
-{0.0, 0.0, 0.0, 1.0};
-static float diffuse[] =
-{1.0, 1.0, 1.0, 1.0};
-static float position0[] =
-{1.0, 1.0, 1.0, 0.0};
-static float position1[] =
-{-1.0, -1.0, 1.0, 0.0};
-static float lmodel_ambient[] =
-{0.5, 0.5, 0.5, 1.0};
-static float lmodel_twoside[] =
-{GL_TRUE};
-
-static float MaterialRed[] =
-{0.7, 0.0, 0.0, 1.0};
-static float MaterialGreen[] =
-{0.1, 0.5, 0.2, 1.0};
-static float MaterialBlue[] =
-{0.0, 0.0, 0.7, 1.0};
-static float MaterialCyan[] =
-{0.2, 0.5, 0.7, 1.0};
-static float MaterialYellow[] =
-{0.7, 0.7, 0.0, 1.0};
-static float MaterialMagenta[] =
-{0.6, 0.2, 0.5, 1.0};
-static float MaterialWhite[] =
-{0.7, 0.7, 0.7, 1.0};
-static float MaterialGray[] =
-{0.2, 0.2, 0.2, 1.0};
-static float MaterialGray5[] =
-{0.5, 0.5, 0.5, 1.0};
-static float MaterialGray6[] =
-{0.6, 0.6, 0.6, 1.0};
-static float MaterialGray8[] =
-{0.8, 0.8, 0.8, 1.0};
+static const float front_shininess[] = {60.0};
+static const float front_specular[] = {0.7, 0.7, 0.7, 1.0};
+static const float ambient[] = {0.0, 0.0, 0.0, 1.0};
+static const float diffuse[] = {1.0, 1.0, 1.0, 1.0};
+static const float position0[] = {1.0, 1.0, 1.0, 0.0};
+static const float position1[] = {-1.0, -1.0, 1.0, 0.0};
+static const float lmodel_ambient[] = {0.5, 0.5, 0.5, 1.0};
+static const float lmodel_twoside[] = {GL_TRUE};
+
+static const float MaterialRed[] = {0.7, 0.0, 0.0, 1.0};
+static const float MaterialGreen[] = {0.1, 0.5, 0.2, 1.0};
+static const float MaterialBlue[] = {0.0, 0.0, 0.7, 1.0};
+static const float MaterialCyan[] = {0.2, 0.5, 0.7, 1.0};
+static const float MaterialYellow[] = {0.7, 0.7, 0.0, 1.0};
+static const float MaterialMagenta[] = {0.6, 0.2, 0.5, 1.0};
+static const float MaterialWhite[] = {0.7, 0.7, 0.7, 1.0};
+static const float MaterialGray[] = {0.2, 0.2, 0.2, 1.0};
+static const float MaterialGray5[] = {0.5, 0.5, 0.5, 1.0};
+static const float MaterialGray6[] = {0.6, 0.6, 0.6, 1.0};
+static const float MaterialGray8[] = {0.8, 0.8, 0.8, 1.0};
 
 static moebiusstruct *moebius = (moebiusstruct *) NULL;
 
@@ -216,6 +210,7 @@ static moebiusstruct *moebius = (moebiusstruct *) NULL;
 static Bool
 mySphere(float radius)
 {
+#if 0
        GLUquadricObj *quadObj;
 
        if ((quadObj = gluNewQuadric()) == 0)
@@ -223,12 +218,19 @@ mySphere(float radius)
        gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
        gluSphere(quadObj, radius, 16, 16);
        gluDeleteQuadric(quadObj);
+#else
+    glPushMatrix();
+    glScalef (radius, radius, radius);
+    unit_sphere (16, 16, False);
+    glPopMatrix();
+#endif
        return True;
 }
 
 static Bool
 myCone(float radius)
 {
+#if 0
        GLUquadricObj *quadObj;
 
        if ((quadObj = gluNewQuadric()) == 0)
@@ -236,19 +238,24 @@ myCone(float radius)
        gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
        gluCylinder(quadObj, radius, 0, radius * 3, 8, 1);
        gluDeleteQuadric(quadObj);
+#else
+    cone (0, 0, 0,
+          0, 0, radius * 3,
+          radius, 0,
+          8, True, True, False);
+#endif
        return True;
 }
 
 static Bool
-draw_moebius_ant(moebiusstruct * mp, float *Material, int mono)
+draw_moebius_ant(moebiusstruct * mp, const float *Material, int mono)
 {
-       static float ant_step = 0;
-       float       cos1 = cos(ant_step);
-       float       cos2 = cos(ant_step + 2 * Pi / 3);
-       float       cos3 = cos(ant_step + 4 * Pi / 3);
-       float       sin1 = sin(ant_step);
-       float       sin2 = sin(ant_step + 2 * Pi / 3);
-       float       sin3 = sin(ant_step + 4 * Pi / 3);
+       float       cos1 = cos(mp->ant_step);
+       float       cos2 = cos(mp->ant_step + 2 * Pi / 3);
+       float       cos3 = cos(mp->ant_step + 4 * Pi / 3);
+       float       sin1 = sin(mp->ant_step);
+       float       sin2 = sin(mp->ant_step + 2 * Pi / 3);
+       float       sin3 = sin(mp->ant_step + 4 * Pi / 3);
 
        if (mono)
                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialGray5);
@@ -397,7 +404,7 @@ draw_moebius_ant(moebiusstruct * mp, float *Material, int mono)
 
        glEnable(GL_LIGHTING);
 
-       ant_step += 0.3;
+       mp->ant_step += 0.3;
        return True;
 }
 
@@ -435,6 +442,10 @@ draw_moebius_strip(ModeInfo * mi)
 
        float       Cx, Cy, Cz;
 
+#ifdef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */
+    solidmoebius = True;
+#endif
+
        if (solidmoebius) {
                glBegin(GL_QUAD_STRIP);
                Phi = 0;
@@ -500,7 +511,7 @@ draw_moebius_strip(ModeInfo * mi)
                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        }
 
-       if (!noants) {
+       if (drawants) {
                /* DRAW BLUE ANT */
                glPushMatrix();
                glRotatef(mp->ant_position + 180, 0, 0, 1);
@@ -549,8 +560,8 @@ draw_moebius_strip(ModeInfo * mi)
 #undef MoebiusDivisions
 #undef MoebiusTransversals
 
-void
-reshape_moebius(ModeInfo * mi, int width, int height)
+ENTRYPOINT void
+reshape_moebius (ModeInfo * mi, int width, int height)
 {
        moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
 
@@ -572,12 +583,10 @@ reshape_moebius(ModeInfo * mi, int width, int height)
 }
 
 static void
-pinit(void)
+pinit(ModeInfo *mi)
 {
-    int status;
+  /* int status; */
        glClearDepth(1.0);
-       glClearColor(0.0, 0.0, 0.0, 1.0);
-
        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
        glLightfv(GL_LIGHT0, GL_POSITION, position0);
@@ -596,11 +605,13 @@ pinit(void)
        /* moebius */
        glShadeModel(GL_SMOOTH);
        glEnable(GL_DEPTH_TEST);
-       glDisable(GL_TEXTURE_2D);
        glDisable(GL_CULL_FACE);
 
+#if 0
+       glEnable(GL_TEXTURE_2D);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 
+#if 0
     clear_gl_error();
        status = gluBuild2DMipmaps(GL_TEXTURE_2D, 3,
                                WoodTextureWidth, WoodTextureHeight,
@@ -614,72 +625,55 @@ pinit(void)
         exit (1);
       }
     check_gl_error("mipmapping");
+#else
+    {
+      XImage *img = xpm_to_ximage (mi->dpy,
+                                   mi->xgwa.visual,
+                                   mi->xgwa.colormap,
+                                   wood_texture);
+         glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA,
+                    img->width, img->height, 0,
+                    GL_RGBA,
+                    /* GL_UNSIGNED_BYTE, */
+                    GL_UNSIGNED_INT_8_8_8_8_REV,
+                    img->data);
+      check_gl_error("texture");
+      XDestroyImage (img);
+    }
+#endif
 
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+#endif
 
        glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_shininess);
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_specular);
 }
 
 
-
-void
-release_moebius(ModeInfo * mi)
-{
-       if (moebius != NULL) {
-               (void) free((void *) moebius);
-               moebius = (moebiusstruct *) NULL;
-       }
-       FreeAllGL(mi);
-}
-
-Bool
+ENTRYPOINT Bool
 moebius_handle_event (ModeInfo *mi, XEvent *event)
 {
   moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
 
-  if (event->xany.type == ButtonPress &&
-      event->xbutton.button & Button1)
-    {
-      mp->button_down_p = True;
-      gltrackball_start (mp->trackball,
-                         event->xbutton.x, event->xbutton.y,
-                         MI_WIDTH (mi), MI_HEIGHT (mi));
-      return True;
-    }
-  else if (event->xany.type == ButtonRelease &&
-           event->xbutton.button & Button1)
-    {
-      mp->button_down_p = False;
-      return True;
-    }
-  else if (event->xany.type == MotionNotify &&
-           mp->button_down_p)
-    {
-      gltrackball_track (mp->trackball,
-                         event->xmotion.x, event->xmotion.y,
-                         MI_WIDTH (mi), MI_HEIGHT (mi));
-      return True;
-    }
+  if (gltrackball_event_handler (event, mp->trackball,
+                                 MI_WIDTH (mi), MI_HEIGHT (mi),
+                                 &mp->button_down_p))
+    return True;
 
   return False;
 }
 
 
-void
-init_moebius(ModeInfo * mi)
+ENTRYPOINT void
+init_moebius (ModeInfo * mi)
 {
        moebiusstruct *mp;
 
-       if (moebius == NULL) {
-               if ((moebius = (moebiusstruct *) calloc(MI_NUM_SCREENS(mi),
-                                           sizeof (moebiusstruct))) == NULL)
-                       return;
-       }
+       MI_INIT (mi, moebius, NULL);
        mp = &moebius[MI_SCREEN(mi)];
        mp->step = NRAND(90);
        mp->ant_position = NRAND(90);
@@ -687,21 +681,21 @@ init_moebius(ModeInfo * mi)
     {
       double rot_speed = 0.3;
       mp->rot = make_rotator (rot_speed, rot_speed, rot_speed, 1, 0, True);
-      mp->trackball = gltrackball_init ();
+      mp->trackball = gltrackball_init (True);
     }
 
        if ((mp->glx_context = init_GL(mi)) != NULL) {
 
                reshape_moebius(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
                glDrawBuffer(GL_BACK);
-               pinit();
+               pinit(mi);
        } else {
                MI_CLEARWINDOW(mi);
        }
 }
 
-void
-draw_moebius(ModeInfo * mi)
+ENTRYPOINT void
+draw_moebius (ModeInfo * mi)
 {
        moebiusstruct *mp;
 
@@ -723,6 +717,7 @@ draw_moebius(ModeInfo * mi)
 
        glPushMatrix();
 
+
        glTranslatef(0.0, 0.0, -10.0);
 
     gltrackball_rotate (mp->trackball);
@@ -733,6 +728,18 @@ draw_moebius(ModeInfo * mi)
                glScalef(Scale4Iconic * mp->WindH / mp->WindW, Scale4Iconic, Scale4Iconic);
        }
 
+# ifdef HAVE_MOBILE    /* Keep it the same relative size when rotated. */
+    {
+      GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+      int o = (int) current_device_rotation();
+      if (o != 0 && o != 180 && o != -180) {
+        glScalef (1/h, h, 1);  /* #### not quite right */
+        h = 1.7;
+        glScalef (h, h, h);
+      }
+    }
+# endif
+
     {
       double x, y, z;
       get_rotation (mp->rot, &x, &y, &z, !mp->button_down_p);
@@ -743,7 +750,7 @@ draw_moebius(ModeInfo * mi)
 
        /* moebius */
        if (!draw_moebius_strip(mi)) {
-               release_moebius(mi);
+               MI_ABORT(mi);
                return;
        }
 
@@ -757,8 +764,9 @@ draw_moebius(ModeInfo * mi)
        mp->step += 0.025;
 }
 
-void
-change_moebius(ModeInfo * mi)
+#ifndef STANDALONE
+ENTRYPOINT void
+change_moebius (ModeInfo * mi)
 {
        moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
 
@@ -768,5 +776,9 @@ change_moebius(ModeInfo * mi)
        glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(mp->glx_context));
        pinit();
 }
+#endif /* !STANDALONE */
+
+
+XSCREENSAVER_MODULE ("Moebius", moebius)
 
 #endif