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

Comparing ray/src/hd/sm_ogl.c (file contents):
Revision 3.3 by gwlarson, Thu Sep 3 08:14:29 1998 UTC vs.
Revision 3.4 by gwlarson, Thu Sep 3 11:29:00 1998 UTC

# Line 20 | Line 20 | static char SCCSid[] = "$SunId$ SGI";
20   #include "sm_list.h"
21   #include "sm_geom.h"
22   #include "sm.h"
23 #include "lookup.h"
23  
24   #ifdef TEST_DRIVER
25   #include "sm_draw.h"
# Line 29 | Line 28 | MAKE STATIC LATER: ui.c using for now;
28   */
29   char smClean_notify = TRUE;
30   #else
31 < static char smClean_notify = TRUE;
31 > static int smClean_notify = TRUE;
32   #endif
33  
35 extern unsigned long qthash();
36 extern int qtcmp();
37 extern int free();
38
39 static LUTAB qtr_tab = {qthash,qtcmp,NULL,(void (*)())free,0,NULL,0};
40
34   typedef struct {
42        BYTE    rgb[3];         /* average color */
35          float   dist;           /* average distance */
36 +        BYTE    rgb[3];         /* average color */
37   } QTRAVG;               /* average quadtree value */
38  
39 + typedef struct {
40 +        QUADTREE        qt;     /* quadtree node (key & hash value) */
41 +        QTRAVG          av;     /* node average */
42 + } QT_LUENT;             /* lookup table entry */
43  
44 < unsigned long
45 < qthash(qtc)                     /* hash a quadtree node value */
49 < char *qtc;
50 < {
51 <    register unsigned long qt = qtc;
44 > static QT_LUENT *qt_htbl = NULL;        /* quadtree hash table */
45 > static int      qt_hsiz = 0;            /* quadtree hash table size */
46  
53    return(qt>>10 ^ qt<<5);
54 }
47  
48   int
57 qtcmp(qt1, qt2)
58 char *qt1, *qt2;
59 {
60    return(qt1 - qt2);
61 }
62
63
64 int
49   mark_active_tris(qtptr,arg)
50   QUADTREE *qtptr;
51   char *arg;
# Line 155 | Line 139 | smClean()
139      smClean_notify = TRUE;
140   }
141  
142 + int
143 + qtHash_init(nel)                /* initialize for at least nel elements */
144 + int     nel;
145 + {
146 +        static int  hsiztab[] = {
147 +                8191, 16381, 32749, 65521, 131071, 262139, 524287, 1048573, 0
148 +        };
149 +        register int  i;
150  
151 +        if (nel <= 0) {                 /* call to free table */
152 +                if (qt_hsiz) {
153 +                        free((char *)qt_htbl);
154 +                        qt_htbl = NULL;
155 +                        qt_hsiz = 0;
156 +                }
157 +                return(0);
158 +        }
159 +        nel += nel>>1;                  /* 66% occupancy */
160 +        for (i = 0; hsiztab[i]; i++)
161 +                if (hsiztab[i] > nel)
162 +                        break;
163 +        if (!(qt_hsiz = hsiztab[i]))
164 +                qt_hsiz = nel*2 + 1;            /* not always prime */
165 +        qt_htbl = (QT_LUENT *)calloc(qt_hsiz, sizeof(QT_LUENT));
166 +        if (qt_htbl == NULL)
167 +                qt_hsiz = 0;
168 +        for (i = qt_hsiz; i--; )
169 +                qt_htbl[i].qt = EMPTY;
170 +        return(qt_hsiz);
171 + }
172 +
173 + QT_LUENT *
174 + qtHash_find(qt)                 /* find a quadtree table entry */
175 + QUADTREE qt;
176 + {
177 +        int     i, n;
178 +        register int    ndx;
179 +        register QT_LUENT       *le;
180 +
181 +        if (qt_hsiz == 0)
182 +                qtHash_init(1);
183 + tryagain:                               /* hash table lookup */
184 +        ndx = (unsigned long)qt % qt_hsiz;
185 +        for (i = 0, n = 1; i < qt_hsiz; i++, n += 2) {
186 +                le = &qt_htbl[ndx];
187 +                if (QT_IS_EMPTY(le->qt) || le->qt == qt)
188 +                        return(le);
189 +                if ((ndx += n) >= qt_hsiz)      /* this happens rarely */
190 +                        ndx = ndx % qt_hsiz;
191 +        }
192 +                                        /* table is full, reallocate */
193 +        le = qt_htbl;
194 +        ndx = qt_hsiz;
195 +        if (!qtHash_init(ndx+1)) {      /* no more memory! */
196 +                qt_htbl = le;
197 +                qt_hsiz = ndx;
198 +                return(NULL);
199 +        }
200 +        if (!ndx)
201 +                goto tryagain;
202 +                                        /* copy old table to new */
203 +        while (ndx--)
204 +                if (!QT_IS_EMPTY(le[ndx].qt))
205 +                        copystruct(qtHash_find(le[ndx].qt), &le[ndx]);
206 +        free((char *)le);
207 +        goto tryagain;                  /* should happen only once! */
208 + }
209 +
210   stCount_level_leaves(lcnt, qt)  /* count quadtree leaf nodes at each level */
211   int lcnt[];
212   register QUADTREE qt;
# Line 183 | Line 234 | SM *sm;
234   int lvl;
235   {
236    FVECT a,b,c;
237 <  LUENT *le;
237 >  register QT_LUENT *le;
238    QTRAVG *rc[4];
188  register QTRAVG *ra;
239    
240    if (QT_IS_EMPTY(qt))                          /* empty leaf node */
241      return(NULL);
242    if (QT_IS_TREE(qt) && !QT_IS_FLAG(qt))        /* not in our frustum */
243      return(NULL);
244                                          /* else look up node */
245 <  if ((le = lu_find(&qtr_tab,(char *)qt)) == NULL)
246 <    goto nomemory;
247 <  ra = (QTRAVG *)le->data;
198 <  if (QT_IS_TREE(qt) && (ra == NULL || lvl > 0))
245 >  if ((le = qtHash_find(qt)) == NULL)
246 >    error(SYSTEM, "out of memory in qtRender_level");
247 >  if (QT_IS_TREE(qt) && (QT_IS_EMPTY(le->qt) || lvl > 0))
248    {                                     /* compute children */
249      qtSubdivide_tri(v0,v1,v2,a,b,c);
250      rc[0] = qtRender_level(QT_NTH_CHILD(qt,0),v0,a,c,sm,lvl-1);
# Line 203 | Line 252 | int lvl;
252      rc[2] = qtRender_level(QT_NTH_CHILD(qt,2),c,b,v2,sm,lvl-1);
253      rc[3] = qtRender_level(QT_NTH_CHILD(qt,3),b,c,a,sm,lvl-1);
254    }
255 <  if (ra == NULL)
255 >  if (QT_IS_EMPTY(le->qt))
256    {                                     /* let's make some data! */
257      int rgbs[3];
258      double distsum;
259 <    int i;
211 <    register int n;
259 >    register int i, n;
260                                          /* average our triangle vertices */
261      rgbs[0] = rgbs[1] = rgbs[2] = 0;
262      distsum = 0.; n = 0;
263      if(QT_IS_TREE(qt))
264      {                                   /* from subtree */
265        for (i = 4; i--; )
266 <        if ((ra = rc[i]) != NULL)
266 >        if (rc[i] != NULL)
267          {
268 <          rgbs[0] += ra->rgb[0]; rgbs[1] += ra->rgb[1]; rgbs[2] += ra->rgb[2];
269 <          distsum += ra->dist; n++;
268 >          rgbs[0] += rc[i]->rgb[0]; rgbs[1] += rc[i]->rgb[1];
269 >          rgbs[2] += rc[i]->rgb[2]; distsum += rc[i]->dist; n++;
270          }
271      }
272      else
# Line 247 | Line 295 | int lvl;
295      }
296      if (!n)
297        return(NULL);
298 <    if ((ra = (QTRAVG *)malloc(sizeof(QTRAVG))) == NULL)
299 <      goto nomemory;
300 <    ra->rgb[0] = rgbs[0]/n; ra->rgb[1] = rgbs[1]/n; ra->rgb[2] = rgbs[2]/n;
253 <    ra->dist = distsum/(double)n;
254 <    le->key = (char *)qt;
255 <    le->data = (char *)ra;
298 >    le->qt = qt;
299 >    le->av.rgb[0] = rgbs[0]/n; le->av.rgb[1] = rgbs[1]/n;
300 >    le->av.rgb[2] = rgbs[2]/n; le->av.dist = distsum/(double)n;
301    }
302    if (lvl == 0 || (lvl > 0 && QT_IS_LEAF(qt)))
303    {                             /* render this node */
304                                          /* compute pseudo vertices */
305      VCOPY(a,v0); VCOPY(b,v1); VCOPY(c,v2);
306      normalize(a); normalize(b); normalize(c);
307 <    VSUM(a,SM_VIEW_CENTER(sm),a,ra->dist);
308 <    VSUM(b,SM_VIEW_CENTER(sm),b,ra->dist);
309 <    VSUM(c,SM_VIEW_CENTER(sm),c,ra->dist);
307 >    VSUM(a,SM_VIEW_CENTER(sm),a,le->av.dist);
308 >    VSUM(b,SM_VIEW_CENTER(sm),b,le->av.dist);
309 >    VSUM(c,SM_VIEW_CENTER(sm),c,le->av.dist);
310                                          /* draw triangle */
311 <    glColor3ub(ra->rgb[0],ra->rgb[1],ra->rgb[2]);
311 >    glColor3ub(le->av.rgb[0],le->av.rgb[1],le->av.rgb[2]);
312      /* NOTE: Triangle vertex order may change */
313      glVertex3d(c[0],c[1],c[2]);
314      glVertex3d(b[0],b[1],b[2]);
315      glVertex3d(a[0],a[1],a[2]);
316    }
317 <  return(ra);
273 < nomemory:
274 <  error(SYSTEM, "out of memory in qtRender_level");
317 >  return(&le->av);
318   }
319  
320  
# Line 709 | Line 752 | smUpdate(view,qual)
752    {
753      smClean_notify = FALSE;
754      smNew_tri_cnt = 0;
755 <    lu_done(&qtr_tab);
755 >    qtHash_init(0);
756    }
757  
758   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines