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

Comparing ray/src/hd/rhd_odraw.c (file contents):
Revision 3.2 by gwlarson, Sun Dec 20 20:37:53 1998 UTC vs.
Revision 3.12 by gwlarson, Mon Mar 8 17:31:49 1999 UTC

# Line 1 | Line 1
1 < /* Copyright (c) 1998 Silicon Graphics, Inc. */
1 > /* Copyright (c) 1999 Silicon Graphics, Inc. */
2  
3   #ifndef lint
4   static char SCCSid[] = "$SunId$ SGI";
# Line 10 | Line 10 | static char SCCSid[] = "$SunId$ SGI";
10  
11   #include "standard.h"
12  
13 #include <sys/types.h>
13   #include <GL/glx.h>
14   #include <GL/glu.h>
15  
17 #include "random.h"
16   #include "rhd_odraw.h"
17  
18   #ifndef DEPTHEPS
# Line 26 | Line 24 | static char SCCSid[] = "$SunId$ SGI";
24   #ifndef SFREEFRAC
25   #define SFREEFRAC       0.2             /* fraction to free at a time */
26   #endif
27 + #ifndef REDRAWTHRESH
28 + #define REDRAWTHRESH    10240           /* number of samples for dissolve */
29 + #endif
30   #ifndef MAXFAN
31   #define MAXFAN          32              /* maximum arms in a triangle fan */
32   #endif
# Line 58 | Line 59 | int    n;
59          int     nbytes, i, j, k, nextsamp, count, blockdiv;
60          int     res[2];
61  
62 <        if (odNViews) {                 /* deallocate view structures */
63 <                for (i = 0; i < odNViews; i++) {
62 >        if (odNViews > 0) {             /* deallocate view structures */
63 >                for (i = odNViews; i--; ) {
64                          free((char *)odView[i].bmap);
65 +                        free((char *)odView[i].pmap);
66                          if (odView[i].emap != NULL)
67                                  free((char *)odView[i].emap);
68                  }
# Line 109 | Line 111 | int    n;
111          if (blockdiv < 8) blockdiv = 8;
112          nextsamp = 0; count /= blockdiv*blockdiv;       /* # blocks */
113          while (i--) {                   /* initialize each view */
112                odView[i].emap = NULL;
113                odView[i].dmap = NULL;
114                  dev_auxview(i, res);
115                  odView[i].hhi = res[0];
116                  odView[i].hlow = (res[0] + blockdiv/2) / blockdiv;
# Line 118 | Line 118 | int    n;
118                  odView[i].vhi = res[1];
119                  odView[i].vlow = (res[1] + blockdiv/2) / blockdiv;
120                  if (odView[i].vlow < 1) odView[i].vlow = 1;
121 +                odView[i].emap = NULL;
122 +                odView[i].dmap = NULL;
123 +                odView[i].pmap = (int4 *)calloc(FL4NELS(res[0]*res[1]),
124 +                                sizeof(int4));
125 +                if (odView[i].pmap == NULL)
126 +                        return(0);
127                  j = odView[i].hlow*odView[i].vlow;
128                  odView[i].bmap = (struct ODblock *)malloc(
129                                  j * sizeof(struct ODblock));
# Line 126 | Line 132 | int    n;
132                  DCHECK(count<=0 | nextsamp>=n,
133                                  CONSISTENCY, "counter botch in odInit");
134                  if (!i) count = j;
135 +                odView[i].sfirst = nextsamp;
136                  while (j--) {           /* initialize blocks & free lists */
137                          odView[i].bmap[j].pthresh = FHUGE;
138                          odView[i].bmap[j].first = k = nextsamp;
# Line 137 | Line 144 | int    n;
144                          odS.nextfree(k-1) = ENDFREE;
145                          odView[i].bmap[j].nused = 0;
146                  }
147 +                odView[i].snext = nextsamp;
148 +                odView[i].n2redraw = 0;
149          }
150          CLR4ALL(odS.redraw, odS.nsamp);         /* clear redraw flags */
151          for (i = odS.nsamp; i--; ) {            /* clear values */
# Line 179 | Line 188 | double prox;
188          if (prox > bp->pthresh)
189                  return(-1);             /* worse than free list occupants */
190                                          /* check for duplicate pixel */
191 <        for (i = bp->first+bp->nsamp; i-- > bp->first; )
191 >        if (CHK4(odView[vn].pmap, vh*odView[vn].hhi + hh))
192 >                i = bp->first + bp->nsamp;
193 >        else
194 >                i = 0;
195 >        while (i-- > bp->first)
196                  if (hh == odS.ip[i][0] && vh == odS.ip[i][1]) { /* found it! */
197                                                  /* search free list for it */
198                          if (i == bp->free)
# Line 193 | Line 206 | double prox;
206                                                  bp->nused++;
207                                                  goto gotit;
208                                          }
209 <                        if (prox >= 0.999*odS.closeness(i))
209 >                        if (prox >= 0.99*odS.closeness(i))
210                                  return(-1);     /* previous sample is fine */
211                          goto gotit;
212                  }
213          if (bp->free != ENDFREE) {      /* allocate from free list */
214                  i = bp->free;
215 +                if (odS.ip[i][0] >= 0 & odS.ip[i][1] >= 0)
216 +                        CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi +
217 +                                                        odS.ip[i][0]);
218                  bp->free = odS.nextfree(i);
219                  bp->nused++;
220                  goto gotit;
# Line 222 | Line 238 | double prox;
238                  bp->nused--;
239          }
240          i = si[0];                      /* use worst sample */
241 +        CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi + odS.ip[i][0]);
242   gotit:
243          odS.ip[i][0] = hh;
244          odS.ip[i][1] = vh;
245          odS.closeness(i) = prox;
246 +        SET4(odView[vn].pmap, vh*odView[vn].hhi + hh);
247          return(i);
248   }
249  
# Line 288 | Line 306 | FVECT  d, p;
306                  else                                    /* else map it now */
307                          tmMapPixels(odS.rgb[id], &odS.brt[id], odS.chr[id], 1);
308                  SET4(odS.redraw, id);                   /* mark for redraw */
309 +                odView[i].n2redraw++;
310          }
311   }
312  
# Line 301 | Line 320 | int    newhist;
320   }
321  
322  
323 + odRedrawAll()                           /* mark all samples for redraw */
324 + {
325 +        register int    i;
326 +
327 +        if ((needmapping&(NEWMAP|NEWRGB)) == (NEWMAP|NEWRGB))
328 +                return;                 /* will be called later, anyway */
329 +        for (i = odS.nsamp; i--; )
330 +                if (odS.ip[i][0] >= 0)
331 +                        SET4(odS.redraw, i);
332 +                                        /* not right, but not important */
333 +        for (i = 0; i < odNViews; i++)
334 +                odView[i].n2redraw = odView[i].snext - odView[i].sfirst;
335 + }
336 +
337 +
338   odRedraw(vn, hmin, vmin, hmax, vmax)    /* redraw view region */
339   int     vn, hmin, vmin, hmax, vmax;
340   {
# Line 327 | Line 361 | int    vn, hmin, vmin, hmax, vmax;
361                  for (j = vmin; j <= vmax; j++) {
362                          bp = odView[vn].bmap + j*odView[vn].hlow + i;
363                          for (k = bp->nsamp; k--; )
364 <                                if (odS.ip[bp->first+k][0] >= 0)
364 >                                if (odS.ip[bp->first+k][0] >= 0) {
365                                          SET4(odS.redraw, bp->first+k);
366 +                                        odView[vn].n2redraw++;
367 +                                }
368                  }
369   }
370  
# Line 409 | Line 445 | GLfloat        *dm;
445   odUpdate(vn)                            /* update this view */
446   int     vn;
447   {
448 <        int     i, j;
449 <        register struct ODblock *bp;
450 <        register int    k;
448 >        static short    primes[] = {9431,6803,4177,2659,1609,887,587,251,47,1};
449 >        int     myprime;
450 >        register int    i, n;
451  
452          DCHECK(vn<0 | vn>=odNViews, CONSISTENCY,
453                          "bad view number in odUpdate");
# Line 420 | Line 456 | int    vn;
456                  if (needmapping & NEWMAP) {
457                          if (needmapping & NEWHIST)
458                                  tmClearHisto();
459 +                        needmapping &= ~NEWHIST;
460                          if (tmAddHisto(odS.brt,odS.nsamp,1) != TM_E_OK)
461                                  return;
462                          if (tmComputeMapping(0.,0.,0.) != TM_E_OK)
463                                  return;
464 <                        for (k = odS.nsamp; k--; )      /* redraw all */
465 <                                if (odS.ip[k][0] >= 0)
429 <                                        SET4(odS.redraw, k);
464 >                        needmapping &= ~NEWMAP;
465 >                        odRedrawAll();                  /* redraw everything */
466                  }
467                  if (tmMapPixels(odS.rgb,odS.brt,odS.chr,odS.nsamp) != TM_E_OK)
468                          return;
469 <                needmapping = 0;                /* reset flag */
469 >                needmapping &= ~NEWRGB;
470          }
471 <                                        /* draw each block in view */
472 <        for (j = odView[vn].vlow; j--; )
473 <                for (i = 0; i < odView[vn].hlow; i++) {
474 <                                        /* get block */
475 <                        bp = odView[vn].bmap + j*odView[vn].hlow + i;
476 <                                        /* do quick, conservative flag check */
477 <                        for (k = (bp->first+bp->nsamp+31)>>5;
478 <                                        k-- > bp->first>>5; )
479 <                                if (odS.redraw[k])
480 <                                        break;          /* non-zero flag */
481 <                        if (k < bp->first>>5)
482 <                                continue;               /* no flags set */
483 <                        for (k = bp->nsamp; k--; )      /* sample by sample */
484 <                                if (CHK4(odS.redraw, bp->first+k)) {
485 <                                        odDrawBlockSamp(vn, i, j, bp->first+k);
486 <                                        CLR4(odS.redraw, bp->first+k);
487 <                                }
471 >        if (odView[vn].n2redraw <= 0)
472 >                return;
473 > #if REDRAWTHRESH
474 >        if (odView[vn].n2redraw < REDRAWTHRESH)
475 >                goto quickdraw;
476 >                                        /* pick a good prime step size */
477 >        n = odView[vn].snext - odView[vn].sfirst;
478 >        for (i = 0; primes[i]<<5 >= n; i++)
479 >                ;
480 >        while ((myprime = primes[i++]) > 1)
481 >                if (n % myprime)
482 >                        break;
483 >                                        /* dissolve in new samples */
484 >        for (i = odView[vn].sfirst; n-- > 0; i += myprime) {
485 >                if (i >= odView[vn].snext)
486 >                        i -= odView[vn].snext - odView[vn].sfirst;
487 >                if (CHK4(odS.redraw, i)) {
488 >                        odDrawSamp(vn, i);
489 >                        CLR4(odS.redraw, i);
490                  }
491 +        }
492 +        odView[vn].n2redraw = 0;
493 +        return;
494 + quickdraw:                              /* quicker sparse flag checking */
495 + #endif
496 +                                        /* redraw samples at end */
497 +        for (i = odView[vn].snext-31; i < odView[vn].snext; i++)
498 +                if (CHK4(odS.redraw, i)) {
499 +                        odDrawSamp(vn, i);
500 +                        CLR4(odS.redraw, i);
501 +                }
502 +                                        /* faster flag checks in middle */
503 +        for (n = odView[vn].snext>>5; n-- > (odView[vn].sfirst+0x1f)>>5; )
504 +                for (i = 0; odS.redraw[n]; i++)         /* skips faster */
505 +                        if (odS.redraw[n] & 1L<<i) {
506 +                                odDrawSamp(vn, (n<<5)+i);
507 +                                odS.redraw[n] &= ~(1L<<i);
508 +                        }
509 +                                        /* redraw samples at beginning */
510 +        for (i = odView[vn].sfirst; i < odView[vn].sfirst+31; i++)
511 +                if (CHK4(odS.redraw, i)) {
512 +                        odDrawSamp(vn, i);
513 +                        CLR4(odS.redraw, i);
514 +                }
515 +        odView[vn].n2redraw = 0;
516   }
517  
518  
519 +                                        /* this turned out to be unnecessary */
520   #if 0
521   static
522   clip_end(p, o, vp)                      /* clip line segment to view */
# Line 490 | Line 554 | register struct ODview *vp;
554   double  sz;
555   {
556          int     na, dv;
557 <        double  hrad, vrad, phi0, phi;
557 >        double  hrad, vrad, phi;
558          register int    i;
559  
560          DCHECK(sz > 1, CONSISTENCY, "super-unary size in make_arms");
561 <        na = MAXFAN*sz*sz + 0.5;                /* keep area constant */
561 >        na = MAXFAN*sz + 0.5;                   /* keep arc length constant */
562          if (na < MINFAN) na = MINFAN;
563          hrad = FANSIZE*sz*vp->hhi/vp->hlow;
564          vrad = FANSIZE*sz*vp->vhi/vp->vlow;
565          if (hrad*vrad < 2.25)
566                  hrad = vrad = 1.5;
503        phi0 = (2.*PI) * frandom();
567          dv = OMAXDEPTH*sz + 0.5;
568          for (i = 0; i < na; i++) {
569 <                phi = phi0 + (2.*PI)*i/na;
569 >                phi = (2.*PI)*i/na;
570                  ar[i][0] = cp[0] + tcos(phi)*hrad + 0.5;
571                  ar[i][1] = cp[1] + tsin(phi)*vrad + 0.5;
572                  ar[i][2] = dv;
# Line 556 | Line 619 | register struct ODview *vp;
619          n = rise + run;
620          while (n--)                     /* run out arm, checking depth */
621                  if (run2 > rise2) {
559                        if (depthchange(vp, x, y, x+xstep, y))
560                                break;
622                          x += xstep;
623                          rise2 += rise;
624 <                } else {
564 <                        if (depthchange(vp, x, y, x, y+ystep))
624 >                        if (depthchange(vp, x-xstep, y, x, y))
625                                  break;
626 +                } else {
627                          y += ystep;
628                          run2 += run;
629 +                        if (depthchange(vp, x, y-ystep, x, y))
630 +                                break;
631                  }
632          if (n < 0)                      /* found something? */
633                  return;
# Line 588 | Line 651 | register int   h, v;
651   }
652  
653  
654 < odDrawBlockSamp(vn, h, v, id)           /* draw sample in view block */
655 < int     vn, h, v;
654 > static int
655 > blockedge(vp, bi0, bi1)                 /* check for edge between blocks? */
656 > register struct ODview  *vp;
657 > register int    bi0, bi1;
658 > {
659 >        if (bi1 == bi0)
660 >                return(0);              /* same block */
661 >        if (bi1 < 0)
662 >                return(1);              /* end off view */
663 >        if (CHK4(vp->emap, bi1))
664 >                return(1);              /* end block has edges */
665 >        if (bi1 == bi0+1 || bi1 == bi0-1 ||
666 >                        bi1 == bi0+vp->hlow || bi1 == bi0-vp->hlow)
667 >                return(0);              /* end in adjacent block -- no edges */
668 >        return(1);                      /* conservative for rarer case */
669 > }
670 >
671 >
672 > odDrawSamp(vn, id)                      /* draw view sample */
673 > int     vn;
674   register int    id;
675   {
676          GLshort arm[MAXFAN][3];
677 <        int     narms, blockindex, bi1;
677 >        int     narms, blockindex;
678          register struct ODview  *vp;
679          double  size;
680          int     home_edges;
681          register int    i;
682  
683          vp = odView + vn;
684 <        blockindex = v*vp->hlow + h;
685 <        DCHECK(odS.ip[id][0]*vp->hlow/vp->hhi != h |
605 <                        odS.ip[id][1]*vp->vlow/vp->vhi != v,
606 <                        CONSISTENCY, "bad sample position in odDrawBlockSamp");
684 >        blockindex = getblock(vp, odS.ip[id][0], odS.ip[id][1]);
685 >        DCHECK(blockindex<0, CONSISTENCY, "bad sample handed to odDrawSamp");
686          DCHECK(vp->bmap[blockindex].nused <= 0,
687 <                        CONSISTENCY, "bad in-use count in odDrawBlockSamp");
687 >                        CONSISTENCY, "bad in-use count in odDrawSamp");
688                                          /* create triangle fan */
689          size = 1./sqrt((double)vp->bmap[blockindex].nused);
690          narms = make_arms(arm, odS.ip[id], vp, size);
691          if (vp->emap != NULL) {         /* check for edge collisions */
692                  home_edges = CHK4(vp->emap, blockindex);
693                  for (i = 0; i < narms; i++)
694 <                        /* the following test is flawed, because we could
695 <                         * be passing through a block on a diagonal run */
617 <                        if (home_edges ||
618 <                                ( (bi1 = getblock(vp, arm[i][0], arm[i][1]))
619 <                                                != blockindex &&
620 <                                        (bi1 < 0 || CHK4(vp->emap, bi1)) ))
694 >                        if (home_edges || blockedge(vp, blockindex,
695 >                                        getblock(vp, arm[i][0], arm[i][1])))
696                                  clip_edge(arm[i], odS.ip[id], vp);
697          }
698                                          /* draw triangle fan */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines