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.1 by gwlarson, Fri Dec 18 11:55:19 1998 UTC vs.
Revision 3.5 by gwlarson, Tue Dec 22 17:05:54 1998 UTC

# Line 38 | Line 38 | static char SCCSid[] = "$SunId$ SGI";
38  
39   #define NEWMAP          01              /* need to recompute mapping */
40   #define NEWRGB          02              /* need to remap RGB values */
41 + #define NEWHIST         04              /* clear histogram as well */
42  
43   struct ODview   *odView;        /* our view list */
44   int     odNViews;               /* number of views in our list */
# Line 57 | Line 58 | int    n;
58          int     nbytes, i, j, k, nextsamp, count, blockdiv;
59          int     res[2];
60  
61 <        if (odNViews) {                 /* deallocate view structures */
62 <                for (i = 0; i < odNViews; i++) {
61 >        if (odNViews > 0) {             /* deallocate view structures */
62 >                for (i = odNViews; i--; ) {
63                          free((char *)odView[i].bmap);
64 +                        free((char *)odView[i].pmap);
65                          if (odView[i].emap != NULL)
66                                  free((char *)odView[i].emap);
67                  }
# Line 73 | Line 75 | int    n;
75                  for (i = 1024; nbytes > i-8; i <<= 1)
76                          ;
77                  n = (i-8)/SAMP32 * 32;
78 <                needmapping = NEWMAP;
78 >                needmapping = NEWHIST;
79          }
80          if (n != odS.nsamp) {   /* (re)allocate sample array */
81                  if (odS.nsamp)
# Line 108 | Line 110 | int    n;
110          if (blockdiv < 8) blockdiv = 8;
111          nextsamp = 0; count /= blockdiv*blockdiv;       /* # blocks */
112          while (i--) {                   /* initialize each view */
111                odView[i].emap = NULL;
112                odView[i].dmap = NULL;
113                  dev_auxview(i, res);
114                  odView[i].hhi = res[0];
115                  odView[i].hlow = (res[0] + blockdiv/2) / blockdiv;
# Line 117 | Line 117 | int    n;
117                  odView[i].vhi = res[1];
118                  odView[i].vlow = (res[1] + blockdiv/2) / blockdiv;
119                  if (odView[i].vlow < 1) odView[i].vlow = 1;
120 +                odView[i].emap = NULL;
121 +                odView[i].dmap = NULL;
122 +                odView[i].pmap = (int4 *)calloc(FL4NELS(res[0]*res[1]),
123 +                                sizeof(int4));
124 +                if (odView[i].pmap == NULL)
125 +                        return(0);
126                  j = odView[i].hlow*odView[i].vlow;
127                  odView[i].bmap = (struct ODblock *)malloc(
128                                  j * sizeof(struct ODblock));
# Line 125 | Line 131 | int    n;
131                  DCHECK(count<=0 | nextsamp>=n,
132                                  CONSISTENCY, "counter botch in odInit");
133                  if (!i) count = j;
134 <                while (j--) {
134 >                odView[i].sfirst = nextsamp;
135 >                while (j--) {           /* initialize blocks & free lists */
136 >                        odView[i].bmap[j].pthresh = FHUGE;
137                          odView[i].bmap[j].first = k = nextsamp;
138                          nextsamp += odView[i].bmap[j].nsamp =
139                                  (n - nextsamp)/count--;
# Line 135 | Line 143 | int    n;
143                          odS.nextfree(k-1) = ENDFREE;
144                          odView[i].bmap[j].nused = 0;
145                  }
146 +                odView[i].snext = nextsamp;
147          }
148          CLR4ALL(odS.redraw, odS.nsamp);         /* clear redraw flags */
149 <        for (i = odS.nsamp; i--; )              /* clear values */
149 >        for (i = odS.nsamp; i--; ) {            /* clear values */
150                  odS.ip[i][0] = odS.ip[i][1] = -1;
151 +                odS.brt[i] = TM_NOBRT;
152 +        }
153 +        needmapping |= NEWMAP;                  /* compute new map on update */
154          return(odS.nsamp);                      /* return number of samples */
155   }
156  
# Line 156 | Line 168 | int    *s0, *s1;
168  
169  
170   int
171 < odAllocBlockSamp(vn, hl, vl)            /* allocate sample from block */
172 < int     vn, hl, vl;
171 > odAllocBlockSamp(vn, hh, vh, prox)      /* allocate sample from block */
172 > int     vn, hh, vh;
173 > double  prox;
174   {
175          int     si[SAMPSPERBLOCK+SAMPSPERBLOCK/4];
176 +        int     hl, vl;
177          VIEW    *vw;
178          FVECT   ro, rd;
179          int     res[2];
180          register struct ODblock *bp;
181 <        register int    i;
182 <
181 >        register int    i, j;
182 >                                        /* get block */
183 >        hl = hh*odView[vn].hlow/odView[vn].hhi;
184 >        vl = vh*odView[vn].vlow/odView[vn].vhi;
185          bp = odView[vn].bmap + vl*odView[vn].hlow + hl;
186 <        if (bp->free != ENDFREE) {      /* check free list first */
186 >        if (prox > bp->pthresh)
187 >                return(-1);             /* worse than free list occupants */
188 >                                        /* check for duplicate pixel */
189 >        if (CHK4(odView[vn].pmap, vh*odView[vn].hhi + hh))
190 >                i = bp->first + bp->nsamp;
191 >        else
192 >                i = -1;
193 >        while (i-- > bp->first)
194 >                if (hh == odS.ip[i][0] && vh == odS.ip[i][1]) { /* found it! */
195 >                                                /* search free list for it */
196 >                        if (i == bp->free)
197 >                                break;          /* special case */
198 >                        if (bp->free != ENDFREE)
199 >                                for (j = bp->free; odS.nextfree(j) != ENDFREE;
200 >                                                j = odS.nextfree(j))
201 >                                        if (odS.nextfree(j) == i) {
202 >                                                odS.nextfree(j) =
203 >                                                        odS.nextfree(i);
204 >                                                bp->nused++;
205 >                                                goto gotit;
206 >                                        }
207 >                        if (prox >= 0.999*odS.closeness(i))
208 >                                return(-1);     /* previous sample is fine */
209 >                        goto gotit;
210 >                }
211 >        DCHECK(i>=-1, WARNING, "pixel in presence map not found in block");
212 >        if (bp->free != ENDFREE) {      /* allocate from free list */
213                  i = bp->free;
214 +                if (odS.ip[i][0] >= 0 & odS.ip[i][1] >= 0)
215 +                        CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi +
216 +                                                        odS.ip[i][0]);
217                  bp->free = odS.nextfree(i);
218                  bp->nused++;
219 <                return(i);
219 >                goto gotit;
220          }
221          DCHECK(bp->nsamp<=0, CONSISTENCY,
222                          "no available samples in odAllocBlockSamp");
# Line 183 | Line 228 | int    vn, hl, vl;
228          for (i = bp->nsamp; i--; )      /* figure out which are worse */
229                  si[i] = bp->first + i;
230          qsort((char *)si, bp->nsamp, sizeof(int), sampcmp);
231 <        i = bp->nsamp*SFREEFRAC + .5;   /* put them in a list */
231 >        i = bp->nsamp*SFREEFRAC + .5;   /* put them into free list */
232 >        if (i >= bp->nsamp) i = bp->nsamp-1;    /* paranoia */
233 >        bp->pthresh = odS.closeness(si[i]);     /* new proximity threshold */
234          while (--i > 0) {
235                  odS.nextfree(si[i]) = bp->free;
236                  bp->free = si[i];
237                  bp->nused--;
238          }
239 <        return(si[0]);                  /* return first free sample */
239 >        i = si[0];                      /* use worst sample */
240 >        CLR4(odView[vn].pmap, odS.ip[i][1]*odView[vn].hhi + odS.ip[i][0]);
241 > gotit:
242 >        odS.ip[i][0] = hh;
243 >        odS.ip[i][1] = vh;
244 >        odS.closeness(i) = prox;
245 >        SET4(odView[vn].pmap, vh*odView[vn].hhi + hh);
246 >        return(i);
247   }
248  
249  
# Line 198 | Line 252 | COLR   c;
252   FVECT   d, p;
253   {
254          FVECT   disp;
255 <        double  d0, d1, h, v;
255 >        double  d0, d1, h, v, prox;
256          register VIEW   *vw;
257 <        int     hl, vl, hh, vh;
257 >        int     hh, vh;
258          int     res[2];
259          register int    i, id;
260  
# Line 235 | Line 289 | FVECT  d, p;
289                                                  (1.+DEPTHEPS)*d0 < d1))
290                          continue;                       /* occlusion error */
291                  }
238                hl = hh*odView[i].hlow/res[0];
239                vl = vh*odView[i].vlow/res[1];
240                                                /* may duplicate samples */
241                id = odAllocBlockSamp(i, hl, vl);
242                odS.ip[id][0] = hh;
243                odS.ip[id][1] = vh;
292                  if (p != NULL) {                /* compute closeness (sin^2) */
293                          d1 = DOT(disp, d);
294 <                        odS.closeness(id) = 1. - d1*d1/DOT(disp,disp);
294 >                        prox = 1. - d1*d1/DOT(disp,disp);
295                  } else
296 <                        odS.closeness(id) = 0.;
296 >                        prox = 0.;
297 >                                                /* allocate sample */
298 >                id = odAllocBlockSamp(i, hh, vh, prox);
299 >                if (id < 0)
300 >                        continue;               /* not good enough */
301                                                          /* convert color */
302                  tmCvColrs(&odS.brt[id], odS.chr[id], c, 1);
303                  if (imm_mode | needmapping)             /* if immediate mode */
# Line 257 | Line 309 | FVECT  d, p;
309   }
310  
311  
312 < odRemap()                               /* recompute tone mapping */
312 > odRemap(newhist)                        /* recompute tone mapping */
313 > int     newhist;
314   {
315          needmapping |= NEWMAP|NEWRGB;
316 +        if (newhist)
317 +                needmapping |= NEWHIST;
318   }
319  
320  
# Line 303 | Line 358 | GLfloat        *dm;
358          int     i, j, hmin, hmax, vmin, vmax;
359          register int    k, l;
360  
306        DCHECK(vn<0 | vn>=odNViews, CONSISTENCY,
307                        "bad view number in odDepthMap");
361          if (dm == NULL) {                       /* free edge map */
362 +                if (vn<0 | vn>=odNViews)
363 +                        return;                 /* too late -- they're gone! */
364                  if (odView[vn].emap != NULL)
365                          free((char *)odView[vn].emap);
366                  odView[vn].emap = NULL;
367                  odView[vn].dmap = NULL;
368                  return;
369          }
370 +        DCHECK(vn<0 | vn>=odNViews, CONSISTENCY,
371 +                        "bad view number in odDepthMap");
372          odView[vn].dmap = dm;                   /* initialize edge map */
373          if (odView[vn].emap == NULL) {
374                  odView[vn].emap = (int4 *)malloc(
# Line 369 | Line 426 | GLfloat        *dm;
426   odUpdate(vn)                            /* update this view */
427   int     vn;
428   {
429 <        int     i, j;
373 <        register struct ODblock *bp;
374 <        register int    k;
429 >        register int    i, j;
430  
431          DCHECK(vn<0 | vn>=odNViews, CONSISTENCY,
432                          "bad view number in odUpdate");
433                                          /* need to do some tone mapping? */
434          if (needmapping & NEWRGB) {
435                  if (needmapping & NEWMAP) {
436 <                        tmClearHisto();
436 >                        if (needmapping & NEWHIST)
437 >                                tmClearHisto();
438                          if (tmAddHisto(odS.brt,odS.nsamp,1) != TM_E_OK)
439                                  return;
440                          if (tmComputeMapping(0.,0.,0.) != TM_E_OK)
441                                  return;
442 <                        for (k = odS.nsamp; k--; )      /* redraw all */
443 <                                if (odS.ip[k][0] >= 0)
444 <                                        SET4(odS.redraw, k);
442 >                        for (i = odS.nsamp; i--; )      /* redraw all */
443 >                                if (odS.ip[i][0] >= 0)
444 >                                        SET4(odS.redraw, i);
445                  }
446                  if (tmMapPixels(odS.rgb,odS.brt,odS.chr,odS.nsamp) != TM_E_OK)
447                          return;
448                  needmapping = 0;                /* reset flag */
449          }
450 <                                        /* draw each block in view */
451 <        for (i = odView[vn].hlow; i--; )
452 <                for (j = odView[vn].vlow; j--; ) {
453 <                                        /* get block */
454 <                        bp = odView[vn].bmap + j*odView[vn].hlow + i;
455 <                                        /* do quick, conservative flag check */
400 <                        for (k = (bp->first+bp->nsamp+31)>>5;
401 <                                        k-- > bp->first>>5; )
402 <                                if (odS.redraw[k])
403 <                                        break;          /* non-zero flag */
404 <                        if (k < bp->first>>5)
405 <                                continue;               /* no flags set */
406 <                        for (k = bp->nsamp; k--; )      /* sample by sample */
407 <                                if (CHK4(odS.redraw, bp->first+k)) {
408 <                                        odDrawBlockSamp(vn, i, j, bp->first+k);
409 <                                        CLR4(odS.redraw, bp->first+k);
410 <                                }
450 >                                        /* this code segment was too slow */
451 > #if 0
452 >        for (i = odView[vn].sfirst; i < odView[vn].snext; i++)
453 >                if (CHK4(odS.redraw, i)) {
454 >                        odDrawSamp(vn, i);
455 >                        CLR4(odS.redraw, i);
456                  }
457 + #endif
458 +                                        /* redraw samples at each end */
459 +        for (i = odView[vn].sfirst; i < odView[vn].sfirst+31; i++)
460 +                if (CHK4(odS.redraw, i)) {
461 +                        odDrawSamp(vn, i);
462 +                        CLR4(odS.redraw, i);
463 +                }
464 +        for (i = odView[vn].snext-31; i < odView[vn].snext; i++)
465 +                if (CHK4(odS.redraw, i)) {
466 +                        odDrawSamp(vn, i);
467 +                        CLR4(odS.redraw, i);
468 +                }
469 +                                        /* faster flag checks in middle */
470 +        for (j = odView[vn].snext>>5; j-- > (odView[vn].sfirst+0x1f)>>5; )
471 +                for (i = 0; odS.redraw[j]; i++)         /* skips faster */
472 +                        if (odS.redraw[j] & 1L<<i) {
473 +                                odDrawSamp(vn, (j<<5)+i);
474 +                                odS.redraw[j] &= ~(1L<<i);
475 +                        }
476   }
477  
478  
479 +                                        /* this turned out to be unnecessary */
480   #if 0
481   static
482   clip_end(p, o, vp)                      /* clip line segment to view */
# Line 547 | Line 612 | register int   h, v;
612   }
613  
614  
615 < odDrawBlockSamp(vn, h, v, id)           /* draw sample in view block */
616 < int     vn, h, v;
615 > odDrawSamp(vn, id)                      /* draw view sample */
616 > int     vn;
617   register int    id;
618   {
619          GLshort arm[MAXFAN][3];
# Line 559 | Line 624 | register int   id;
624          register int    i;
625  
626          vp = odView + vn;
627 <        blockindex = v*vp->hlow + h;
628 <        DCHECK(odS.ip[id][0]*vp->hlow/vp->hhi != h |
564 <                        odS.ip[id][1]*vp->vlow/vp->vhi != v,
565 <                        CONSISTENCY, "bad sample position in odDrawBlockSamp");
627 >        blockindex = getblock(vp, odS.ip[id][0], odS.ip[id][1]);
628 >        DCHECK(blockindex<0, CONSISTENCY, "bad sample handed to odDrawSamp");
629          DCHECK(vp->bmap[blockindex].nused <= 0,
630 <                        CONSISTENCY, "bad in-use count in odDrawBlockSamp");
630 >                        CONSISTENCY, "bad in-use count in odDrawSamp");
631                                          /* create triangle fan */
632          size = 1./sqrt((double)vp->bmap[blockindex].nused);
633          narms = make_arms(arm, odS.ip[id], vp, size);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines