--- ray/src/hd/rhd_glx.c 1998/08/25 18:11:17 3.22 +++ ray/src/hd/rhd_glx.c 1999/01/03 13:40:25 3.27 @@ -21,7 +21,6 @@ static char SCCSid[] = "$SunId$ SGI"; #endif #include "standard.h" -#include "rhd_sample.h" #include #include @@ -29,6 +28,8 @@ static char SCCSid[] = "$SunId$ SGI"; #ifdef STEREO #include #endif + +#include "rhd_sample.h" #ifdef DOBJ #include "rhdobj.h" #endif @@ -36,7 +37,7 @@ static char SCCSid[] = "$SunId$ SGI"; #include "x11icon.h" #ifndef RAYQLEN -#define RAYQLEN 250 /* max. rays to queue before flush */ +#define RAYQLEN 1024 /* max. rays to queue before flush */ #endif #ifndef FEQ @@ -45,6 +46,8 @@ static char SCCSid[] = "$SunId$ SGI"; #define GAMMA 1.4 /* default gamma correction */ +#define FRAMESTATE(s) (((s)&(ShiftMask|ControlMask))==(ShiftMask|ControlMask)) + #define MOVPCT 7 /* percent distance to move /frame */ #define MOVDIR(b) ((b)==Button1 ? 1 : (b)==Button2 ? 0 : -1) #define MOVDEG (-5) /* degrees to orbit CW/down /frame */ @@ -74,7 +77,11 @@ static char SCCSid[] = "$SunId$ SGI"; struct driver odev; /* global device driver structure */ +char odev_args[64]; /* command arguments */ + +#ifdef STEREO static VIEW vwright; /* right eye view */ +#endif static int rayqleft = 0; /* rays left to queue before flush */ @@ -99,7 +106,7 @@ static int inpresflags; /* input result flags */ static int headlocked = 0; /* lock vertical motion */ static int resizewindow(), getevent(), getkey(), moveview(), wipeclean(), - setglpersp(), getmove(), fixwindow(), mytmflags(); + setglpersp(), getframe(), getmove(), fixwindow(), mytmflags(); #ifdef STEREO static int pushright(), popright(); @@ -216,6 +223,7 @@ char *id; pheight *= 2.; setstereobuf(STEREO_BUFFER_LEFT); #endif + checkglerr("setting rendering parameters"); copystruct(&odev.v, &stdview); odev.v.type = VT_PER; /* map the window */ @@ -300,18 +308,25 @@ register VIEW *nv; dev_input(); /* get resize event */ } copystruct(&odev.v, nv); /* setview() already called */ + } #ifdef STEREO - copystruct(&vwright, nv); - d = eyesepdist / sqrt(nv->hn2); - VSUM(vwright.vp, nv->vp, nv->hvec, d); - /* setview(&vwright); -- Unnecessary */ + copystruct(&vwright, nv); + d = eyesepdist / sqrt(nv->hn2); + VSUM(vwright.vp, nv->vp, nv->hvec, d); + /* setview(&vwright); -- Unnecessary */ #endif - } wipeclean(); return(1); } +dev_section(gfn, pfn) /* add octree for geometry rendering */ +char *gfn, *pfn; +{ + /* unimplemented */ +} + + dev_auxcom(cmd, args) /* process an auxiliary command */ char *cmd, *args; { @@ -390,13 +405,11 @@ dev_flush() /* flush output */ if (mapped) { #ifdef STEREO pushright(); /* update right eye */ - glClear(GL_DEPTH_BUFFER_BIT); smUpdate(&vwright, 100); #ifdef DOBJ dobj_render(); /* usually in foreground */ #endif popright(); /* update left eye */ - glClear(GL_DEPTH_BUFFER_BIT); #endif smUpdate(&odev.v, 100); checkglerr("rendering mesh"); @@ -435,6 +448,7 @@ pushright() /* push on right view */ glPushMatrix(); d = -eyesepdist / sqrt(odev.v.hn2); glTranslated(d*odev.v.hvec[0], d*odev.v.hvec[1], d*odev.v.hvec[2]); + checkglerr("setting right view"); } @@ -487,7 +501,10 @@ getevent() /* get next event */ getkey(levptr(XKeyPressedEvent)); break; case ButtonPress: - getmove(levptr(XButtonPressedEvent)); + if (FRAMESTATE(levptr(XButtonPressedEvent)->state)) + getframe(levptr(XButtonPressedEvent)); + else + getmove(levptr(XButtonPressedEvent)); break; } } @@ -506,8 +523,6 @@ static draw_grids(fore) /* draw holodeck section grids */ int fore; { - if (!mapped) - return; if (fore) glColor4ub(0, 255, 255, 0); else @@ -515,6 +530,7 @@ int fore; glBegin(GL_LINES); /* draw each grid line */ gridlines(draw3dline); glEnd(); + checkglerr("drawing grid lines"); } @@ -549,6 +565,14 @@ int dx, dy, mov, orb; return(0); /* not on window */ VCOPY(wip, rsL.wp[li]); #endif +#ifdef DEBUG + fprintf(stderr, "moveview: hit %s at (%f,%f,%f) (t=%f)\n", + li < 0 ? "object" : "mesh", + wip[0], wip[1], wip[2], + (wip[0]-odev.v.vp[0])*odir[0] + + (wip[1]-odev.v.vp[1])*odir[1] + + (wip[2]-odev.v.vp[2])*odir[2]); +#endif VSUM(odir, wip, odev.v.vp, -1.); } else /* panning with constant viewpoint */ VCOPY(nv.vdir, odir); @@ -581,6 +605,29 @@ int dx, dy, mov, orb; static +getframe(ebut) /* get focus frame */ +XButtonPressedEvent *ebut; +{ + int startx = ebut->x, starty = ebut->y; + int endx, endy; + + XMaskEvent(ourdisplay, ButtonReleaseMask, levptr(XEvent)); + endx = levptr(XButtonReleasedEvent)->x; + endy = levptr(XButtonReleasedEvent)->y; + if (endx == startx | endy == starty) { + XBell(ourdisplay, 0); + return; + } + if (endx < startx) {register int c = endx; endx = startx; startx = c;} + if (endy < starty) {register int c = endy; endy = starty; starty = c;} + sprintf(odev_args, "%.3f %.3f %.3f %.3f", + (startx+.5)/odev.hres, 1.-(endy+.5)/odev.vres, + (endx+.5)/odev.hres, 1.-(starty+.5)/odev.vres); + inpresflags |= DFL(DC_FOCUS); +} + + +static getmove(ebut) /* get view change */ XButtonPressedEvent *ebut; { @@ -593,22 +640,27 @@ XButtonPressedEvent *ebut; int rootx, rooty, wx, wy; unsigned int statemask; - XNoOp(ourdisplay); + XNoOp(ourdisplay); /* makes sure we're not idle */ lasttime = time(0); nframes = 0; while (!XCheckMaskEvent(ourdisplay, ButtonReleaseMask, levptr(XEvent))) { - + /* get cursor position */ if (!XQueryPointer(ourdisplay, gwind, &rootw, &childw, &rootx, &rooty, &wx, &wy, &statemask)) break; /* on another screen */ draw_grids(0); /* clear old grid lines */ +#ifdef STEREO + pushright(); draw_grids(0); popright(); +#endif + /* compute view motion */ if (!moveview(wx, odev.vres-1-wy, movdir, movorb)) { sleep(1); lasttime++; - continue; + continue; /* cursor in bad place */ } + draw_grids(1); /* redraw grid */ #ifdef STEREO pushright(); draw_grids(1); @@ -618,14 +670,13 @@ XButtonPressedEvent *ebut; #endif popright(); #endif - draw_grids(1); + /* redraw mesh */ smUpdate(&odev.v, qlevel); #ifdef DOBJ - dobj_render(); + dobj_render(); /* redraw object */ #endif glFlush(); - checkglerr("moving view"); - nframes++; + nframes++; /* figure out good quality level */ thistime = time(0); if (thistime - lasttime >= 3 || nframes > (int)(3*3*TARGETFPS)) { @@ -659,20 +710,18 @@ register VIEW *vp; double d, xmin, xmax, ymin, ymax; if (mindpth >= maxdpth) { - dev_zmin = 0.1; + dev_zmin = 1.; dev_zmax = 100.; } else { dev_zmin = 0.5*mindpth; - dev_zmax = 1.5*maxdpth; - if (dev_zmin > dev_zmax/100.) - dev_zmin = dev_zmax/100.; + dev_zmax = 5.0*maxdpth; } if (odev.v.vfore > FTINY) dev_zmin = odev.v.vfore; if (odev.v.vaft > FTINY) dev_zmax = odev.v.vaft; - if (dev_zmin < dev_zmax/5000.) - dev_zmin = dev_zmax/5000.; + if (dev_zmin < dev_zmax/100.) + dev_zmin = dev_zmax/100.; xmax = dev_zmin * tan(PI/180./2. * odev.v.horiz); xmin = -xmax; d = odev.v.hoff * (xmax - xmin); @@ -690,6 +739,7 @@ register VIEW *vp; odev.v.vp[1] + odev.v.vdir[1], odev.v.vp[2] + odev.v.vdir[2], odev.v.vup[0], odev.v.vup[1], odev.v.vup[2]); + checkglerr("setting perspective view"); } @@ -712,6 +762,9 @@ static getkey(ekey) /* get input key */ register XKeyPressedEvent *ekey; { + Window rootw, childw; + int rootx, rooty, wx, wy; + unsigned int statemask; int n; char buf[8]; @@ -734,6 +787,18 @@ register XKeyPressedEvent *ekey; case 'v': /* spit out view */ inpresflags |= DFL(DC_GETVIEW); return; + case 'f': /* frame view position */ + if (!XQueryPointer(ourdisplay, gwind, &rootw, &childw, + &rootx, &rooty, &wx, &wy, &statemask)) + return; /* on another screen */ + sprintf(odev_args, "%.4f %.4f", (wx+.5)/odev.hres, + 1.-(wy+.5)/odev.vres); + inpresflags |= DFL(DC_FOCUS); + return; + case 'F': /* unfocus */ + odev_args[0] = '\0'; + inpresflags |= DFL(DC_FOCUS); + return; case '\n': case '\r': /* resume computation */ inpresflags |= DFL(DC_RESUME); @@ -744,8 +809,9 @@ register XKeyPressedEvent *ekey; case CTRL('L'): /* refresh from server */ if (inpresflags & DFL(DC_REDRAW)) return; + setglpersp(&odev.v); /* reset clipping planes */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_DEPTH_TEST); + glDisable(GL_DEPTH_TEST); /* so grids will clear */ draw_grids(1); #ifdef STEREO pushright(); @@ -757,7 +823,6 @@ register XKeyPressedEvent *ekey; glFlush(); smInit(rsL.max_samp); /* get rid of old values */ inpresflags |= DFL(DC_REDRAW); /* resend values from server */ - setglpersp(&odev.v); /* reset clipping planes */ rayqleft = 0; /* hold off update */ return; case 'K': /* kill rtrace process(es) */