/* gflux - creates a fluctuating 3D grid
* requires OpenGL or MesaGL
*
- * Copyright (c) Josiah Pease, 2000
+ * Copyright (c) Josiah Pease, 2000, 2003
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
*/
-/*-
- * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock.
- * otherwise caddr_t is not defined correctly
- */
-
-#include <X11/Intrinsic.h>
-
-
#ifdef STANDALONE
-# define PROGCLASS "gflux"
-# define HACK_INIT init_gflux
-# define HACK_DRAW draw_gflux
-# define HACK_RESHAPE reshape_gflux
-# define HACK_HANDLE_EVENT gflux_handle_event
-# define EVENT_MASK PointerMotionMask
-# define gflux_opts xlockmore_opts
-#define DEFAULTS "*delay: 20000 \n" \
- "*showFPS: False \n" \
- "*mode: light" "\n" \
- "*squares: 19 \n" \
- "*resolution: 0 \n" \
- "*flat: 0 \n" \
- "*speed: 0.05 \n" \
- "*rotationx: 0.01 \n" \
- "*rotationy: 0.0 \n" \
- "*rotationz: 0.1 \n" \
- "*waves: 3 \n" \
- "*waveChange: 50 \n" \
- "*waveHeight: 0.8 \n" \
- "*waveFreq: 3.0 \n" \
- "*zoom: 1.0 \n"
+#define DEFAULTS "*delay: 20000\n" \
+ "*showFPS: False\n" \
+ "*mode: light\n" \
+ "*useSHM: True \n"
+# define refresh_gflux 0
# include "xlockmore.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
# include "xlock.h" /* from the xlockmore distribution */
# endif /* VMS */
#endif
-#ifdef HAVE_PPM
-#include <ppm.h>
-#endif
-
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
#include <stdlib.h>
#include <stdio.h>
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <GL/glx.h>
-
#include <math.h>
#include "grab-ximage.h"
#include "gltrackball.h"
-static enum {wire=0,solid,light,checker,textured,grab} _draw; /* draw style */
-static int _squares = 19; /* grid size */
-static int _resolution = 4; /* wireframe resolution */
-static int _flat = 0;
+static enum {wire=0,solid,light,checker,grab} _draw;
+
+# define DEF_SQUARES "19"
+# define DEF_RESOLUTION "4"
+# define DEF_DRAW "2"
+# define DEF_FLAT "0"
+# define DEF_SPEED "0.05"
+# define DEF_ROTATIONX "0.01"
+# define DEF_ROTATIONY "0.0"
+# define DEF_ROTATIONZ "0.1"
+# define DEF_WAVES "3"
+# define DEF_WAVE_CHANGE "50"
+# define DEF_WAVE_HEIGHT "1.0"
+# define DEF_WAVE_FREQ "3.0"
+# define DEF_ZOOM "1.0"
+
+
+
+static int _squares; /* grid size */
+static int _resolution; /* wireframe resolution */
+static int _flat;
-static float _speed = 0.05;
-static float _rotationx = 0.01;
-static float _rotationy = 0.0;
-static float _rotationz = 0.1;
-static float _zoom = 1.0;
+static float _speed;
+static float _rotationx;
+static float _rotationy;
+static float _rotationz;
+static float _zoom;
-static int _waves = 3;
-static int _waveChange = 50;
-static float _waveHeight = 1.0;
-static float _waveFreq = 3.0;
+static int _waves;
+static int _waveChange;
+static float _waveHeight;
+static float _waveFreq;
-static trackball_state *trackball;
-static Bool button_down_p = False;
#define WIDTH 320
#define HEIGHT 240
static XrmOptionDescRec opts[] = {
- {"-squares", ".gflux.squares", XrmoptionSepArg, (caddr_t) NULL},
- {"-resolution", ".gflux.resolution", XrmoptionSepArg, (caddr_t) NULL},
-/* {"-draw", ".gflux.draw", XrmoptionSepArg, (caddr_t) NULL},*/
- {"-mode", ".gflux.mode", XrmoptionSepArg, (caddr_t) NULL},
- {"-flat", ".gflux.flat", XrmoptionSepArg, (caddr_t) NULL},
- {"-speed", ".gflux.speed", XrmoptionSepArg, (caddr_t) NULL},
- {"-rotationx", ".gflux.rotationx", XrmoptionSepArg, (caddr_t) NULL},
- {"-rotationy", ".gflux.rotationy", XrmoptionSepArg, (caddr_t) NULL},
- {"-rotationz", ".gflux.rotationz", XrmoptionSepArg, (caddr_t) NULL},
- {"-waves", ".gflux.waves", XrmoptionSepArg, (caddr_t) NULL},
- {"-waveChange", ".gflux.waveChange", XrmoptionSepArg, (caddr_t) NULL},
- {"-waveHeight", ".gflux.waveHeight", XrmoptionSepArg, (caddr_t) NULL},
- {"-waveFreq", ".gflux.waveFreq", XrmoptionSepArg, (caddr_t) NULL},
- {"-zoom", ".gflux.zoom", XrmoptionSepArg, (caddr_t) NULL},
+ {"-squares", ".gflux.squares", XrmoptionSepArg, 0},
+ {"-resolution", ".gflux.resolution", XrmoptionSepArg, 0},
+/* {"-draw", ".gflux.draw", XrmoptionSepArg, 0},*/
+ {"-mode", ".gflux.mode", XrmoptionSepArg, 0},
+ {"-wireframe", ".gflux.mode", XrmoptionNoArg, "wire"},
+ {"-flat", ".gflux.flat", XrmoptionSepArg, 0},
+ {"-speed", ".gflux.speed", XrmoptionSepArg, 0},
+ {"-rotationx", ".gflux.rotationx", XrmoptionSepArg, 0},
+ {"-rotationy", ".gflux.rotationy", XrmoptionSepArg, 0},
+ {"-rotationz", ".gflux.rotationz", XrmoptionSepArg, 0},
+ {"-waves", ".gflux.waves", XrmoptionSepArg, 0},
+ {"-waveChange", ".gflux.waveChange", XrmoptionSepArg, 0},
+ {"-waveHeight", ".gflux.waveHeight", XrmoptionSepArg, 0},
+ {"-waveFreq", ".gflux.waveFreq", XrmoptionSepArg, 0},
+ {"-zoom", ".gflux.zoom", XrmoptionSepArg, 0},
};
static argtype vars[] = {
- {(caddr_t *) & _squares, "squares", "Squares", "19", t_Int},
- {(caddr_t *) & _resolution, "resolution", "Resolution", "4", t_Int},
-/* {(caddr_t *) & _draw, "draw", "Draw", "2", t_Int},*/
- {(caddr_t *) & _flat, "flat", "Flat", "0", t_Int},
- {(caddr_t *) & _speed, "speed", "Speed", "0.05", t_Float},
- {(caddr_t *) & _rotationx, "rotationx", "Rotationx", "0.01", t_Float},
- {(caddr_t *) & _rotationy, "rotationy", "Rotationy", "0.0", t_Float},
- {(caddr_t *) & _rotationz, "rotationz", "Rotationz", "0.1", t_Float},
- {(caddr_t *) & _waves, "waves", "Waves", "3", t_Int},
- {(caddr_t *) & _waveChange, "waveChange", "WaveChange", "50", t_Int},
- {(caddr_t *) & _waveHeight, "waveHeight", "WaveHeight", "1.0", t_Float},
- {(caddr_t *) & _waveFreq, "waveFreq", "WaveFreq", "3.0", t_Float},
- {(caddr_t *) & _zoom, "zoom", "Zoom", "1.0", t_Float},
+ {&_squares, "squares", "Squares", DEF_SQUARES, t_Int},
+ {&_resolution, "resolution", "Resolution", DEF_RESOLUTION, t_Int},
+/* {&_draw, "draw", "Draw", DEF_DRAW, t_Int},*/
+ {&_flat, "flat", "Flat", DEF_FLAT, t_Int},
+ {&_speed, "speed", "Speed", DEF_SPEED, t_Float},
+ {&_rotationx, "rotationx", "Rotationx", DEF_ROTATIONX, t_Float},
+ {&_rotationy, "rotationy", "Rotationy", DEF_ROTATIONY, t_Float},
+ {&_rotationz, "rotationz", "Rotationz", DEF_ROTATIONZ, t_Float},
+ {&_waves, "waves", "Waves", DEF_WAVES, t_Int},
+ {&_waveChange, "waveChange", "WaveChange", DEF_WAVE_CHANGE, t_Int},
+ {&_waveHeight, "waveHeight", "WaveHeight", DEF_WAVE_HEIGHT, t_Float},
+ {&_waveFreq, "waveFreq", "WaveFreq", DEF_WAVE_FREQ, t_Float},
+ {&_zoom, "zoom", "Zoom", DEF_ZOOM, t_Float},
};
{"-zoom num", "camera control (1.0)"},
};
-ModeSpecOpt gflux_opts = {countof(opts), opts, countof(vars), vars, desc};
+ENTRYPOINT ModeSpecOpt gflux_opts = {countof(opts), opts, countof(vars), vars, desc};
#ifdef USE_MODULES
ModStruct gflux_description =
{"gflux", "init_gflux", "draw_gflux", "release_gflux",
"draw_gflux", "init_gflux", NULL, &gflux_opts,
1000, 1, 2, 1, 4, 1.0, "",
- "Gflux: an OpenGL gflux", 0, NULL};
+ "GFlux: an OpenGL gflux", 0, NULL};
#endif
/* structure for holding the gflux data */
-typedef struct {
+typedef struct gfluxstruct {
ModeInfo *modeinfo;
int screen_width, screen_height;
GLXContext *glx_context;
double dispy[MAXWAVES];
double dispx[MAXWAVES];
GLfloat colour[3];
- int imageWidth;
- int imageHeight;
-#ifdef HAVE_PPM
- pixval imageMax;
- pixel **image;
-#else
- int imageMax;
- GLubyte *image;
-#endif
- GLint texName;
+ GLuint texName;
GLfloat tex_xscale;
GLfloat tex_yscale;
- void (*drawFunc)(void);
+ XRectangle img_geom;
+ int img_width, img_height;
+ int (*drawFunc)(struct gfluxstruct *);
+
+ trackball_state *trackball;
+ Bool button_down_p;
+
+ double time;
+ double anglex;
+ double angley;
+ double anglez;
+
+ int counter;
+ int newWave;
+
+ Bool mipmap_p;
+ Bool waiting_for_image_p;
+
} gfluxstruct;
-static gfluxstruct *gflux = NULL;
+static gfluxstruct *gfluxes = NULL;
/* prototypes */
-void initLighting(void);
-void initTexture(void);
-void loadTexture(void);
-void grabTexture(void);
-void createTexture(void);
-void displaySolid(void); /* drawFunc implementations */
-void displayLight(void);
-void displayTexture(void);
-void displayWire(void);
-void calcGrid(void);
-double getGrid(double,double,double);
+static void initLighting(void);
+static void grabTexture(gfluxstruct *);
+static void createTexture(gfluxstruct *);
+static int displaySolid(gfluxstruct *); /* drawFunc implementations */
+static int displayLight(gfluxstruct *);
+static int displayTexture(gfluxstruct *);
+static int displayWire(gfluxstruct *);
+static void calcGrid(gfluxstruct *);
+static double getGrid(gfluxstruct *,double,double,double);
/* as macro for speed */
/* could do with colour cycling here */
/* void genColour(double);*/
#define genColour(X) \
{\
- gflux->colour[0] = 0.0;\
- gflux->colour[1] = 0.5+0.5*(X);\
- gflux->colour[2] = 0.5-0.5*(X);\
+ gp->colour[0] = 0.0;\
+ gp->colour[1] = 0.5+0.5*(X);\
+ gp->colour[2] = 0.5-0.5*(X);\
}
/* BEGINNING OF FUNCTIONS */
-Bool
+ENTRYPOINT Bool
gflux_handle_event (ModeInfo *mi, XEvent *event)
{
+ gfluxstruct *gp = &gfluxes[MI_SCREEN(mi)];
+
if (event->xany.type == ButtonPress &&
- event->xbutton.button & Button1)
+ event->xbutton.button == Button1)
{
- button_down_p = True;
- gltrackball_start (trackball,
+ gp->button_down_p = True;
+ gltrackball_start (gp->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)
+ event->xbutton.button == Button1)
+ {
+ gp->button_down_p = False;
+ return True;
+ }
+ else if (event->xany.type == ButtonPress &&
+ (event->xbutton.button == Button4 ||
+ event->xbutton.button == Button5 ||
+ event->xbutton.button == Button6 ||
+ event->xbutton.button == Button7))
{
- button_down_p = False;
+ gltrackball_mousewheel (gp->trackball, event->xbutton.button, 10,
+ !!event->xbutton.state);
return True;
}
else if (event->xany.type == MotionNotify &&
- button_down_p)
+ gp->button_down_p)
{
- gltrackball_track (trackball,
+ gltrackball_track (gp->trackball,
event->xmotion.x, event->xmotion.y,
MI_WIDTH (mi), MI_HEIGHT (mi));
return True;
static void
-userRot(void)
+userRot(gfluxstruct *gp)
{
- gltrackball_rotate (trackball);
+ /* Do it twice because we don't track the device's orientation. */
+ glRotatef( current_device_rotation(), 0, 0, 1);
+ gltrackball_rotate (gp->trackball);
+ glRotatef(-current_device_rotation(), 0, 0, 1);
}
/* draw the gflux once */
-void draw_gflux(ModeInfo * mi)
+ENTRYPOINT void draw_gflux(ModeInfo * mi)
{
- gfluxstruct *gp = &gflux[MI_SCREEN(mi)];
+ gfluxstruct *gp = &gfluxes[MI_SCREEN(mi)];
Display *display = MI_DISPLAY(mi);
Window window = MI_WINDOW(mi);
if (!gp->glx_context) return;
+ /* Just keep running before the texture has come in. */
+ /* if (gp->waiting_for_image_p) return; */
+
glXMakeCurrent(display, window, *(gp->glx_context));
- calcGrid();
- gflux->drawFunc();
+ calcGrid(gp);
+ mi->polygon_count = gp->drawFunc(gp);
if (mi->fps_p) do_fps (mi);
glXSwapBuffers(display, window);
}
/* reset the projection matrix */
-void resetProjection(void) {
+static void resetProjection(void)
+{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-_zoom,_zoom,-0.8*_zoom,0.8*_zoom,2,6);
}
/* Standard reshape function */
-void
+ENTRYPOINT void
reshape_gflux(ModeInfo *mi, int width, int height)
{
glViewport( 0, 0, width, height );
/* main OpenGL initialization routine */
-void initializeGL(ModeInfo *mi, GLsizei width, GLsizei height)
+static void initializeGL(ModeInfo *mi, GLsizei width, GLsizei height)
{
+ gfluxstruct *gp = &gfluxes[MI_SCREEN(mi)];
+
reshape_gflux(mi, width, height);
glViewport( 0, 0, width, height );
- gflux->tex_xscale = 1.0; /* maybe changed later */
- gflux->tex_yscale = 1.0;
+ gp->tex_xscale = 1.0; /* maybe changed later */
+ gp->tex_yscale = 1.0;
switch(_draw) {
case solid :
- gflux->drawFunc = (displaySolid);
+ gp->drawFunc = (displaySolid);
glEnable(GL_DEPTH_TEST);
break;
case light :
- gflux->drawFunc = (displayLight);
+ gp->drawFunc = (displayLight);
glEnable(GL_DEPTH_TEST);
initLighting();
break;
case checker :
- gflux->drawFunc = (displayTexture);
+ gp->drawFunc = (displayTexture);
glEnable(GL_DEPTH_TEST);
- createTexture();
- initTexture();
- initLighting();
- break;
- case textured :
- gflux->drawFunc = (displayTexture);
- glEnable(GL_DEPTH_TEST);
- loadTexture();
- initTexture();
+ createTexture(gp);
initLighting();
break;
case grab :
- gflux->drawFunc = (displayTexture);
+ gp->drawFunc = (displayTexture);
glEnable(GL_DEPTH_TEST);
- grabTexture();
- initTexture();
+ grabTexture(gp);
initLighting();
break;
case wire :
default :
- gflux->drawFunc = (displayWire);
+ gp->drawFunc = (displayWire);
glDisable(GL_DEPTH_TEST);
break;
}
/* xgflux initialization routine */
-void init_gflux(ModeInfo * mi)
+ENTRYPOINT void init_gflux(ModeInfo * mi)
{
int screen = MI_SCREEN(mi);
gfluxstruct *gp;
- if (gflux == NULL) {
- if ((gflux = (gfluxstruct *)
+ if (gfluxes == NULL) {
+ if ((gfluxes = (gfluxstruct *)
calloc(MI_NUM_SCREENS(mi), sizeof (gfluxstruct))) == NULL)
return;
}
- gp = &gflux[screen];
+ gp = &gfluxes[screen];
+
+ gp->trackball = gltrackball_init ();
- trackball = gltrackball_init ();
+ gp->time = frand(1000.0); /* don't run two screens in lockstep */
{
- char *s = get_string_resource ("mode", "Mode");
+ char *s = get_string_resource (mi->dpy, "mode", "Mode");
if (!s || !*s) _draw = wire;
else if (!strcasecmp (s, "wire")) _draw = wire;
else if (!strcasecmp (s, "solid")) _draw = solid;
else if (!strcasecmp (s, "light")) _draw = light;
else if (!strcasecmp (s, "checker")) _draw = checker;
- else if (!strcasecmp (s, "stdin")) _draw = textured;
else if (!strcasecmp (s, "grab")) _draw = grab;
else
{
}
/* cleanup code */
-void release_gflux(ModeInfo * mi)
+ENTRYPOINT void release_gflux(ModeInfo * mi)
{
- if(gflux->image!=NULL) free(gflux->image);
- if(gflux->glx_context!=NULL) free(gflux->glx_context);
- if (gflux != NULL) {
- (void) free((void *) gflux);
- gflux = NULL;
+ if (gfluxes != NULL) {
+ free((void *) gfluxes);
+ gfluxes = NULL;
}
FreeAllGL(mi);
}
-#ifdef HAVE_PPM
-/* load pnm from stdin using pnm libs */
-void loadTexture(void)
+static void createTexture(gfluxstruct *gp)
{
- FILE *file = stdin;
- gflux->image = ppm_readppm( file,
- &(gflux->imageHeight), &(gflux->imageWidth), &(gflux->imageMax) );
-}
+ int size = 4;
+ unsigned int data[] = { 0xFFFFFFFF, 0xAAAAAAAA, 0xFFFFFFFF, 0xAAAAAAAA,
+ 0xAAAAAAAA, 0xFFFFFFFF, 0xAAAAAAAA, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xAAAAAAAA, 0xFFFFFFFF, 0xAAAAAAAA,
+ 0xAAAAAAAA, 0xFFFFFFFF, 0xAAAAAAAA, 0xFFFFFFFF };
-/* creates an image for texture mapping */
-void createTexture(void)
-{
- int i,j,c;
- pixel **result;
+ gp->tex_xscale = size;
+ gp->tex_yscale = size;
- gflux->imageHeight = gflux->imageWidth = 8;
+ glGenTextures (1, &gp->texName);
+ glBindTexture (GL_TEXTURE_2D, gp->texName);
- result = ppm_allocarray(gflux->imageHeight,gflux->imageWidth);
- for(i=0;i<gflux->imageHeight;i++) {
- for(j=0;j<gflux->imageWidth;j++) {
- c = (((i)%2 ^ (j)%2) ? 100 : 200 );
- PPM_ASSIGN( result[i][j] , c, c, c );
- }
- }
- gflux->image = result;
-}
-
-/* specifies image as texture */
-void initTexture(void)
-{
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glGenTextures(1, &gflux->texName);
- glBindTexture(GL_TEXTURE_2D, gflux->texName);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
- clear_gl_error();
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, gflux->imageWidth,
- gflux->imageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, *(gflux->image));
- check_gl_error("texture");
-}
+ glTexImage2D (GL_TEXTURE_2D, 0, 3, size, size, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, data);
-#else /* HAVE_PPM FALSE */
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-#define presult(A,B,C) (*(result+(A)*(gflux->imageWidth)*4+(B)*4+(C)))
-void loadTexture(void)
-{
- int i, j, levels, width, height;
- int red,green,blue;
- char s[4];
- int ppmType=0;
- FILE *file = stdin;
- GLubyte *result;
-
- fgets(s,4,file);
-
- if(!strncmp(s,"P6",2)) ppmType=6;
- if(!strncmp(s,"P5",2)) ppmType=5;
- if(!strncmp(s,"P3",2)) ppmType=3;
- if(!strncmp(s,"P2",2)) ppmType=2;
- if(!ppmType)exit(1);
-
- while((i=getc(file))=='#')
- {
- while(getc(file)!='\n');
- }
- ungetc(i,file);
-
- fscanf(file,"%d %d %d",&width,&height,&levels);
-
- result = malloc(sizeof(GLubyte)*4*width*height);
- gflux->imageWidth = width;
- gflux->imageHeight = height;
-
- switch(ppmType) {
- case 2 : /* ASCII grey */
- for(i=0;i<height;i++) {
- for(j=0;j<width;j++) {
- fscanf(file,"%d",&red);
- presult(j,i,0) = red;
- presult(j,i,1) = red;
- presult(j,i,2) = red;
- }
- }
- break;
- case 3 : /* ASCII rgb */
- for(i=0;i<height;i++) {
- for(j=0;j<width;j++) {
- fscanf(file,"%d %d %d",&red,&green,&blue);
- presult(j,i,0) = red;
- presult(j,i,1) = green;
- presult(j,i,2) = blue;
- }
- }
- break;
- case 5 : /* Binary grey */
- getc(file); /* seems nessessary */
- for(i=0;i<height;i++) {
- for(j=0;j<width;j++) {
- red = getc(file);
- presult(j,i,0) = red;
- presult(j,i,1) = red;
- presult(j,i,2) = red;
- }
- }
- break;
- case 6 : /* Binary rgb */
- getc(file); /* seems nessessary */
- for(i=0;i<height;i++) {
- for(j=0;j<width;j++) {
- red = getc(file);
- green = getc(file);
- blue = getc(file);
- presult(j,i,0) = red;
- presult(j,i,1) = green;
- presult(j,i,2) = blue;
- }
- }
- break;
- }
- gflux->image = result;
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
-void createTexture(void)
-{
- int i,j,c;
- GLubyte *result;
-
- gflux->imageHeight = gflux->imageWidth = 8;
-
- result = malloc(sizeof(GLubyte)*4*gflux->imageHeight*gflux->imageWidth);
- for(i=0;i<gflux->imageHeight;i++) {
- for(j=0;j<gflux->imageWidth;j++) {
- c = (((i)%2 ^ (j)%2) ? 100 : 200 );
- presult(i,j,0) = (GLubyte) c;
- presult(i,j,1) = (GLubyte) c;
- presult(i,j,2) = (GLubyte) c;
- presult(i,j,3) = (GLubyte) 255;
- }
- }
- gflux->image = result;
-}
-/* specifies image as texture */
-void initTexture(void)
+static void
+image_loaded_cb (const char *filename, XRectangle *geometry,
+ int image_width, int image_height,
+ int texture_width, int texture_height,
+ void *closure)
{
- clear_gl_error();
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glGenTextures(1, &gflux->texName);
- glBindTexture(GL_TEXTURE_2D, gflux->texName);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- check_gl_error("texture parameter");
-
- /* Bail out if the texture is too large. */
- {
- GLint width;
- glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, gflux->imageWidth,
- gflux->imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0,
- GL_TEXTURE_WIDTH, &width);
- if (width <= 0)
- {
- glGetIntegerv (GL_MAX_TEXTURE_SIZE, &width);
- fprintf (stderr,
- "%s: texture too large (%dx%d -- probable max %dx%d)\n",
- progname, gflux->imageWidth, gflux->imageHeight,
- width, width);
- return;
- }
- }
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gflux->imageWidth,
- gflux->imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, gflux->image);
- check_gl_error("texture creation");
+ gfluxstruct *gp = (gfluxstruct *) closure;
+ gp->img_geom = *geometry;
+
+ gp->tex_xscale = (GLfloat) image_width / texture_width;
+ gp->tex_yscale = -(GLfloat) image_height / texture_height;
+ gp->img_width = image_width;
+ gp->img_height = image_height;
+
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ (gp->mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR));
+
+ gp->waiting_for_image_p = False;
}
-#undef presult
-#endif
-
-
-void
-grabTexture(void)
+static void
+grabTexture(gfluxstruct *gp)
{
- int real_width = gflux->modeinfo->xgwa.width;
- int real_height = gflux->modeinfo->xgwa.height;
- XImage *ximage = screen_to_ximage (gflux->modeinfo->xgwa.screen,
- gflux->window);
- Bool bigimage = False;
- int size = 0;
-
- if (ximage->width > 1280 || /* that's too damned big... */
- ximage->height > 1280)
- {
- Display *dpy = gflux->modeinfo->dpy;
- Visual *v = gflux->modeinfo->xgwa.visual;
- int real_size = (ximage->width < ximage->height ?
- real_width : real_height);
- XImage *x2;
- int x, y, xoff, yoff;
- size = (ximage->width < ximage->height ?
- ximage->width : ximage->height);
- bigimage = True;
-
- if (size > 1024) size = 1024;
-
- x2 = XCreateImage (dpy, v, 32, ZPixmap, 0, 0, size, size, 32, 0);
- xoff = (real_width > size ? (random() % (real_width - size)) : 0);
- yoff = (real_height > size ? (random() % (real_height - size)) : 0);
-
-# if 0
- fprintf(stderr, "%s: cropping texture from %dx%d to %dx%d @ %d,%d\n",
- progname, ximage->width, ximage->height, x2->width, x2->height,
- xoff, yoff);
-# endif
- x2->data = ximage->data; /* we can reuse the same array */
- for (y = 0; y < x2->height; y++)
- for (x = 0; x < x2->width; x++)
- XPutPixel (x2, x, y, XGetPixel (ximage, x+xoff, y+yoff));
-
- real_width = real_height = real_size;
- ximage->data = 0;
- XDestroyImage (ximage);
- ximage = x2;
- }
-
- /* Add a border. */
- {
- unsigned long gray = 0xAAAAAAAAL; /* so shoot me */
- int width = (bigimage ? size : real_width);
- int height = (bigimage ? size : real_height);
- int i;
- for (i = 0; i < real_height; i++)
- {
- XPutPixel (ximage, 0, i, gray);
- XPutPixel (ximage, width-1, i, gray);
- }
- for (i = 0; i < real_width; i++)
- {
- XPutPixel (ximage, i, 0, gray);
- XPutPixel (ximage, i, height-1, gray);
- }
- }
-
- gflux->imageWidth = ximage->width;
- gflux->imageHeight = ximage->height;
- gflux->image = ximage->data;
-
- if (bigimage) /* don't scale really large images */
- {
- gflux->tex_xscale = 1;
- gflux->tex_yscale = 1;
- }
- else
- {
- gflux->tex_xscale = ((GLfloat) real_width / (GLfloat) ximage->width);
- gflux->tex_yscale = ((GLfloat) real_height / (GLfloat) ximage->height);
- }
-
- ximage->data = 0;
- XDestroyImage (ximage);
+ if (MI_IS_WIREFRAME(gp->modeinfo))
+ return;
+
+ gp->waiting_for_image_p = True;
+ gp->mipmap_p = True;
+ load_texture_async (gp->modeinfo->xgwa.screen, gp->modeinfo->window,
+ *gp->glx_context, 0, 0, gp->mipmap_p, gp->texName,
+ image_loaded_cb, gp);
}
-void initLighting(void)
+static void initLighting(void)
{
- static float ambientA[] = {0.0, 0.0, 0.0, 1.0};
- static float diffuseA[] = {1.0, 1.0, 1.0, 1.0};
- static float positionA[] = {5.0, 5.0, 15.0, 1.0};
+ static const float ambientA[] = {0.0, 0.0, 0.0, 1.0};
+ static const float diffuseA[] = {1.0, 1.0, 1.0, 1.0};
+ static const float positionA[] = {5.0, 5.0, 15.0, 1.0};
- static float front_mat_shininess[] = {30.0};
- static float front_mat_specular[] = {0.5, 0.5, 0.5, 1.0};
+ static const float front_mat_shininess[] = {30.0};
+ static const float front_mat_specular[] = {0.5, 0.5, 0.5, 1.0};
- static float mat_diffuse[] = {0.5, 0.5, 0.5, 1.0};
+ static const float mat_diffuse[] = {0.5, 0.5, 0.5, 1.0};
glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
/* storing the values in an array */
/* is a posibility */
/************************************/
-void displayTexture(void)
+static int displayTexture(gfluxstruct *gp)
{
- static double time = 0.0;
- static double anglex = 0.0;
- static double angley = 0.0;
- static double anglez = 0.0;
-
+ int polys = 0;
double x,y,u,v;
double z;
double dx = 2.0/((double)_squares);
double du = 2.0/((double)_squares);
double dv = 2.0/((double)_squares);
- double xs = gflux->tex_xscale;
- double ys = gflux->tex_yscale;
+ double xs = gp->tex_xscale;
+ double ys = gp->tex_yscale;
+
+ double minx, miny, maxx, maxy;
+ double minu, minv;
+
+#if 0
+ minx = (GLfloat) gp->img_geom.x / gp->img_width;
+ miny = (GLfloat) gp->img_geom.y / gp->img_height;
+ maxx = ((GLfloat) (gp->img_geom.x + gp->img_geom.width) /
+ gp->img_width);
+ maxy = ((GLfloat) (gp->img_geom.y + gp->img_geom.height) /
+ gp->img_height);
+ minu = minx;
+ minv = miny;
+ minx = (minx * 2) - 1;
+ miny = (miny * 2) - 1;
+ maxx = (maxx * 2) - 1;
+ maxy = (maxy * 2) - 1;
+#else
+ minx = -1;
+ miny = -1;
+ maxx = 1;
+ maxy = 1;
+ minv = 0;
+ minu = 0;
+#endif
glMatrixMode (GL_TEXTURE);
glLoadIdentity ();
glMatrixMode (GL_MODELVIEW);
glLoadIdentity();
- glRotatef(anglex,1,0,0);
- glRotatef(angley,0,1,0);
- glRotatef(anglez,0,0,1);
- userRot();
+ userRot(gp);
+ glRotatef(gp->anglex,1,0,0);
+ glRotatef(gp->angley,0,1,0);
+ glRotatef(gp->anglez,0,0,1);
glScalef(1,1,(GLfloat)_waveHeight);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
clear_gl_error();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glBindTexture(GL_TEXTURE_2D, gflux->texName);
+ glBindTexture(GL_TEXTURE_2D, gp->texName);
check_gl_error("texture binding");
glColor3f(0.5,0.5,0.5);
- for(x=-1,u= 0;x<0.9999;x+=dx,u+=du) {
+ for(x = minx, u = minu; x < maxx - 0.01; x += dx, u += du) {
glBegin(GL_QUAD_STRIP);
- for(y=-1,v= 0;y<=1;y+=dy,v+=dv) {
- z = getGrid(x,y,time);
- /* genColour(z);
- glColor3fv(gflux->colour);
- */ glTexCoord2f(u*xs,v*ys);
+ for (y = miny, v = minv; y <= maxy + 0.01; y += dy, v += dv) {
+ z = getGrid(gp,x,y,gp->time);
+ glTexCoord2f(u*xs,v*ys);
glNormal3f(
- getGrid(x+dx,y,time)-getGrid(x-dx,y,time),
- getGrid(x,y+dy,time)-getGrid(x,y-dy,time),
+ getGrid(gp,x+dx,y,gp->time)-getGrid(gp, x-dx,y,gp->time),
+ getGrid(gp,x,y+dy,gp->time)-getGrid(gp, x,y-dy,gp->time),
1
);
glVertex3f(x,y,z);
- z = getGrid(x+dx,y,time);
- /* genColour(z);
- glColor3fv(gflux->colour);
- */ glTexCoord2f((u+du)*xs,v*ys);
+ z = getGrid(gp,x+dx,y,gp->time);
+ glTexCoord2f((u+du)*xs,v*ys);
glNormal3f(
- getGrid(x+dx+dx,y,time)-getGrid(x,y,time),
- getGrid(x+dx,y+dy,time)-getGrid(x+dx,y-dy,time),
+ getGrid(gp,x+dx+dx,y,gp->time)-getGrid(gp, x,y,gp->time),
+ getGrid(gp,x+dx,y+dy,gp->time)-getGrid(gp, x+dx,y-dy,gp->time),
1
);
glVertex3f(x+dx,y,z);
+ polys++;
}
glEnd();
}
- if (! button_down_p) {
- time -= _speed;
- anglex -= _rotationx;
- angley -= _rotationy;
- anglez -= _rotationz;
+ /* Draw a border around the grid.
+ */
+ glColor3f(0.4, 0.4, 0.4);
+ glDisable(GL_TEXTURE_2D);
+ glEnable (GL_LINE_SMOOTH);
+
+ glBegin(GL_LINE_LOOP);
+ y = miny;
+ for (x = minx; x <= maxx; x += dx) {
+ glVertex3f (x, y, getGrid (gp, x, y, gp->time));
+ polys++;
+ }
+ x = maxx;
+ for (y = miny; y <= maxy; y += dy) {
+ glVertex3f (x, y, getGrid (gp, x, y, gp->time));
+ polys++;
}
+ y = maxy;
+ for (x = maxx; x >= minx; x -= dx) {
+ glVertex3f (x, y, getGrid (gp, x, y, gp->time));
+ polys++;
+ }
+ x = minx;
+ for (y = maxy; y >= miny; y -= dy) {
+ glVertex3f (x, y, getGrid (gp, x, y, gp->time));
+ polys++;
+ }
+ glEnd();
+ glEnable(GL_TEXTURE_2D);
+
+ if (! gp->button_down_p) {
+ gp->time -= _speed;
+ gp->anglex -= _rotationx;
+ gp->angley -= _rotationy;
+ gp->anglez -= _rotationz;
+ }
+ return polys;
}
-void displaySolid(void)
-{
- static double time = 0.0;
- static double anglex = 0.0;
- static double angley = 0.0;
- static double anglez = 0.0;
+static int displaySolid(gfluxstruct *gp)
+{
+ int polys = 0;
double x,y;
double z;
double dx = 2.0/((double)_squares);
double dy = 2.0/((double)_squares);
glLoadIdentity();
- glRotatef(anglex,1,0,0);
- glRotatef(angley,0,1,0);
- glRotatef(anglez,0,0,1);
- userRot();
+ glRotatef(gp->anglex,1,0,0);
+ glRotatef(gp->angley,0,1,0);
+ glRotatef(gp->anglez,0,0,1);
+ userRot(gp);
glScalef(1,1,(GLfloat)_waveHeight);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
for(x=-1;x<0.9999;x+=dx) {
glBegin(GL_QUAD_STRIP);
for(y=-1;y<=1;y+=dy) {
- z = getGrid(x,y,time);
+ z = getGrid(gp, x,y,gp->time);
genColour(z);
- glColor3fv(gflux->colour);
+ glColor3fv(gp->colour);
glVertex3f(x,y,z);
- z = getGrid(x+dx,y,time);
+ z = getGrid(gp, x+dx,y,gp->time);
genColour(z);
- glColor3fv(gflux->colour);
+ glColor3fv(gp->colour);
glVertex3f(x+dx,y,z);
+ polys++;
}
glEnd();
}
- if (! button_down_p) {
- time -= _speed;
- anglex -= _rotationx;
- angley -= _rotationy;
- anglez -= _rotationz;
+ if (! gp->button_down_p) {
+ gp->time -= _speed;
+ gp->anglex -= _rotationx;
+ gp->angley -= _rotationy;
+ gp->anglez -= _rotationz;
}
+ return polys;
}
-void displayLight(void)
+static int displayLight(gfluxstruct *gp)
{
- static double time = 0.0;
- static double anglex = 0.0;
- static double angley = 0.0;
- static double anglez = 0.0;
-
+ int polys = 0;
double x,y;
double z;
double dx = 2.0/((double)_squares);
double dy = 2.0/((double)_squares);
glLoadIdentity();
- glRotatef(anglex,1,0,0);
- glRotatef(angley,0,1,0);
- glRotatef(anglez,0,0,1);
- userRot();
+ glRotatef(gp->anglex,1,0,0);
+ glRotatef(gp->angley,0,1,0);
+ glRotatef(gp->anglez,0,0,1);
+ userRot(gp);
glScalef(1,1,(GLfloat)_waveHeight);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
for(x=-1;x<0.9999;x+=dx) {
glBegin(GL_QUAD_STRIP);
for(y=-1;y<=1;y+=dy) {
- z = getGrid(x,y,time);
+ z = getGrid(gp, x,y,gp->time);
genColour(z);
- glColor3fv(gflux->colour);
+ glColor3fv(gp->colour);
glNormal3f(
- getGrid(x+dx,y,time)-getGrid(x-dx,y,time),
- getGrid(x,y+dy,time)-getGrid(x,y-dy,time),
+ getGrid(gp, x+dx,y,gp->time)-getGrid(gp, x-dx,y,gp->time),
+ getGrid(gp, x,y+dy,gp->time)-getGrid(gp, x,y-dy,gp->time),
1
);
glVertex3f(x,y,z);
- z = getGrid(x+dx,y,time);
+ z = getGrid(gp, x+dx,y,gp->time);
genColour(z);
- glColor3fv(gflux->colour);
+ glColor3fv(gp->colour);
glNormal3f(
- getGrid(x+dx+dx,y,time)-getGrid(x,y,time),
- getGrid(x+dx,y+dy,time)-getGrid(x+dx,y-dy,time),
+ getGrid(gp, x+dx+dx,y,gp->time)-getGrid(gp, x,y,gp->time),
+ getGrid(gp, x+dx,y+dy,gp->time)-getGrid(gp, x+dx,y-dy,gp->time),
1
);
glVertex3f(x+dx,y,z);
+ polys++;
}
glEnd();
}
- if (! button_down_p) {
- time -= _speed;
- anglex -= _rotationx;
- angley -= _rotationy;
- anglez -= _rotationz;
+ if (! gp->button_down_p) {
+ gp->time -= _speed;
+ gp->anglex -= _rotationx;
+ gp->angley -= _rotationy;
+ gp->anglez -= _rotationz;
}
+ return polys;
}
-void displayWire(void)
+static int displayWire(gfluxstruct *gp)
{
- static double time = 0.0;
- static double anglex = 0.0;
- static double angley = 0.0;
- static double anglez = 0.0;
-
+ int polys = 0;
double x,y;
double z;
double dx1 = 2.0/((double)(_squares*_resolution)) - 0.00001;
double dy2 = 2.0/((double)_squares) - 0.00001;
glLoadIdentity();
- glRotatef(anglex,1,0,0);
- glRotatef(angley,0,1,0);
- glRotatef(anglez,0,0,1);
- userRot();
+ glRotatef(gp->anglex,1,0,0);
+ glRotatef(gp->angley,0,1,0);
+ glRotatef(gp->anglez,0,0,1);
+ userRot(gp);
glScalef(1,1,(GLfloat)_waveHeight);
glClear(GL_COLOR_BUFFER_BIT);
for(x=-1;x<=1;x+=dx2) {
glBegin(GL_LINE_STRIP);
for(y=-1;y<=1;y+=dy1) {
- z = getGrid(x,y,time);
+ z = getGrid(gp, x,y,gp->time);
genColour(z);
- glColor3fv(gflux->colour);
+ glColor3fv(gp->colour);
glVertex3f(x,y,z);
+ polys++;
}
glEnd();
}
for(y=-1;y<=1;y+=dy2) {
glBegin(GL_LINE_STRIP);
for(x=-1;x<=1;x+=dx1) {
- z = getGrid(x,y,time);
+ z = getGrid(gp, x,y,gp->time);
genColour(z);
- glColor3fv(gflux->colour);
+ glColor3fv(gp->colour);
glVertex3f(x,y,z);
+ polys++;
}
glEnd();
}
- if (! button_down_p) {
- time -= _speed;
- anglex -= _rotationx;
- angley -= _rotationy;
- anglez -= _rotationz;
+ if (! gp->button_down_p) {
+ gp->time -= _speed;
+ gp->anglex -= _rotationx;
+ gp->angley -= _rotationy;
+ gp->anglez -= _rotationz;
}
+ return polys;
}
/* generates new ripples */
-void calcGrid(void)
+static void calcGrid(gfluxstruct *gp)
{
- static int counter=0;
double tmp;
- static int newWave;
- if (button_down_p) return;
+ if (gp->button_down_p) return;
tmp = 1.0/((double)_waveChange);
- if(!(counter%_waveChange)) {
- newWave = ((int)(counter*tmp))%_waves;
- gflux->dispx[newWave] = -frand(1.0);
- gflux->dispy[newWave] = -frand(1.0);
- gflux->freq[newWave] = _waveFreq * frand(1.0);
- gflux->wa[newWave] = 0.0;
+ if(!(gp->counter%_waveChange)) {
+ gp->newWave = ((int)(gp->counter*tmp))%_waves;
+ gp->dispx[gp->newWave] = -frand(1.0);
+ gp->dispy[gp->newWave] = -frand(1.0);
+ gp->freq[gp->newWave] = _waveFreq * frand(1.0);
+ gp->wa[gp->newWave] = 0.0;
}
- counter++;
- gflux->wa[newWave] += tmp;
- gflux->wa[(newWave+1)%_waves] -= tmp;
+ gp->counter++;
+ gp->wa[gp->newWave] += tmp;
+ gp->wa[(gp->newWave+1)%_waves] -= tmp;
}
/* returns a height for the grid given time and x,y space co-ords */
-double getGrid(double x, double y, double a)
+static double getGrid(gfluxstruct *gp, double x, double y, double a)
{
register int i;
double retval=0.0;
tmp = 1.0/((float)_waves);
for(i=0;i<_waves;i++) {
- retval += gflux->wa[i] * tmp * sin( gflux->freq[i]
- * ( (x+gflux->dispx[i]) * (x+gflux->dispx[i])
- + (y+gflux->dispy[i]) * (y+gflux->dispy[i]) +a ) );
+ retval += gp->wa[i] * tmp * sin( gp->freq[i]
+ * ( (x+gp->dispx[i]) * (x+gp->dispx[i])
+ + (y+gp->dispy[i]) * (y+gp->dispy[i]) +a ) );
}
return(retval);
}
-#endif
+XSCREENSAVER_MODULE ("GFlux", gflux)
+
+#endif