ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhd_glx.c
(Generate patch)

Comparing ray/src/hd/rhd_glx.c (file contents):
Revision 3.23 by gwlarson, Thu Aug 27 19:33:05 1998 UTC vs.
Revision 3.30 by schorsch, Mon Jul 21 22:30:18 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ SGI";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * OpenGL GLX driver for holodeck display.
6   * Based on old GLX driver using cones.
# Line 21 | Line 18 | static char SCCSid[] = "$SunId$ SGI";
18   #endif
19  
20   #include "standard.h"
24 #include "rhd_sample.h"
21  
26 #include <sys/types.h>
22   #include <GL/glx.h>
23   #include <GL/glu.h>
24   #ifdef STEREO
25   #include <X11/extensions/SGIStereo.h>
26   #endif
27 +
28 + #include "rhd_sample.h"
29   #ifdef DOBJ
30   #include "rhdobj.h"
31   #endif
# Line 36 | Line 33 | static char SCCSid[] = "$SunId$ SGI";
33   #include "x11icon.h"
34  
35   #ifndef RAYQLEN
36 < #define RAYQLEN         250             /* max. rays to queue before flush */
36 > #define RAYQLEN         1024            /* max. rays to queue before flush */
37   #endif
38  
39   #ifndef FEQ
# Line 45 | Line 42 | static char SCCSid[] = "$SunId$ SGI";
42  
43   #define GAMMA           1.4             /* default gamma correction */
44  
45 + #define FRAMESTATE(s)   (((s)&(ShiftMask|ControlMask))==(ShiftMask|ControlMask))
46 +
47   #define MOVPCT          7               /* percent distance to move /frame */
48   #define MOVDIR(b)       ((b)==Button1 ? 1 : (b)==Button2 ? 0 : -1)
49   #define MOVDEG          (-5)            /* degrees to orbit CW/down /frame */
50   #define MOVORB(s)       ((s)&ShiftMask ? 1 : (s)&ControlMask ? -1 : 0)
51  
52   #ifndef TARGETFPS
53 < #define TARGETFPS       4.0             /* target frames/sec during motion */
53 > #define TARGETFPS       2.0             /* target frames/sec during motion */
54   #endif
55  
56   #define MINWIDTH        480             /* minimum graphics window width */
# Line 74 | Line 73 | static char SCCSid[] = "$SunId$ SGI";
73  
74   struct driver   odev;                   /* global device driver structure */
75  
76 + char odev_args[64];                     /* command arguments */
77 +
78   #ifdef STEREO
79   static VIEW     vwright;                /* right eye view */
80   #endif
# Line 101 | Line 102 | static int     inpresflags;            /* input result flags */
102   static int      headlocked = 0;         /* lock vertical motion */
103  
104   static int  resizewindow(), getevent(), getkey(), moveview(), wipeclean(),
105 <                setglpersp(), getmove(), fixwindow(), mytmflags();
105 >                setglpersp(), getframe(), getmove(), fixwindow(), mytmflags();
106  
107   #ifdef STEREO
108   static int  pushright(), popright();
109   #endif
110 + static double   getdistance();
111 + #define mapdepth(d) ((d)> 0.9995 ? FHUGE: dev_zmin/ \
112 +                     (1.-(d)*(1.-dev_zmin/dev_zmax)))
113  
114   extern time_t   time();
115  
# Line 219 | Line 223 | char  *id;
223          setstereobuf(STEREO_BUFFER_LEFT);
224   #endif
225          checkglerr("setting rendering parameters");
226 <        copystruct(&odev.v, &stdview);
226 >        odev.v = stdview;
227          odev.v.type = VT_PER;
228                                          /* map the window */
229          XMapWindow(ourdisplay, gwind);
# Line 256 | Line 260 | dev_close()                    /* close our display and free resources
260   dev_clear()                     /* clear our representation */
261   {
262          smInit(rsL.max_samp);
263 <        wipeclean();
263 >        wipeclean(1);
264          rayqleft = 0;                   /* hold off update */
265   }
266  
# Line 302 | Line 306 | register VIEW  *nv;
306                          XResizeWindow(ourdisplay, gwind, odev.hres, odev.vres);
307                          dev_input();    /* get resize event */
308                  }
309 <                copystruct(&odev.v, nv);        /* setview() already called */
309 >                odev.v = *nv;   /* setview() already called */
310 >        }
311   #ifdef STEREO
312 <                copystruct(&vwright, nv);
313 <                d = eyesepdist / sqrt(nv->hn2);
314 <                VSUM(vwright.vp, nv->vp, nv->hvec, d);
315 <                /* setview(&vwright);   -- Unnecessary */
312 >        vwright = *nv;
313 >        d = eyesepdist / sqrt(nv->hn2);
314 >        VSUM(vwright.vp, nv->vp, nv->hvec, d);
315 >        /* setview(&vwright);   -- Unnecessary */
316   #endif
317 <        }
313 <        wipeclean();
317 >        wipeclean(0);
318          return(1);
319   }
320  
321  
322 + dev_section(gfn, pfn)           /* add octree for geometry rendering */
323 + char    *gfn, *pfn;
324 + {
325 +        /* unimplemented */
326 + }
327 +
328 +
329   dev_auxcom(cmd, args)           /* process an auxiliary command */
330   char    *cmd, *args;
331   {
# Line 393 | Line 404 | dev_flush()                    /* flush output */
404          if (mapped) {
405   #ifdef STEREO
406                  pushright();                    /* update right eye */
407 <                smUpdate(&vwright, 100);
407 >                smUpdate(&vwright, MAXQUALITY);
408   #ifdef DOBJ
409                  dobj_render();                  /* usually in foreground */
410   #endif
411                  popright();                     /* update left eye */
412   #endif
413 <                smUpdate(&odev.v, 100);
413 >                smUpdate(&odev.v, MAXQUALITY);
414                  checkglerr("rendering mesh");
415   #ifdef DOBJ
416                  dobj_render();
# Line 489 | Line 500 | getevent()                     /* get next event */
500                  getkey(levptr(XKeyPressedEvent));
501                  break;
502          case ButtonPress:
503 <                getmove(levptr(XButtonPressedEvent));
503 >                if (FRAMESTATE(levptr(XButtonPressedEvent)->state))
504 >                        getframe(levptr(XButtonPressedEvent));
505 >                else
506 >                        getmove(levptr(XButtonPressedEvent));
507                  break;
508          }
509   }
# Line 518 | Line 532 | int    fore;
532          checkglerr("drawing grid lines");
533   }
534  
535 + static double
536 + getdistance(dx, dy, direc)      /* distance from fore plane along view ray */
537 + int     dx, dy;
538 + FVECT   direc;
539 + {
540 +        GLfloat gldepth;
541 +        double  dist;
542  
543 +        if (dx<0 | dx>=odev.hres | dy<0 | dy>=odev.vres)
544 +                return(FHUGE);
545 +        glReadPixels(dx,dy, 1,1, GL_DEPTH_COMPONENT,GL_FLOAT, &gldepth);
546 +        dist = mapdepth(gldepth);
547 +        if (dist >= .99*FHUGE)
548 +                return(FHUGE);
549 +        return((dist-odev.v.vfore)/DOT(direc,odev.v.vdir));
550 + }
551 +
552 +
553   static
554   moveview(dx, dy, mov, orb)      /* move our view */
555   int     dx, dy, mov, orb;
556   {
557          VIEW    nv;
558          FVECT   odir, v1, wip;
559 <        double  d;
559 >        double  d,d1;
560          register int    li;
561                                  /* start with old view */
562 <        copystruct(&nv, &odev.v);
562 >        nv = odev.v;
563                                  /* orient our motion */
564          if (viewray(v1, odir, &odev.v,
565                          (dx+.5)/odev.hres, (dy+.5)/odev.vres) < -FTINY)
566                  return(0);              /* outside view */
567          if (mov | orb) {        /* moving relative to geometry */
568 +                d = getdistance(dx, dy, odir);/*distance from front plane */
569   #ifdef DOBJ
570 <                d = dobj_trace(NULL, v1, odir); /* check objects */
570 >                d1 = dobj_trace(NULL, v1, odir);        /* check objects */
571                                                  /* check holodeck */
572 <                if ((li = smFindSamp(v1, odir)) >= 0) {
573 <                        VCOPY(wip, rsL.wp[li]);
542 <                        if (d < .99*FHUGE && d*d <= dist2(v1, wip))
543 <                                li = -1;        /* object is closer */
544 <                } else if (d >= .99*FHUGE)
545 <                        return(0);              /* nothing visible */
546 <                if (li < 0)
547 <                        VSUM(wip, v1, odir, d); /* else get object point */
548 < #else
549 <                if ((li = smFindSamp(v1, odir)) < 0)
550 <                        return(0);      /* not on window */
551 <                VCOPY(wip, rsL.wp[li]);
572 >                if (d1 < d)
573 >                        d = d1;
574   #endif
575 <                VSUM(odir, wip, odev.v.vp, -1.);
575 >                if (d >= .99*FHUGE)
576 >                        d = 0.5*(dev_zmax+dev_zmin);    /* just guess */
577 >                VSUM(wip, v1, odir, d);
578 >                VSUB(odir, wip, odev.v.vp);
579 > #if 0
580 >                fprintf(stderr, "moveview: hit %s at (%f,%f,%f) (t=%f)\n",
581 >                                li < 0 ? "object" : "mesh",
582 >                                wip[0], wip[1], wip[2],
583 >                                (wip[0]-odev.v.vp[0])*odir[0] +
584 >                                (wip[1]-odev.v.vp[1])*odir[1] +
585 >                                (wip[2]-odev.v.vp[2])*odir[2]);
586 > #endif
587          } else                  /* panning with constant viewpoint */
588                  VCOPY(nv.vdir, odir);
589          if (orb && mov) {               /* orbit left/right */
# Line 582 | Line 615 | int    dx, dy, mov, orb;
615  
616  
617   static
618 + getframe(ebut)                          /* get focus frame */
619 + XButtonPressedEvent     *ebut;
620 + {
621 +        int     startx = ebut->x, starty = ebut->y;
622 +        int     endx, endy;
623 +
624 +        XMaskEvent(ourdisplay, ButtonReleaseMask, levptr(XEvent));
625 +        endx = levptr(XButtonReleasedEvent)->x;
626 +        endy = levptr(XButtonReleasedEvent)->y;
627 +        if (endx == startx | endy == starty) {
628 +                XBell(ourdisplay, 0);
629 +                return;
630 +        }
631 +        if (endx < startx) {register int c = endx; endx = startx; startx = c;}
632 +        if (endy < starty) {register int c = endy; endy = starty; starty = c;}
633 +        sprintf(odev_args, "%.3f %.3f %.3f %.3f",
634 +                        (startx+.5)/odev.hres, 1.-(endy+.5)/odev.vres,
635 +                        (endx+.5)/odev.hres, 1.-(starty+.5)/odev.vres);
636 +        inpresflags |= DFL(DC_FOCUS);
637 + }
638 +
639 +
640 + static
641   getmove(ebut)                           /* get view change */
642   XButtonPressedEvent     *ebut;
643   {
644          int     movdir = MOVDIR(ebut->button);
645          int     movorb = MOVORB(ebut->state);
646 <        int     qlevel = 99;
646 >        int     qlevel = MAXQUALITY-1;
647          time_t  lasttime, thistime;
648          int     nframes;
649          Window  rootw, childw;
# Line 596 | Line 652 | XButtonPressedEvent    *ebut;
652  
653          XNoOp(ourdisplay);              /* makes sure we're not idle */
654  
655 <        lasttime = time(0); nframes = 0;
655 >        nframes = 0;
656          while (!XCheckMaskEvent(ourdisplay,
657                          ButtonReleaseMask, levptr(XEvent))) {
658                                          /* get cursor position */
# Line 630 | Line 686 | XButtonPressedEvent    *ebut;
686                  dobj_render();          /* redraw object */
687   #endif
688                  glFlush();
689 <                nframes++;              /* figure out good quality level */
689 >                                        /* figure out good quality level */
690 >                if (!nframes++) {               /* ignore first frame */
691 >                        lasttime = time(0);
692 >                        continue;
693 >                }
694                  thistime = time(0);
695 <                if (thistime - lasttime >= 3 ||
695 >                if (thistime - lasttime >= 6 ||
696                                  nframes > (int)(3*3*TARGETFPS)) {
697 <                        qlevel = thistime<=lasttime ? 1000 :
697 >                        qlevel = thistime<=lasttime ? 3*MAXQUALITY :
698                                  (int)((double)nframes/(thistime-lasttime)
699                                          / TARGETFPS * qlevel + 0.5);
700 <                        lasttime = thistime; nframes = 0;
701 <                        if (qlevel > 99) {
702 <                                if (qlevel > 300) {     /* put on the brakes */
700 >                        nframes = 0;
701 >                        if (qlevel >= MAXQUALITY) {
702 >                                if (qlevel >= 3*MAXQUALITY) {   /* brakes!! */
703                                          sleep(1);
704                                          lasttime++;
705                                  }
706 <                                qlevel = 99;
706 >                                qlevel = MAXQUALITY-1;
707                          } else if (qlevel < 1)
708                                  qlevel = 1;
709                  }
# Line 664 | Line 724 | register VIEW  *vp;
724          double  d, xmin, xmax, ymin, ymax;
725  
726          if (mindpth >= maxdpth) {
727 <                dev_zmin = 0.1;
727 >                dev_zmin = 1.;
728                  dev_zmax = 100.;
729          } else {
730 <                dev_zmin = 0.5*mindpth;
731 <                dev_zmax = 1.5*maxdpth;
672 <                if (dev_zmin > dev_zmax/100.)
673 <                        dev_zmin = dev_zmax/100.;
730 >                dev_zmin = 0.1*mindpth;
731 >                dev_zmax = 5.0*maxdpth;
732          }
733          if (odev.v.vfore > FTINY)
734                  dev_zmin = odev.v.vfore;
735          if (odev.v.vaft > FTINY)
736                  dev_zmax = odev.v.vaft;
737 <        if (dev_zmin < dev_zmax/5000.)
738 <                dev_zmin = dev_zmax/5000.;
737 >        if (dev_zmin*500. < dev_zmax)
738 >                dev_zmax = dev_zmin*500.;
739          xmax = dev_zmin * tan(PI/180./2. * odev.v.horiz);
740          xmin = -xmax;
741          d = odev.v.hoff * (xmax - xmin);
# Line 700 | Line 758 | register VIEW  *vp;
758  
759  
760   static
761 < wipeclean()                     /* prepare for redraw */
761 > wipeclean(tmflag)                       /* prepare for redraw */
762 > int     tmflag;
763   {
764                                          /* clear depth buffer */
765   #ifdef STEREO
# Line 709 | Line 768 | wipeclean()                    /* prepare for redraw */
768          setstereobuf(STEREO_BUFFER_LEFT);
769   #endif
770          glClear(GL_DEPTH_BUFFER_BIT);
771 <        smClean();                      /* reset drawing routines */
771 >        smClean(tmflag);                /* reset drawing routines */
772          setglpersp(&odev.v);            /* reset view & clipping planes */
773   }
774  
# Line 718 | Line 777 | static
777   getkey(ekey)                            /* get input key */
778   register XKeyPressedEvent  *ekey;
779   {
780 +        Window  rootw, childw;
781 +        int     rootx, rooty, wx, wy;
782 +        unsigned int    statemask;
783          int  n;
784          char    buf[8];
785  
# Line 740 | Line 802 | register XKeyPressedEvent  *ekey;
802          case 'v':                       /* spit out view */
803                  inpresflags |= DFL(DC_GETVIEW);
804                  return;
805 +        case 'f':                       /* frame view position */
806 +                if (!XQueryPointer(ourdisplay, gwind, &rootw, &childw,
807 +                                &rootx, &rooty, &wx, &wy, &statemask))
808 +                        return;         /* on another screen */
809 +                sprintf(odev_args, "%.4f %.4f", (wx+.5)/odev.hres,
810 +                                1.-(wy+.5)/odev.vres);
811 +                inpresflags |= DFL(DC_FOCUS);
812 +                return;
813 +        case 'F':                       /* unfocus */
814 +                odev_args[0] = '\0';
815 +                inpresflags |= DFL(DC_FOCUS);
816 +                return;
817          case '\n':
818          case '\r':                      /* resume computation */
819                  inpresflags |= DFL(DC_RESUME);
820                  return;
821          case CTRL('R'):                 /* redraw screen */
822 <                wipeclean();
822 >                wipeclean(1);
823                  return;
824          case CTRL('L'):                 /* refresh from server */
825                  if (inpresflags & DFL(DC_REDRAW))
# Line 795 | Line 869 | register XExposeEvent  *eexp;
869          }
870          if (eexp->count)                /* wait for final exposure */
871                  return;
872 <        wipeclean();                    /* clear depth */
872 >        wipeclean(0);                   /* clear depth */
873   }
874  
875  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines