/* -*- Mode: C; tab-width: 4 -*- */
/* moebius --- Moebius Strip II, an Escher-like GL scene with ants. */
-#if !defined( lint ) && !defined( SABER )
+#if 0
static const char sccsid[] = "@(#)moebius.c 5.01 2001/03/01 xlockmore";
-
#endif
/*-
* 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 moebius_opts xlockmore_opts
+# define refresh_moebius 0
# define DEFAULTS "*delay: 20000 \n" \
- "*showFPS: False \n" \
- "*wireframe: False \n"
+ "*showFPS: False \n"
# include "xlockmore.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
# include "xlock.h" /* from the xlockmore distribution */
-
#endif /* !STANDALONE */
#ifdef MODE_moebius
-
-#include <GL/glu.h>
#include "e_textures.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[] =
{
- {(char *) "-solidmoebius", (char *) ".moebius.solidmoebius", XrmoptionNoArg, (caddr_t) "on"},
- {(char *) "+solidmoebius", (char *) ".moebius.solidmoebius", XrmoptionNoArg, (caddr_t) "off"},
- {(char *) "-noants", (char *) ".moebius.noants", XrmoptionNoArg, (caddr_t) "on"},
- {(char *) "+noants", (char *) ".moebius.noants", XrmoptionNoArg, (caddr_t) "off"}
+ {"-solidmoebius", ".moebius.solidmoebius", XrmoptionNoArg, "on"},
+ {"+solidmoebius", ".moebius.solidmoebius", XrmoptionNoArg, "off"},
+ {"-ants", ".moebius.drawants", XrmoptionNoArg, "on"},
+ {"+ants", ".moebius.drawants", XrmoptionNoArg, "off"}
};
static argtype vars[] =
{
- {(caddr_t *) & solidmoebius, (char *) "solidmoebius", (char *) "Solidmoebius", (char *) DEF_SOLIDMOEBIUS, t_Bool},
- {(caddr_t *) & noants, (char *) "noants", (char *) "Noants", (char *) DEF_NOANTS, t_Bool}
+ {&solidmoebius, "solidmoebius", "Solidmoebius", DEF_SOLIDMOEBIUS, t_Bool},
+ {&drawants, "drawants", "Drawants", DEF_DRAWANTS, t_Bool}
};
static OptionStruct desc[] =
{
- {(char *) "-/+solidmoebius", (char *) "select between a SOLID or a NET Moebius Strip"},
- {(char *) "-/+noants", (char *) "turn on/off walking ants"}
+ {"-/+solidmoebius", "select between a SOLID or a NET Moebius Strip"},
+ {"-/+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
GLint WindH, WindW;
GLfloat step;
GLfloat ant_position;
+ float ant_step;
GLXContext *glx_context;
-
- GLfloat rotx, roty, rotz; /* current object rotation */
- GLfloat dx, dy, dz; /* current rotational velocity */
- GLfloat ddx, ddy, ddz; /* current rotational acceleration */
- GLfloat d_max; /* max velocity */
-
+ 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;
}
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);
glEnable(GL_LIGHTING);
- ant_step += 0.3;
+ mp->ant_step += 0.3;
return True;
}
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
- if (!noants) {
+ if (drawants) {
/* DRAW BLUE ANT */
glPushMatrix();
glRotatef(mp->ant_position + 180, 0, 0, 1);
#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)];
GL_RGB, GL_UNSIGNED_BYTE, WoodTextureData);
if (status)
{
- const char *s = gluErrorString (status);
+ const char *s = (char *) gluErrorString (status);
fprintf (stderr, "%s: error mipmapping %dx%d texture: %s\n",
progname, WoodTextureWidth, WoodTextureHeight,
(s ? s : "(unknown)"));
-/* lifted from lament.c */
-#define RANDSIGN() ((LRAND() & 1) ? 1 : -1)
-#define FLOATRAND(a) (((double)LRAND() / (double)MAXRAND) * a)
-
-static void
-rotate(GLfloat *pos, GLfloat *v, GLfloat *dv, GLfloat max_v, Bool verbose)
+ENTRYPOINT void
+release_moebius (ModeInfo * mi)
{
- double ppos = *pos;
-
- /* tick position */
- if (ppos < 0)
- ppos = -(ppos + *v);
- else
- ppos += *v;
-
- if (ppos > 1.0)
- ppos -= 1.0;
- else if (ppos < 0)
- ppos += 1.0;
-
- if ((ppos < 0.0) || (ppos > 1.0)) {
- if (verbose) {
- (void) fprintf(stderr, "Weirdness in rotate()\n");
- (void) fprintf(stderr, "ppos = %g\n", ppos);
- }
- return;
- }
-
- *pos = (*pos > 0 ? ppos : -ppos);
+ if (moebius != NULL) {
+ (void) free((void *) moebius);
+ moebius = (moebiusstruct *) NULL;
+ }
+ FreeAllGL(mi);
+}
- /* accelerate */
- *v += *dv;
+ENTRYPOINT Bool
+moebius_handle_event (ModeInfo *mi, XEvent *event)
+{
+ moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
- /* clamp velocity */
- if (*v > max_v || *v < -max_v)
+ if (event->xany.type == ButtonPress &&
+ event->xbutton.button == Button1)
{
- *dv = -*dv;
+ mp->button_down_p = True;
+ gltrackball_start (mp->trackball,
+ event->xbutton.x, event->xbutton.y,
+ MI_WIDTH (mi), MI_HEIGHT (mi));
+ return True;
}
- /* If it stops, start it going in the other direction. */
- else if (*v < 0)
+ else if (event->xany.type == ButtonRelease &&
+ event->xbutton.button == Button1)
{
- if (random() % 4)
- {
- *v = 0;
-
- /* keep going in the same direction */
- if (random() % 2)
- *dv = 0;
- else if (*dv < 0)
- *dv = -*dv;
- }
- else
- {
- /* reverse gears */
- *v = -*v;
- *dv = -*dv;
- *pos = -*pos;
- }
+ mp->button_down_p = False;
+ return True;
}
-
- /* Alter direction of rotational acceleration randomly. */
- if (! (random() % 120))
- *dv = -*dv;
-
- /* Change acceleration very occasionally. */
- if (! (random() % 200))
+ else if (event->xany.type == ButtonPress &&
+ (event->xbutton.button == Button4 ||
+ event->xbutton.button == Button5 ||
+ event->xbutton.button == Button6 ||
+ event->xbutton.button == Button7))
{
- if (*dv == 0)
- *dv = 0.00001;
- else if (random() & 1)
- *dv *= 1.2;
- else
- *dv *= 0.8;
+ gltrackball_mousewheel (mp->trackball, event->xbutton.button, 10,
+ !!event->xbutton.state);
+ 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;
}
-}
-void
-release_moebius(ModeInfo * mi)
-{
- if (moebius != NULL) {
- (void) free((void *) moebius);
- moebius = (moebiusstruct *) NULL;
- }
- FreeAllGL(mi);
+ return False;
}
-void
-init_moebius(ModeInfo * mi)
+
+ENTRYPOINT void
+init_moebius (ModeInfo * mi)
{
moebiusstruct *mp;
mp->step = NRAND(90);
mp->ant_position = NRAND(90);
- mp->rotx = FLOATRAND(1.0) * RANDSIGN();
- mp->roty = FLOATRAND(1.0) * RANDSIGN();
- mp->rotz = FLOATRAND(1.0) * RANDSIGN();
-
- /* bell curve from 0-1.5 degrees, avg 0.75 */
- mp->dx = (FLOATRAND(1) + FLOATRAND(1) + FLOATRAND(1)) / (360*2);
- mp->dy = (FLOATRAND(1) + FLOATRAND(1) + FLOATRAND(1)) / (360*2);
- mp->dz = (FLOATRAND(1) + FLOATRAND(1) + FLOATRAND(1)) / (360*2);
-
- mp->d_max = mp->dx * 2;
-
- mp->ddx = 0.00006 + FLOATRAND(0.00003);
- mp->ddy = 0.00006 + FLOATRAND(0.00003);
- mp->ddz = 0.00006 + FLOATRAND(0.00003);
-
- mp->ddx = 0.00001;
- mp->ddy = 0.00001;
- mp->ddz = 0.00001;
+ {
+ double rot_speed = 0.3;
+ mp->rot = make_rotator (rot_speed, rot_speed, rot_speed, 1, 0, True);
+ mp->trackball = gltrackball_init ();
+ }
if ((mp->glx_context = init_GL(mi)) != NULL) {
}
}
-void
-draw_moebius(ModeInfo * mi)
+ENTRYPOINT void
+draw_moebius (ModeInfo * mi)
{
moebiusstruct *mp;
glTranslatef(0.0, 0.0, -10.0);
+ gltrackball_rotate (mp->trackball);
+
if (!MI_IS_ICONIC(mi)) {
glScalef(Scale4Window * mp->WindH / mp->WindW, Scale4Window, Scale4Window);
} else {
}
{
- GLfloat x = mp->rotx;
- GLfloat y = mp->roty;
- GLfloat z = mp->rotz;
- if (x < 0) x = 1 - (x + 1);
- if (y < 0) y = 1 - (y + 1);
- if (z < 0) z = 1 - (z + 1);
- glRotatef(x * 360, 1.0, 0.0, 0.0);
- glRotatef(y * 360, 0.0, 1.0, 0.0);
- glRotatef(z * 360, 0.0, 0.0, 1.0);
+ double x, y, z;
+ get_rotation (mp->rot, &x, &y, &z, !mp->button_down_p);
+ glRotatef (x * 360, 1.0, 0.0, 0.0);
+ glRotatef (y * 360, 0.0, 1.0, 0.0);
+ glRotatef (z * 360, 0.0, 0.0, 1.0);
}
/* moebius */
glPopMatrix();
- rotate(&mp->rotx, &mp->dx, &mp->ddx, mp->d_max, MI_IS_VERBOSE(mi));
- rotate(&mp->roty, &mp->dy, &mp->ddy, mp->d_max, MI_IS_VERBOSE(mi));
- rotate(&mp->rotz, &mp->dz, &mp->ddz, mp->d_max, MI_IS_VERBOSE(mi));
-
if (MI_IS_FPS(mi)) do_fps (mi);
glFlush();
mp->step += 0.025;
}
-void
-change_moebius(ModeInfo * mi)
+#ifndef STANDALONE
+ENTRYPOINT void
+change_moebius (ModeInfo * mi)
{
moebiusstruct *mp = &moebius[MI_SCREEN(mi)];
glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(mp->glx_context));
pinit();
}
+#endif /* !STANDALONE */
+
+
+XSCREENSAVER_MODULE ("Moebius", moebius)
#endif