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.5 by gwlarson, Fri Sep 11 11:52:26 1998 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines