--- ray/src/hd/rhd_odraw.c 1998/12/21 13:17:00 3.3 +++ ray/src/hd/rhd_odraw.c 1998/12/23 17:42:24 3.6 @@ -14,7 +14,6 @@ static char SCCSid[] = "$SunId$ SGI"; #include #include -#include "random.h" #include "rhd_odraw.h" #ifndef DEPTHEPS @@ -131,6 +130,7 @@ int n; DCHECK(count<=0 | nextsamp>=n, CONSISTENCY, "counter botch in odInit"); if (!i) count = j; + odView[i].sfirst = nextsamp; while (j--) { /* initialize blocks & free lists */ odView[i].bmap[j].pthresh = FHUGE; odView[i].bmap[j].first = k = nextsamp; @@ -142,6 +142,7 @@ int n; odS.nextfree(k-1) = ENDFREE; odView[i].bmap[j].nused = 0; } + odView[i].snext = nextsamp; } CLR4ALL(odS.redraw, odS.nsamp); /* clear redraw flags */ for (i = odS.nsamp; i--; ) { /* clear values */ @@ -316,6 +317,18 @@ int newhist; } +odRedrawAll() /* mark all samples for redraw */ +{ + register int i; + + if ((needmapping&(NEWMAP|NEWRGB)) == (NEWMAP|NEWRGB)) + return; /* will be called later, anyway */ + for (i = odS.nsamp; i--; ) + if (odS.ip[i][0] >= 0) + SET4(odS.redraw, i); +} + + odRedraw(vn, hmin, vmin, hmax, vmax) /* redraw view region */ int vn, hmin, vmin, hmax, vmax; { @@ -424,9 +437,7 @@ GLfloat *dm; odUpdate(vn) /* update this view */ int vn; { - int i, j; - register struct ODblock *bp; - register int k; + register int i, j; DCHECK(vn<0 | vn>=odNViews, CONSISTENCY, "bad view number in odUpdate"); @@ -435,39 +446,49 @@ int vn; if (needmapping & NEWMAP) { if (needmapping & NEWHIST) tmClearHisto(); + needmapping &= ~NEWHIST; if (tmAddHisto(odS.brt,odS.nsamp,1) != TM_E_OK) return; if (tmComputeMapping(0.,0.,0.) != TM_E_OK) return; - for (k = odS.nsamp; k--; ) /* redraw all */ - if (odS.ip[k][0] >= 0) - SET4(odS.redraw, k); + needmapping &= ~NEWMAP; + odRedrawAll(); /* redraw everything */ } if (tmMapPixels(odS.rgb,odS.brt,odS.chr,odS.nsamp) != TM_E_OK) return; - needmapping = 0; /* reset flag */ + needmapping &= ~NEWRGB; } - /* draw each block in view */ - for (j = odView[vn].vlow; j--; ) - for (i = 0; i < odView[vn].hlow; i++) { - /* get block */ - bp = odView[vn].bmap + j*odView[vn].hlow + i; - /* do quick, conservative flag check */ - for (k = (bp->first+bp->nsamp+31)>>5; - k-- > bp->first>>5; ) - if (odS.redraw[k]) - break; /* non-zero flag */ - if (k < bp->first>>5) - continue; /* no flags set */ - for (k = bp->nsamp; k--; ) /* sample by sample */ - if (CHK4(odS.redraw, bp->first+k)) { - odDrawBlockSamp(vn, i, j, bp->first+k); - CLR4(odS.redraw, bp->first+k); - } + /* this code segment was too slow */ +#if 0 + for (i = odView[vn].sfirst; i < odView[vn].snext; i++) + if (CHK4(odS.redraw, i)) { + odDrawSamp(vn, i); + CLR4(odS.redraw, i); } +#else + /* redraw samples at each end */ + for (i = odView[vn].sfirst; i < odView[vn].sfirst+31; i++) + if (CHK4(odS.redraw, i)) { + odDrawSamp(vn, i); + CLR4(odS.redraw, i); + } + for (i = odView[vn].snext-31; i < odView[vn].snext; i++) + if (CHK4(odS.redraw, i)) { + odDrawSamp(vn, i); + CLR4(odS.redraw, i); + } + /* faster flag checks in middle */ + for (j = odView[vn].snext>>5; j-- > (odView[vn].sfirst+0x1f)>>5; ) + for (i = 0; odS.redraw[j]; i++) /* skips faster */ + if (odS.redraw[j] & 1L< 1, CONSISTENCY, "super-unary size in make_arms"); @@ -515,10 +536,9 @@ double sz; vrad = FANSIZE*sz*vp->vhi/vp->vlow; if (hrad*vrad < 2.25) hrad = vrad = 1.5; - phi0 = (2.*PI) * frandom(); dv = OMAXDEPTH*sz + 0.5; for (i = 0; i < na; i++) { - phi = phi0 + (2.*PI)*i/na; + phi = (2.*PI)*i/na; ar[i][0] = cp[0] + tcos(phi)*hrad + 0.5; ar[i][1] = cp[1] + tsin(phi)*vrad + 0.5; ar[i][2] = dv; @@ -603,36 +623,46 @@ register int h, v; } -odDrawBlockSamp(vn, h, v, id) /* draw sample in view block */ -int vn, h, v; +static int +blockedge(vp, bi0, bi1) /* check for edge between blocks? */ +register struct ODview *vp; +register int bi0, bi1; +{ + if (bi1 < 0) + return(1); /* end off view */ + if (CHK4(vp->emap, bi1)) + return(1); /* end has edges */ + if (bi1 == bi0+1 || bi1 == bi0-1 || + bi1 == bi0+vp->hlow || bi1 == bi0-vp->hlow) + return(0); /* end in adjacent block -- no edges */ + return(1); /* conservative for rarer case */ +} + + +odDrawSamp(vn, id) /* draw view sample */ +int vn; register int id; { GLshort arm[MAXFAN][3]; - int narms, blockindex, bi1; + int narms, blockindex; register struct ODview *vp; double size; int home_edges; register int i; vp = odView + vn; - blockindex = v*vp->hlow + h; - DCHECK(odS.ip[id][0]*vp->hlow/vp->hhi != h | - odS.ip[id][1]*vp->vlow/vp->vhi != v, - CONSISTENCY, "bad sample position in odDrawBlockSamp"); + blockindex = getblock(vp, odS.ip[id][0], odS.ip[id][1]); + DCHECK(blockindex<0, CONSISTENCY, "bad sample handed to odDrawSamp"); DCHECK(vp->bmap[blockindex].nused <= 0, - CONSISTENCY, "bad in-use count in odDrawBlockSamp"); + CONSISTENCY, "bad in-use count in odDrawSamp"); /* create triangle fan */ size = 1./sqrt((double)vp->bmap[blockindex].nused); narms = make_arms(arm, odS.ip[id], vp, size); if (vp->emap != NULL) { /* check for edge collisions */ home_edges = CHK4(vp->emap, blockindex); for (i = 0; i < narms; i++) - /* the following test is flawed, because we could - * be passing through a block on a diagonal run */ - if (home_edges || - ( (bi1 = getblock(vp, arm[i][0], arm[i][1])) - != blockindex && - (bi1 < 0 || CHK4(vp->emap, bi1)) )) + if (home_edges || blockedge(vp, blockindex, + getblock(vp, arm[i][0], arm[i][1]))) clip_edge(arm[i], odS.ip[id], vp); } /* draw triangle fan */