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.1 by gregl, Wed Nov 19 18:01:03 1997 UTC vs.
Revision 3.23 by gregl, Tue Jan 6 05:26:19 1998 UTC

# Line 18 | Line 18 | static char SCCSid[] = "$SunId$ SGI";
18  
19   #include  "x11icon.h"
20  
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          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 */
38  
# Line 30 | Line 43 | static char SCCSid[] = "$SunId$ SGI";
43   #define  ourscreen      DefaultScreen(ourdisplay)
44   #define  ourroot        RootWindow(ourdisplay,ourscreen)
45   #define  ourmask        (StructureNotifyMask|ExposureMask|KeyPressMask|\
46 <                        ButtonPressMask)
46 >                        ButtonPressMask|ButtonReleaseMask)
47  
48   #define  levptr(etype)  ((etype *)&currentevent)
49  
# Line 44 | Line 57 | static unsigned long  *pixval = NULL;  /* allocated pix
57   static unsigned long  ourblack=0, ourwhite=1;
58  
59   static Display  *ourdisplay = NULL;     /* our display */
47
60   static XVisualInfo  ourvinfo;           /* our visual information */
49
61   static Window  gwind = 0;               /* our graphics window */
51
62   static GC  ourgc = 0;                   /* our graphics context for drawing */
53
63   static Colormap ourmap = 0;             /* our color map */
64  
65   static double   pwidth, pheight;        /* pixel dimensions (mm) */
66  
67   static int      inpresflags;            /* input result flags */
68  
69 < static int      heightlocked = 0;       /* lock vertical motion */
69 > static int      headlocked = 0;         /* lock vertical motion */
70  
71   static int  getpixels(), xnewcolr(), freepixels(), resizewindow(),
72 <                getevent(), getkey(), fixwindow();
72 >                getevent(), getkey(), moveview(), getmove(), fixwindow();
73   static unsigned long  true_pixel();
74  
75  
# Line 76 | 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 90 | Line 99 | char  *id;
99          char  *gv;
100          double  gamval = GAMMA;
101          int  nplanes;
93        int  n;
102          XSetWindowAttributes    ourwinattr;
103          XWMHints  ourxwmhints;
104          XSizeHints      oursizhints;
105 +                                        /* set quadtree globals */
106 +        qtMinNodesiz = 2;
107                                          /* open display server */
108          ourdisplay = XOpenDisplay(NULL);
109          if (ourdisplay == NULL)
# Line 152 | Line 162 | char  *id;
162          oursizhints.min_height = MINHEIGHT;
163          oursizhints.flags = PMinSize;
164          XSetNormalHints(ourdisplay, gwind, &oursizhints);
155                                        /* map the window and get its size */
156        XMapWindow(ourdisplay, gwind);
157        dev_input();
165                                          /* figure out sensible view */
166          pwidth = (double)DisplayWidthMM(ourdisplay, ourscreen) /
167                          DisplayWidth(ourdisplay, ourscreen);
168          pheight = (double)DisplayHeightMM(ourdisplay, ourscreen) /
169                          DisplayHeight(ourdisplay, ourscreen);
170          copystruct(&odev.v, &stdview);
164        odev.name = id;
171          odev.v.type = VT_PER;
172 <        odev.v.horiz = 2.*180./PI * atan(0.5/VIEWDIST*pwidth*odev.hres);
173 <        odev.v.vert = 2.*180./PI * atan(0.5/VIEWDIST*pheight*odev.vres);
174 <        odev.ifd = ConnectionNumber(ourdisplay);
172 >                                        /* map the window and get its size */
173 >        XMapWindow(ourdisplay, gwind);
174 >        dev_input();                    /* sets size and view angles */
175                                          /* allocate our leaf pile */
176 <        qtDepthEps = 0.02;
177 <        n = odev.hres < odev.vres ? odev.hres : odev.vres;
178 <        qtMinNodesiz = 1;
173 <        if (!qtAllocLeaves(n*n/(qtMinNodesiz*qtMinNodesiz)))
176 >        if (!qtAllocLeaves(DisplayWidth(ourdisplay,ourscreen) *
177 >                        DisplayHeight(ourdisplay,ourscreen) * 3 /
178 >                        (qtMinNodesiz*qtMinNodesiz*2)))
179                  error(SYSTEM, "insufficient memory for leaf storage");
180 +        odev.name = id;
181 +        odev.ifd = ConnectionNumber(ourdisplay);
182   }
183  
184  
# Line 192 | Line 199 | dev_close()                    /* close our display */
199   }
200  
201  
202 +
203 + dev_clear()                     /* clear our quadtree */
204 + {
205 +        qtCompost(100);
206 +        if (ncolors > 0)
207 +                new_ctab(ncolors);
208 +        rayqleft = 0;                   /* hold off update */
209 + }
210 +
211 +
212 + int
213   dev_view(nv)                    /* assign new driver view */
214   VIEW    *nv;
215   {
216 <        if (nv != &odev.v)
216 >        if (nv->type == VT_PAR ||               /* check view legality */
217 >                        nv->horiz > 160. || nv->vert > 160.) {
218 >                error(COMMAND, "illegal view type/angle");
219 >                nv->type = VT_PER;
220 >                nv->horiz = odev.v.horiz;
221 >                nv->vert = odev.v.vert;
222 >                return(0);
223 >        }
224 >        if (nv->vfore > FTINY) {
225 >                error(COMMAND, "cannot handle fore clipping");
226 >                nv->vfore = 0.;
227 >                return(0);
228 >        }
229 >        if (nv != &odev.v) {
230 >                if (!FEQ(nv->horiz,odev.v.horiz) ||     /* resize window? */
231 >                                !FEQ(nv->vert,odev.v.vert)) {
232 >                        int     dw = DisplayWidth(ourdisplay,ourscreen);
233 >                        int     dh = DisplayHeight(ourdisplay,ourscreen);
234 >
235 >                        dw -= 25;       /* for window frame */
236 >                        dh -= 50;
237 >                        odev.hres = 2.*VIEWDIST/pwidth *
238 >                                        tan(PI/180./2.*nv->horiz);
239 >                        odev.vres = 2.*VIEWDIST/pheight *
240 >                                        tan(PI/180./2.*nv->vert);
241 >                        if (odev.hres > dw) {
242 >                                odev.vres = dw * odev.vres / odev.hres;
243 >                                odev.hres = dw;
244 >                        }
245 >                        if (odev.vres > dh) {
246 >                                odev.hres = dh * odev.hres / odev.vres;
247 >                                odev.vres = dh;
248 >                        }
249 >                        XResizeWindow(ourdisplay, gwind, odev.hres, odev.vres);
250 >                        dev_input();    /* wait for resize event */
251 >                }
252                  copystruct(&odev.v, nv);
253 +        }
254          qtReplant();
255 +        return(1);
256   }
257  
258  
# Line 205 | Line 260 | int
260   dev_input()                     /* get X11 input */
261   {
262          inpresflags = 0;
263 +
264          do
265                  getevent();
266  
# Line 236 | Line 292 | int
292   dev_flush()                     /* flush output */
293   {
294          qtUpdate();
295 +        rayqleft = RAYQLEN;
296          return(XPending(ourdisplay));
297   }
298  
# Line 365 | Line 422 | getevent()                     /* get next event */
422                  getkey(levptr(XKeyPressedEvent));
423                  break;
424          case ButtonPress:
425 <                /* getmove(levptr(XButtonPressedEvent)); */
425 >                getmove(levptr(XButtonPressedEvent));
426                  break;
427          }
428   }
429  
430  
431   static
432 + ilclip(dp, wp)                  /* clip world coordinates to device */
433 + int     dp[2][2];
434 + FVECT   wp[2];
435 + {
436 +        static FVECT    vmin = {0.,0.,0.}, vmax = {1.,1.,FHUGE};
437 +        FVECT   ip[2];
438 +                                /* not exactly right, but who cares? */
439 +        viewloc(ip[0], &odev.v, wp[0]);
440 +        viewloc(ip[1], &odev.v, wp[1]);
441 +        if (!clip(ip[0], ip[1], vmin, vmax))
442 +                return(0);
443 +        dp[0][0] = ip[0][0]*odev.hres;
444 +        dp[0][1] = ip[0][1]*odev.vres;
445 +        dp[1][0] = ip[1][0]*odev.hres;
446 +        dp[1][1] = ip[1][1]*odev.vres;
447 +        return(1);
448 + }
449 +
450 +
451 + static
452 + draw3dline(wp)                  /* draw 3d line in world coordinates */
453 + FVECT   wp[2];
454 + {
455 +        int     dp[2][2];
456 +
457 +        if (!ilclip(dp, wp))
458 +                return;
459 +        XDrawLine(ourdisplay, gwind, ourgc,
460 +                        dp[0][0], odev.vres-1 - dp[0][1],
461 +                        dp[1][0], odev.vres-1 - dp[1][1]);
462 + }
463 +
464 +
465 + static
466 + draw_grids()                    /* draw holodeck section grids */
467 + {
468 +        static BYTE     gridrgb[3] = {0x0, 0xff, 0xff};
469 +        unsigned long  pixel;
470 +
471 +        if (!mapped)
472 +                return;
473 +        if (ncolors > 0)
474 +                pixel = pixval[get_pixel(gridrgb, xnewcolr)];
475 +        else
476 +                pixel = true_pixel(gridrgb);
477 +        XSetForeground(ourdisplay, ourgc, pixel);
478 +                                        /* draw each grid line */
479 +        gridlines(draw3dline);
480 + }
481 +
482 +
483 + static
484 + moveview(dx, dy, mov, orb)      /* move our view */
485 + int     dx, dy, mov, orb;
486 + {
487 +        VIEW    nv;
488 +        FVECT   odir, v1;
489 +        double  d;
490 +        register int    li;
491 +                                /* start with old view */
492 +        copystruct(&nv, &odev.v);
493 +                                /* change view direction */
494 +        if (mov | orb) {
495 +                if ((li = qtFindLeaf(dx, dy)) < 0)
496 +                        return(0);      /* not on window */
497 +                VSUM(odir, qtL.wp[li], nv.vp, -1.);
498 +        } else {
499 +                if (viewray(nv.vp, nv.vdir, &odev.v,
500 +                                (dx+.5)/odev.hres, (dy+.5)/odev.vres) < -FTINY)
501 +                        return(0);      /* outside view */
502 +        }
503 +        if (orb && mov) {               /* orbit left/right */
504 +                spinvector(odir, odir, nv.vup, d=MOVDEG*PI/180.*mov);
505 +                VSUM(nv.vp, qtL.wp[li], odir, -1.);
506 +                spinvector(nv.vdir, nv.vdir, nv.vup, d);
507 +        } else if (orb) {               /* orbit up/down */
508 +                fcross(v1, odir, nv.vup);
509 +                if (normalize(v1) == 0.)
510 +                        return(0);
511 +                spinvector(odir, odir, v1, d=MOVDEG*PI/180.*orb);
512 +                VSUM(nv.vp, qtL.wp[li], odir, -1.);
513 +                spinvector(nv.vdir, nv.vdir, v1, d);
514 +        } else if (mov) {               /* move forward/backward */
515 +                d = MOVPCT/100. * mov;
516 +                VSUM(nv.vp, nv.vp, odir, d);
517 +        }
518 +        if (!mov ^ !orb && headlocked) {        /* restore head height */
519 +                VSUM(v1, odev.v.vp, nv.vp, -1.);
520 +                d = DOT(v1, odev.v.vup);
521 +                VSUM(nv.vp, nv.vp, odev.v.vup, d);
522 +        }
523 +        if (setview(&nv) != NULL)
524 +                return(0);      /* illegal view */
525 +        dev_view(&nv);
526 +        inpresflags |= DFL(DC_SETVIEW);
527 +        return(1);
528 + }
529 +
530 +
531 + static
532 + getmove(ebut)                           /* get view change */
533 + XButtonPressedEvent     *ebut;
534 + {
535 +        int     movdir = MOVDIR(ebut->button);
536 +        int     movorb = MOVORB(ebut->state);
537 +        int     oldnodesiz = qtMinNodesiz;
538 +        Window  rootw, childw;
539 +        int     rootx, rooty, wx, wy;
540 +        unsigned int    statemask;
541 +
542 +        qtMinNodesiz = 16;              /* for quicker update */
543 +        XNoOp(ourdisplay);
544 +
545 +        while (!XCheckMaskEvent(ourdisplay,
546 +                        ButtonReleaseMask, levptr(XEvent))) {
547 +
548 +                if (!XQueryPointer(ourdisplay, gwind, &rootw, &childw,
549 +                                &rootx, &rooty, &wx, &wy, &statemask))
550 +                        break;          /* on another screen */
551 +
552 +                if (!moveview(wx, odev.vres-1-wy, movdir, movorb)) {
553 +                        sleep(1);
554 +                        continue;
555 +                }
556 +                XClearWindow(ourdisplay, gwind);
557 +                qtUpdate();
558 +                draw_grids();
559 +        }
560 +        if (!(inpresflags & DFL(DC_SETVIEW))) { /* do final motion */
561 +                movdir = MOVDIR(levptr(XButtonReleasedEvent)->button);
562 +                wx = levptr(XButtonReleasedEvent)->x;
563 +                wy = levptr(XButtonReleasedEvent)->y;
564 +                moveview(wx, odev.vres-1-wy, movdir, movorb);
565 +        }
566 +        dev_flush();
567 +
568 +        qtMinNodesiz = oldnodesiz;      /* restore quadtree resolution */
569 + }
570 +
571 +
572 + static
573   getkey(ekey)                            /* get input key */
574   register XKeyPressedEvent  *ekey;
575   {
# Line 383 | Line 581 | register XKeyPressedEvent  *ekey;
581                  return;
582          switch (buf[0]) {
583          case 'h':                       /* turn on height motion lock */
584 <                heightlocked = 1;
584 >                headlocked = 1;
585                  return;
586          case 'H':                       /* turn off height motion lock */
587 <                heightlocked = 0;
587 >                headlocked = 0;
588                  return;
589 <        case 'Q':
589 >        case 'l':                       /* retrieve last view */
590 >                inpresflags |= DFL(DC_LASTVIEW);
591 >                return;
592 >        case 'p':                       /* pause computation */
593 >                inpresflags |= DFL(DC_PAUSE);
594 >                return;
595 >        case 'v':                       /* spit out view */
596 >                inpresflags |= DFL(DC_GETVIEW);
597 >                return;
598 >        case '\n':
599 >        case '\r':                      /* resume computation */
600 >                inpresflags |= DFL(DC_RESUME);
601 >                return;
602 >        case CTRL('R'):                 /* redraw screen */
603 >                if (ncolors > 0)
604 >                        new_ctab(ncolors);
605 >                qtRedraw(0, 0, odev.hres, odev.vres);
606 >                return;
607 >        case CTRL('L'):                 /* refresh from server */
608 >                if (inpresflags & DFL(DC_REDRAW))
609 >                        return;
610 >                XClearWindow(ourdisplay, gwind);
611 >                draw_grids();
612 >                XFlush(ourdisplay);
613 >                qtCompost(100);                 /* unload the old tree */
614 >                if (ncolors > 0)
615 >                        new_ctab(ncolors);
616 >                inpresflags |= DFL(DC_REDRAW);  /* resend values from server */
617 >                rayqleft = 0;                   /* hold off update */
618 >                return;
619 >        case 'K':                       /* kill rtrace process(es) */
620 >                inpresflags |= DFL(DC_KILL);
621 >                break;
622 >        case 'R':                       /* restart rtrace */
623 >                inpresflags |= DFL(DC_RESTART);
624 >                break;
625 >        case 'C':                       /* clobber holodeck */
626 >                inpresflags |= DFL(DC_CLOBBER);
627 >                break;
628          case 'q':                       /* quit the program */
629 <                inpresflags |= DEV_SHUTDOWN;
629 >                inpresflags |= DFL(DC_QUIT);
630                  return;
631          default:
632                  XBell(ourdisplay, 0);
# Line 404 | Line 640 | fixwindow(eexp)                                /* repair damage to window */
640   register XExposeEvent  *eexp;
641   {
642          if (odev.hres == 0 || odev.vres == 0) { /* first exposure */
407 eputs("Resizing window in fixwindow\n");
643                  odev.hres = eexp->width;
644                  odev.vres = eexp->height;
410                inpresflags |= DEV_NEWSIZE;
645          }
646          qtRedraw(eexp->x, odev.vres - eexp->y - eexp->height,
647                          eexp->x + eexp->width, odev.vres - eexp->y);
# Line 421 | Line 655 | register XConfigureEvent  *ersz;
655          if (ersz->width == odev.hres && ersz->height == odev.vres)
656                  return;
657  
424        if (odev.hres != 0 && odev.vres != 0) {
425                odev.v.horiz = 2.*180./PI * atan(
426                        tan(PI/180./2.*odev.v.horiz) * ersz->width/odev.hres );
427                odev.v.vert = 2.*180./PI * atan(
428                        tan(PI/180./2.*odev.v.vert) * ersz->height/odev.vres );
429                inpresflags |= DEV_NEWVIEW;
430        }
658          odev.hres = ersz->width;
659          odev.vres = ersz->height;
660  
661 <        inpresflags |= DEV_NEWSIZE;
661 >        odev.v.horiz = 2.*180./PI * atan(0.5/VIEWDIST*pwidth*odev.hres);
662 >        odev.v.vert = 2.*180./PI * atan(0.5/VIEWDIST*pheight*odev.vres);
663 >
664 >        inpresflags |= DFL(DC_SETVIEW);
665   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines