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.4 by gwlarson, Mon Dec 21 14:05:43 1998 UTC vs.
Revision 3.16 by schorsch, Thu Jan 1 11:21:55 2004 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   * Routines for drawing samples using depth buffer checks.
6   */
7  
8   #include "standard.h"
9  
13 #include <sys/types.h>
10   #include <GL/glx.h>
11   #include <GL/glu.h>
12  
17 #include "random.h"
13   #include "rhd_odraw.h"
14  
15   #ifndef DEPTHEPS
# Line 26 | Line 21 | static char SCCSid[] = "$SunId$ SGI";
21   #ifndef SFREEFRAC
22   #define SFREEFRAC       0.2             /* fraction to free at a time */
23   #endif
24 + #ifndef REDRAWTHRESH
25 + #define REDRAWTHRESH    10240           /* number of samples for dissolve */
26 + #endif
27   #ifndef MAXFAN
28   #define MAXFAN          32              /* maximum arms in a triangle fan */
29   #endif
# Line 49 | Line 47 | static int     needmapping;    /* what needs doing with tone
47  
48  
49   #define SAMP32  (32*(2*sizeof(short)+sizeof(union ODfunion)+sizeof(TMbright)+\
50 <                        6*sizeof(BYTE))+sizeof(int4))
50 >                        6*sizeof(BYTE))+sizeof(int32))
51  
52 < int
53 < odInit(n)                               /* initialize drawing routines */
54 < int     n;
52 > static int sampcmp(const void *s0, const void *s1);
53 > static int odAllocBlockSamp(int vn, int hh, int vh, double prox);
54 > static int make_arms(GLshort ar[MAXFAN][3], short cp[2], struct ODview *vp,
55 >                double sz);
56 > static int depthchange(struct ODview *vp, int x0, int y0, int x1, int y1);
57 > static void clip_edge(GLshort p[3], short o[2], struct ODview *vp);
58 > static int getblock(struct ODview *vp, int h, int v);
59 > static int blockedge(struct ODview *vp, int bi0, int bi1);
60 > static void odDrawSamp(int vn, int id);
61 >
62 >
63 > extern int
64 > odInit(                         /* initialize drawing routines */
65 >        int     n
66 > )
67   {
68          int     nbytes, i, j, k, nextsamp, count, blockdiv;
69          int     res[2];
70  
71          if (odNViews > 0) {             /* deallocate view structures */
72                  for (i = odNViews; i--; ) {
73 <                        free((char *)odView[i].bmap);
74 <                        free((char *)odView[i].pmap);
73 >                        free((void *)odView[i].bmap);
74 >                        free((void *)odView[i].pmap);
75                          if (odView[i].emap != NULL)
76 <                                free((char *)odView[i].emap);
76 >                                free((void *)odView[i].emap);
77                  }
78 <                free((char *)odView);
78 >                free((void *)odView);
79                  odView = NULL;
80                  odNViews = 0;
81          }
# Line 89 | Line 99 | int    n;
99                          return(0);
100                                  /* assign larger alignment types earlier */
101                  odS.f = (union ODfunion *)odS.base;
102 <                odS.redraw = (int4 *)(odS.f + n);
102 >                odS.redraw = (int32 *)(odS.f + n);
103                  odS.ip = (short (*)[2])(odS.redraw + n/32);
104                  odS.brt = (TMbright *)(odS.ip + n);
105                  odS.chr = (BYTE (*)[3])(odS.brt + n);
# Line 119 | Line 129 | int    n;
129                  if (odView[i].vlow < 1) odView[i].vlow = 1;
130                  odView[i].emap = NULL;
131                  odView[i].dmap = NULL;
132 <                odView[i].pmap = (int4 *)calloc(FL4NELS(res[0]*res[1]),
133 <                                sizeof(int4));
132 >                odView[i].pmap = (int32 *)calloc(FL4NELS(res[0]*res[1]),
133 >                                sizeof(int32));
134                  if (odView[i].pmap == NULL)
135                          return(0);
136                  j = odView[i].hlow*odView[i].vlow;
# Line 131 | Line 141 | int    n;
141                  DCHECK(count<=0 | nextsamp>=n,
142                                  CONSISTENCY, "counter botch in odInit");
143                  if (!i) count = j;
144 +                odView[i].sfirst = nextsamp;
145                  while (j--) {           /* initialize blocks & free lists */
146                          odView[i].bmap[j].pthresh = FHUGE;
147                          odView[i].bmap[j].first = k = nextsamp;
# Line 142 | Line 153 | int    n;
153                          odS.nextfree(k-1) = ENDFREE;
154                          odView[i].bmap[j].nused = 0;
155                  }
156 +                odView[i].snext = nextsamp;
157 +                odView[i].n2redraw = 0;
158          }
159          CLR4ALL(odS.redraw, odS.nsamp);         /* clear redraw flags */
160          for (i = odS.nsamp; i--; ) {            /* clear values */
# Line 156 | Line 169 | int    n;
169  
170  
171   int
172 < sampcmp(s0, s1)                 /* sample order, descending proximity */
173 < int     *s0, *s1;
172 > sampcmp(                        /* sample order, descending proximity */
173 >        const void      *s0,
174 >        const void      *s1
175 > )
176   {
177 <        register double diff = odS.closeness(*s1) - odS.closeness(*s0);
177 >        register double diff = odS.closeness(*(int*)s1) - odS.closeness(*(int*)s0);
178  
179          return (diff > FTINY ? 1 : diff < -FTINY ? -1 : 0);
180   }
181  
182  
183   int
184 < odAllocBlockSamp(vn, hh, vh, prox)      /* allocate sample from block */
185 < int     vn, hh, vh;
186 < double  prox;
184 > odAllocBlockSamp(       /* allocate sample from block */
185 >        int     vn,
186 >        int     hh,
187 >        int     vh,
188 >        double  prox
189 > )
190   {
191          int     si[SAMPSPERBLOCK+SAMPSPERBLOCK/4];
192          int     hl, vl;
193          VIEW    *vw;
176        FVECT   ro, rd;
194          int     res[2];
195          register struct ODblock *bp;
196          register int    i, j;
# Line 187 | Line 204 | double prox;
204          if (CHK4(odView[vn].pmap, vh*odView[vn].hhi + hh))
205                  i = bp->first + bp->nsamp;
206          else
207 <                i = -1;
207 >                i = 0;
208          while (i-- > bp->first)
209                  if (hh == odS.ip[i][0] && vh == odS.ip[i][1]) { /* found it! */
210                                                  /* search free list for it */
# Line 202 | Line 219 | double prox;
219                                                  bp->nused++;
220                                                  goto gotit;
221                                          }
222 <                        if (prox >= 0.999*odS.closeness(i))
222 >                        if (prox >= 0.99*odS.closeness(i))
223                                  return(-1);     /* previous sample is fine */
224                          goto gotit;
225                  }
209        DCHECK(i>=-1, WARNING, "pixel in presence map not found in block");
226          if (bp->free != ENDFREE) {      /* allocate from free list */
227                  i = bp->free;
228 <                if (odS.ip[i][0] >= 0 & odS.ip[i][1] >= 0)
228 >                if ((odS.ip[i][0] >= 0) & (odS.ip[i][1] >= 0))
229                          CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi +
230                                                          odS.ip[i][0]);
231                  bp->free = odS.nextfree(i);
# Line 245 | Line 261 | gotit:
261   }
262  
263  
264 < odSample(c, d, p)                       /* add a sample value */
265 < COLR    c;
266 < FVECT   d, p;
264 > extern void
265 > odSample(                       /* add a sample value */
266 >        COLR    c,
267 >        FVECT   d,
268 >        FVECT   p
269 > )
270   {
271          FVECT   disp;
272          double  d0, d1, h, v, prox;
# Line 297 | Line 316 | FVECT  d, p;
316                  if (id < 0)
317                          continue;               /* not good enough */
318                                                          /* convert color */
319 <                tmCvColrs(&odS.brt[id], odS.chr[id], c, 1);
319 >                tmCvColrs(&odS.brt[id], odS.chr[id], (COLR *)c, 1);
320                  if (imm_mode | needmapping)             /* if immediate mode */
321                          needmapping |= NEWRGB;          /* map it later */
322                  else                                    /* else map it now */
323                          tmMapPixels(odS.rgb[id], &odS.brt[id], odS.chr[id], 1);
324                  SET4(odS.redraw, id);                   /* mark for redraw */
325 +                odView[i].n2redraw++;
326          }
327   }
328  
329  
330 < odRemap(newhist)                        /* recompute tone mapping */
331 < int     newhist;
330 > extern void
331 > odRemap(                        /* recompute tone mapping */
332 >        int     newhist
333 > )
334   {
335          needmapping |= NEWMAP|NEWRGB;
336          if (newhist)
# Line 316 | Line 338 | int    newhist;
338   }
339  
340  
341 < odRedraw(vn, hmin, vmin, hmax, vmax)    /* redraw view region */
342 < int     vn, hmin, vmin, hmax, vmax;
341 > extern void
342 > odRedrawAll(void)                               /* mark all samples for redraw */
343   {
344 +        register int    i;
345 +
346 +        if ((needmapping&(NEWMAP|NEWRGB)) == (NEWMAP|NEWRGB))
347 +                return;                 /* will be called later, anyway */
348 +        for (i = odS.nsamp; i--; )
349 +                if (odS.ip[i][0] >= 0)
350 +                        SET4(odS.redraw, i);
351 +                                        /* not right, but not important */
352 +        for (i = 0; i < odNViews; i++)
353 +                odView[i].n2redraw = odView[i].snext - odView[i].sfirst;
354 + }
355 +
356 +
357 + extern void
358 + odRedraw(       /* redraw view region */
359 +        int     vn,
360 +        int     hmin,
361 +        int     vmin,
362 +        int     hmax,
363 +        int     vmax
364 + )
365 + {
366          int     i, j;
367          register struct ODblock *bp;
368          register int    k;
369  
370 <        if (vn<0 | vn>=odNViews)
370 >        if ((vn<0) | (vn>=odNViews))
371                  return;
372                                  /* check view limits */
373          if (hmin < 0) hmin = 0;
374          if (hmax >= odView[vn].hhi) hmax = odView[vn].hhi-1;
375          if (vmin < 0) vmin = 0;
376          if (vmax >= odView[vn].vhi) vmax = odView[vn].vhi-1;
377 <        if (hmax <= hmin | vmax <= vmin)
377 >        if ((hmax <= hmin) | (vmax <= vmin))
378                  return;
379                                  /* convert to low resolution */
380          hmin = hmin * odView[vn].hlow / odView[vn].hhi;
# Line 342 | Line 386 | int    vn, hmin, vmin, hmax, vmax;
386                  for (j = vmin; j <= vmax; j++) {
387                          bp = odView[vn].bmap + j*odView[vn].hlow + i;
388                          for (k = bp->nsamp; k--; )
389 <                                if (odS.ip[bp->first+k][0] >= 0)
389 >                                if (odS.ip[bp->first+k][0] >= 0) {
390                                          SET4(odS.redraw, bp->first+k);
391 +                                        odView[vn].n2redraw++;
392 +                                }
393                  }
394   }
395  
396  
397 < odDepthMap(vn, dm)                      /* assign depth map for view */
398 < int     vn;
399 < GLfloat *dm;
397 > extern void
398 > odDepthMap(                     /* assign depth map for view */
399 >        int     vn,
400 >        GLfloat *dm
401 > )
402   {
403          double  d0, d1;
404          int     i, j, hmin, hmax, vmin, vmax;
405          register int    k, l;
406  
407          if (dm == NULL) {                       /* free edge map */
408 <                if (vn<0 | vn>=odNViews)
408 >                if ((vn<0) | (vn>=odNViews))
409                          return;                 /* too late -- they're gone! */
410                  if (odView[vn].emap != NULL)
411 <                        free((char *)odView[vn].emap);
411 >                        free((void *)odView[vn].emap);
412                  odView[vn].emap = NULL;
413                  odView[vn].dmap = NULL;
414                  return;
# Line 369 | Line 417 | GLfloat        *dm;
417                          "bad view number in odDepthMap");
418          odView[vn].dmap = dm;                   /* initialize edge map */
419          if (odView[vn].emap == NULL) {
420 <                odView[vn].emap = (int4 *)malloc(
421 <                        FL4NELS(odView[vn].hlow*odView[vn].vlow)*sizeof(int4));
420 >                odView[vn].emap = (int32 *)malloc(
421 >                        FL4NELS(odView[vn].hlow*odView[vn].vlow)*sizeof(int32));
422                  if (odView[vn].emap == NULL)
423                          error(SYSTEM, "out of memory in odDepthMap");
424          }
# Line 421 | Line 469 | GLfloat        *dm;
469   }
470  
471  
472 < odUpdate(vn)                            /* update this view */
473 < int     vn;
472 > extern void
473 > odUpdate(                               /* update this view */
474 >        int     vn
475 > )
476   {
477 <        register int    i, j;
477 >        static short    primes[] = {9431,6803,4177,2659,1609,887,587,251,47,1};
478 >        int     myprime;
479 >        register int    i, n;
480  
481          DCHECK(vn<0 | vn>=odNViews, CONSISTENCY,
482                          "bad view number in odUpdate");
# Line 433 | Line 485 | int    vn;
485                  if (needmapping & NEWMAP) {
486                          if (needmapping & NEWHIST)
487                                  tmClearHisto();
488 +                        needmapping &= ~NEWHIST;
489                          if (tmAddHisto(odS.brt,odS.nsamp,1) != TM_E_OK)
490                                  return;
491                          if (tmComputeMapping(0.,0.,0.) != TM_E_OK)
492                                  return;
493 <                        for (i = odS.nsamp; i--; )      /* redraw all */
494 <                                if (odS.ip[i][0] >= 0)
442 <                                        SET4(odS.redraw, i);
493 >                        needmapping &= ~NEWMAP;
494 >                        odRedrawAll();                  /* redraw everything */
495                  }
496 <                if (tmMapPixels(odS.rgb,odS.brt,odS.chr,odS.nsamp) != TM_E_OK)
496 >                if (tmMapPixels((BYTE *)(odS.rgb), odS.brt,
497 >                                (BYTE *)(odS.chr), odS.nsamp) != TM_E_OK)
498                          return;
499 <                needmapping = 0;                /* reset flag */
499 >                needmapping &= ~NEWRGB;
500          }
501 <                                        /* draw samples flagged for redraw */
502 <        for (j = FL4NELS(odS.nsamp); j--; )
503 <                for (i = 0; odS.redraw[j]; i++)         /* skips faster */
504 <                        if (odS.redraw[j] & 1L<<i) {
505 <                                odDrawSamp(vn, (j<<5)+i);
506 <                                odS.redraw[j] &= ~(1L<<i);
501 >        if (odView[vn].n2redraw <= 0)
502 >                return;
503 > #if REDRAWTHRESH
504 >        if (odView[vn].n2redraw < REDRAWTHRESH)
505 >                goto quickdraw;
506 >                                        /* pick a good prime step size */
507 >        n = odView[vn].snext - odView[vn].sfirst;
508 >        for (i = 0; primes[i]<<5 >= n; i++)
509 >                ;
510 >        while ((myprime = primes[i++]) > 1)
511 >                if (n % myprime)
512 >                        break;
513 >                                        /* dissolve in new samples */
514 >        for (i = odView[vn].sfirst; n-- > 0; i += myprime) {
515 >                if (i >= odView[vn].snext)
516 >                        i -= odView[vn].snext - odView[vn].sfirst;
517 >                if (CHK4(odS.redraw, i)) {
518 >                        odDrawSamp(vn, i);
519 >                        CLR4(odS.redraw, i);
520 >                }
521 >        }
522 >        odView[vn].n2redraw = 0;
523 >        return;
524 > quickdraw:                              /* quicker sparse flag checking */
525 > #endif
526 >                                        /* redraw samples at end */
527 >        for (i = odView[vn].snext-31; i < odView[vn].snext; i++)
528 >                if (CHK4(odS.redraw, i)) {
529 >                        odDrawSamp(vn, i);
530 >                        CLR4(odS.redraw, i);
531 >                }
532 >                                        /* faster flag checks in middle */
533 >        for (n = odView[vn].snext>>5; n-- > (odView[vn].sfirst+0x1f)>>5; )
534 >                for (i = 0; odS.redraw[n]; i++)         /* skips faster */
535 >                        if (odS.redraw[n] & 1L<<i) {
536 >                                odDrawSamp(vn, (n<<5)+i);
537 >                                odS.redraw[n] &= ~(1L<<i);
538                          }
539 +                                        /* redraw samples at beginning */
540 +        for (i = odView[vn].sfirst; i < odView[vn].sfirst+31; i++)
541 +                if (CHK4(odS.redraw, i)) {
542 +                        odDrawSamp(vn, i);
543 +                        CLR4(odS.redraw, i);
544 +                }
545 +        odView[vn].n2redraw = 0;
546   }
547  
548  
549 +                                        /* this turned out to be unnecessary */
550   #if 0
551   static
552   clip_end(p, o, vp)                      /* clip line segment to view */
# Line 485 | Line 577 | register struct ODview *vp;
577  
578  
579   static int
580 < make_arms(ar, cp, vp, sz)               /* make arms for triangle fan */
581 < GLshort ar[MAXFAN][3];
582 < short   cp[2];
583 < register struct ODview  *vp;
584 < double  sz;
580 > make_arms(              /* make arms for triangle fan */
581 >        GLshort ar[MAXFAN][3],
582 >        short   cp[2],
583 >        register struct ODview  *vp,
584 >        double  sz
585 > )
586   {
587          int     na, dv;
588 <        double  hrad, vrad, phi0, phi;
588 >        double  hrad, vrad, phi;
589          register int    i;
590  
591          DCHECK(sz > 1, CONSISTENCY, "super-unary size in make_arms");
592 <        na = MAXFAN*sz*sz + 0.5;                /* keep area constant */
592 >        na = MAXFAN*sz + 0.5;                   /* keep arc length constant */
593          if (na < MINFAN) na = MINFAN;
594          hrad = FANSIZE*sz*vp->hhi/vp->hlow;
595          vrad = FANSIZE*sz*vp->vhi/vp->vlow;
596          if (hrad*vrad < 2.25)
597                  hrad = vrad = 1.5;
505        phi0 = (2.*PI) * frandom();
598          dv = OMAXDEPTH*sz + 0.5;
599          for (i = 0; i < na; i++) {
600 <                phi = phi0 + (2.*PI)*i/na;
600 >                phi = (2.*PI)*i/na;
601                  ar[i][0] = cp[0] + tcos(phi)*hrad + 0.5;
602                  ar[i][1] = cp[1] + tsin(phi)*vrad + 0.5;
603                  ar[i][2] = dv;
# Line 516 | Line 608 | double sz;
608  
609  
610   static int
611 < depthchange(vp, x0, y0, x1, y1)         /* check depth discontinuity */
612 < register struct ODview  *vp;
613 < int     x0, y0, x1, y1;
611 > depthchange(            /* check depth discontinuity */
612 >        register struct ODview  *vp,
613 >        int     x0,
614 >        int     y0,
615 >        int     x1,
616 >        int     y1
617 > )
618   {
619          register double d0, d1;
620  
621          DCHECK(x0<0 | x0>=vp->hhi | y0<0 | y0>=vp->vhi,
622                          CONSISTENCY, "coordinates off view in depthchange");
623  
624 <        if (x1<0 | x1>=vp->hhi | y1<0 | y1>=vp->vhi)
624 >        if ((x1<0) | (x1>=vp->hhi) | (y1<0) | (y1>=vp->vhi))
625                  return(1);
626  
627          d0 = vp->dmap[y0*vp->hhi + x0];
# Line 535 | Line 631 | int    x0, y0, x1, y1;
631   }
632  
633  
634 < static
635 < clip_edge(p, o, vp)                     /* clip line segment to depth edge */
636 < GLshort p[3];
637 < short   o[2];
638 < register struct ODview  *vp;
634 > static void
635 > clip_edge(                      /* clip line segment to depth edge */
636 >        GLshort p[3],
637 >        short   o[2],
638 >        register struct ODview  *vp
639 > )
640   {
641          int     x, y, xstep, ystep, rise, rise2, run, run2, n;
642  
# Line 558 | Line 655 | register struct ODview *vp;
655          n = rise + run;
656          while (n--)                     /* run out arm, checking depth */
657                  if (run2 > rise2) {
561                        if (depthchange(vp, x, y, x+xstep, y))
562                                break;
658                          x += xstep;
659                          rise2 += rise;
660 <                } else {
566 <                        if (depthchange(vp, x, y, x, y+ystep))
660 >                        if (depthchange(vp, x-xstep, y, x, y))
661                                  break;
662 +                } else {
663                          y += ystep;
664                          run2 += run;
665 +                        if (depthchange(vp, x, y-ystep, x, y))
666 +                                break;
667                  }
668          if (n < 0)                      /* found something? */
669                  return;
# Line 580 | Line 677 | register struct ODview *vp;
677  
678  
679   static int
680 < getblock(vp, h, v)                      /* get block index */
681 < register struct ODview  *vp;
682 < register int    h, v;
680 > getblock(                       /* get block index */
681 >        register struct ODview  *vp,
682 >        register int    h,
683 >        register int    v
684 > )
685   {
686 <        if (h<0 | h>=vp->hhi | v<0 | v>=vp->vhi)
686 >        if ((h<0) | (h>=vp->hhi) | (v<0) | (v>=vp->vhi))
687                  return(-1);
688          return(h*vp->hlow/vp->hhi + v*vp->vlow/vp->vhi*vp->hlow);
689   }
690  
691  
692 < odDrawSamp(vn, id)                      /* draw view sample */
693 < int     vn;
694 < register int    id;
692 > static int
693 > blockedge(                      /* check for edge between blocks? */
694 >        register struct ODview  *vp,
695 >        register int    bi0,
696 >        register int    bi1
697 > )
698   {
699 +        if (bi1 == bi0)
700 +                return(0);              /* same block */
701 +        if (bi1 < 0)
702 +                return(1);              /* end off view */
703 +        if (CHK4(vp->emap, bi1))
704 +                return(1);              /* end block has edges */
705 +        if (bi1 == bi0+1 || bi1 == bi0-1 ||
706 +                        bi1 == bi0+vp->hlow || bi1 == bi0-vp->hlow)
707 +                return(0);              /* end in adjacent block -- no edges */
708 +        return(1);                      /* conservative for rarer case */
709 + }
710 +
711 +
712 + static void
713 + odDrawSamp(                     /* draw view sample */
714 +        int     vn,
715 +        register int    id
716 + )
717 + {
718          GLshort arm[MAXFAN][3];
719 <        int     narms, blockindex, bi1;
719 >        int     narms, blockindex;
720          register struct ODview  *vp;
721          double  size;
722          int     home_edges;
# Line 612 | Line 733 | register int   id;
733          if (vp->emap != NULL) {         /* check for edge collisions */
734                  home_edges = CHK4(vp->emap, blockindex);
735                  for (i = 0; i < narms; i++)
736 <                        /* the following test is flawed, because we could
737 <                         * 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)) ))
736 >                        if (home_edges || blockedge(vp, blockindex,
737 >                                        getblock(vp, arm[i][0], arm[i][1])))
738                                  clip_edge(arm[i], odS.ip[id], vp);
739          }
740                                          /* draw triangle fan */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines