/* -*- Mode: C; tab-width: 4 -*- */
+/* vim: set ai ts=4 sw=4: */
-#if !defined( lint ) && !defined( SABER )
+#if 0
/*static const char sccsid[] = "@(#)gleidescope.c 1.0 03/06/27 xlockmore";*/
#endif
-/* enable -grab switch */
-/*#define GRAB*/
+/* enable -grab switch for animations */
+#undef GRAB
+
+#undef DISPLAY_TEXTURE
/*-
* Permission to use, copy, modify, and distribute this software and its
* no preference is given.
* Made grid slightly bigger so you can't see
* the edge when zooming and moving.
+ * 20061226 1.4 acd Now uses GL Display Lists.
+ * 20070318 1.5 acd Generates textures.
+ * Fixed texture size problem (and introduced another).
+ * 20070412 1.6 acd Textures now have independant sizes.
+ * 20070413 1.7 acd Added Lissajous movement pattern.
+ * 20070414 1.8 acd Added corners movement pattern.
+ * 20080319 1.9 acd Changes to arguments for saner gleidescope.xml.
+ *
+ * TODO
+ * generate textures myself - render random shapes to 256x256 texture. (done)
+ * lower res for checks and random - use 256 and 4x4 or 8x8 pixels. (disabled for now)
+ * gnome-saver doesn't let you specify source directory so add that to this.
+ * image loading routine is too slow - rotation grinds to a halt - stop using it. (better in version 5)
+ * image loading also looks bad for non-square images - edges are black. (fixed)
+ * possible to see edge of the world on widescreen terminals - use larger grid and hidden hex removal?
+ * fading textures may have different max_tx - use two sets. (done)
+ * choice of movement patterns. (3 implemented, chooseable at compile time)
+ * look into rangle and tangle.
*/
-#include <X11/Intrinsic.h>
-#include "colors.h"
-
-#include "xpm-ximage.h"
-
/*
**----------------------------------------------------------------------------
** Defines
*/
#ifdef STANDALONE
-# define PROGCLASS "gleidescope"
-# define HACK_INIT init_gleidescope
-# define HACK_DRAW draw_gleidescope
-# define HACK_RESHAPE reshape_gleidescope
-# define HACK_HANDLE_EVENT gleidescope_handle_event
-# define EVENT_MASK PointerMotionMask
-# define gleidescope_opts xlockmore_opts
# define DEFAULTS \
"*delay: 20000 \n" \
"*showFPS: False \n" \
- "*move: False \n" \
- "*rotate: False \n" \
- "*zoom: False \n" \
- "*image: DEFAULT \n" \
- "*size: -1 \n" \
- "*duration: 30 \n" \
- "*useSHM: True \n"
+ "*size: 0 \n" \
+ "*useSHM: True \n" \
+ "*suppressRotationAnimation: True\n" \
+# define refresh_gleidescope 0
+# define release_gleidescope 0
# include "xlockmore.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
# include "xlock.h" /* from the xlockmore distribution */
#ifdef USE_GL
-#include <GL/glu.h>
+#include "colors.h"
+#include "xpm-ximage.h"
+#include "grab-ximage.h"
+
+#ifdef GRAB
+void grab_frame(Display *display, Window window);
+#endif
/* acd TODO should all these be in gleidestruct? */
+/* they can't be, because of the idiotic way the xlockmore "argtype vars"
+ interface works. -jwz */
#ifdef GRAB
static Bool grab; /* grab images */
#endif
static Bool nomove; /* no moving camera */
static Bool rotate; /* rotate in place */
static Bool norotate; /* no rotate in place */
-static int size = -1; /* size */
static Bool zoom; /* zooming camera */
static Bool nozoom; /* no zooming camera */
-static char *image; /* name of texture to load */
+static char *image_str; /* name of texture to load */
static int duration; /* length of time to display grabbed image */
-#define MAX_TANGLE_VEL 2.0
+#define MAX_CAM_SPEED 1.0
+#define MAX_ANGLE_VEL 1.0
+#define INITIAL_ANGLE_VEL 0.2
+#define INITIAL_ANGLE_ACC 0.001
+#define TWISTING_PROBABILITY 1000 /* 1 in ... of change of acceleration */
-static float tangle = 0; /* texture angle */
-static float tangle_vel = 0.0; /* texture velocity */
-static float tangle_acc = 0.0; /* texture acceleration */
+#define RADIANS (M_PI / 180)
+#define ANGLE_120 (M_PI * 2 / 3)
+#define ANGLE_240 (M_PI * 4 / 3)
-#define MAX_RANGLE_VEL 1.5
+#define DEF_GRAB "False"
+#define DEF_MOVE "False"
+#define DEF_NOMOVE "False"
+#define DEF_ROTATE "False"
+#define DEF_NOROTATE "False"
+#define DEF_ZOOM "False"
+#define DEF_NOZOOM "False"
+#define DEF_IMAGE "DEFAULT"
+#define DEF_DURATION "30"
-static float rangle = 0; /* rotate angle */
-static float rangle_vel = 0.0; /* rotate velocity */
-static float rangle_acc = 0.0; /* rotate acceleration */
static XrmOptionDescRec opts[] =
{
{"-no-move", ".gleidescope.nomove", XrmoptionNoArg, "true"},
{"-rotate", ".gleidescope.rotate", XrmoptionNoArg, "true"},
{"-no-rotate", ".gleidescope.norotate", XrmoptionNoArg, "true"},
- /*{"-size", ".gleidescope.size", XrmoptionNoArg, "-1"},*/
{"-zoom", ".gleidescope.zoom", XrmoptionNoArg, "true"},
{"-no-zoom", ".gleidescope.nozoom", XrmoptionNoArg, "true"},
{"-image", ".gleidescope.image", XrmoptionSepArg, "DEFAULT"},
static argtype vars[] = {
#ifdef GRAB
- {&grab, "grab", "Grab", "False", t_Bool},
+ {&grab, "grab", "Grab", DEF_GRAB, t_Bool},
#endif
- {&move, "move", "Move", "False", t_Bool},
- {&nomove, "nomove", "noMove", "False", t_Bool},
- {&rotate, "rotate", "Rotate", "False", t_Bool},
- {&norotate, "norotate", "noRotate", "False", t_Bool},
- /*{&size, "size", "Size", "-1", t_Int},*/
- {&zoom, "zoom", "Zoom", "False", t_Bool},
- {&nozoom, "nozoom", "noZoom", "False", t_Bool},
- {&image, "image", "Image", "DEFAULT", t_String},
- {&duration, "duration", "Duration", "30", t_Int},
+ {&move, "move", "Move", DEF_MOVE, t_Bool},
+ {&nomove, "nomove", "noMove", DEF_NOMOVE, t_Bool},
+ {&rotate, "rotate", "Rotate", DEF_ROTATE, t_Bool},
+ {&norotate, "norotate", "noRotate", DEF_NOROTATE, t_Bool},
+ {&zoom, "zoom", "Zoom", DEF_ZOOM, t_Bool},
+ {&nozoom, "nozoom", "noZoom", DEF_NOZOOM, t_Bool},
+ {&image_str, "image", "Image", DEF_IMAGE, t_String},
+ {&duration, "duration", "Duration", DEF_DURATION, t_Int},
};
static OptionStruct desc[] = {
{"-no-move", "camera won't move"},
{"-rotate", "camera will rotate"},
{"-no-rotate", "camera won't rotate"},
- /*{"-size", "size of the hexagons (1-10)"},*/
{"-zoom", "camera will zoom"},
{"-no-zoom", "camera won't zoom"},
{"-image", "xpm / xbm image file to use for texture"},
{"-duration", "length of time texture will be used"},
};
-ModeSpecOpt gleidescope_opts = {
+ENTRYPOINT ModeSpecOpt gleidescope_opts = {
sizeof opts / sizeof opts[0], opts,
sizeof vars / sizeof vars[0], vars,
desc
#ifdef USE_MODULES
ModStruct gleidescope_description = {
- "gleidescope", "init_gleidescope", "draw_gleidescope", "release_gleidescope",
+ "gleidescope", "init_gleidescope", "draw_gleidescope", NULL,
"draw_gleidescope", "init_gleidescope", NULL, &gleidescope_opts,
1000, 1, 2, 1, 4, 1.0, "",
"GL Kaleidescope", 0, NULL};
GLfloat z;
} vectorf;
+typedef struct {
+ GLfloat x;
+ GLfloat y;
+} vector2f;
+
+typedef struct {
+ GLuint id; /* opengl texture id */
+ GLfloat width, height; /* texture width and height */
+ GLfloat min_tx, min_ty; /* minimum texture sizes */
+ GLfloat max_tx, max_ty; /* maximum texture sizes */
+ time_t start_time;
+ Bool button_down_p;
+ Bool mipmap_p;
+ Bool waiting_for_image_p;
+ /* r_phase is for triangle rotation speed */
+ GLfloat x_period, y_period, r_period;
+ GLfloat x_phase, y_phase, r_phase;
+} texture;
+
#define MAX_FADE 500 /* number of fade cycles */
typedef struct {
float tic;
GLXContext *glx_context;
Window window;
- GLfloat max_tx, max_ty; /* maximum texture sizes */
- GLuint textures[2]; /* texture handles */
- GLuint visible; /* texture handle for new texture */
+ texture textures[2]; /* texture handles */
+ GLuint visible; /* index for current texture */
GLint fade;
time_t start_time;
Bool button_down_p;
+
+ int size;
+ int list;
+
+ float tangle; /* texture angle (degrees) */
+ float tangle_vel; /* texture velocity */
+ float tangle_acc; /* texture acceleration */
+
+ float rangle; /* rotate angle */
+ float rangle_vel; /* rotate velocity */
+ float rangle_acc; /* rotate acceleration */
+
+ /* mouse */
+ int xstart;
+ int ystart;
+ double xmouse;
+ double ymouse;
+
+ Bool mipmap_p;
+ Bool waiting_for_image_p;
+
} gleidestruct;
+#define frandrange(x, y) (x + frand(y - x))
+
#define XOFFSET (0.8660254f) /* sin 60' */
#define YOFFSET (1.5000000f) /* cos 60' + 1 */
int i, x, y;
- size--;
+ gp->size--;
- i = size;
+ i = gp->size;
for (y = -size ; y <= size ; y++) {
for (x = -i ; x <= i ; x += 2) {
printf("{XOFFSET * %d, YOFFSET * %d, 0},\n", x, y);
}
#endif
-hex_t hex[] = {
+/* acd - this is terrible - 120+ hexes */
+static const hex_t hex[] = {
/* edges of size 7 */
/* number of hexagons required to cover screen depends on camera distance */
/* at a distance of 10 this is just about enough. */
static gleidestruct *gleidescope = NULL;
+#if 0
/*
*load defaults in config structure
*/
-void setdefaultconfig(void)
+static void setdefaultconfig(void)
{
#ifdef GRAB
grab = False;
zoom = False;
image = NULL;
}
+#endif
-static int xstart;
-static int ystart;
-static double xmouse = 0.0;
-static double ymouse = 0.0;
-
-Bool
+ENTRYPOINT Bool
gleidescope_handle_event(ModeInfo *mi, XEvent *event)
{
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
printf("event:%d\n", event->xany.type);
printf("button:%d\n", event->xbutton.button);
*/
- switch(event->xany.type)
- {
- case ButtonPress:
-
+ if (event->xany.type == ButtonPress)
+ {
if (event->xbutton.button == Button1 ||
event->xbutton.button == Button3)
{
/* store initial values of mouse */
- xstart = event->xbutton.x;
- ystart = event->xbutton.y;
+ gp->xstart = event->xbutton.x;
+ gp->ystart = event->xbutton.y;
/* button is down */
gp->button_down_p = True;
return True;
}
#endif
- break;
-
- case ButtonRelease:
-
+ } else if (event->xany.type == ButtonRelease)
+ {
if (event->xbutton.button == Button1 ||
event->xbutton.button == Button3)
{
gp->button_down_p = False;
return True;
}
- break;
-
- case MotionNotify:
-
+ } else if (event->xany.type == MotionNotify)
+ {
if (gp->button_down_p)
{
/* update mouse position */
- xmouse += (double)(event->xmotion.x - xstart) / MI_WIDTH(mi);
- ymouse += (double)(event->xmotion.y - ystart) / MI_HEIGHT(mi);
- xstart = event->xmotion.x;
- ystart = event->xmotion.y;
+ gp->xmouse += (double)(event->xmotion.x - gp->xstart) / MI_WIDTH(mi);
+ gp->ymouse += (double)(event->xmotion.y - gp->ystart) / MI_HEIGHT(mi);
+ gp->xstart = event->xmotion.x;
+ gp->ystart = event->xmotion.y;
return True;
}
- break;
- }
+ }
+ else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event))
+ {
+ gp->start_time = -1;
+ gp->fade = 0;
+ return True;
+ }
return False;
}
-#include "grab-ximage.h"
static void
-getSnapshot(ModeInfo *mi, GLuint name)
+image_loaded_cb (const char *filename, XRectangle *geometry,
+ int image_width, int image_height,
+ int texture_width, int texture_height,
+ void *closure)
+{
+ texture *tp = (texture *) closure;
+
+#if 0
+ gp->max_tx = (GLfloat) image_width / texture_width;
+ gp->max_ty = (GLfloat) image_height / texture_height;
+#endif
+
+ /* new - taken from flipscreen */
+ tp->width = texture_width;
+ tp->height = texture_height;
+ tp->min_tx = (GLfloat) geometry->x / tp->width;
+ tp->min_ty = (GLfloat) geometry->y / tp->height;
+ tp->max_tx = (GLfloat) (geometry->x + geometry->width) / tp->width;
+ tp->max_ty = (GLfloat) (geometry->y + geometry->height) / tp->height;
+
+#ifdef DEBUG
+ printf("Image w,h: (%d, %d)\n", image_width, image_height);
+ printf("Texture w,h: (%d, %d)\n", texture_width, texture_height);
+ printf("Geom x,y: (%d, %d)\n", geometry->x, geometry->y);
+ printf("Geom w,h: (%d, %d)\n", geometry->width, geometry->height);
+ printf("Max Tx,Ty: (%f, %f)\n", tp->max_tx, tp->max_ty);
+#endif
+
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ (tp->mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR));
+
+ tp->waiting_for_image_p = False;
+ tp->start_time = time ((time_t *) 0);
+}
+
+static void
+getSnapshot(ModeInfo *mi, texture *texture)
{
- Bool mipmap_p = True;
- int iw, ih, tw, th;
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
+#ifdef DEBUG
+ printf("getSnapshot");
+#endif
+
if (MI_IS_WIREFRAME(mi))
return;
- glBindTexture (GL_TEXTURE_2D, name);
- if (! screen_to_texture (mi->xgwa.screen, mi->window, 0, 0,
- mipmap_p, NULL, NULL, &iw, &ih, &tw, &th))
- exit (1);
+ gp->mipmap_p = True;
+ load_texture_async (mi->xgwa.screen, mi->window,
+ *gp->glx_context, 0, 0, gp->mipmap_p,
+ texture->id, image_loaded_cb, texture);
+ texture->start_time = time((time_t *)0);
+}
- gp->max_tx = (GLfloat) iw / tw;
- gp->max_ty = (GLfloat) ih / th;
+#define TEXTURE_SIZE 256
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- (mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR));
+static void
+plot(unsigned char *buffer, int x, int y, int r, int g, int b, int a) {
+ int c;
+ if (x < 0 || x >= TEXTURE_SIZE || y < 0 || y >= TEXTURE_SIZE) {
+ return;
+ }
+ c = ((x * TEXTURE_SIZE) + y) * 4;
+ /*printf("(%d,%d)[%d]\n", x, y, c);*/
+ buffer[c + 0] = r;
+ buffer[c + 1] = g;
+ buffer[c + 2] = b;
+ buffer[c + 3] = a;
+}
+
+#if 0
+static void
+plot2(unsigned char *buffer, int x, int y, int r, int g, int b, int a) {
+ int c;
+ if (x < 0 || x >= TEXTURE_SIZE || y < 0 || y >= TEXTURE_SIZE) {
+ return;
+ }
+ c = ((x * TEXTURE_SIZE) + y) * 4;
+ /*printf("(%d,%d)[%d]\n", x, y, c);*/
+ buffer[c + 0] = r;
+ buffer[c + 1] = g;
+ buffer[c + 2] = b;
+ buffer[c + 3] = a;
+
+ if (y + 1 < TEXTURE_SIZE) {
+ buffer[c + 4] = r;
+ buffer[c + 5] = g;
+ buffer[c + 6] = b;
+ buffer[c + 7] = a;
+ }
- /* remember time of last image change */
- gp->start_time = time ((time_t *) 0);
+ if (x + 1 < TEXTURE_SIZE) {
+ c += (TEXTURE_SIZE * 4);
+ buffer[c + 0] = r;
+ buffer[c + 1] = g;
+ buffer[c + 2] = b;
+ buffer[c + 3] = a;
+ if (y + 1 < TEXTURE_SIZE) {
+ buffer[c + 4] = r;
+ buffer[c + 5] = g;
+ buffer[c + 6] = b;
+ buffer[c + 7] = a;
+ }
+ }
}
+#endif
+/* draw geometric shapes to texture */
+/* modifies passed in buffer */
static void
-setup_file_texture (ModeInfo *mi, char *filename, GLuint name)
+draw_shapes (unsigned char *buffer) {
+ int a = 0xff;
+ int x, y, w, h;
+ int i, j;
+ int s;
+ float left, right;
+
+ for (i = 0 ; i < TEXTURE_SIZE * TEXTURE_SIZE * 4 ; i += 4) {
+ buffer[i + 0] = 0x00;
+ buffer[i + 1] = 0x00;
+ buffer[i + 2] = 0x00;
+ buffer[i + 3] = 0xff;
+ }
+
+ for (s = 0 ; s < 25 ; s++) {
+ int shape = random() % 3;
+
+ /* 8 bits */
+ int r = (random() & 0xff);
+ int g = (random() & 0xff);
+ int b = (random() & 0xff);
+
+ switch (shape) {
+ case 0:
+ /* rectangle */
+ x = (random() % TEXTURE_SIZE) - (TEXTURE_SIZE / 4); /* top left */
+ y = (random() % TEXTURE_SIZE) - (TEXTURE_SIZE / 4);
+ w = 10 + random() % (TEXTURE_SIZE / 4); /* size */
+ h = 10 + random() % (TEXTURE_SIZE / 4);
+#ifdef DEBUG
+ printf("Rectangle: (%d, %d)(%d, %d)\n", x, y, w, h);
+#endif
+ if (x < 0) {
+ x = 0;
+ }
+ if (y < 0) {
+ y = 0;
+ }
+ for (i = x ; i < x + w && i < TEXTURE_SIZE; i++) {
+ for (j = y ; j < y + h && j < TEXTURE_SIZE; j++) {
+ plot(buffer, i, j, r, g, b, a);
+ }
+ }
+ break;
+
+ case 1:
+ /* circle */
+ x = random() % TEXTURE_SIZE; /* centre */
+ y = random() % TEXTURE_SIZE;
+ h = 10 + random() % (TEXTURE_SIZE / 8); /* radius */
+#ifdef DEBUG
+ printf("Circle: %d, %d, %d\n", x, y, h);
+#endif
+ for (i = 0 ; i < h ; i++) {
+ int xdist = i * i;
+ for (j = 0 ; j < h ; j++) {
+ int ydist = j * j;
+ /*
+ printf("xdist: %d\n", xdist);
+ printf("ydist: %d\n", ydist);
+ printf("radius: %d\n", h * h);
+ */
+ if ((xdist + ydist) < (h * h)) {
+ plot(buffer, x + i, y + j, r, b, g, a);
+ /* check we haven't already done these */
+ if (j != 0) {
+ plot(buffer, x + i, y - j, r, b, g, a);
+ }
+ if (i != 0) {
+ plot(buffer, x - i, y + j, r, b, g, a);
+ if (j != 0) {
+ plot(buffer, x - i, y - j, r, b, g, a);
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case 2:
+ /* triangle */
+ x = random() % TEXTURE_SIZE; /* top */
+ y = random() % TEXTURE_SIZE;
+ h = 10 + random() % (TEXTURE_SIZE / 4); /* height */
+#ifdef DEBUG
+ printf("Triangle: %d, %d, %d\n", x, y, h);
+#endif
+ left = x;
+ right = x;
+ for (i = 0 ; i < h ; i++) {
+ for (j = left ; j < right ; j++) {
+ plot(buffer, j, y + i, r, g, b, a);
+ }
+ left -= .5;
+ right += .5;
+ }
+ break;
+ }
+ }
+}
+
+static void
+setup_random_texture (ModeInfo *mi, texture *texture)
+{
+ int width = 0, height = 0;
+ char buf[1024];
+ unsigned char *my_data = NULL;
+#if 0
+ int i, j, c;
+ int style;
+ int r0, g0, b0, a0, r1, g1, b1, a1;
+#endif
+
+#ifdef DEBUG
+ printf("RandomTexture\n");
+#endif
+
+ /* use this texture */
+ glBindTexture(GL_TEXTURE_2D, texture->id);
+
+ clear_gl_error();
+
+ /*
+ * code for various generated patterns - noise, stripes, checks etc.
+ * random geometric shapes looked the best.
+ */
+
+#if 0
+ style = random() & 0x3;
+ r0 = random() & 0xff;
+ g0 = random() & 0xff;
+ b0 = random() & 0xff;
+ a0 = 0xff;
+ r1 = random() & 0xff;
+ g1 = random() & 0xff;
+ b1 = random() & 0xff;
+ a1 = 0xff;
+
+ switch (style) {
+ case 0: /* random */
+ printf("Random0\n");
+ height = width = TEXTURE_SIZE;
+ my_data = (void *)malloc(width * height * 4);
+ for (i = 0 ; i < width ; i += 2) {
+ for (j = 0 ; j < height ; j += 2) {
+ r0 = random() & 0xff;
+ g0 = random() & 0xff;
+ b0 = random() & 0xff;
+ a0 = 0xff;
+ plot2(my_data, i, j, r0, g0, b0, a0);
+ }
+ }
+ break;
+
+ case 1: /* shapes */
+#endif
+#ifdef DEBUG
+ printf("Shapes\n");
+#endif
+ height = width = TEXTURE_SIZE;
+ my_data = (void *)malloc(width * height * 4);
+ draw_shapes(my_data);
+#if 0
+ break;
+
+ case 2: /* check */
+ printf("Check\n");
+ height = width = TEXTURE_SIZE;
+ my_data = (void *)malloc(width * height * 4);
+ for (i = 0 ; i < height ; i += 2) {
+ for (j = 0 ; j < width ; j += 2) {
+ if (((i + j) & 0x3) == 0) {
+ plot2(my_data, i, j, r0, g0, b0, a0);
+ } else {
+ plot2(my_data, i, j, r1, g1, b1, a1);
+ }
+ }
+ }
+ break;
+
+ case 3: /* random stripes */
+ printf("Stripes 2\n");
+ height = width = TEXTURE_SIZE;
+ my_data = (void *)malloc(width * height * 4);
+ for (i = 0 ; i < height ; i += 2) {
+ r0 = random() & 0xff;
+ g0 = random() & 0xff;
+ b0 = random() & 0xff;
+ a0 = 0xff;
+ for (j = 0 ; j < width ; j += 2) {
+ plot2(my_data, i, j, r0, g0, b0, a0);
+ }
+ }
+ break;
+ }
+#endif
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ width, height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, my_data);
+ sprintf (buf, "random texture: (%dx%d)",
+ width, height);
+ check_gl_error(buf);
+
+ /* setup parameters for texturing */
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
+
+ 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);
+ if (random() & 0x1) {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ } else {
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+
+ if (my_data != NULL) {
+ free(my_data);
+ my_data = NULL;
+ }
+
+ /* use full texture */
+ /* acd - was 1.0 */
+ texture->min_tx = 0.0;
+ texture->max_tx = 2.0;
+ texture->min_ty = 0.0;
+ texture->max_ty = 2.0;
+ texture->start_time = time((time_t *)0);
+}
+
+static Bool
+setup_file_texture (ModeInfo *mi, char *filename, texture *texture)
{
Display *dpy = mi->dpy;
Visual *visual = mi->xgwa.visual;
Colormap cmap = mi->xgwa.colormap;
XImage *image = xpm_file_to_ximage (dpy, visual, cmap, filename);
+ if (!image) return False;
+
+#ifdef DEBUG
+ printf("FileTexture\n");
+#endif
/* use this texture */
- glBindTexture(GL_TEXTURE_2D, name);
+ glBindTexture(GL_TEXTURE_2D, texture->id);
clear_gl_error();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ /* use full texture */
+ texture->min_tx = 0.0;
+ texture->max_tx = 1.0;
+ texture->min_ty = 0.0;
+ texture->max_ty = 1.0;
+ texture->start_time = time((time_t *)0);
+ return True;
}
static void
-setup_texture(ModeInfo * mi, GLuint id)
+setup_texture(ModeInfo * mi, texture *texture)
{
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
- if (!image || !*image || !strcmp(image, "DEFAULT")) {
- /* no image specified - grab screen */
- getSnapshot(mi, id);
- /* max_tx and max_ty set in getSnapshot() */
+ if (!image_str || !*image_str || !strcmp(image_str, "DEFAULT")) {
+ BUILTIN:
+ /* no image specified - use system settings */
+#ifdef DEBUG
+ printf("SetupTexture: get_snapshot\n");
+#endif
+ getSnapshot(mi, texture);
} else {
- /* use supplied image file */
- setup_file_texture(mi, image, id);
-
- /* set tx params to use whole image */
- gp->max_tx = 1.0f;
- gp->max_ty = 1.0f;
+ if (strcmp(image_str, "GENERATE") == 0) {
+#ifdef DEBUG
+ printf("SetupTexture: random_texture\n");
+#endif
+ setup_random_texture(mi, texture);
+ } else {
+ /* use supplied image file */
+#ifdef DEBUG
+ printf("SetupTexture: file_texture\n");
+#endif
+ if (! setup_file_texture(mi, image_str, texture))
+ goto BUILTIN;
+ }
}
+ /* copy start time from texture */
+ gp->start_time = texture->start_time;
check_gl_error("texture initialization");
- /* Need to flip the texture top for bottom for some reason. */
- glMatrixMode (GL_TEXTURE);
- glScalef (1, -1, 1);
- glMatrixMode (GL_MODELVIEW);
+ /* acd
+ * resultant loaded image is upside down BUT
+ * it's a kaledescope and half of the hexagon is backwards anyway...
+ */
+
+ /* TODO: values for lissajous movement */
+ texture->x_period = frandrange(-2.0, 2.0);
+ texture->y_period = frandrange(-2.0, 2.0);
+ texture->r_period = frandrange(-2.0, 2.0);
+ texture->x_phase = frand(M_PI * 2);
+ texture->y_phase = frand(M_PI * 2);
+ texture->r_phase = frand(M_PI * 2);
+#ifdef DEBUG
+ printf("XPeriod %f XPhase %f\n", texture->x_period, texture->x_phase);
+ printf("YPeriod %f YPhase %f\n", texture->y_period, texture->y_phase);
+ printf("RPeriod %f RPhase %f\n", texture->r_period, texture->r_phase);
+#endif
}
#define VERTEX0 glVertex3f( 0.0000f, 0.000f, 0.0f);
#define VERTEX5 glVertex3f(-XOFFSET, -0.500f, 0.0f);
#define VERTEX6 glVertex3f(-XOFFSET, 0.500f, 0.0f);
+/*
+** Three different functions for calculating texture coordinates
+** which modify how the texture triangle moves over the source image.
+** Choose one.
+*/
+
+#if 0
+/* the classic equilateral triangle rotating around centre */
+static void
+calculate_texture_coords(ModeInfo *mi, texture *texture, vector2f t[3]) {
+
+ gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
+ GLfloat centre_x = 0.5;
+ GLfloat centre_y = 0.5;
+ GLfloat radius_x = (texture->max_tx - texture->min_tx) / 2;
+ GLfloat radius_y = (texture->max_ty - texture->min_ty) / 2;
+ GLfloat tangle2;
+ t[0].x = centre_x;
+ t[0].y = centre_y;
+
+ /* t[1] */
+ t[1].x = centre_x + .95 * radius_x * cos((gp->ymouse * 2 * M_PI) + (gp->tangle * RADIANS));
+ t[1].y = centre_y + .95 * radius_y * sin((gp->ymouse * 2 * M_PI) + (gp->tangle * RADIANS));
+
+ /* t[2] is always 60' further around than t2 */
+ tangle2 = (gp->ymouse * 2 * M_PI) + (gp->tangle * RADIANS) + (M_PI * 2 / 6);
+ t[2].x = centre_x + .95 * radius_x * cos(tangle2);
+ t[2].y = centre_y + .95 * radius_y * sin(tangle2);
+#if 0
+ printf("texcoords:[%f,%f]->[%f,%f](%f,%f)\n", t[0].x, t[0].y, t[1].x, t[1].y, texture->max_tx, texture->max_ty);
+#endif
+}
+#endif
+
+#if 1
+/* new lissajous movement pattern */
+static void
+calculate_texture_coords(ModeInfo *mi, texture *texture, vector2f t[3]) {
+
+ /* equilateral triangle rotating around centre */
+ gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
+ GLfloat width = texture->max_tx - texture->min_tx;
+ GLfloat height = texture->max_ty - texture->min_ty;
+ /* centre */
+ GLfloat centre_x = texture->min_tx + (width * .5);
+ GLfloat centre_y = texture->min_ty + (height * .5);
+ /* m radius and t radius should be = .5 */
+ /* triangle radius is 30% available space */
+ GLfloat t_radius_x = width * .3;
+ GLfloat t_radius_y = height * .3;
+ /* movement radius is 30% available space */
+ GLfloat m_radius_x = width * .2;
+ GLfloat m_radius_y = height * .2;
+ GLfloat angle2;
+
+ /* centre of triangle */
+ GLfloat angle = (gp->ymouse * 2 * M_PI) + (gp->tangle * RADIANS); /* to radians */
+ GLfloat t_centre_x = centre_x + m_radius_x * cos(texture->x_period * angle + texture->x_phase);
+ GLfloat t_centre_y = centre_y + m_radius_y * sin(texture->y_period * angle + texture->y_phase);
+
+#if 0
+ printf("WH: %f, %f - tWH: %f, %f\n", width, height, texture->width, texture->height);
+ printf("size: (%f, %f)\n", width, height);
+ printf("centre: (%f, %f)\n", centre_x, centre_y);
+#endif
+
+ angle2 = texture->r_period * angle + texture->r_phase;
+ t[0].x = t_centre_x + t_radius_x * cos(angle2);
+ t[0].y = t_centre_y + t_radius_y * sin(angle2);
+ t[1].x = t_centre_x + t_radius_x * cos(angle2 + ANGLE_120);
+ t[1].y = t_centre_y + t_radius_y * sin(angle2 + ANGLE_120);
+ t[2].x = t_centre_x + t_radius_x * cos(angle2 + ANGLE_240);
+ t[2].y = t_centre_y + t_radius_y * sin(angle2 + ANGLE_240);
+
+#if 0
+ printf("texcoords:[%f,%f]->[%f,%f](%f,%f)\n", t[0].x, t[0].y, t[1].x, t[1].y, texture->max_tx, texture->max_ty);
+#endif
+}
+#endif
+
+#if 0
+/* corners into corners - meant to maximise coverage */
static void
-draw_hexagons(ModeInfo *mi, int translucency, GLuint texture)
+calculate_texture_coords(ModeInfo *mi, texture *texture, vector2f t[3]) {
+
+ /* equilateral triangle rotating around centre */
+ gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
+ GLfloat width = texture->max_tx - texture->min_tx;
+ GLfloat height = texture->max_ty - texture->min_ty;
+ /* centre */
+ GLfloat centre_x = texture->min_tx + (width * .5);
+ GLfloat centre_y = texture->min_ty + (height * .5);
+ /* m radius and t radius should be = .5 */
+ /* triangle radius calculated using maths 8) */
+#define TRADIUS (M_SQRT2 - 1.0)
+#define MRADIUS (1.0 - (M_SQRT2 / 2.0))
+ GLfloat t_radius_x = width * TRADIUS * .95;
+ GLfloat t_radius_y = height * TRADIUS * .95;
+ /* movement radius also calculated using maths */
+ GLfloat m_radius_x = width * MRADIUS * .95;
+ GLfloat m_radius_y = height * MRADIUS * .95;
+ GLfloat angle, angle2;
+ GLfloat t_centre_x, t_centre_y;
+
+ /* centre of triangle */
+ angle = gp->tangle * RADIANS; /* to radians */
+ t_centre_x = centre_x + m_radius_x * cos(angle);
+ t_centre_y = centre_y + m_radius_y * sin(angle);
+#if 0
+ printf("angle: %f, %f\n", angle, gp->tangle);
+ printf("tcentre: %f,%f\n", t_centre_x, t_centre_y);
+ printf("tradius: %f,%f\n", t_radius_x, t_radius_y);
+
+ printf("size: (%f, %f)\n", width, height);
+ printf("centre: (%f, %f)\n", centre_x, centre_y);
+ printf("centre: (%f, %f)\n", centre_x, centre_y);
+ printf("TRADIUS: %f\n", TRADIUS);
+ printf("MRADIUS: %f\n", MRADIUS);
+#endif
+
+ /* angle2 is tied to tangle */
+ angle2 = (180.0 - ((30.0 / 90.0) * gp->tangle)) * RADIANS;
+#if 0
+ printf("Angle1: %f\tAngle2: %f\n", angle / RADIANS, angle2 / RADIANS);
+#endif
+ t[0].x = t_centre_x + t_radius_x * cos(angle2);
+ t[0].y = t_centre_y + t_radius_y * sin(angle2);
+ t[1].x = t_centre_x + t_radius_x * cos(angle2 + ANGLE_120);
+ t[1].y = t_centre_y + t_radius_y * sin(angle2 + ANGLE_120);
+ t[2].x = t_centre_x + t_radius_x * cos(angle2 + ANGLE_240);
+ t[2].y = t_centre_y + t_radius_y * sin(angle2 + ANGLE_240);
+
+#if 0
+ printf("texcoords:[%f,%f][%f,%f][%f,%f]\n", t[0].x, t[0].y, t[1].x, t[1].y, t[2].x, t[2].y);
+#endif
+}
+#endif
+
+static int
+draw_hexagons(ModeInfo *mi, int translucency, texture *texture)
{
+ int polys = 0;
int i;
- GLfloat col[4];
- GLfloat t1x, t1y, t2x, t2y, t3x, t3y;
+ vector2f t[3];
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
- GLfloat tangle2;
- col[0] = 1.0;
- col[1] = 1.0;
- col[2] = 1.0;
- col[3] = (float)translucency / MAX_FADE;
-
- /* calculate vertices of equilateral triangle within image. */
- /* t1 is always in centre */
- t1x = gp->max_tx / 2;
- t1y = gp->max_ty / 2;
- /* t2 rotates */
- t2x = (gp->max_tx / 2) * (1 + cos((ymouse * 2 * M_PI) + (tangle * M_PI / 180)));
- t2y = (gp->max_ty / 2) * (1 + sin((ymouse * 2 * M_PI) + (tangle * M_PI / 180)));
- /* t3 is always 60' further around than t2 */
- tangle2 = (ymouse * 2 * M_PI) + (tangle * M_PI / 180) + (M_PI * 2 / 6);
- t3x = (gp->max_tx / 2) * (1 + (cos(tangle2)));
- t3y = (gp->max_ty / 2) * (1 + (sin(tangle2)));
- /* NB image is flipped vertically hence: */
- t1y = 1 - t1y;
- t2y = 1 - t2y;
- t3y = 1 - t3y;
- /*printf("texcoords:[%f,%f]->[%f,%f](%f,%f)\n", t1x, t1y, t2x, t2y, gp->max_tx, gp->max_ty);*/
+ calculate_texture_coords(mi, texture, t);
glColor4f(1.0, 1.0, 1.0, (float)translucency / MAX_FADE);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_FALSE);
- glBindTexture(GL_TEXTURE_2D, gp->textures[texture]);
+ glBindTexture(GL_TEXTURE_2D, texture->id);
+ if (gp->list == -1) {
+ gp->list = glGenLists(1);
+ }
+
+ /* compile new list */
+ glNewList(gp->list, GL_COMPILE);
+ glBegin(GL_TRIANGLES);
+
+ /*
+ ** six triangles to each hexagon
+ */
+
+ glTexCoord2f(t[0].x, t[0].y);
+ VERTEX0;
+ glTexCoord2f(t[1].x, t[1].y);
+ VERTEX1;
+ glTexCoord2f(t[2].x, t[2].y);
+ VERTEX6;
+
+ glTexCoord2f(t[0].x, t[0].y);
+ VERTEX0;
+ glTexCoord2f(t[2].x, t[2].y);
+ VERTEX6;
+ glTexCoord2f(t[1].x, t[1].y);
+ VERTEX5;
+
+ glTexCoord2f(t[0].x, t[0].y);
+ VERTEX0;
+ glTexCoord2f(t[1].x, t[1].y);
+ VERTEX5;
+ glTexCoord2f(t[2].x, t[2].y);
+ VERTEX4;
+
+ glTexCoord2f(t[0].x, t[0].y);
+ VERTEX0;
+ glTexCoord2f(t[2].x, t[2].y);
+ VERTEX4;
+ glTexCoord2f(t[1].x, t[1].y);
+ VERTEX3;
+
+ glTexCoord2f(t[0].x, t[0].y);
+ VERTEX0;
+ glTexCoord2f(t[1].x, t[1].y);
+ VERTEX3;
+ glTexCoord2f(t[2].x, t[2].y);
+ VERTEX2;
+
+ glTexCoord2f(t[0].x, t[0].y);
+ VERTEX0;
+ glTexCoord2f(t[2].x, t[2].y);
+ VERTEX2;
+ glTexCoord2f(t[1].x, t[1].y);
+ VERTEX1;
+
+ glEnd();
+ glEndList();
+
+ /* call the list n times */
for (i = 0 ; i < sizeof(hex) / sizeof(hex[0]) ; i++) {
glPushMatrix();
glTranslatef(hex[i].x, hex[i].y, 0.0);
-
- glBegin(GL_TRIANGLES);
-
- /*
- ** six triangles to each hexagon
- */
-
- glTexCoord2f(t1x, t1y);
- VERTEX0;
- glTexCoord2f(t2x, t2y);
- VERTEX1;
- glTexCoord2f(t3x, t3y);
- VERTEX6;
-
- glTexCoord2f(t1x, t1y);
- VERTEX0;
- glTexCoord2f(t3x, t3y);
- VERTEX6;
- glTexCoord2f(t2x, t2y);
- VERTEX5;
-
- glTexCoord2f(t1x, t1y);
- VERTEX0;
- glTexCoord2f(t2x, t2y);
- VERTEX5;
- glTexCoord2f(t3x, t3y);
- VERTEX4;
-
- glTexCoord2f(t1x, t1y);
- VERTEX0;
- glTexCoord2f(t3x, t3y);
- VERTEX4;
- glTexCoord2f(t2x, t2y);
- VERTEX3;
-
- glTexCoord2f(t1x, t1y);
- VERTEX0;
- glTexCoord2f(t2x, t2y);
- VERTEX3;
- glTexCoord2f(t3x, t3y);
- VERTEX2;
-
- glTexCoord2f(t1x, t1y);
- VERTEX0;
- glTexCoord2f(t3x, t3y);
- VERTEX2;
- glTexCoord2f(t2x, t2y);
- VERTEX1;
-
- glEnd();
+ glCallList(gp->list);
+ polys += 6;
glPopMatrix();
}
glVertex3f(1.0, 1.0, -0.1);
glTexCoord2f(0.0, 1.0);
glVertex3f(0.0, 1.0, -0.1);
+ polys++;
glEnd();
/* acd debug - display texture triangle */
- glColor4f(1.0, 1.0, 1.0, 1.0);
+ glColor4f(1.0, 0.5, 1.0, 1.0);
glBegin(GL_LINE_LOOP);
- glVertex3f(t1x, t1y, -0.11);
- glVertex3f(t2x, t2y, -0.11);
- glVertex3f(t3x, t3y, -0.11);
+ glVertex3f(t[0].x, t[0].y, -0.11);
+ glVertex3f(t[1].x, t[1].y, -0.11);
+ glVertex3f(t[2].x, t[2].y, -0.11);
+ polys++;
glEnd();
glPopMatrix();
#endif
glDisable(GL_TEXTURE_2D);
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
+ return polys;
}
/*
GLfloat x_angle, y_angle, z_angle;
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
vectorf v1;
- GLfloat pos[4];
- glClearColor(0.5, 0.5, 0.5, 1.0);
+ mi->polygon_count = 0;
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
z_angle = gp->cam_z_phase + gp->tic * gp->cam_z_speed;
if (move) {
- v1.x = 2 * sin(x_angle);
- v1.y = 2 * sin(y_angle);
+ v1.x = 1 * sin(x_angle);
+ v1.y = 1 * sin(y_angle);
} else {
v1.x = 0;
v1.y = 0;
}
/* size is changed in pinit() to be distance from plane */
- size = MI_SIZE(mi);
- if (size > 10) {
- size = 10;
+ gp->size = MI_SIZE(mi);
+ if (gp->size > 10) {
+ gp->size = 10;
}
- if (size < -1) {
- size = -1;
+ if (gp->size <= 0) {
+ gp->size = 0;
}
- if (size != -1) {
+ if (gp->size > 0) {
/* user defined size */
- v1.z = size;
+ v1.z = gp->size;
} else if (zoom) {
/* max distance given by adding the constant and the multiplier */
- v1.z = 5.0 + 4.0 * sin(z_angle);
+ v1.z = 5.0 + 3.0 * sin(z_angle);
} else {
/* default */
v1.z = 7.0;
float new_rangle_vel = 0.0;
/* update camera rotation angle and velocity */
- rangle += rangle_vel;
- new_rangle_vel = rangle_vel + rangle_acc;
- if (new_rangle_vel > -MAX_RANGLE_VEL && new_rangle_vel < MAX_RANGLE_VEL)
+ gp->rangle += gp->rangle_vel;
+ new_rangle_vel = gp->rangle_vel + gp->rangle_acc;
+ if (new_rangle_vel > -MAX_ANGLE_VEL && new_rangle_vel < MAX_ANGLE_VEL)
{
/* new velocity is within limits */
- rangle_vel = new_rangle_vel;
+ gp->rangle_vel = new_rangle_vel;
}
- /* randomly change twisting speed */
- if ((random() % 1000) < 1)
- {
- rangle_acc = frand(0.002) - 0.001;
+ /* randomly change twisting speed - 3ff = 1024 */
+ if ((random() % TWISTING_PROBABILITY) < 1.0) {
+ gp->rangle_acc = INITIAL_ANGLE_ACC * frand(1.0);
+ if (gp->rangle_vel > 0.0) {
+ gp->rangle_acc = -gp->rangle_acc;
+ }
}
}
+#if 0
+ printf("Rangle: %f : %f : %f\n", gp->rangle, gp->rangle_vel, gp->rangle_acc);
+ printf("Tangle: %f : %f : %f\n", gp->tangle, gp->tangle_vel, gp->tangle_acc);
+#endif
#ifdef WOBBLE
/* this makes the image wobble - requires -move and a larger grid */
gluLookAt(
v1.x, v1.y, v1.z,
v1.x, v1.y, 0.0,
- sin((xmouse * M_PI * 2) + rangle * M_PI / 180),
- cos((xmouse * M_PI * 2) + rangle * M_PI / 180),
+ sin((gp->xmouse * M_PI * 2) + gp->rangle * RADIANS),
+ cos((gp->xmouse * M_PI * 2) + gp->rangle * RADIANS),
0.0);
#endif
- /* light position same as camera */
- pos[0] = v1.x;
- pos[1] = v1.y;
- pos[2] = v1.z;
- pos[3] = 0;
+# 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, 1/h, 1/h);
+ }
+# endif
if (gp->fade == 0)
{
/* not fading */
- draw_hexagons(mi, MAX_FADE, gp->visible);
+ mi->polygon_count +=
+ draw_hexagons(mi, MAX_FADE, &gp->textures[gp->visible]);
}
else
{
- /* fading - show both textures with alpha */
- draw_hexagons(mi, MAX_FADE - gp->fade, gp->visible);
- draw_hexagons(mi, gp->fade, 1 - gp->visible);
+ /* fading - show both textures with alpha
+ NB first is always max alpha */
+ mi->polygon_count +=
+ draw_hexagons(mi, MAX_FADE, &gp->textures[1 - gp->visible]);
+ mi->polygon_count +=
+ draw_hexagons(mi, MAX_FADE - gp->fade, &gp->textures[gp->visible]);
/* fade some more */
gp->fade++;
{
float new_tangle_vel = 0.0;
- tangle += tangle_vel;
+ gp->tangle += gp->tangle_vel;
/* work out new texture angle velocity */
- new_tangle_vel = tangle_vel + tangle_acc;
- if (new_tangle_vel > -MAX_TANGLE_VEL && new_tangle_vel < MAX_TANGLE_VEL)
+ new_tangle_vel = gp->tangle_vel + gp->tangle_acc;
+ if (new_tangle_vel > -MAX_ANGLE_VEL && new_tangle_vel < MAX_ANGLE_VEL)
{
/* new velocity is inside limits */
- tangle_vel = new_tangle_vel;
+ gp->tangle_vel = new_tangle_vel;
}
- /* randomly change texture angle acceleration */
- if ((random() % 1000) < 1)
- {
- tangle_acc = frand(0.002) - 0.001;
+ /* randomly change twisting speed - 3ff = 1024 */
+ if ((random() % TWISTING_PROBABILITY) < 1.0) {
+ gp->tangle_acc = INITIAL_ANGLE_ACC * frand(1.0);
+ if (gp->tangle_vel > 0.0) {
+ gp->tangle_acc = -gp->tangle_acc;
+ }
}
}
/*
* new window size or exposure
*/
-void reshape_gleidescope(ModeInfo *mi, int width, int height)
+ENTRYPOINT void reshape_gleidescope(ModeInfo *mi, int width, int height)
{
+ gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
GLfloat h = (GLfloat) height / (GLfloat) width;
+ glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(gp->glx_context));
+
glViewport(0, 0, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.0, 1/h, 0.1, 2000.0);
glMatrixMode (GL_MODELVIEW);
-
glLineWidth(1);
glPointSize(1);
}
gp->start_time = (time_t)0;
/* set the texture size to default */
+ /*
gp->max_tx = 1.0;
gp->max_ty = 1.0;
+ */
/* no fading */
gp->fade = 0;
glDisable(GL_LIGHTING);
/* space for textures */
- glGenTextures(1, &gp->textures[0]);
- glGenTextures(1, &gp->textures[1]);
+ glGenTextures(1, &gp->textures[0].id);
+ glGenTextures(1, &gp->textures[1].id);
gp->visible = 0;
- setup_texture(mi, gp->textures[gp->visible]);
+ setup_texture(mi, &gp->textures[gp->visible]);
/*
** want to choose a value for arg randomly if neither -arg nor -no-arg
}
/* define cam variables */
- gp->cam_x_speed = frand(3.0) - 1.5;
+ gp->cam_x_speed = MAX_CAM_SPEED * frandrange(-.5, 0.5);
gp->cam_x_phase = random() % 360;
- gp->cam_y_speed = frand(3.0) - 1.5;
+ gp->cam_y_speed = MAX_CAM_SPEED * frandrange(-.5, 0.5);
gp->cam_y_phase = random() % 360;
- gp->cam_z_speed = frand(3.0) - 1.5;
+ gp->cam_z_speed = MAX_CAM_SPEED * frandrange(-.5, 0.5);
gp->cam_z_phase = random() % 360;
/* initial angular speeds */
- rangle_vel = frand(0.2) - 0.1;
- tangle_vel = frand(0.2) - 0.1;
- rangle_acc = frand(0.002) - 0.001;
- tangle_acc = frand(0.002) - 0.001;
+ gp->rangle_vel = INITIAL_ANGLE_VEL * frandrange(-.5, 0.5);
+ gp->tangle_vel = INITIAL_ANGLE_VEL * frandrange(-.5, 0.5);
+ gp->rangle_acc = INITIAL_ANGLE_ACC * frandrange(-.5, 0.5);
+ gp->tangle_acc = INITIAL_ANGLE_ACC * frandrange(-.5, 0.5);
/* jwz */
+#if 0
{
GLfloat speed = 15;
- rangle_vel *= speed;
- tangle_vel *= speed;
- rangle_acc *= speed;
- tangle_acc *= speed;
+ gp->rangle_vel *= speed;
+ gp->tangle_vel *= speed;
+ gp->rangle_acc *= speed;
+ gp->tangle_acc *= speed;
}
+#endif
/* distance is 11 - size */
- if (size != -1) {
+ if (gp->size != -1) {
if (zoom) {
fprintf(stderr, "-size given. ignoring -zoom.\n");
zoom = False;
}
- if (size < 1) {
- size = 1;
- } else if (size >= 10) {
- size = 10;
+ if (gp->size < 1) {
+ gp->size = 1;
+ } else if (gp->size >= 10) {
+ gp->size = 10;
}
- size = 11 - size;
+ gp->size = 11 - gp->size;
}
#ifdef DEBUG
#endif
}
-void
+static void free_gleidescope(ModeInfo * mi);
+
+ENTRYPOINT void
init_gleidescope(ModeInfo * mi)
{
gleidestruct *gp;
int screen = MI_SCREEN(mi);
-
- if (gleidescope == NULL) {
- gleidescope = (gleidestruct *) calloc(MI_NUM_SCREENS(mi), sizeof (gleidestruct));
- if (gleidescope == NULL) {
- return;
- }
- }
+ MI_INIT(mi, gleidescope, free_gleidescope);
gp = &gleidescope[screen];
gp->window = MI_WINDOW(mi);
+ gp->size = -1;
+ gp->list = -1;
if ((gp->glx_context = init_GL(mi)) != NULL) {
reshape_gleidescope(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+ clear_gl_error(); /* WTF? sometimes "invalid op" from glViewport! */
glDrawBuffer(GL_BACK);
}
}
-void
+ENTRYPOINT void
draw_gleidescope(ModeInfo * mi)
{
gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
if (!gp->glx_context)
return;
+ /* Just keep running before the texture has come in. */
+ /* if (gp->waiting_for_image_p) return; */
+
glDrawBuffer(GL_BACK);
glXMakeCurrent(display, window, *(gp->glx_context));
#ifdef GRAB
if (grab) {
- grab_frame(mi);
+ grab_frame(display, window);
}
#endif
/* need to change texture? */
if ((gp->start_time != 0) && (duration != -1) && gp->fade == 0) {
if (gp->start_time + duration <= time((time_t *)0)) {
+#ifdef DEBUG
+ printf("Start Time: %lu - Current Time: %lu\n", (unsigned long)gp->start_time, (unsigned long)time((time_t *)0));
+ printf("Changing Texture\n");
+#endif
/* get new snapshot (into back buffer) and start fade count */
- getSnapshot(mi, gp->textures[1 - gp->visible]);
+ setup_texture(mi, &gp->textures[1 - gp->visible]);
+ /* restart fading */
gp->fade = 1;
}
}
}
-void
-release_gleidescope(ModeInfo * mi)
+static void
+free_gleidescope(ModeInfo * mi)
{
- if (gleidescope != NULL) {
- int screen;
-
- for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
- gleidestruct *gp = &gleidescope[screen];
+ gleidestruct *gp = &gleidescope[MI_SCREEN(mi)];
- /* acd - is this needed? */
- if (gp->glx_context) {
- /* Display lists MUST be freed while their glXContext is current. */
- glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context));
+ /* acd - is this needed? */
+ if (gp->glx_context) {
+ /* Display lists MUST be freed while their glXContext is current. */
+ glXMakeCurrent(MI_DISPLAY(mi), gp->window, *(gp->glx_context));
- /* acd - was code here for freeing things that are no longer in struct */
- }
- }
- (void) free((void *) gleidescope);
- gleidescope = NULL;
+ /* acd - was code here for freeing things that are no longer in struct */
}
-
- FreeAllGL(mi);
}
+XSCREENSAVER_MODULE ("Gleidescope", gleidescope)
+
#endif