* 10-Feb-2004: jon.dowdall@bigpond.com Added motion blur
*
* The mirrorblob screensaver draws a pulsing blob on the screen. Options
- * include adding a background (via screen_to_texture), texturing the blob,
+ * include adding a background (via load_texture_async), texturing the blob,
* making the blob semi-transparent and varying the resolution of the blob
* tessellation.
*
* The blob was inspired by a lavalamp is in no way a simulation. The code is
* just an attempt to generate some eye-candy.
*
- * Much of xscreensaver code framework is taken from the pulsar module by David
+ * Much of xmirrorblob code framework is taken from the pulsar module by David
* Konerding and the glslideshow by Mike Oliphant and Jamie Zawinski.
*
*/
#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
#ifdef STANDALONE
-# define PROGCLASS "Screensaver"
-# define HACK_INIT init_screensaver
-# define HACK_DRAW draw_screensaver
-# define HACK_RESHAPE reshape_screensaver
-# define screensaver_opts xlockmore_opts
+#define DEFAULTS \
+ "*delay: " DEF_DELAY "\n" \
+ "*showFPS: " DEF_FPS "\n" \
+ "*useSHM: True \n"
+
+# define refresh_mirrorblob 0
+# define mirrorblob_handle_event 0
+# include "xlockmore.h" /* from the xmirrorblob distribution */
+#else /* !STANDALONE */
+# include "xlock.h" /* from the xlockmore distribution */
+#endif /* !STANDALONE */
+
+#ifdef USE_GL /* whole file */
+
#define DEF_DELAY "10000"
#define DEF_FPS "False"
#define DEF_HOLD_TIME "30"
#define DEF_FADE_TIME "5"
-#define DEFAULTS \
- "*delay: " DEF_DELAY "\n" \
- "*showFPS: " DEF_FPS "\n" \
- "*useSHM: True \n"
-
-# include "xlockmore.h" /* from the xscreensaver distribution */
-#else /* !STANDALONE */
-# include "xlock.h" /* from the xlockmore distribution */
-#endif /* !STANDALONE */
-
-#ifdef USE_GL /* whole file */
-
#ifdef HAVE_XMU
# ifndef VMS
# include <X11/Xmu/Drawing.h>
# endif /* VMS */
#endif
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include "GL/glx.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-/*#include <string.h>*/
#include "grab-ximage.h"
#undef countof
static int hold_time;
static XrmOptionDescRec opts[] = {
- {"-wire", ".blob.wire", XrmoptionNoArg, "true" },
- {"+wire", ".blob.wire", XrmoptionNoArg, "false" },
+ {"-wireframe", ".blob.wire", XrmoptionNoArg, "true" },
+ {"+wireframe", ".blob.wire", XrmoptionNoArg, "false" },
{"-blend", ".blob.blend", XrmoptionNoArg, "true" },
{"+blend", ".blob.blend", XrmoptionNoArg, "false" },
{"-fog", ".blob.fog", XrmoptionNoArg, "true" },
{"-hold_time", "Number of frames before next image"},
};
-ModeSpecOpt screensaver_opts = {countof(opts), opts, countof(vars), vars, desc};
+ENTRYPOINT ModeSpecOpt mirrorblob_opts = {countof(opts), opts, countof(vars), vars, desc};
#ifdef USE_MODULES
-ModStruct screensaver_description =
-{"screensaver", "init_screensaver", "draw_screensaver", "release_screensaver",
- "draw_screensaver", "init_screensaver", NULL, &screensaver_opts,
+ModStruct mirrorblob_description =
+{"mirrorblob", "init_mirrorblob", "draw_mirrorblob", "release_mirrorblob",
+ "draw_mirrorblob", "init_mirrorblob", NULL, &mirrorblob_opts,
1000, 1, 2, 1, 4, 1.0, "",
- "OpenGL screensaver", 0, NULL};
+ "OpenGL mirrorblob", 0, NULL};
#endif
-/* structure for holding the screensaver data */
-typedef struct {
- int screen_width, screen_height;
- GLXContext *glx_context;
- Window window;
- XColor fg, bg;
-} screensaverstruct;
-
-static screensaverstruct *Screensaver = NULL;
+#define NUM_TEXTURES 2
/*****************************************************************************
* Types used in blob code
Vector3D pos;
} Field_Data;
-/*****************************************************************************
- * Static blob data
- *****************************************************************************/
+typedef enum
+{
+ HOLDING=0,
+ TRANSITIONING
+} Frame_State;
-static Row_Data *row_data;
-/* Parameters controlling the position of the blob as a whole */
-static Vector3D blob_center = {0.0, 0.0, 0.0};
-static Vector3D blob_anchor = {0.0, 0.0, 0.0};
-static Vector3D blob_velocity = {0.0, 0.0, 0.0};
-static Vector3D blob_force = {0.0, 0.0, 0.0};
+/* structure for holding the mirrorblob data */
+typedef struct {
+ int screen_width, screen_height;
+ GLXContext *glx_context;
+ Window window;
+ XColor fg, bg;
+ double freak, v_freak;
-/* Count of the total number of points */
-static int num_points;
+ Row_Data *row_data;
-static Vector3D *dots = NULL;
-static Vector3D *normals = NULL;
-static Colour *colours = NULL;
-static Vector2D *tex_coords = NULL;
+ /* Parameters controlling the position of the blob as a whole */
+ Vector3D blob_center;
+ Vector3D blob_anchor;
+ Vector3D blob_velocity;
+ Vector3D blob_force;
-/* Pointer to the field function results */
-static double *field = 0, *wall_field = 0;
+ /* Count of the total number of points */
+ int num_points;
-Field_Data *field_data;
+ Vector3D *dots;
+ Vector3D *normals;
+ Colour *colours;
+ Vector2D *tex_coords;
-/* Use 2 textures to allow a gradual fade between images */
-#define NUM_TEXTURES 2
-static int current_texture;
+ /* Pointer to the field function results */
+ double *field, *wall_field;
-/* Ratio of used texture size to total texture size */
-GLfloat tex_width[NUM_TEXTURES], tex_height[NUM_TEXTURES];
-GLuint textures[NUM_TEXTURES];
+ Field_Data *field_data;
-typedef enum
-{
- HOLDING,
- TRANSITIONING
-} Frame_State;
+ /* Use 2 textures to allow a gradual fade between images */
+ int current_texture;
+
+ /* Ratio of used texture size to total texture size */
+ GLfloat tex_width[NUM_TEXTURES], tex_height[NUM_TEXTURES];
+ GLuint textures[NUM_TEXTURES];
-static Frame_State state = HOLDING;
-static double state_start_time = 0;
+ Frame_State state;
+ double state_start_time;
-static int colour_cycle = 0;
+ int colour_cycle;
+
+ Bool mipmap_p;
+ Bool waiting_for_image_p;
+ Bool first_image_p;
+
+} mirrorblobstruct;
+
+static mirrorblobstruct *Mirrorblob = NULL;
/******************************************************************************
*
/****************************************************************************
*
- * Load a texture using the screen_to_texture function.
+ * Load a texture.
*/
-void
-grab_texture(ModeInfo *mi, int texture_index)
+
+static void
+image_loaded_cb (const char *filename, XRectangle *geometry,
+ int image_width, int image_height,
+ int texture_width, int texture_height,
+ void *closure)
{
- Bool mipmap_p = True;
- int iw, ih, tw, th;
+ mirrorblobstruct *mp = (mirrorblobstruct *) closure;
+ GLint texid = -1;
+ int texture_index = -1;
+ int i;
+
+ glGetIntegerv (GL_TEXTURE_BINDING_2D, &texid);
+ if (texid < 0) abort();
+
+ for (i = 0; i < NUM_TEXTURES; i++) {
+ if (mp->textures[i] == texid) {
+ texture_index = i;
+ break;
+ }
+ }
+ if (texture_index < 0) abort();
- glBindTexture (GL_TEXTURE_2D, textures[texture_index]);
+ mp->tex_width [texture_index] = (GLfloat) image_width / texture_width;
+ mp->tex_height[texture_index] = -(GLfloat) image_height / texture_height;
- if (! screen_to_texture (mi->xgwa.screen, mi->window, 0, 0, mipmap_p,
- NULL, NULL, &iw, &ih, &tw, &th))
- exit(1);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ (mp->mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR));
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- tex_width [texture_index] = (GLfloat) iw / tw;
- tex_height[texture_index] = -(GLfloat) ih / th;
+ mp->waiting_for_image_p = False;
+ mp->first_image_p = True;
+}
- 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));
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+static void
+grab_texture(ModeInfo *mi, int texture_index)
+{
+ mirrorblobstruct *mp = &Mirrorblob[MI_SCREEN(mi)];
+
+ mp->waiting_for_image_p = True;
+ mp->mipmap_p = True;
+ load_texture_async (mi->xgwa.screen, mi->window,
+ *mp->glx_context, 0, 0, mp->mipmap_p,
+ mp->textures[texture_index],
+ image_loaded_cb, mp);
}
/******************************************************************************
static void
initialize_gl(ModeInfo *mi, GLsizei width, GLsizei height)
{
+ mirrorblobstruct *gp = &Mirrorblob[MI_SCREEN(mi)];
+
GLfloat fogColor[4] = { 0.1, 0.1, 0.1, 0.1 };
/* Lighting values */
GLfloat lightPos0[] = {500.0f, 100.0f, 200.0f, 1.0f };
glLightModeli (GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
glEnable (GL_TEXTURE_2D);
- current_texture = 0;
- glGenTextures (NUM_TEXTURES, textures);
- grab_texture (mi, current_texture);
+ gp->current_texture = 0;
+ glGenTextures (NUM_TEXTURES, gp->textures);
+ grab_texture (mi, gp->current_texture);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
}
* Return 0 on success.
*/
static int
-initialise_blob(int width,
- int height,
+initialise_blob(mirrorblobstruct *gp,
+ int width, int height,
int field_array_size)
{
/* Loop variables */
int x, y, i;
double xd;
- colour_cycle = 0;
+ gp->colour_cycle = 0;
- row_data = (Row_Data *) malloc (y_resolution * sizeof (Row_Data));
- if (!row_data)
+ gp->row_data = (Row_Data *) malloc (y_resolution * sizeof (Row_Data));
+ if (!gp->row_data)
{
fprintf(stderr, "Couldn't allocate row data buffer\n");
return -1;
}
- field_data = (Field_Data *) malloc (field_points * sizeof (Field_Data));
- if (!field_data)
+ gp->field_data = (Field_Data *) malloc (field_points * sizeof (Field_Data));
+ if (!gp->field_data)
{
fprintf(stderr, "Couldn't allocate field data buffer\n");
return -1;
}
- field = (double *)malloc(field_array_size * sizeof(double));
- if (!field)
+ gp->field = (double *)malloc(field_array_size * sizeof(double));
+ if (!gp->field)
{
fprintf(stderr, "Couldn't allocate field buffer\n");
return -1;
}
- wall_field = (double *)malloc(field_array_size * sizeof(double));
- if (!wall_field)
+ gp->wall_field = (double *)malloc(field_array_size * sizeof(double));
+ if (!gp->wall_field)
{
fprintf(stderr, "Couldn't allocate wall field buffer\n");
return -1;
}
- dots = (Vector3D *)malloc(x_resolution * y_resolution * sizeof(Vector3D));
- if (!dots)
+ gp->dots = (Vector3D *)malloc(x_resolution * y_resolution * sizeof(Vector3D));
+ if (!gp->dots)
{
fprintf(stderr, "Couldn't allocate points buffer\n");
return -1;
}
- glVertexPointer (3, GL_DOUBLE, 0, (GLvoid *) dots);
+ glVertexPointer (3, GL_DOUBLE, 0, (GLvoid *) gp->dots);
- normals = (Vector3D *)malloc(x_resolution * y_resolution * sizeof(Vector3D));
- if (!normals)
+ gp->normals = (Vector3D *)malloc(x_resolution * y_resolution * sizeof(Vector3D));
+ if (!gp->normals)
{
fprintf(stderr, "Couldn't allocate normals buffer\n");
return -1;
}
- glNormalPointer (GL_DOUBLE, 0, (GLvoid *) normals);
+ glNormalPointer (GL_DOUBLE, 0, (GLvoid *) gp->normals);
if (do_colour)
{
- colours = (Colour *)malloc(x_resolution * y_resolution * sizeof(Colour));
- if (!colours)
+ gp->colours = (Colour *)malloc(x_resolution * y_resolution * sizeof(Colour));
+ if (!gp->colours)
{
fprintf(stderr, "Couldn't allocate colours buffer\n");
return -1;
}
- glColorPointer (4, GL_UNSIGNED_BYTE, 0, (GLvoid *) colours);
+ glColorPointer (4, GL_UNSIGNED_BYTE, 0, (GLvoid *) gp->colours);
}
if (do_texture)
{
- tex_coords = (Vector2D *)malloc(x_resolution * y_resolution
+ gp->tex_coords = (Vector2D *)malloc(x_resolution * y_resolution
* sizeof(Vector2D));
- if (!tex_coords)
+ if (!gp->tex_coords)
{
fprintf(stderr, "Couldn't allocate tex_coords buffer\n");
return -1;
}
- glTexCoordPointer (2, GL_DOUBLE, 0, (GLvoid *) tex_coords);
+ glTexCoordPointer (2, GL_DOUBLE, 0, (GLvoid *) gp->tex_coords);
}
- num_points = 0;
+ gp->num_points = 0;
/* Generate constant row data and count of total number of points */
for (y = 0; y < y_resolution; y++)
{
- row_data[y].cosyd = cos(PI * (double)(y * (y_resolution + 1))
+ gp->row_data[y].cosyd = cos(PI * (double)(y * (y_resolution + 1))
/ (double)(y_resolution * y_resolution));
- row_data[y].sinyd = sin(PI * (double)(y * (y_resolution + 1))
+ gp->row_data[y].sinyd = sin(PI * (double)(y * (y_resolution + 1))
/ (double)(y_resolution * y_resolution));
- row_data[y].num_x_points = (int)(x_resolution * row_data[y].sinyd + 1.0);
- num_points += row_data[y].num_x_points;
+ gp->row_data[y].num_x_points = (int)(x_resolution * gp->row_data[y].sinyd + 1.0);
+ gp->num_points += gp->row_data[y].num_x_points;
}
/* Initialise field data */
for (i = 0; i < field_points; i++)
{
- field_data[i].ax = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5);
- field_data[i].ay = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5);
- field_data[i].apower = (((double)random() / (double)RAND_MAX) - 0.5);
-
- field_data[i].pos.x = 1.5 * sin(PI * field_data[i].ay)
- * cos(PI * field_data[i].ax);
- field_data[i].pos.y = 1.5 * cos(PI * field_data[i].ay);
- field_data[i].pos.z = 1.5 * sin(PI * field_data[i].ay)
- * sin(PI * field_data[i].ax);
-
- field_data[i].cx = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5);
- field_data[i].cy = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5);
- field_data[i].cpower = (((double)random() / (double)RAND_MAX) - 0.5);
-
- field_data[i].vx = 0.0;
- field_data[i].vy = 0.0;
- field_data[i].vpower = 0.0;
-
- field_data[i].mx = 0.003 * ((double)random() / (double)RAND_MAX);
- field_data[i].my = 0.003 * ((double)random() / (double)RAND_MAX);
- field_data[i].mpower = 0.003 * ((double)random() / (double)RAND_MAX);
+ gp->field_data[i].ax = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5);
+ gp->field_data[i].ay = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5);
+ gp->field_data[i].apower = (((double)random() / (double)RAND_MAX) - 0.5);
+
+ gp->field_data[i].pos.x = 1.5 * sin(PI * gp->field_data[i].ay)
+ * cos(PI * gp->field_data[i].ax);
+ gp->field_data[i].pos.y = 1.5 * cos(PI * gp->field_data[i].ay);
+ gp->field_data[i].pos.z = 1.5 * sin(PI * gp->field_data[i].ay)
+ * sin(PI * gp->field_data[i].ax);
+
+ gp->field_data[i].cx = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5);
+ gp->field_data[i].cy = 2.0 * (((double)random() / (double)RAND_MAX) - 0.5);
+ gp->field_data[i].cpower = (((double)random() / (double)RAND_MAX) - 0.5);
+
+ gp->field_data[i].vx = 0.0;
+ gp->field_data[i].vy = 0.0;
+ gp->field_data[i].vpower = 0.0;
+
+ gp->field_data[i].mx = 0.003 * ((double)random() / (double)RAND_MAX);
+ gp->field_data[i].my = 0.003 * ((double)random() / (double)RAND_MAX);
+ gp->field_data[i].mpower = 0.003 * ((double)random() / (double)RAND_MAX);
}
/* Initialise lookup table of field strength */
xd = 2.0 * (((double)i / (double)field_array_size));
xd = 3.0 * xd * xd * xd * xd;
- field[i] = 0.4 / (field_points * (xd + 0.1));
+ gp->field[i] = 0.4 / (field_points * (xd + 0.1));
xd = 10.0 * (((double)i / (double)field_array_size));
- wall_field[i] = 0.4 / (xd * xd * xd * xd + 1.0);
+ gp->wall_field[i] = 0.4 / (xd * xd * xd * xd + 1.0);
}
for (y = 0; y < y_resolution; y++)
{
- for (x = 0; x < row_data[y].num_x_points; x++)
+ for (x = 0; x < gp->row_data[y].num_x_points; x++)
{
i = x + y * x_resolution;
- xd = 2.0 * (((double)x / (double)row_data[y].num_x_points) - 0.5);
-
- dots[i].x = row_data[y].sinyd * cos(PI * xd);
- dots[i].y = row_data[y].cosyd;
- dots[i].z = row_data[y].sinyd * sin(PI * xd);
- normals[i].x = row_data[y].sinyd * cos(PI * xd);
- normals[i].y = row_data[y].cosyd;
- normals[i].z = row_data[y].sinyd * sin(PI * xd);
+ xd = 2.0 * (((double)x / (double)gp->row_data[y].num_x_points) - 0.5);
+
+ gp->dots[i].x = gp->row_data[y].sinyd * cos(PI * xd);
+ gp->dots[i].y = gp->row_data[y].cosyd;
+ gp->dots[i].z = gp->row_data[y].sinyd * sin(PI * xd);
+ gp->normals[i].x = gp->row_data[y].sinyd * cos(PI * xd);
+ gp->normals[i].y = gp->row_data[y].cosyd;
+ gp->normals[i].z = gp->row_data[y].sinyd * sin(PI * xd);
if (do_texture)
{
- tex_coords[i].x = 2.0 - 2.0 * x / (float) row_data[y].num_x_points;
- tex_coords[i].y = 1.0 - y / (float) y_resolution;
+ gp->tex_coords[i].x = 2.0 - 2.0 * x / (float) gp->row_data[y].num_x_points;
+ gp->tex_coords[i].y = 1.0 - y / (float) y_resolution;
}
}
}
* Calculate the blob shape.
*/
static void
-calc_blob(int width,
- int height,
+calc_blob(mirrorblobstruct *gp,
+ int width, int height,
int field_array_size,
float limit,
double fade)
{
- static double freak = 0.0;
-
- static double v_freak = 0.0007;
-
/* Loop variables */
int x, y, i, index, index1, index2, index3;
/* position of a point */
/* Color components */
- colour_cycle++;
+ gp->colour_cycle++;
/* Update position and strength of points used to distort the blob */
for (i = 0; i < field_points; i++)
{
- field_data[i].vx += field_data[i].mx*(field_data[i].cx - field_data[i].ax);
- field_data[i].vy += field_data[i].my*(field_data[i].cy - field_data[i].ay);
- field_data[i].vpower += field_data[i].mpower
- * (field_data[i].cpower - field_data[i].apower);
-
- field_data[i].ax += 0.1 * field_data[i].vx;
- field_data[i].ay += 0.1 * field_data[i].vy;
- field_data[i].apower += 0.1 * field_data[i].vpower;
-
- field_data[i].pos.x = 1.0 * sin(PI * field_data[i].ay)
- * cos(PI * field_data[i].ax);
- field_data[i].pos.y = 1.0 * cos(PI * field_data[i].ay);
- field_data[i].pos.z = 1.0 * sin(PI * field_data[i].ay)
- * sin(PI * field_data[i].ax);
+ gp->field_data[i].vx += gp->field_data[i].mx*(gp->field_data[i].cx - gp->field_data[i].ax);
+ gp->field_data[i].vy += gp->field_data[i].my*(gp->field_data[i].cy - gp->field_data[i].ay);
+ gp->field_data[i].vpower += gp->field_data[i].mpower
+ * (gp->field_data[i].cpower - gp->field_data[i].apower);
+
+ gp->field_data[i].ax += 0.1 * gp->field_data[i].vx;
+ gp->field_data[i].ay += 0.1 * gp->field_data[i].vy;
+ gp->field_data[i].apower += 0.1 * gp->field_data[i].vpower;
+
+ gp->field_data[i].pos.x = 1.0 * sin(PI * gp->field_data[i].ay)
+ * cos(PI * gp->field_data[i].ax);
+ gp->field_data[i].pos.y = 1.0 * cos(PI * gp->field_data[i].ay);
+ gp->field_data[i].pos.z = 1.0 * sin(PI * gp->field_data[i].ay)
+ * sin(PI * gp->field_data[i].ax);
}
- blob_force.x = 0.0;
- blob_force.y = 0.0;
- blob_force.z = 0.0;
+ gp->blob_force.x = 0.0;
+ gp->blob_force.y = 0.0;
+ gp->blob_force.z = 0.0;
for (y = 0; y < y_resolution; y++)
{
- for (x = 0; x < row_data[y].num_x_points; x++)
+ for (x = 0; x < gp->row_data[y].num_x_points; x++)
{
index = x + y * x_resolution;
- xd = 2.0 * PI * (((double)x / (double)row_data[y].num_x_points) - 0.5);
+ xd = 2.0 * PI * (((double)x / (double)gp->row_data[y].num_x_points) - 0.5);
radius = 1.0 + 0.0 * sin (xd * 10);
- zd = radius * row_data[y].sinyd * sin(xd);
- xd = radius * row_data[y].sinyd * cos(xd);
- yd = radius * row_data[y].cosyd;
+ zd = radius * gp->row_data[y].sinyd * sin(xd);
+ xd = radius * gp->row_data[y].sinyd * cos(xd);
+ yd = radius * gp->row_data[y].cosyd;
- normals[index].x = xd;
- normals[index].y = yd;
- normals[index].z = zd;
+ gp->normals[index].x = xd;
+ gp->normals[index].y = yd;
+ gp->normals[index].z = zd;
offset_x = 0.0;
offset_y = 0.0;
strength = 0.0;
for ( i = 0; i < field_points; i++)
{
- xdist = field_data[i].pos.x - xd;
- ydist = field_data[i].pos.y - yd;
- zdist = field_data[i].pos.z - zd;
+ xdist = gp->field_data[i].pos.x - xd;
+ ydist = gp->field_data[i].pos.y - yd;
+ zdist = gp->field_data[i].pos.z - zd;
dist = field_array_size * (xdist * xdist + ydist * ydist
+ zdist * zdist) * 0.1;
- strength += PI * field_data[i].apower;
+ strength += PI * gp->field_data[i].apower;
if (dist < field_array_size)
{
- offset_x += xd * field_data[i].apower * field[dist];
- offset_y += yd * field_data[i].apower * field[dist];
- offset_z += zd * field_data[i].apower * field[dist];
+ offset_x += xd * gp->field_data[i].apower * gp->field[dist];
+ offset_y += yd * gp->field_data[i].apower * gp->field[dist];
+ offset_z += zd * gp->field_data[i].apower * gp->field[dist];
- blob_force.x += 1.0 * xd * field_data[i].apower * field[dist];
- blob_force.y += 1.0 * yd * field_data[i].apower * field[dist];
- blob_force.z += 1.0 * zd * field_data[i].apower * field[dist];
+ gp->blob_force.x += 1.0 * xd * gp->field_data[i].apower * gp->field[dist];
+ gp->blob_force.y += 1.0 * yd * gp->field_data[i].apower * gp->field[dist];
+ gp->blob_force.z += 1.0 * zd * gp->field_data[i].apower * gp->field[dist];
- strength *= 2.0 * field[dist];
+ strength *= 2.0 * gp->field[dist];
}
if (incremental)
{
- xd += offset_x * freak * freak;
- yd += offset_y * freak * freak;
- zd += offset_z * freak * freak;
+ xd += offset_x * gp->freak * gp->freak;
+ yd += offset_y * gp->freak * gp->freak;
+ zd += offset_z * gp->freak * gp->freak;
}
if (incremental == 1)
{
yd += offset_y;
zd += offset_z;
}
- xd += blob_center.x;
- yd += blob_center.y;
- zd += blob_center.z;
+ xd += gp->blob_center.x;
+ yd += gp->blob_center.y;
+ zd += gp->blob_center.z;
if (do_colour)
{
- colours[index].red = 128 + (int)(sin(strength + colour_cycle * 0.01 + 2.0 * PI * x / row_data[y].num_x_points) * 127.0);
- colours[index].green = 128 + (int)(cos(strength + colour_cycle * 0.025) * 127.0);
- colours[index].blue = 128 + (int)(sin(strength + colour_cycle * 0.03 + 2.0 * PI * y / y_resolution) * 127.0);
- colours[index].alpha = (int)(255.0 * fade);
+ gp->colours[index].red = 128 + (int)(sin(strength + gp->colour_cycle * 0.01 + 2.0 * PI * x / gp->row_data[y].num_x_points) * 127.0);
+ gp->colours[index].green = 128 + (int)(cos(strength + gp->colour_cycle * 0.025) * 127.0);
+ gp->colours[index].blue = 128 + (int)(sin(strength + gp->colour_cycle * 0.03 + 2.0 * PI * y / y_resolution) * 127.0);
+ gp->colours[index].alpha = (int)(255.0 * fade);
}
/* Add walls */
dist = field_array_size * (zd + limit) * (zd + limit) * 0.5;
if (dist < field_array_size)
{
- xd += (xd - blob_center.x) * wall_field[dist];
- yd += (yd - blob_center.y) * wall_field[dist];
- blob_force.z += (zd + limit);
+ xd += (xd - gp->blob_center.x) * gp->wall_field[dist];
+ yd += (yd - gp->blob_center.y) * gp->wall_field[dist];
+ gp->blob_force.z += (zd + limit);
}
else
{
dist = field_array_size * (zd - limit) * (zd - limit) * 0.5;
if (dist < field_array_size)
{
- xd += (xd - blob_center.x) * wall_field[dist];
- yd += (yd - blob_center.y) * wall_field[dist];
- blob_force.z -= (zd - limit);
+ xd += (xd - gp->blob_center.x) * gp->wall_field[dist];
+ yd += (yd - gp->blob_center.y) * gp->wall_field[dist];
+ gp->blob_force.z -= (zd - limit);
}
if (yd < -limit) yd = -limit;
dist = field_array_size * (yd + limit) * (yd + limit) * 0.5;
if (dist < field_array_size)
{
- xd += (xd - blob_center.x) * wall_field[dist];
- zd += (zd - blob_center.z) * wall_field[dist];
- blob_force.y += (yd + limit);
+ xd += (xd - gp->blob_center.x) * gp->wall_field[dist];
+ zd += (zd - gp->blob_center.z) * gp->wall_field[dist];
+ gp->blob_force.y += (yd + limit);
}
else
{
dist = field_array_size * (yd - limit) * (yd - limit) * 0.5;
if (dist < field_array_size)
{
- xd += (xd - blob_center.x) * wall_field[dist];
- zd += (zd - blob_center.z) * wall_field[dist];
- blob_force.y -= (yd - limit);
+ xd += (xd - gp->blob_center.x) * gp->wall_field[dist];
+ zd += (zd - gp->blob_center.z) * gp->wall_field[dist];
+ gp->blob_force.y -= (yd - limit);
}
}
dist = field_array_size * (xd + limit) * (xd + limit) * 0.5;
if (dist < field_array_size)
{
- yd += (yd - blob_center.y) * wall_field[dist];
- zd += (zd - blob_center.z) * wall_field[dist];
- blob_force.x += (xd + limit);
+ yd += (yd - gp->blob_center.y) * gp->wall_field[dist];
+ zd += (zd - gp->blob_center.z) * gp->wall_field[dist];
+ gp->blob_force.x += (xd + limit);
}
else
{
dist = field_array_size * (xd - limit) * (xd - limit) * 0.5;
if (dist < field_array_size)
{
- yd += (yd - blob_center.y) * wall_field[dist];
- zd += (zd - blob_center.z) * wall_field[dist];
- blob_force.x -= (xd - limit);
+ yd += (yd - gp->blob_center.y) * gp->wall_field[dist];
+ zd += (zd - gp->blob_center.z) * gp->wall_field[dist];
+ gp->blob_force.x -= (xd - limit);
}
}
}
}
- dots[index].x = xd;
- dots[index].y = yd;
- dots[index].z = zd;
+ gp->dots[index].x = xd;
+ gp->dots[index].y = yd;
+ gp->dots[index].z = zd;
}
}
index1 = 0;
index2 = y * x_resolution;
index3 = 1 + y * x_resolution;
- calculate_normal (dots[index1], dots[index2], dots[index3], &normals[index1]);
+ calculate_normal (gp->dots[index1], gp->dots[index2], gp->dots[index3], &gp->normals[index1]);
if (do_texture)
{
if (offset_texture)
{
- tex_coords[index1].x = dots[index1].x * 0.125 + 0.5
- * (1.0 + 0.25 * asin(normals[index1].x) / (0.5 * PI));
- tex_coords[index1].y = dots[index1].y * 0.125 + 0.5
- * (1.0 + 0.25 * asin(normals[index1].y) / (0.5 * PI));
+ gp->tex_coords[index1].x = gp->dots[index1].x * 0.125 + 0.5
+ * (1.0 + 0.25 * asin(gp->normals[index1].x) / (0.5 * PI));
+ gp->tex_coords[index1].y = gp->dots[index1].y * 0.125 + 0.5
+ * (1.0 + 0.25 * asin(gp->normals[index1].y) / (0.5 * PI));
}
else
{
- tex_coords[index1].x = 0.5 * (1.0 + (asin(normals[index1].x)
+ gp->tex_coords[index1].x = 0.5 * (1.0 + (asin(gp->normals[index1].x)
/ (0.5 * PI)));
- tex_coords[index1].y = 0.5 * (1.0 + (asin(normals[index1].y)
+ gp->tex_coords[index1].y = 0.5 * (1.0 + (asin(gp->normals[index1].y)
/ (0.5 * PI)));
}
- tex_coords[index1].x *= tex_width[current_texture];
- tex_coords[index1].y *= tex_height[current_texture];
+ gp->tex_coords[index1].x *= gp->tex_width[gp->current_texture];
+ gp->tex_coords[index1].y *= gp->tex_height[gp->current_texture];
}
for (y = 1; y < y_resolution - 1; y++)
{
- if (row_data[y - 1].num_x_points)
+ if (gp->row_data[y - 1].num_x_points)
{
- for (x = 0; x < row_data[y].num_x_points; x++)
+ for (x = 0; x < gp->row_data[y].num_x_points; x++)
{
- if (x == row_data[y].num_x_points - 1)
+ if (x == gp->row_data[y].num_x_points - 1)
{
index1 = y * x_resolution;
}
index1 = x + 1 + y * x_resolution;
}
index2 = x + y * x_resolution;
- index3 = ((x + 0.5) * row_data[y - 1].num_x_points
- / row_data[y].num_x_points) + (y - 1) * x_resolution;
- calculate_normal (dots[index1], dots[index2], dots[index3],
- &normals[index1]);
+ index3 = ((x + 0.5) * gp->row_data[y - 1].num_x_points
+ / gp->row_data[y].num_x_points) + (y - 1) * x_resolution;
+ calculate_normal (gp->dots[index1], gp->dots[index2], gp->dots[index3],
+ &gp->normals[index1]);
if (do_texture)
{
if (offset_texture)
{
- tex_coords[index1].x = dots[index1].x * 0.125 + 0.5
- * (1.0 + 0.25 * asin(normals[index1].x) / (0.5 * PI));
- tex_coords[index1].y = dots[index1].y * 0.125 + 0.5
- * (1.0 + 0.25 * asin(normals[index1].y) / (0.5 * PI));
+ gp->tex_coords[index1].x = gp->dots[index1].x * 0.125 + 0.5
+ * (1.0 + 0.25 * asin(gp->normals[index1].x) / (0.5 * PI));
+ gp->tex_coords[index1].y = gp->dots[index1].y * 0.125 + 0.5
+ * (1.0 + 0.25 * asin(gp->normals[index1].y) / (0.5 * PI));
}
else
{
- tex_coords[index1].x = 0.5 * (1.0 + (asin(normals[index1].x)
+ gp->tex_coords[index1].x = 0.5 * (1.0 + (asin(gp->normals[index1].x)
/ (0.5 * PI)));
- tex_coords[index1].y = 0.5 * (1.0 + (asin(normals[index1].y)
+ gp->tex_coords[index1].y = 0.5 * (1.0 + (asin(gp->normals[index1].y)
/ (0.5 * PI)));
}
- tex_coords[index1].x *= tex_width[current_texture];
- tex_coords[index1].y *= tex_height[current_texture];
+ gp->tex_coords[index1].x *= gp->tex_width[gp->current_texture];
+ gp->tex_coords[index1].y *= gp->tex_height[gp->current_texture];
}
}
}
index1 = (y_resolution - 1) * x_resolution;
index2 = (y_resolution - 2) * x_resolution;
index3 = 1 + (y_resolution - 2) * x_resolution;
- calculate_normal (dots[index1], dots[index2], dots[index3], &normals[index1]);
+ calculate_normal (gp->dots[index1], gp->dots[index2], gp->dots[index3], &gp->normals[index1]);
if (do_texture)
{
if (offset_texture)
{
- tex_coords[index1].x = dots[index1].x * 0.125 + 0.5
- * (1.0 + 0.25 * asin(normals[index1].x) / (0.5 * PI));
- tex_coords[index1].y = dots[index1].y * 0.125 + 0.5
- * (1.0 + 0.25 * asin(normals[index1].y) / (0.5 * PI));
+ gp->tex_coords[index1].x = gp->dots[index1].x * 0.125 + 0.5
+ * (1.0 + 0.25 * asin(gp->normals[index1].x) / (0.5 * PI));
+ gp->tex_coords[index1].y = gp->dots[index1].y * 0.125 + 0.5
+ * (1.0 + 0.25 * asin(gp->normals[index1].y) / (0.5 * PI));
}
else
{
- tex_coords[index1].x = 0.5 * (1.0 + (asin(normals[index1].x)
+ gp->tex_coords[index1].x = 0.5 * (1.0 + (asin(gp->normals[index1].x)
/ (0.5 * PI)));
- tex_coords[index1].y = 0.5 * (1.0 + (asin(normals[index1].y)
+ gp->tex_coords[index1].y = 0.5 * (1.0 + (asin(gp->normals[index1].y)
/ (0.5 * PI)));
}
- tex_coords[index1].x *= tex_width[current_texture];
- tex_coords[index1].y *= tex_height[current_texture];
+ gp->tex_coords[index1].x *= gp->tex_width[gp->current_texture];
+ gp->tex_coords[index1].y *= gp->tex_height[gp->current_texture];
}
- freak += v_freak;
- v_freak += -freak / 2000000.0;
+ gp->freak += gp->v_freak;
+ gp->v_freak += -gp->freak / 2000000.0;
/* Update the center of the whole blob */
- blob_velocity.x += (blob_anchor.x - blob_center.x) / 80.0
- + 0.01 * blob_force.x / num_points;
- blob_velocity.y += (blob_anchor.y - blob_center.y) / 80.0
- + 0.01 * blob_force.y / num_points;
- blob_velocity.z += (blob_anchor.z - blob_center.z) / 80.0
- + 0.01 * blob_force.z / num_points;
-
- blob_center.x += blob_velocity.x * 0.5;
- blob_center.y += blob_velocity.y * 0.5;
- blob_center.z += blob_velocity.z * 0.5;
-
- blob_velocity.x *= 0.99;
- blob_velocity.y *= 0.99;
- blob_velocity.z *= 0.99;
+ gp->blob_velocity.x += (gp->blob_anchor.x - gp->blob_center.x) / 80.0
+ + 0.01 * gp->blob_force.x / gp->num_points;
+ gp->blob_velocity.y += (gp->blob_anchor.y - gp->blob_center.y) / 80.0
+ + 0.01 * gp->blob_force.y / gp->num_points;
+ gp->blob_velocity.z += (gp->blob_anchor.z - gp->blob_center.z) / 80.0
+ + 0.01 * gp->blob_force.z / gp->num_points;
+
+ gp->blob_center.x += gp->blob_velocity.x * 0.5;
+ gp->blob_center.y += gp->blob_velocity.y * 0.5;
+ gp->blob_center.z += gp->blob_velocity.z * 0.5;
+
+ gp->blob_velocity.x *= 0.99;
+ gp->blob_velocity.y *= 0.99;
+ gp->blob_velocity.z *= 0.99;
}
/******************************************************************************
* with the more interesting bits of the code.
*/
static void
-draw_blob (void)
+draw_blob (mirrorblobstruct *gp)
{
int x, y, x2, x3;
int index1, index2, index3;
for (y = 1; y < y_resolution; y++)
{
- if (row_data[y - 1].num_x_points)
+ if (gp->row_data[y - 1].num_x_points)
{
- for (x = 0; x < row_data[y].num_x_points; x++)
+ for (x = 0; x < gp->row_data[y].num_x_points; x++)
{
glBegin (GL_TRIANGLES);
- if (x == row_data[y].num_x_points - 1)
+ if (x == gp->row_data[y].num_x_points - 1)
{
index1 = y * x_resolution;
}
index1 = x + 1 + y * x_resolution;
}
index2 = x + y * x_resolution;
- index3 = ((x + 0.5) * row_data[y - 1].num_x_points
- / row_data[y].num_x_points) + (y - 1) * x_resolution;
+ index3 = ((x + 0.5) * gp->row_data[y - 1].num_x_points
+ / gp->row_data[y].num_x_points) + (y - 1) * x_resolution;
glArrayElement(index1);
glArrayElement(index2);
glArrayElement(index3);
glEnd();
- lower = ((x - 0.5) * row_data[y - 1].num_x_points
- / (float)row_data[y].num_x_points);
- upper = ((x + 0.5) * row_data[y - 1].num_x_points
- / (float)row_data[y].num_x_points);
+ lower = ((x - 0.5) * gp->row_data[y - 1].num_x_points
+ / (float)gp->row_data[y].num_x_points);
+ upper = ((x + 0.5) * gp->row_data[y - 1].num_x_points
+ / (float)gp->row_data[y].num_x_points);
if (upper > lower)
{
for (x2 = lower; x2 <= upper; x2++)
{
x3 = x2;
- while (x3 < 0) x3 += row_data[y - 1].num_x_points;
- while (x3 >= row_data[y - 1].num_x_points)
- x3 -= row_data[y - 1].num_x_points;
+ while (x3 < 0) x3 += gp->row_data[y - 1].num_x_points;
+ while (x3 >= gp->row_data[y - 1].num_x_points)
+ x3 -= gp->row_data[y - 1].num_x_points;
index2 = x3 + (y - 1) * x_resolution;
if (x2 < upper)
{
x3 = x2 + 1;
- while (x3 < 0) x3 += row_data[y - 1].num_x_points;
- while (x3 >= row_data[y - 1].num_x_points)
- x3 -= row_data[y - 1].num_x_points;
+ while (x3 < 0) x3 += gp->row_data[y - 1].num_x_points;
+ while (x3 >= gp->row_data[y - 1].num_x_points)
+ x3 -= gp->row_data[y - 1].num_x_points;
index3 = x3 + (y - 1) * x_resolution;
if (x2 == lower)
{
static void
draw_background (ModeInfo *mi)
{
+ mirrorblobstruct *gp = &Mirrorblob[MI_SCREEN(mi)];
+
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glEnable (GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glTexCoord2f (0.0, 0.0);
glVertex2i (0, 0);
- glTexCoord2f (0.0, -tex_height[current_texture]);
+ glTexCoord2f (0.0, -gp->tex_height[gp->current_texture]);
glVertex2i (0, MI_HEIGHT(mi));
- glTexCoord2f (tex_width[current_texture], -tex_height[current_texture]);
+ glTexCoord2f (gp->tex_width[gp->current_texture], -gp->tex_height[gp->current_texture]);
glVertex2i (MI_WIDTH(mi), MI_HEIGHT(mi));
- glTexCoord2f (tex_width[current_texture], 0.0);
+ glTexCoord2f (gp->tex_width[gp->current_texture], 0.0);
glVertex2i (MI_WIDTH(mi), 0);
glEnd();
static GLvoid
draw_scene(ModeInfo * mi)
{
+ mirrorblobstruct *gp = &Mirrorblob[MI_SCREEN(mi)];
+
double fade = 0.0;
double current_time;
check_gl_error ("draw_scene");
glColor4d(1.0, 1.0, 1.0, 1.0);
current_time = double_time();
- switch (state)
+ switch (gp->state)
{
case TRANSITIONING:
- fade = (current_time - state_start_time) / fade_time;
+ fade = (current_time - gp->state_start_time) / fade_time;
break;
case HOLDING:
*/
if (do_texture)
{
- glBindTexture (GL_TEXTURE_2D, textures[current_texture]);
+ glBindTexture (GL_TEXTURE_2D, gp->textures[gp->current_texture]);
}
if (do_paint_background && !do_wire)
/* When transitioning between two images paint the new image over the old
* image with a varying alpha value to get a smooth fade.
*/
- if (state == TRANSITIONING)
+ if (gp->state == TRANSITIONING)
{
glDisable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
/* Select the texture to transition to */
- glBindTexture (GL_TEXTURE_2D, textures[1 - current_texture]);
+ glBindTexture (GL_TEXTURE_2D, gp->textures[1 - gp->current_texture]);
glColor4d (1.0, 1.0, 1.0, fade);
draw_background (mi);
/* Select the original texture to draw the blob */
- glBindTexture (GL_TEXTURE_2D, textures[current_texture]);
+ glBindTexture (GL_TEXTURE_2D, gp->textures[gp->current_texture]);
glEnable (GL_DEPTH_TEST);
}
/* Clear the depth buffer bit so the backgound is behind the blob */
fade = fade * 0.5;
}
- calc_blob(MI_WIDTH(mi), MI_HEIGHT(mi), 1024, 2.5, fade);
+ calc_blob(gp, MI_WIDTH(mi), MI_HEIGHT(mi), 1024, 2.5, fade);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDisable (GL_BLEND);
glColor4d (1.0, 1.0, 1.0, 1.0);
}
- draw_blob();
+ draw_blob(gp);
if (do_blend && do_colour)
{
*/
if (do_texture && (hold_time > 0))
{
- switch (state)
+ switch (gp->state)
{
case TRANSITIONING:
glClear(GL_DEPTH_BUFFER_BIT);
glEnable (GL_BLEND);
/* Select the texture to transition to */
- glBindTexture (GL_TEXTURE_2D, textures[1 - current_texture]);
+ glBindTexture (GL_TEXTURE_2D, gp->textures[1 - gp->current_texture]);
glColor4d (1.0, 1.0, 1.0, fade);
- draw_blob ();
+ draw_blob (gp);
- if ((current_time - state_start_time) > fade_time)
+ if ((current_time - gp->state_start_time) > fade_time)
{
- state = HOLDING;
- state_start_time = current_time;
- current_texture = 1 - current_texture;
+ gp->state = HOLDING;
+ gp->state_start_time = current_time;
+ gp->current_texture = 1 - gp->current_texture;
}
break;
case HOLDING:
- if ((current_time - state_start_time) > hold_time)
+ if ((current_time - gp->state_start_time) > hold_time)
{
- grab_texture (mi, 1 - current_texture);
- state = TRANSITIONING;
+ grab_texture (mi, 1 - gp->current_texture);
+ gp->state = TRANSITIONING;
/* Get the time again rather than using the current time so
* that the time taken by the grab_texture function is not part
* of the fade time
*/
- state_start_time = double_time();
+ gp->state_start_time = double_time();
}
break;
}
/******************************************************************************
*
- * XScreensaver screen update entry
+ * XMirrorblob screen update entry
*/
-void
-draw_screensaver(ModeInfo * mi)
+ENTRYPOINT void
+draw_mirrorblob(ModeInfo * mi)
{
- screensaverstruct *gp = &Screensaver[MI_SCREEN(mi)];
+ mirrorblobstruct *gp = &Mirrorblob[MI_SCREEN(mi)];
Display *display = MI_DISPLAY(mi);
Window window = MI_WINDOW(mi);
if (!gp->glx_context)
return;
+ /* Wait for the first image; for subsequent images, load them in the
+ background while animating. */
+ if (gp->waiting_for_image_p && gp->first_image_p)
+ return;
+
glXMakeCurrent(display, window, *(gp->glx_context));
draw_scene(mi);
if (mi->fps_p) do_fps (mi);
/******************************************************************************
*
- * XScreensaver screen resize entry
+ * XMirrorblob screen resize entry
*/
-void
-reshape_screensaver(ModeInfo *mi, int width, int height)
+ENTRYPOINT void
+reshape_mirrorblob(ModeInfo *mi, int width, int height)
{
glViewport( 0, 0, MI_WIDTH(mi), MI_HEIGHT(mi) );
reset_projection(width, height);
/******************************************************************************
*
- * XScreensaver initialise entry
+ * XMirrorblob initialise entry
*/
-void
-init_screensaver(ModeInfo * mi)
+ENTRYPOINT void
+init_mirrorblob(ModeInfo * mi)
{
int screen = MI_SCREEN(mi);
- screensaverstruct *gp;
+ mirrorblobstruct *gp;
- if (Screensaver == NULL)
+ if (Mirrorblob == NULL)
{
- if ((Screensaver = (screensaverstruct *)
- calloc(MI_NUM_SCREENS(mi), sizeof (screensaverstruct))) == NULL)
+ if ((Mirrorblob = (mirrorblobstruct *)
+ calloc(MI_NUM_SCREENS(mi), sizeof (mirrorblobstruct))) == NULL)
{
return;
}
}
- gp = &Screensaver[screen];
+ gp = &Mirrorblob[screen];
gp->window = MI_WINDOW(mi);
if ((gp->glx_context = init_GL(mi)) != NULL)
{
- reshape_screensaver(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+ reshape_mirrorblob(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
initialize_gl(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
}
else
MI_CLEARWINDOW(mi);
}
- initialise_blob(MI_WIDTH(mi), MI_HEIGHT(mi), 1024);
- state_start_time = double_time();
+ initialise_blob(gp, MI_WIDTH(mi), MI_HEIGHT(mi), 1024);
+ gp->state_start_time = double_time();
+
+ gp->freak = 0.0;
+ gp->v_freak = 0.0007;
+ gp->first_image_p = True;
}
/******************************************************************************
*
- * XScreensaver cleanup entry
+ * XMirrorblob cleanup entry
*/
-void
-release_screensaver(ModeInfo * mi)
+ENTRYPOINT void
+release_mirrorblob(ModeInfo * mi)
{
- if (row_data) free(row_data);
- if (field_data) free(field_data);
- if (colours) free(colours);
- if (tex_coords) free(tex_coords);
- if (dots) free(dots);
- if (wall_field) free(wall_field);
- if (field) free(field);
-
- if (Screensaver != NULL)
- {
- (void) free((void *) Screensaver);
- Screensaver = NULL;
+ if (Mirrorblob != NULL) {
+ int i;
+ for (i = 0; i < MI_NUM_SCREENS(mi); i++) {
+ mirrorblobstruct *gp = &Mirrorblob[i];
+ if (gp->row_data) free(gp->row_data);
+ if (gp->field_data) free(gp->field_data);
+ if (gp->colours) free(gp->colours);
+ if (gp->tex_coords) free(gp->tex_coords);
+ if (gp->dots) free(gp->dots);
+ if (gp->wall_field) free(gp->wall_field);
+ if (gp->field) free(gp->field);
}
- FreeAllGL(mi);
+
+ free(Mirrorblob);
+ Mirrorblob = NULL;
+ }
+ FreeAllGL(mi);
}
+
+XSCREENSAVER_MODULE ("MirrorBlob", mirrorblob)
+
#endif