X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Fglx%2Fgflux.c;h=51aa59778b31c20fecd18daba5bc961b8045cbc4;hp=2e9f067037b0564e01beff16234688a488073f46;hb=ffd8c0873576a9e3065696a624dce6b766b77062;hpb=8eb2873d7054e705c4e83f22d18c40946a9e2529 diff --git a/hacks/glx/gflux.c b/hacks/glx/gflux.c index 2e9f0670..51aa5977 100644 --- a/hacks/glx/gflux.c +++ b/hacks/glx/gflux.c @@ -2,7 +2,7 @@ /* 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 @@ -35,22 +35,17 @@ * 21 July 2000 : cleaned up code from bug hunts, manpage written * 24 November 2000 : fixed x co-ord calculation in solid - textured * 05 March 2001 : put back non pnmlib code with #ifdefs + * 11 May 2002 : fixed image problems with large images */ -/*- - * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock. - * otherwise caddr_t is not defined correctly - */ - -#include - - #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" \ @@ -76,13 +71,6 @@ #ifdef USE_GL /* whole file */ -#ifdef HAVE_XPM -# include -# ifndef PIXEL_ALREADY_TYPEDEFED -# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */ -# endif -#endif - #ifdef HAVE_XMU # ifndef VMS # include @@ -108,6 +96,7 @@ #include #include "grab-ximage.h" +#include "gltrackball.h" static enum {wire=0,solid,light,checker,textured,grab} _draw; /* draw style */ @@ -126,41 +115,44 @@ static int _waveChange = 50; static float _waveHeight = 1.0; static float _waveFreq = 3.0; +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}, + {"-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", "19", t_Int}, + {&_resolution, "resolution", "Resolution", "4", t_Int}, +/* {&_draw, "draw", "Draw", "2", t_Int},*/ + {&_flat, "flat", "Flat", "0", t_Int}, + {&_speed, "speed", "Speed", "0.05", t_Float}, + {&_rotationx, "rotationx", "Rotationx", "0.01", t_Float}, + {&_rotationy, "rotationy", "Rotationy", "0.0", t_Float}, + {&_rotationz, "rotationz", "Rotationz", "0.1", t_Float}, + {&_waves, "waves", "Waves", "3", t_Int}, + {&_waveChange, "waveChange", "WaveChange", "50", t_Int}, + {&_waveHeight, "waveHeight", "WaveHeight", "1.0", t_Float}, + {&_waveFreq, "waveFreq", "WaveFreq", "3.0", t_Float}, + {&_zoom, "zoom", "Zoom", "1.0", t_Float}, }; @@ -213,7 +205,7 @@ typedef struct { int imageMax; GLubyte *image; #endif - GLint texName; + GLuint texName; GLfloat tex_xscale; GLfloat tex_yscale; void (*drawFunc)(void); @@ -246,6 +238,43 @@ double getGrid(double,double,double); /* BEGINNING OF FUNCTIONS */ +Bool +gflux_handle_event (ModeInfo *mi, XEvent *event) +{ + if (event->xany.type == ButtonPress && + event->xbutton.button & Button1) + { + button_down_p = True; + gltrackball_start (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) + { + button_down_p = False; + return True; + } + else if (event->xany.type == MotionNotify && + button_down_p) + { + gltrackball_track (trackball, + event->xmotion.x, event->xmotion.y, + MI_WIDTH (mi), MI_HEIGHT (mi)); + return True; + } + + return False; +} + + +static void +userRot(void) +{ + gltrackball_rotate (trackball); +} + /* draw the gflux once */ void draw_gflux(ModeInfo * mi) { @@ -349,6 +378,8 @@ void init_gflux(ModeInfo * mi) } gp = &gflux[screen]; + trackball = gltrackball_init (); + { char *s = get_string_resource ("mode", "Mode"); if (!s || !*s) _draw = wire; @@ -428,9 +459,11 @@ void initTexture(void) 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"); } #else /* HAVE_PPM FALSE */ @@ -580,19 +613,23 @@ grabTexture(void) 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); + gflux->window, + NULL); + 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 size = (ximage->width < ximage->height ? - ximage->width : ximage->height); 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; @@ -619,25 +656,35 @@ grabTexture(void) /* 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, real_width-1, i, gray); + XPutPixel (ximage, width-1, i, gray); } for (i = 0; i < real_width; i++) { XPutPixel (ximage, i, 0, gray); - XPutPixel (ximage, i, real_height-1, gray); + XPutPixel (ximage, i, height-1, gray); } } gflux->imageWidth = ximage->width; gflux->imageHeight = ximage->height; - gflux->image = ximage->data; + gflux->image = (GLubyte *) ximage->data; - gflux->tex_xscale = ((GLfloat) real_width / (GLfloat) ximage->width); - gflux->tex_yscale = ((GLfloat) real_height / (GLfloat) ximage->height); + 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); @@ -708,6 +755,7 @@ void displayTexture(void) glRotatef(anglex,1,0,0); glRotatef(angley,0,1,0); glRotatef(anglez,0,0,1); + userRot(); glScalef(1,1,(GLfloat)_waveHeight); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); @@ -747,10 +795,12 @@ void displayTexture(void) glEnd(); } - time -= _speed; - anglex -= _rotationx; - angley -= _rotationy; - anglez -= _rotationz; + if (! button_down_p) { + time -= _speed; + anglex -= _rotationx; + angley -= _rotationy; + anglez -= _rotationz; + } } void displaySolid(void) { @@ -768,6 +818,7 @@ void displaySolid(void) glRotatef(anglex,1,0,0); glRotatef(angley,0,1,0); glRotatef(anglez,0,0,1); + userRot(); glScalef(1,1,(GLfloat)_waveHeight); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); @@ -787,10 +838,12 @@ void displaySolid(void) glEnd(); } - time -= _speed; - anglex -= _rotationx; - angley -= _rotationy; - anglez -= _rotationz; + if (! button_down_p) { + time -= _speed; + anglex -= _rotationx; + angley -= _rotationy; + anglez -= _rotationz; + } } @@ -810,6 +863,7 @@ void displayLight(void) glRotatef(anglex,1,0,0); glRotatef(angley,0,1,0); glRotatef(anglez,0,0,1); + userRot(); glScalef(1,1,(GLfloat)_waveHeight); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); @@ -839,10 +893,12 @@ void displayLight(void) glEnd(); } - time -= _speed; - anglex -= _rotationx; - angley -= _rotationy; - anglez -= _rotationz; + if (! button_down_p) { + time -= _speed; + anglex -= _rotationx; + angley -= _rotationy; + anglez -= _rotationz; + } } void displayWire(void) @@ -863,6 +919,7 @@ void displayWire(void) glRotatef(anglex,1,0,0); glRotatef(angley,0,1,0); glRotatef(anglez,0,0,1); + userRot(); glScalef(1,1,(GLfloat)_waveHeight); glClear(GL_COLOR_BUFFER_BIT); @@ -887,10 +944,12 @@ void displayWire(void) glEnd(); } - time -= _speed; - anglex -= _rotationx; - angley -= _rotationy; - anglez -= _rotationz; + if (! button_down_p) { + time -= _speed; + anglex -= _rotationx; + angley -= _rotationy; + anglez -= _rotationz; + } } /* generates new ripples */ @@ -900,12 +959,14 @@ void calcGrid(void) double tmp; static int newWave; + if (button_down_p) return; + tmp = 1.0/((double)_waveChange); if(!(counter%_waveChange)) { newWave = ((int)(counter*tmp))%_waves; - gflux->dispx[newWave] = 1.0 - ((double)random())/RAND_MAX; - gflux->dispy[newWave] = 1.0 - ((double)random())/RAND_MAX; - gflux->freq[newWave] = _waveFreq * ((float)random())/RAND_MAX; + gflux->dispx[newWave] = -frand(1.0); + gflux->dispy[newWave] = -frand(1.0); + gflux->freq[newWave] = _waveFreq * frand(1.0); gflux->wa[newWave] = 0.0; } counter++;