X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fflipscreen3d.c;h=735c8d2c0729b6ab5a1e022a10be4f02bc209a5c;hb=96a411663168b0ba5432b407a83be55f3df0c802;hp=c2bca2762f11c0e3e304c8b33785f41d61cbbd11;hpb=8eb2873d7054e705c4e83f22d18c40946a9e2529;p=xscreensaver diff --git a/hacks/glx/flipscreen3d.c b/hacks/glx/flipscreen3d.c index c2bca276..735c8d2c 100644 --- a/hacks/glx/flipscreen3d.c +++ b/hacks/glx/flipscreen3d.c @@ -22,12 +22,15 @@ # 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 */ @@ -96,6 +99,7 @@ static Screenflip *screenflip = NULL; #include #include #include "grab-ximage.h" +#include "gltrackball.h" #ifndef M_PI #define M_PI 3.14159265 @@ -106,9 +110,43 @@ static GLfloat viewer[] = {0.0, 0.0, 15.0}; 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; @@ -142,29 +180,36 @@ void showscreen(int frozen) 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); @@ -275,7 +320,7 @@ void drawgrid(void) glEnd(); } -void display(void) +void display(int wire) { static GLfloat rx=1, ry=1, rz=0; static GLfloat rot = 0; @@ -295,7 +340,7 @@ void display(void) 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) @@ -303,9 +348,10 @@ void display(void) 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; @@ -323,7 +369,7 @@ void display(void) 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; @@ -335,7 +381,7 @@ void display(void) odrot = drot; if (rot > 360 || rot < -360) /* dont overflow rotation! */ rot -= rot; - showscreen(frozen); + showscreen(frozen, wire); glPopMatrix(); glFlush(); } @@ -354,15 +400,21 @@ void reshape_screenflip(ModeInfo *mi, int width, int height) void getSnapshot (ModeInfo *modeinfo) { XImage *ximage; + int status; + + if (MI_IS_WIREFRAME(modeinfo)) + return; - ximage = screen_to_ximage (modeinfo->xgwa.screen, modeinfo->window); + ximage = screen_to_ximage (modeinfo->xgwa.screen, modeinfo->window, NULL); qw = QW; qh = QH; 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; @@ -374,12 +426,30 @@ void getSnapshot (ModeInfo *modeinfo) 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 = (char *) 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); @@ -398,6 +468,8 @@ void init_screenflip(ModeInfo *mi) 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 { @@ -406,12 +478,16 @@ void init_screenflip(ModeInfo *mi) 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); } @@ -430,7 +506,7 @@ void draw_screenflip(ModeInfo *mi) if (regrab) getSnapshot(mi); - display(); + display(MI_IS_WIREFRAME(mi)); if(mi->fps_p) do_fps(mi); glFinish();