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.22 by gwlarson, Tue Aug 25 18:11:17 1998 UTC vs.
Revision 3.31 by greg, Fri Sep 19 18:33:04 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
81  
82   static int      rayqleft = 0;           /* rays left to queue before flush */
83  
# Line 99 | 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 216 | Line 222 | char  *id;
222          pheight *= 2.;
223          setstereobuf(STEREO_BUFFER_LEFT);
224   #endif
225 <        copystruct(&odev.v, &stdview);
225 >        checkglerr("setting rendering parameters");
226 >        odev.v = stdview;
227          odev.v.type = VT_PER;
228                                          /* map the window */
229          XMapWindow(ourdisplay, gwind);
# Line 253 | 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 299 | 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 <        }
310 <        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 390 | Line 404 | dev_flush()                    /* flush output */
404          if (mapped) {
405   #ifdef STEREO
406                  pushright();                    /* update right eye */
407 <                glClear(GL_DEPTH_BUFFER_BIT);
394 <                smUpdate(&vwright, 100);
407 >                smUpdate(&vwright, MAXQUALITY);
408   #ifdef DOBJ
409                  dobj_render();                  /* usually in foreground */
410   #endif
411                  popright();                     /* update left eye */
399                glClear(GL_DEPTH_BUFFER_BIT);
412   #endif
413 <                smUpdate(&odev.v, 100);
413 >                smUpdate(&odev.v, MAXQUALITY);
414                  checkglerr("rendering mesh");
415   #ifdef DOBJ
416                  dobj_render();
# Line 435 | Line 447 | pushright()                    /* push on right view */
447          glPushMatrix();
448          d = -eyesepdist / sqrt(odev.v.hn2);
449          glTranslated(d*odev.v.hvec[0], d*odev.v.hvec[1], d*odev.v.hvec[2]);
450 +        checkglerr("setting right view");
451   }
452  
453  
# Line 487 | 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 506 | Line 522 | static
522   draw_grids(fore)                /* draw holodeck section grids */
523   int     fore;
524   {
509        if (!mapped)
510                return;
525          if (fore)
526                  glColor4ub(0, 255, 255, 0);
527          else
# Line 515 | Line 529 | int    fore;
529          glBegin(GL_LINES);              /* draw each grid line */
530          gridlines(draw3dline);
531          glEnd();
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 +        if (gldepth <= FTINY)
547 +                return (FHUGE); /* call failed */
548 +        dist = mapdepth(gldepth);
549 +        if (dist >= .99*FHUGE)
550 +                return(FHUGE);
551 +        return((dist-odev.v.vfore)/DOT(direc,odev.v.vdir));
552 + }
553 +
554 +
555   static
556   moveview(dx, dy, mov, orb)      /* move our view */
557   int     dx, dy, mov, orb;
558   {
559          VIEW    nv;
560          FVECT   odir, v1, wip;
561 <        double  d;
561 >        double  d,d1;
562          register int    li;
563                                  /* start with old view */
564 <        copystruct(&nv, &odev.v);
564 >        nv = odev.v;
565                                  /* orient our motion */
566          if (viewray(v1, odir, &odev.v,
567                          (dx+.5)/odev.hres, (dy+.5)/odev.vres) < -FTINY)
568                  return(0);              /* outside view */
569          if (mov | orb) {        /* moving relative to geometry */
570 +                d = getdistance(dx, dy, odir);/*distance from front plane */
571   #ifdef DOBJ
572 <                d = dobj_trace(NULL, v1, odir); /* check objects */
572 >                d1 = dobj_trace(NULL, v1, odir);        /* check objects */
573                                                  /* check holodeck */
574 <                if ((li = smFindSamp(v1, odir)) >= 0) {
575 <                        VCOPY(wip, rsL.wp[li]);
541 <                        if (d < .99*FHUGE && d*d <= dist2(v1, wip))
542 <                                li = -1;        /* object is closer */
543 <                } else if (d >= .99*FHUGE)
544 <                        return(0);              /* nothing visible */
545 <                if (li < 0)
546 <                        VSUM(wip, v1, odir, d); /* else get object point */
547 < #else
548 <                if ((li = smFindSamp(v1, odir)) < 0)
549 <                        return(0);      /* not on window */
550 <                VCOPY(wip, rsL.wp[li]);
574 >                if (d1 < d)
575 >                        d = d1;
576   #endif
577 <                VSUM(odir, wip, odev.v.vp, -1.);
577 >                if (d >= .99*FHUGE)
578 >                        d = 0.5*(dev_zmax+dev_zmin);    /* just guess */
579 >                VSUM(wip, v1, odir, d);
580 >                VSUB(odir, wip, odev.v.vp);
581 > #if 0
582 >                fprintf(stderr, "moveview: hit %s at (%f,%f,%f) (t=%f)\n",
583 >                                li < 0 ? "object" : "mesh",
584 >                                wip[0], wip[1], wip[2],
585 >                                (wip[0]-odev.v.vp[0])*odir[0] +
586 >                                (wip[1]-odev.v.vp[1])*odir[1] +
587 >                                (wip[2]-odev.v.vp[2])*odir[2]);
588 > #endif
589          } else                  /* panning with constant viewpoint */
590                  VCOPY(nv.vdir, odir);
591          if (orb && mov) {               /* orbit left/right */
# Line 581 | Line 617 | int    dx, dy, mov, orb;
617  
618  
619   static
620 + getframe(ebut)                          /* get focus frame */
621 + XButtonPressedEvent     *ebut;
622 + {
623 +        int     startx = ebut->x, starty = ebut->y;
624 +        int     endx, endy;
625 +
626 +        XMaskEvent(ourdisplay, ButtonReleaseMask, levptr(XEvent));
627 +        endx = levptr(XButtonReleasedEvent)->x;
628 +        endy = levptr(XButtonReleasedEvent)->y;
629 +        if (endx == startx | endy == starty) {
630 +                XBell(ourdisplay, 0);
631 +                return;
632 +        }
633 +        if (endx < startx) {register int c = endx; endx = startx; startx = c;}
634 +        if (endy < starty) {register int c = endy; endy = starty; starty = c;}
635 +        sprintf(odev_args, "%.3f %.3f %.3f %.3f",
636 +                        (startx+.5)/odev.hres, 1.-(endy+.5)/odev.vres,
637 +                        (endx+.5)/odev.hres, 1.-(starty+.5)/odev.vres);
638 +        inpresflags |= DFL(DC_FOCUS);
639 + }
640 +
641 +
642 + static
643   getmove(ebut)                           /* get view change */
644   XButtonPressedEvent     *ebut;
645   {
646          int     movdir = MOVDIR(ebut->button);
647          int     movorb = MOVORB(ebut->state);
648 <        int     qlevel = 99;
648 >        int     qlevel = MAXQUALITY-1;
649          time_t  lasttime, thistime;
650          int     nframes;
651          Window  rootw, childw;
652          int     rootx, rooty, wx, wy;
653          unsigned int    statemask;
654  
655 <        XNoOp(ourdisplay);
655 >        XNoOp(ourdisplay);              /* makes sure we're not idle */
656  
657 <        lasttime = time(0); nframes = 0;
657 >        nframes = 0;
658          while (!XCheckMaskEvent(ourdisplay,
659                          ButtonReleaseMask, levptr(XEvent))) {
660 <
660 >                                        /* get cursor position */
661                  if (!XQueryPointer(ourdisplay, gwind, &rootw, &childw,
662                                  &rootx, &rooty, &wx, &wy, &statemask))
663                          break;          /* on another screen */
664  
665                  draw_grids(0);          /* clear old grid lines */
666 + #ifdef STEREO
667 +                pushright(); draw_grids(0); popright();
668 + #endif
669 +                                        /* compute view motion */
670                  if (!moveview(wx, odev.vres-1-wy, movdir, movorb)) {
671                          sleep(1);
672                          lasttime++;
673 <                        continue;
673 >                        continue;       /* cursor in bad place */
674                  }
675 +                draw_grids(1);          /* redraw grid */
676   #ifdef STEREO
677                  pushright();
678                  draw_grids(1);
# Line 618 | Line 682 | XButtonPressedEvent    *ebut;
682   #endif
683                  popright();
684   #endif
685 <                draw_grids(1);
685 >                                        /* redraw mesh */
686                  smUpdate(&odev.v, qlevel);
687   #ifdef DOBJ
688 <                dobj_render();
688 >                dobj_render();          /* redraw object */
689   #endif
690                  glFlush();
691 <                checkglerr("moving view");
692 <                nframes++;
691 >                                        /* figure out good quality level */
692 >                if (!nframes++) {               /* ignore first frame */
693 >                        lasttime = time(0);
694 >                        continue;
695 >                }
696                  thistime = time(0);
697 <                if (thistime - lasttime >= 3 ||
697 >                if (thistime - lasttime >= 6 ||
698                                  nframes > (int)(3*3*TARGETFPS)) {
699 <                        qlevel = thistime<=lasttime ? 1000 :
699 >                        qlevel = thistime<=lasttime ? 3*MAXQUALITY :
700                                  (int)((double)nframes/(thistime-lasttime)
701                                          / TARGETFPS * qlevel + 0.5);
702 <                        lasttime = thistime; nframes = 0;
703 <                        if (qlevel > 99) {
704 <                                if (qlevel > 300) {     /* put on the brakes */
702 >                        nframes = 0;
703 >                        if (qlevel >= MAXQUALITY) {
704 >                                if (qlevel >= 3*MAXQUALITY) {   /* brakes!! */
705                                          sleep(1);
706                                          lasttime++;
707                                  }
708 <                                qlevel = 99;
708 >                                qlevel = MAXQUALITY-1;
709                          } else if (qlevel < 1)
710                                  qlevel = 1;
711                  }
# Line 659 | Line 726 | register VIEW  *vp;
726          double  d, xmin, xmax, ymin, ymax;
727  
728          if (mindpth >= maxdpth) {
729 <                dev_zmin = 0.1;
729 >                dev_zmin = 1.;
730                  dev_zmax = 100.;
731          } else {
732 <                dev_zmin = 0.5*mindpth;
733 <                dev_zmax = 1.5*maxdpth;
667 <                if (dev_zmin > dev_zmax/100.)
668 <                        dev_zmin = dev_zmax/100.;
732 >                dev_zmin = 0.1*mindpth;
733 >                dev_zmax = 5.0*maxdpth;
734          }
735          if (odev.v.vfore > FTINY)
736                  dev_zmin = odev.v.vfore;
737          if (odev.v.vaft > FTINY)
738                  dev_zmax = odev.v.vaft;
739 <        if (dev_zmin < dev_zmax/5000.)
740 <                dev_zmin = dev_zmax/5000.;
739 >        if (dev_zmin*500. < dev_zmax)
740 >                dev_zmax = dev_zmin*500.;
741          xmax = dev_zmin * tan(PI/180./2. * odev.v.horiz);
742          xmin = -xmax;
743          d = odev.v.hoff * (xmax - xmin);
# Line 690 | Line 755 | register VIEW  *vp;
755                  odev.v.vp[1] + odev.v.vdir[1],
756                  odev.v.vp[2] + odev.v.vdir[2],
757                  odev.v.vup[0], odev.v.vup[1], odev.v.vup[2]);
758 +        checkglerr("setting perspective view");
759   }
760  
761  
762   static
763 < wipeclean()                     /* prepare for redraw */
763 > wipeclean(tmflag)                       /* prepare for redraw */
764 > int     tmflag;
765   {
766                                          /* clear depth buffer */
767   #ifdef STEREO
# Line 703 | Line 770 | wipeclean()                    /* prepare for redraw */
770          setstereobuf(STEREO_BUFFER_LEFT);
771   #endif
772          glClear(GL_DEPTH_BUFFER_BIT);
773 <        smClean();                      /* reset drawing routines */
773 >        smClean(tmflag);                /* reset drawing routines */
774          setglpersp(&odev.v);            /* reset view & clipping planes */
775   }
776  
# Line 712 | Line 779 | static
779   getkey(ekey)                            /* get input key */
780   register XKeyPressedEvent  *ekey;
781   {
782 +        Window  rootw, childw;
783 +        int     rootx, rooty, wx, wy;
784 +        unsigned int    statemask;
785          int  n;
786          char    buf[8];
787  
# Line 734 | Line 804 | register XKeyPressedEvent  *ekey;
804          case 'v':                       /* spit out view */
805                  inpresflags |= DFL(DC_GETVIEW);
806                  return;
807 +        case 'f':                       /* frame view position */
808 +                if (!XQueryPointer(ourdisplay, gwind, &rootw, &childw,
809 +                                &rootx, &rooty, &wx, &wy, &statemask))
810 +                        return;         /* on another screen */
811 +                sprintf(odev_args, "%.4f %.4f", (wx+.5)/odev.hres,
812 +                                1.-(wy+.5)/odev.vres);
813 +                inpresflags |= DFL(DC_FOCUS);
814 +                return;
815 +        case 'F':                       /* unfocus */
816 +                odev_args[0] = '\0';
817 +                inpresflags |= DFL(DC_FOCUS);
818 +                return;
819          case '\n':
820          case '\r':                      /* resume computation */
821                  inpresflags |= DFL(DC_RESUME);
822                  return;
823          case CTRL('R'):                 /* redraw screen */
824 <                wipeclean();
824 >                wipeclean(1);
825                  return;
826          case CTRL('L'):                 /* refresh from server */
827                  if (inpresflags & DFL(DC_REDRAW))
828                          return;
829 +                setglpersp(&odev.v);            /* reset clipping planes */
830                  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
831 <                glDisable(GL_DEPTH_TEST);
831 >                glDisable(GL_DEPTH_TEST);       /* so grids will clear */
832                  draw_grids(1);
833   #ifdef STEREO
834                  pushright();
# Line 757 | Line 840 | register XKeyPressedEvent  *ekey;
840                  glFlush();
841                  smInit(rsL.max_samp);           /* get rid of old values */
842                  inpresflags |= DFL(DC_REDRAW);  /* resend values from server */
760                setglpersp(&odev.v);            /* reset clipping planes */
843                  rayqleft = 0;                   /* hold off update */
844                  return;
845          case 'K':                       /* kill rtrace process(es) */
# Line 789 | Line 871 | register XExposeEvent  *eexp;
871          }
872          if (eexp->count)                /* wait for final exposure */
873                  return;
874 <        wipeclean();                    /* clear depth */
874 >        wipeclean(0);                   /* clear depth */
875   }
876  
877  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines