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

Comparing ray/src/hd/rhd_x11.c (file contents):
Revision 3.10 by gregl, Fri Dec 5 09:38:55 1997 UTC vs.
Revision 3.26 by gwlarson, Wed Jun 17 15:44:07 1998 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1997 Silicon Graphics, Inc. */
1 > /* Copyright (c) 1998 Silicon Graphics, Inc. */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ SGI";
# Line 18 | Line 18 | static char SCCSid[] = "$SunId$ SGI";
18  
19   #include  "x11icon.h"
20  
21 < #define CTRL(c)         ((c)-'@')
21 > #ifndef RAYQLEN
22 > #define RAYQLEN         50000           /* max. rays to queue before flush */
23 > #endif
24  
25 + #ifndef FEQ
26 + #define FEQ(a,b)        ((a)-(b) <= FTINY && (a)-(b) >= -FTINY)
27 + #endif
28 +
29   #define GAMMA           2.2             /* default gamma correction */
30  
31 < #define MOVPCT          10              /* percent distance to move */
31 > #define MOVPCT          7               /* percent distance to move /frame */
32   #define MOVDIR(b)       ((b)==Button1 ? 1 : (b)==Button2 ? 0 : -1)
33 + #define MOVDEG          (-5)            /* degrees to orbit CW/down /frame */
34 + #define MOVORB(s)       ((s)&ShiftMask ? 1 : (s)&ControlMask ? -1 : 0)
35  
36   #define MINWIDTH        480             /* minimum graphics window width */
37   #define MINHEIGHT       400             /* minimum graphics window height */
# Line 77 | Line 85 | mytmflags()                    /* figure out tone mapping flags */
85          for (cp = tail; *cp && *cp != '.'; cp++)
86                  ;
87          if (cp-tail == 3 && !strncmp(tail, "x11", 3))
88 <                return(TM_F_CAMERA);
88 >                return(TM_F_CAMERA|TM_F_NOSTDERR);
89          if (cp-tail == 4 && !strncmp(tail, "x11h", 4))
90 <                return(TM_F_HUMAN);
90 >                return(TM_F_HUMAN|TM_F_NOSTDERR);
91          error(USER, "illegal driver name");
92   }
93  
# Line 88 | Line 96 | dev_open(id)                   /* initialize X11 driver */
96   char  *id;
97   {
98          extern char  *getenv();
99 <        char  *gv;
99 >        static RGBPRIMS myprims = STDPRIMS;
100 >        char  *ev;
101          double  gamval = GAMMA;
102 +        RGBPRIMP        dpri = stdprims;
103          int  nplanes;
104          XSetWindowAttributes    ourwinattr;
105          XWMHints  ourxwmhints;
# Line 122 | Line 132 | char  *id;
132                  ourwhite = WhitePixel(ourdisplay,ourscreen);
133          }
134                                          /* set gamma and tone mapping */
135 <        if ((gv = XGetDefault(ourdisplay, "radiance", "gamma")) != NULL
136 <                        || (gv = getenv("DISPLAY_GAMMA")) != NULL)
137 <                gamval = atof(gv);
138 <        if (tmInit(mytmflags(), stdprims, gamval) == NULL)
135 >        if ((ev = XGetDefault(ourdisplay, "radiance", "gamma")) != NULL
136 >                        || (ev = getenv("DISPLAY_GAMMA")) != NULL)
137 >                gamval = atof(ev);
138 >        if ((ev = getenv("DISPLAY_PRIMARIES")) != NULL &&
139 >                        sscanf(ev, "%f %f %f %f %f %f %f %f",
140 >                                &myprims[RED][CIEX],&myprims[RED][CIEY],
141 >                                &myprims[GRN][CIEX],&myprims[GRN][CIEY],
142 >                                &myprims[BLU][CIEX],&myprims[BLU][CIEY],
143 >                                &myprims[WHT][CIEX],&myprims[WHT][CIEY]) >= 6)
144 >                dpri = myprims;
145 >        if (tmInit(mytmflags(), dpri, gamval) == NULL)
146                  error(SYSTEM, "not enough memory in dev_open");
147                                          /* open window */
148          ourwinattr.background_pixel = ourblack;
# Line 154 | Line 171 | char  *id;
171          oursizhints.min_height = MINHEIGHT;
172          oursizhints.flags = PMinSize;
173          XSetNormalHints(ourdisplay, gwind, &oursizhints);
157                                        /* map the window and get its size */
158        XMapWindow(ourdisplay, gwind);
159        dev_input();
160                                        /* allocate our leaf pile */
161        if (!qtAllocLeaves(DisplayWidth(ourdisplay,ourscreen) *
162                        DisplayHeight(ourdisplay,ourscreen) /
163                        (qtMinNodesiz*qtMinNodesiz)))
164                error(SYSTEM, "insufficient memory for leaf storage");
165
174                                          /* figure out sensible view */
175          pwidth = (double)DisplayWidthMM(ourdisplay, ourscreen) /
176                          DisplayWidth(ourdisplay, ourscreen);
177          pheight = (double)DisplayHeightMM(ourdisplay, ourscreen) /
178                          DisplayHeight(ourdisplay, ourscreen);
179          copystruct(&odev.v, &stdview);
172        odev.name = id;
180          odev.v.type = VT_PER;
181 <        odev.v.horiz = 2.*180./PI * atan(0.5/VIEWDIST*pwidth*odev.hres);
182 <        odev.v.vert = 2.*180./PI * atan(0.5/VIEWDIST*pheight*odev.vres);
181 >                                        /* map the window and get its size */
182 >        XMapWindow(ourdisplay, gwind);
183 >        dev_input();                    /* sets size and view angles */
184 >                                        /* allocate our leaf pile */
185 >        if (!qtAllocLeaves(DisplayWidth(ourdisplay,ourscreen) *
186 >                        DisplayHeight(ourdisplay,ourscreen) * 3 /
187 >                        (qtMinNodesiz*qtMinNodesiz*2)))
188 >                error(SYSTEM, "insufficient memory for leaf storage");
189 >        odev.name = id;
190          odev.ifd = ConnectionNumber(ourdisplay);
191   }
192  
# Line 194 | Line 208 | dev_close()                    /* close our display */
208   }
209  
210  
211 +
212 + dev_clear()                     /* clear our quadtree */
213 + {
214 +        qtCompost(100);
215 +        if (ncolors > 0)
216 +                new_ctab(ncolors);
217 +        rayqleft = 0;                   /* hold off update */
218 + }
219 +
220 +
221 + int
222   dev_view(nv)                    /* assign new driver view */
223   VIEW    *nv;
224   {
225 <        if (nv != &odev.v)
225 >        if (nv->type == VT_PAR ||               /* check view legality */
226 >                        nv->horiz > 160. || nv->vert > 160.) {
227 >                error(COMMAND, "illegal view type/angle");
228 >                nv->type = VT_PER;
229 >                nv->horiz = odev.v.horiz;
230 >                nv->vert = odev.v.vert;
231 >                return(0);
232 >        }
233 >        if (nv->vfore > FTINY) {
234 >                error(COMMAND, "cannot handle fore clipping");
235 >                nv->vfore = 0.;
236 >                return(0);
237 >        }
238 >        if (nv != &odev.v) {
239 >                if (!FEQ(nv->horiz,odev.v.horiz) ||     /* resize window? */
240 >                                !FEQ(nv->vert,odev.v.vert)) {
241 >                        int     dw = DisplayWidth(ourdisplay,ourscreen);
242 >                        int     dh = DisplayHeight(ourdisplay,ourscreen);
243 >
244 >                        dw -= 25;       /* for window frame */
245 >                        dh -= 50;
246 >                        odev.hres = 2.*VIEWDIST/pwidth *
247 >                                        tan(PI/180./2.*nv->horiz);
248 >                        odev.vres = 2.*VIEWDIST/pheight *
249 >                                        tan(PI/180./2.*nv->vert);
250 >                        if (odev.hres > dw) {
251 >                                odev.vres = dw * odev.vres / odev.hres;
252 >                                odev.hres = dw;
253 >                        }
254 >                        if (odev.vres > dh) {
255 >                                odev.hres = dh * odev.hres / odev.vres;
256 >                                odev.vres = dh;
257 >                        }
258 >                        XResizeWindow(ourdisplay, gwind, odev.hres, odev.vres);
259 >                        dev_input();    /* wait for resize event */
260 >                }
261                  copystruct(&odev.v, nv);
262 +        }
263          qtReplant();
264 +        return(1);
265   }
266  
267  
268 + dev_auxcom(cmd, args)           /* process an auxiliary command */
269 + char    *cmd, *args;
270 + {
271 +        sprintf(errmsg, "%s: unknown command", cmd);
272 +        error(COMMAND, errmsg);
273 + }
274 +
275 +
276 + VIEW *
277 + dev_auxview(n, hvres)           /* return nth auxiliary view */
278 + int     n;
279 + int     hvres[2];
280 + {
281 +        if (n)
282 +                return(NULL);
283 +        hvres[0] = odev.hres; hvres[1] = odev.vres;
284 +        return(&odev.v);
285 + }
286 +
287 +
288   int
289   dev_input()                     /* get X11 input */
290   {
# Line 239 | Line 321 | int
321   dev_flush()                     /* flush output */
322   {
323          qtUpdate();
324 +        rayqleft = RAYQLEN;
325          return(XPending(ourdisplay));
326   }
327  
# Line 414 | Line 497 | draw_grids()                   /* draw holodeck section grids */
497          static BYTE     gridrgb[3] = {0x0, 0xff, 0xff};
498          unsigned long  pixel;
499  
500 <        if (!mapped || odev.v.type != VT_PER)
500 >        if (!mapped)
501                  return;
502          if (ncolors > 0)
503                  pixel = pixval[get_pixel(gridrgb, xnewcolr)];
# Line 427 | Line 510 | draw_grids()                   /* draw holodeck section grids */
510  
511  
512   static
513 < moveview(dx, dy, move)          /* move our view */
514 < int     dx, dy, move;
513 > moveview(dx, dy, mov, orb)      /* move our view */
514 > int     dx, dy, mov, orb;
515   {
516          VIEW    nv;
517 +        FVECT   odir, v1;
518          double  d;
519 <        register int    i, li;
519 >        register int    li;
520                                  /* start with old view */
521          copystruct(&nv, &odev.v);
522                                  /* change view direction */
523 <        if (move) {
523 >        if (mov | orb) {
524                  if ((li = qtFindLeaf(dx, dy)) < 0)
525                          return(0);      /* not on window */
526 <                for (i = 0; i < 3; i++)
443 <                        nv.vdir[i] = qtL.wp[li][i] - nv.vp[i];
526 >                VSUM(odir, qtL.wp[li], nv.vp, -1.);
527          } else {
528                  if (viewray(nv.vp, nv.vdir, &odev.v,
529                                  (dx+.5)/odev.hres, (dy+.5)/odev.vres) < -FTINY)
530                          return(0);      /* outside view */
531          }
532 <                                /* move viewpoint */
533 <        if (move > 0)
534 <                for (i = 0; i < 3; i++)
535 <                        nv.vp[i] += MOVPCT/100. * nv.vdir[i];
536 <        else if (move < 0)
537 <                for (i = 0; i < 3; i++)
538 <                        nv.vp[i] -= MOVPCT/100. * nv.vdir[i];
539 <        if (move && headlocked) {
540 <                d = 0;          /* bring head back to same height */
541 <                for (i = 0; i < 3; i++)
542 <                        d += odev.v.vup[i] * (odev.v.vp[i] - nv.vp[i]);
543 <                for (i = 0; i < 3; i++)
544 <                        nv.vp[i] += d * odev.v.vup[i];
532 >        if (orb && mov) {               /* orbit left/right */
533 >                spinvector(odir, odir, nv.vup, d=MOVDEG*PI/180.*mov);
534 >                VSUM(nv.vp, qtL.wp[li], odir, -1.);
535 >                spinvector(nv.vdir, nv.vdir, nv.vup, d);
536 >        } else if (orb) {               /* orbit up/down */
537 >                fcross(v1, odir, nv.vup);
538 >                if (normalize(v1) == 0.)
539 >                        return(0);
540 >                spinvector(odir, odir, v1, d=MOVDEG*PI/180.*orb);
541 >                VSUM(nv.vp, qtL.wp[li], odir, -1.);
542 >                spinvector(nv.vdir, nv.vdir, v1, d);
543 >        } else if (mov) {               /* move forward/backward */
544 >                d = MOVPCT/100. * mov;
545 >                VSUM(nv.vp, nv.vp, odir, d);
546          }
547 +        if (!mov ^ !orb && headlocked) {        /* restore head height */
548 +                VSUM(v1, odev.v.vp, nv.vp, -1.);
549 +                d = DOT(v1, odev.v.vup);
550 +                VSUM(nv.vp, nv.vp, odev.v.vup, d);
551 +        }
552          if (setview(&nv) != NULL)
553                  return(0);      /* illegal view */
554          dev_view(&nv);
555 <        inpresflags |= DEV_NEWVIEW;
555 >        inpresflags |= DFL(DC_SETVIEW);
556          return(1);
557   }
558  
# Line 472 | Line 561 | static
561   getmove(ebut)                           /* get view change */
562   XButtonPressedEvent     *ebut;
563   {
564 <        int     whichbutton = ebut->button;
564 >        int     movdir = MOVDIR(ebut->button);
565 >        int     movorb = MOVORB(ebut->state);
566          int     oldnodesiz = qtMinNodesiz;
567          Window  rootw, childw;
568          int     rootx, rooty, wx, wy;
# Line 488 | Line 578 | XButtonPressedEvent    *ebut;
578                                  &rootx, &rooty, &wx, &wy, &statemask))
579                          break;          /* on another screen */
580  
581 <                if (!moveview(wx, odev.vres-1-wy, MOVDIR(whichbutton))) {
581 >                if (!moveview(wx, odev.vres-1-wy, movdir, movorb)) {
582                          sleep(1);
583                          continue;
584                  }
# Line 496 | Line 586 | XButtonPressedEvent    *ebut;
586                  qtUpdate();
587                  draw_grids();
588          }
589 <        if (!(inpresflags & DEV_NEWVIEW)) {     /* do final motion */
590 <                whichbutton = levptr(XButtonReleasedEvent)->button;
589 >        if (!(inpresflags & DFL(DC_SETVIEW))) { /* do final motion */
590 >                movdir = MOVDIR(levptr(XButtonReleasedEvent)->button);
591                  wx = levptr(XButtonReleasedEvent)->x;
592                  wy = levptr(XButtonReleasedEvent)->y;
593 <                moveview(wx, odev.vres-1-wy, MOVDIR(whichbutton));
593 >                moveview(wx, odev.vres-1-wy, movdir, movorb);
594          }
595          dev_flush();
596  
# Line 525 | Line 615 | register XKeyPressedEvent  *ekey;
615          case 'H':                       /* turn off height motion lock */
616                  headlocked = 0;
617                  return;
618 <        case CTRL('S'):
618 >        case 'l':                       /* retrieve last view */
619 >                inpresflags |= DFL(DC_LASTVIEW);
620 >                return;
621          case 'p':                       /* pause computation */
622 <                inpresflags |= DEV_WAIT;
622 >                inpresflags |= DFL(DC_PAUSE);
623                  return;
624          case 'v':                       /* spit out view */
625 <                fputs(VIEWSTR, stderr);
534 <                fprintview(&odev.v, stderr);
535 <                fputc('\n', stderr);
625 >                inpresflags |= DFL(DC_GETVIEW);
626                  return;
537        case CTRL('Q'):
627          case '\n':
628          case '\r':                      /* resume computation */
629 <                inpresflags |= DEV_RESUME;
629 >                inpresflags |= DFL(DC_RESUME);
630                  return;
631          case CTRL('R'):                 /* redraw screen */
632                  if (ncolors > 0)
# Line 545 | Line 634 | register XKeyPressedEvent  *ekey;
634                  qtRedraw(0, 0, odev.hres, odev.vres);
635                  return;
636          case CTRL('L'):                 /* refresh from server */
637 <                if (inpresflags & DEV_REDRAW)
637 >                if (inpresflags & DFL(DC_REDRAW))
638                          return;
639                  XClearWindow(ourdisplay, gwind);
640                  draw_grids();
# Line 553 | Line 642 | register XKeyPressedEvent  *ekey;
642                  qtCompost(100);                 /* unload the old tree */
643                  if (ncolors > 0)
644                          new_ctab(ncolors);
645 <                inpresflags |= DEV_REDRAW;      /* resend values from server */
645 >                inpresflags |= DFL(DC_REDRAW);  /* resend values from server */
646 >                rayqleft = 0;                   /* hold off update */
647                  return;
648 <        case CTRL('D'):
649 <        case 'Q':
648 >        case 'K':                       /* kill rtrace process(es) */
649 >                inpresflags |= DFL(DC_KILL);
650 >                break;
651 >        case 'R':                       /* restart rtrace */
652 >                inpresflags |= DFL(DC_RESTART);
653 >                break;
654 >        case 'C':                       /* clobber holodeck */
655 >                inpresflags |= DFL(DC_CLOBBER);
656 >                break;
657          case 'q':                       /* quit the program */
658 <                inpresflags |= DEV_SHUTDOWN;
658 >                inpresflags |= DFL(DC_QUIT);
659                  return;
660          default:
661                  XBell(ourdisplay, 0);
# Line 574 | Line 671 | register XExposeEvent  *eexp;
671          if (odev.hres == 0 || odev.vres == 0) { /* first exposure */
672                  odev.hres = eexp->width;
673                  odev.vres = eexp->height;
577                inpresflags |= DEV_NEWSIZE;
674          }
675          qtRedraw(eexp->x, odev.vres - eexp->y - eexp->height,
676                          eexp->x + eexp->width, odev.vres - eexp->y);
# Line 588 | Line 684 | register XConfigureEvent  *ersz;
684          if (ersz->width == odev.hres && ersz->height == odev.vres)
685                  return;
686  
591        if (odev.hres != 0 && odev.vres != 0) {
592                odev.v.horiz = 2.*180./PI * atan(
593                        tan(PI/180./2.*odev.v.horiz) * ersz->width/odev.hres );
594                odev.v.vert = 2.*180./PI * atan(
595                        tan(PI/180./2.*odev.v.vert) * ersz->height/odev.vres );
596                inpresflags |= DEV_NEWVIEW;
597        }
687          odev.hres = ersz->width;
688          odev.vres = ersz->height;
689  
690 <        inpresflags |= DEV_NEWSIZE;
690 >        odev.v.horiz = 2.*180./PI * atan(0.5/VIEWDIST*pwidth*odev.hres);
691 >        odev.v.vert = 2.*180./PI * atan(0.5/VIEWDIST*pheight*odev.vres);
692 >
693 >        inpresflags |= DFL(DC_SETVIEW);
694   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines