/* 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
* 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
*/
# 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" \
#include <math.h>
#include "grab-ximage.h"
+#include "gltrackball.h"
static enum {wire=0,solid,light,checker,textured,grab} _draw; /* draw style */
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 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},
};
int imageMax;
GLubyte *image;
#endif
- GLint texName;
+ GLuint texName;
GLfloat tex_xscale;
GLfloat tex_yscale;
void (*drawFunc)(void);
/* 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)
{
}
gp = &gflux[screen];
+ trackball = gltrackball_init ();
+
{
char *s = get_string_resource ("mode", "Mode");
if (!s || !*s) _draw = wire;
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;
/* 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);
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);
glEnd();
}
- time -= _speed;
- anglex -= _rotationx;
- angley -= _rotationy;
- anglez -= _rotationz;
+ if (! button_down_p) {
+ time -= _speed;
+ anglex -= _rotationx;
+ angley -= _rotationy;
+ anglez -= _rotationz;
+ }
}
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);
glEnd();
}
- time -= _speed;
- anglex -= _rotationx;
- angley -= _rotationy;
- anglez -= _rotationz;
+ if (! button_down_p) {
+ time -= _speed;
+ anglex -= _rotationx;
+ angley -= _rotationy;
+ anglez -= _rotationz;
+ }
}
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);
glEnd();
}
- time -= _speed;
- anglex -= _rotationx;
- angley -= _rotationy;
- anglez -= _rotationz;
+ if (! button_down_p) {
+ time -= _speed;
+ anglex -= _rotationx;
+ angley -= _rotationy;
+ anglez -= _rotationz;
+ }
}
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);
glEnd();
}
- time -= _speed;
- anglex -= _rotationx;
- angley -= _rotationy;
- anglez -= _rotationz;
+ if (! button_down_p) {
+ time -= _speed;
+ anglex -= _rotationx;
+ angley -= _rotationy;
+ anglez -= _rotationz;
+ }
}
/* generates new ripples */
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++;