# define HACK_INIT init_screenflip
# define HACK_DRAW draw_screenflip
# define HACK_RESHAPE reshape_screenflip
+# define HACK_HANDLE_EVENT screenflip_handle_event
+# define EVENT_MASK PointerMotionMask
# define screenflip_opts xlockmore_opts
/* insert defaults here */
#define DEFAULTS "*delay: 20000 \n" \
"*showFPS: False \n" \
"*rotate: True \n" \
+ "*wireframe: False \n" \
# include "xlockmore.h" /* from the xscreensaver distribution */
#else /* !STANDALONE */
#include <stdio.h>
#include <stdlib.h>
#include "grab-ximage.h"
+#include "gltrackball.h"
#ifndef M_PI
#define M_PI 3.14159265
int regrab = 0;
int fadetime = 0; /* fade before regrab */
+static trackball_state *trackball;
+static Bool button_down_p = False;
+
+
+Bool
+screenflip_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;
+}
+
/* draw the texture mapped quad (actually two back to back)*/
-void showscreen(int frozen)
+void showscreen(int frozen, int wire)
{
static GLfloat r = 1, g = 1, b = 1, a = 1;
GLfloat qxw, qyh;
if (!frozen) {
w *= sin (stretch_val_x) + 1;
x *= sin (stretch_val_x) + 1;
+ if (!button_down_p) {
if (!fadetime) stretch_val_x += stretch_val_dx;
if (stretch_val_x > 2*M_PI && !(random() % 5))
stretch_val_dx = (float)(random() % 100) / 5000;
else
stretch_val_x -= 2*M_PI;
+ }
- if (!fadetime) stretch_val_y += stretch_val_dy;
+ if (!button_down_p && !fadetime) stretch_val_y += stretch_val_dy;
h *= sin (stretch_val_y) / 2 + 1;
y *= sin (stretch_val_y) / 2 + 1;
+ if (!button_down_p) {
if (stretch_val_y > 2*M_PI && !(random() % 5))
stretch_val_dy = (float)(random() % 100) / 5000;
else
stretch_val_y -= 2*M_PI;
+ }
}
glColor4f(r, g, b, a);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glDepthMask(GL_FALSE);
+ if (!wire)
+ {
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDepthMask(GL_FALSE);
+ }
- glBegin(GL_QUADS);
+ glBegin(wire ? GL_LINE_LOOP : GL_QUADS);
glNormal3f(0, 0, 1);
glEnd();
}
-void display(void)
+void display(int wire)
{
static GLfloat rx=1, ry=1, rz=0;
static GLfloat rot = 0;
frozen = 0;
glTranslatef(5 * sin(theta), 5 * sin(rho), 10 * cos(gamma) - 10);
/* randomly change the speed */
- if (!(random() % 300)) {
+ if (!button_down_p && !(random() % 300)) {
if (random() % 2)
drho = 1/60 - (float)(random() % 100)/3000;
if (random() % 2)
if (random() % 2)
dgamma = 1/60 - (float)(random() % 100)/3000;
}
+ gltrackball_rotate (trackball);
if (rotate) glRotatef(rot, rx, ry, rz);
/* update variables with each frame */
- if (!fadetime) {
+ if(!button_down_p && !fadetime) {
theta += dtheta;
rho += drho;
gamma += dgamma;
rot = 0;
frozen = 1;
}
- if (!fadetime && (rot >= 360 || rot <= -360) && !(random() % 7)) { /* rotate change */
+ if (!button_down_p && !fadetime && (rot >= 360 || rot <= -360) && !(random() % 7)) { /* rotate change */
rx = (GLfloat)(random() % 100) / 100;
ry = (GLfloat)(random() % 100) / 100;
rz = (GLfloat)(random() % 100) / 100;
odrot = drot;
if (rot > 360 || rot < -360) /* dont overflow rotation! */
rot -= rot;
- showscreen(frozen);
+ showscreen(frozen, wire);
glPopMatrix();
glFlush();
}
void getSnapshot (ModeInfo *modeinfo)
{
XImage *ximage;
+ int status;
+
+ if (MI_IS_WIREFRAME(modeinfo))
+ return;
ximage = screen_to_ximage (modeinfo->xgwa.screen, modeinfo->window);
tw = modeinfo->xgwa.width;
th = modeinfo->xgwa.height;
+#if 0 /* jwz: this makes the image start off the bottom right of the screen */
qx += (qw*tw/winw);
qy -= (qh*th/winh);
+#endif
qw *= (GLfloat)tw/winw;
qh *= (GLfloat)th/winh;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR);
- if (gluBuild2DMipmaps(GL_TEXTURE_2D, 3,
- ximage->width, ximage->height,
- GL_RGBA, GL_UNSIGNED_BYTE, ximage->data)) {
- printf("Error!\n");
- exit(1);
- }
+
+ clear_gl_error();
+ status = gluBuild2DMipmaps(GL_TEXTURE_2D, 3,
+ ximage->width, ximage->height,
+ GL_RGBA, GL_UNSIGNED_BYTE, ximage->data);
+
+ if (!status && glGetError())
+ /* Some implementations of gluBuild2DMipmaps(), but set a GL error anyway.
+ We could just call check_gl_error(), but that would exit. */
+ status = -1;
+
+ if (status)
+ {
+ const char *s = gluErrorString (status);
+ fprintf (stderr, "%s: error mipmapping %dx%d texture: %s\n",
+ progname, ximage->width, ximage->height,
+ (s ? s : "(unknown)"));
+ fprintf (stderr, "%s: turning on -wireframe.\n", progname);
+ MI_IS_WIREFRAME(modeinfo) = 1;
+ clear_gl_error();
+ }
+ check_gl_error("mipmapping"); /* should get a return code instead of a
+ GL error, but just in case... */
+
free(ximage->data);
ximage->data = 0;
XDestroyImage (ximage);
c = &screenflip[screen];
c->window = MI_WINDOW(mi);
+ trackball = gltrackball_init ();
+
if ((c->glx_context = init_GL(mi)) != NULL) {
reshape_screenflip(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
} else {
winh = MI_WIN_HEIGHT(mi);
winw = MI_WIN_WIDTH(mi);
glClearColor(0.0,0.0,0.0,0.0);
- glShadeModel(GL_SMOOTH);
- glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
- glCullFace(GL_FRONT);
- glDisable(GL_LIGHTING);
+
+ if (! MI_IS_WIREFRAME(mi))
+ {
+ glShadeModel(GL_SMOOTH);
+ glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_FRONT);
+ glDisable(GL_LIGHTING);
+ }
getSnapshot(mi);
}
if (regrab)
getSnapshot(mi);
- display();
+ display(MI_IS_WIREFRAME(mi));
if(mi->fps_p) do_fps(mi);
glFinish();