X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fflipscreen3d.c;h=7d17818889ca5e1e3928f6679bb48f4a0f365d34;hb=2d04c4f22466851aedb6ed0f2919d148f726b889;hp=c2bca2762f11c0e3e304c8b33785f41d61cbbd11;hpb=8eb2873d7054e705c4e83f22d18c40946a9e2529;p=xscreensaver diff --git a/hacks/glx/flipscreen3d.c b/hacks/glx/flipscreen3d.c index c2bca276..7d178188 100644 --- a/hacks/glx/flipscreen3d.c +++ b/hacks/glx/flipscreen3d.c @@ -1,5 +1,5 @@ /* - * screenflip - takes snapshots of the screen and flips it around + * flipscreen3d - takes snapshots of the screen and flips it around * * version 1.0 - Oct 24, 2001 * @@ -18,16 +18,20 @@ #ifdef STANDALONE -# define PROGCLASS "Screenflip" +# define PROGCLASS "FlipScreen3D" # 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" \ +#define DEFAULTS "*delay: 20000 \n" \ + "*showFPS: False \n" \ + "*rotate: True \n" \ + "*wireframe: False \n" \ + "*useSHM: True \n" # include "xlockmore.h" /* from the xscreensaver distribution */ #else /* !STANDALONE */ @@ -48,6 +52,7 @@ int rotate; int winw, winh; int tw, th; /* texture width, height */ int tx, ty; +GLfloat min_tx, min_ty; GLfloat max_tx, max_ty; #define QW 12 @@ -60,13 +65,13 @@ GLfloat qx = -6 , qy = 6; static XrmOptionDescRec opts[] = { - {"+rotate", ".screenflip.rotate", XrmoptionNoArg, (caddr_t) "false" }, - {"-rotate", ".screenflip.rotate", XrmoptionNoArg, (caddr_t) "true" }, + {"+rotate", ".screenflip.rotate", XrmoptionNoArg, "false" }, + {"-rotate", ".screenflip.rotate", XrmoptionNoArg, "true" }, }; static argtype vars[] = { - {(caddr_t *) &rotate, "rotate", "Rotate", "True", t_Bool}, + {&rotate, "rotate", "Rotate", "True", t_Bool}, }; @@ -96,6 +101,7 @@ static Screenflip *screenflip = NULL; #include #include #include "grab-ximage.h" +#include "gltrackball.h" #ifndef M_PI #define M_PI 3.14159265 @@ -106,12 +112,53 @@ 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 == ButtonPress && + (event->xbutton.button == Button4 || + event->xbutton.button == Button5)) + { + gltrackball_mousewheel (trackball, event->xbutton.button, 10, + !!event->xbutton.state); + 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; GLfloat x, y, w, h; /* static int stretch; */ static GLfloat stretch_val_x = 0, stretch_val_y = 0; @@ -134,66 +181,56 @@ void showscreen(int frozen) if (stretch_val_dy == 0 && !frozen && !(random() % 25)) stretch_val_dy = (float)(random() % 100) / 5000; - qxw = qx+qw; - qyh = qy-qh; - x = qx; y = qy; - w = qxw; h = qyh; + x = qx; + y = qy; + w = qx+qw; + h = qy-qh; 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); - - glTexCoord2f(0, max_ty); - glVertex3f(x, y, 0); - - glTexCoord2f(max_tx, max_ty); - glVertex3f(w, y, 0); - - glTexCoord2f(max_tx, 0); - glVertex3f(w, h, 0); - - glTexCoord2f(0, 0); - glVertex3f(x, h, 0); + glTexCoord2f(max_tx, max_ty); glVertex3f(w, h, 0); + glTexCoord2f(max_tx, min_ty); glVertex3f(w, y, 0); + glTexCoord2f(min_tx, min_ty); glVertex3f(x, y, 0); + glTexCoord2f(min_tx, max_ty); glVertex3f(x, h, 0); glNormal3f(0, 0, -1); - - glTexCoord2f(0, max_ty); - glVertex3f(x, y, -0.05); - - glTexCoord2f(0, 0); - glVertex3f(x, h, -0.05); - - glTexCoord2f(max_tx, 0); - glVertex3f(w, h, -0.05); - - glTexCoord2f(max_tx, max_ty); - glVertex3f(w, y, -0.05); - + glTexCoord2f(min_tx, min_ty); glVertex3f(x, y, -0.05); + glTexCoord2f(max_tx, min_ty); glVertex3f(w, y, -0.05); + glTexCoord2f(max_tx, max_ty); glVertex3f(w, h, -0.05); + glTexCoord2f(min_tx, max_ty); glVertex3f(x, h, -0.05); glEnd(); @@ -275,7 +312,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 +332,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 +340,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 +361,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 +373,7 @@ void display(void) odrot = drot; if (rot > 360 || rot < -360) /* dont overflow rotation! */ rot -= rot; - showscreen(frozen); + showscreen(frozen, wire); glPopMatrix(); glFlush(); } @@ -353,36 +391,30 @@ void reshape_screenflip(ModeInfo *mi, int width, int height) void getSnapshot (ModeInfo *modeinfo) { - XImage *ximage; - - ximage = screen_to_ximage (modeinfo->xgwa.screen, modeinfo->window); - - qw = QW; qh = QH; - tw = modeinfo->xgwa.width; - th = modeinfo->xgwa.height; - - qx += (qw*tw/winw); - qy -= (qh*th/winh); - - qw *= (GLfloat)tw/winw; - qh *= (GLfloat)th/winh; - - max_tx = (GLfloat) tw / (GLfloat) ximage->width; - max_ty = (GLfloat) th / (GLfloat) ximage->height; - - - 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); - } - free(ximage->data); - ximage->data = 0; - XDestroyImage (ximage); + Bool mipmap_p = True; + XRectangle geom; + int iw, ih; + + if (MI_IS_WIREFRAME(modeinfo)) + return; + + if (! screen_to_texture (modeinfo->xgwa.screen, modeinfo->window, 0, 0, + mipmap_p, NULL, &geom, &iw, &ih, &tw, &th)) + exit (1); + + min_tx = (GLfloat) geom.x / tw; + min_ty = (GLfloat) geom.y / th; + max_tx = (GLfloat) (geom.x + geom.width) / tw; + max_ty = (GLfloat) (geom.y + geom.height) / th; + + qx = -QW/2 + ((GLfloat) geom.x * QW / iw); + qy = QH/2 - ((GLfloat) geom.y * QH / ih); + qw = QW * ((GLfloat) geom.width / iw); + qh = QH * ((GLfloat) geom.height / ih); + + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + (mipmap_p ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR)); } void init_screenflip(ModeInfo *mi) @@ -398,6 +430,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 +440,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_BACK); + glDisable(GL_LIGHTING); + } getSnapshot(mi); } @@ -430,7 +468,7 @@ void draw_screenflip(ModeInfo *mi) if (regrab) getSnapshot(mi); - display(); + display(MI_IS_WIREFRAME(mi)); if(mi->fps_p) do_fps(mi); glFinish();