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.7 by gwlarson, Wed Sep 16 18:16:29 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
48 < qtcmp(qt1, qt2)
49 < char *qt1, *qt2;
48 > mark_active_tris(qtptr,fptr,arg1,arg2)
49 > QUADTREE *qtptr;
50 > int *fptr,arg1,*arg2;
51   {
52 <    return(qt1 - qt2);
53 < }
52 >  QUADTREE qt = *qtptr;
53 >  OBJECT *os,*optr;
54 >  register int i,t_id;
55  
56 +  if (!QT_IS_LEAF(qt))
57 +    return(TRUE);
58 +  
59 +  if(!QT_FLAG_FILL_TRI(*fptr))
60 +     (*fptr)++;
61 +  /* For each triangle in the set, set the which flag*/
62 +  os = qtqueryset(qt);
63  
64 +  for (i = QT_SET_CNT(os), optr = QT_SET_PTR(os); i > 0; i--)
65 +  {
66 +    t_id = QT_SET_NEXT_ELEM(optr);
67 +    /* Set the render flag */
68 +    if(SM_IS_NTH_T_BASE(smMesh,t_id))
69 +        continue;
70 +    SM_SET_NTH_T_ACTIVE(smMesh,t_id);
71 +    /* NOTE:Also set the LRU clock bit: MAY WANT TO CHANGE: */      
72 +    SM_SET_NTH_T_LRU(smMesh,t_id);
73 +  }
74 +  return(TRUE);
75 + }
76 +
77   int
78 < mark_active_tris(qtptr,arg)
78 > mark_active_interior(qtptr,q0,q1,q2,t0,t1,t2,n,arg1,arg2,arg3)
79   QUADTREE *qtptr;
80 < char *arg;
80 > FVECT q0,q1,q2;
81 > FVECT t0,t1,t2;
82 > int n;
83 > int *arg1,arg2,*arg3;
84   {
85    QUADTREE qt = *qtptr;
86 <  OBJECT os[QT_MAX_SET+1],*optr;
86 >  OBJECT *os,*optr;
87    register int i,t_id;
88  
89    if (!QT_IS_LEAF(qt))
90      return(TRUE);
91    /* For each triangle in the set, set the which flag*/
92 <  qtgetset(os,qt);
92 >  os = qtqueryset(qt);
93  
94    for (i = QT_SET_CNT(os), optr = QT_SET_PTR(os); i > 0; i--)
95    {
# Line 82 | Line 98 | char *arg;
98      if(SM_IS_NTH_T_BASE(smMesh,t_id))
99          continue;
100      SM_SET_NTH_T_ACTIVE(smMesh,t_id);
101 <    /* FOR NOW:Also set the LRU clock bit: MAY WANT TO CHANGE: */      
101 >    /* NOTE:Also set the LRU clock bit: MAY WANT TO CHANGE: */      
102      SM_SET_NTH_T_LRU(smMesh,t_id);
103    }
104    return(TRUE);
# Line 114 | Line 130 | VIEW *view;
130         Also set the triangles LRU clock counter
131         */
132      /* Near face triangles */
133 <    smLocator_apply_func(smMesh,nr[0],nr[2],nr[3],mark_active_tris,NULL);
134 <    smLocator_apply_func(smMesh,nr[2],nr[0],nr[1],mark_active_tris,NULL);
133 >    smLocator_apply_func(smMesh,nr[0],nr[2],nr[3],mark_active_tris,
134 >                         mark_active_interior,NULL,NULL);
135 >    smLocator_apply_func(smMesh,nr[2],nr[0],nr[1],mark_active_tris,
136 >                         mark_active_interior,NULL,NULL);
137      /* Right face triangles */
138 <    smLocator_apply_func(smMesh,nr[0],far[3],far[0],mark_active_tris,NULL);
139 <    smLocator_apply_func(smMesh,far[3],nr[0],nr[3],mark_active_tris,NULL);
138 >    smLocator_apply_func(smMesh,nr[0],far[3],far[0],mark_active_tris,
139 >                         mark_active_interior,NULL,NULL);
140 >    smLocator_apply_func(smMesh,far[3],nr[0],nr[3],mark_active_tris,
141 >                         mark_active_interior,NULL,NULL);
142      /* Left face triangles */
143 <    smLocator_apply_func(smMesh,nr[1],far[2],nr[2],mark_active_tris,NULL);
144 <    smLocator_apply_func(smMesh,far[2],nr[1],far[1],mark_active_tris,NULL);
143 >    smLocator_apply_func(smMesh,nr[1],far[2],nr[2],mark_active_tris,
144 >                         mark_active_interior,NULL,NULL);
145 >    smLocator_apply_func(smMesh,far[2],nr[1],far[1],mark_active_tris,
146 >                         mark_active_interior,NULL,NULL);
147      /* Top face triangles */
148 <    smLocator_apply_func(smMesh,nr[0],far[0],nr[1],mark_active_tris,NULL);
149 <    smLocator_apply_func(smMesh,nr[1],far[0],far[1],mark_active_tris,NULL);
148 >    smLocator_apply_func(smMesh,nr[0],far[0],nr[1],mark_active_tris,
149 >                         mark_active_interior,NULL,NULL);
150 >    smLocator_apply_func(smMesh,nr[1],far[0],far[1],mark_active_tris,
151 >                         mark_active_interior,NULL,NULL);
152      /* Bottom face triangles */
153 <    smLocator_apply_func(smMesh,nr[3],nr[2],far[3],mark_active_tris,NULL);
154 <    smLocator_apply_func(smMesh,nr[2],far[2],far[3],mark_active_tris,NULL);
153 >    smLocator_apply_func(smMesh,nr[3],nr[2],far[3],mark_active_tris,
154 >                         mark_active_interior,NULL,NULL);
155 >    smLocator_apply_func(smMesh,nr[2],far[2],far[3],mark_active_tris,
156 >                         mark_active_interior,NULL,NULL);
157      /* Far face triangles */
158 <    smLocator_apply_func(smMesh,far[0],far[2],far[1],mark_active_tris,NULL);
159 <    smLocator_apply_func(smMesh,far[2],far[0],far[3],mark_active_tris,NULL);
160 <
158 >    smLocator_apply_func(smMesh,far[0],far[2],far[1],mark_active_tris,
159 >                         mark_active_interior,NULL,NULL);
160 >    
161 >    smLocator_apply_func(smMesh,far[2],far[0],far[3],mark_active_tris,
162 >                         mark_active_interior,NULL,NULL);
163   #ifdef TEST_DRIVER
164      VCOPY(FrustumFar[0],far[0]);
165      VCOPY(FrustumFar[1],far[1]);
# Line 155 | Line 183 | smClean()
183      smClean_notify = TRUE;
184   }
185  
186 + int
187 + qtCache_init(nel)               /* initialize for at least nel elements */
188 + int     nel;
189 + {
190 +        static int  hsiztab[] = {
191 +                8191, 16381, 32749, 65521, 131071, 262139, 524287, 1048573, 0
192 +        };
193 +        register int  i;
194  
195 +        if (nel <= 0) {                 /* call to free table */
196 +                if (qt_hsiz) {
197 +                        free((char *)qt_htbl);
198 +                        qt_htbl = NULL;
199 +                        qt_hsiz = 0;
200 +                }
201 +                return(0);
202 +        }
203 +        nel += nel>>1;                  /* 66% occupancy */
204 +        for (i = 0; hsiztab[i]; i++)
205 +                if (hsiztab[i] > nel)
206 +                        break;
207 +        if (!(qt_hsiz = hsiztab[i]))
208 +                qt_hsiz = nel*2 + 1;            /* not always prime */
209 +        qt_htbl = (QT_LUENT *)calloc(qt_hsiz, sizeof(QT_LUENT));
210 +        if (qt_htbl == NULL)
211 +                qt_hsiz = 0;
212 +        for (i = qt_hsiz; i--; )
213 +                qt_htbl[i].qt = EMPTY;
214 +        return(qt_hsiz);
215 + }
216 +
217 + QT_LUENT *
218 + qtCache_find(qt)                /* find a quadtree table entry */
219 + QUADTREE qt;
220 + {
221 +        int     i, n;
222 +        register int    ndx;
223 +        register QT_LUENT       *le;
224 +
225 +        if (qt_hsiz == 0 && !qtCache_init(1))
226 +                return(NULL);
227 + tryagain:                               /* hash table lookup */
228 +        ndx = (unsigned long)qt % qt_hsiz;
229 +        for (i = 0, n = 1; i < qt_hsiz; i++, n += 2) {
230 +                le = &qt_htbl[ndx];
231 +                if (QT_IS_EMPTY(le->qt) || le->qt == qt)
232 +                        return(le);
233 +                if ((ndx += n) >= qt_hsiz)      /* this happens rarely */
234 +                        ndx = ndx % qt_hsiz;
235 +        }
236 +                                        /* table is full, reallocate */
237 +        le = qt_htbl;
238 +        ndx = qt_hsiz;
239 +        if (!qtCache_init(ndx+1)) {     /* no more memory! */
240 +                qt_htbl = le;
241 +                qt_hsiz = ndx;
242 +                return(NULL);
243 +        }
244 +                                        /* copy old table to new and free */
245 +        while (ndx--)
246 +                if (!QT_IS_EMPTY(le[ndx].qt))
247 +                        copystruct(qtCache_find(le[ndx].qt), &le[ndx]);
248 +        free((char *)le);
249 +        goto tryagain;                  /* should happen only once! */
250 + }
251 +
252   stCount_level_leaves(lcnt, qt)  /* count quadtree leaf nodes at each level */
253   int lcnt[];
254   register QUADTREE qt;
# Line 183 | Line 276 | SM *sm;
276   int lvl;
277   {
278    FVECT a,b,c;
279 <  LUENT *le;
279 >  register QT_LUENT *le;
280    QTRAVG *rc[4];
281 <  register QTRAVG *ra;
281 >  TRI *tri;
282    
283    if (QT_IS_EMPTY(qt))                          /* empty leaf node */
284      return(NULL);
285    if (QT_IS_TREE(qt) && !QT_IS_FLAG(qt))        /* not in our frustum */
286      return(NULL);
287                                          /* else look up node */
288 <  if ((le = lu_find(&qtr_tab,(char *)qt)) == NULL)
289 <    goto nomemory;
290 <  ra = (QTRAVG *)le->data;
198 <  if (QT_IS_TREE(qt) && (ra == NULL || lvl > 0))
288 >  if ((le = qtCache_find(qt)) == NULL)
289 >    error(SYSTEM, "out of memory in qtRender_level");
290 >  if (QT_IS_TREE(qt) && (QT_IS_EMPTY(le->qt) || lvl > 0))
291    {                                     /* compute children */
292      qtSubdivide_tri(v0,v1,v2,a,b,c);
293      rc[0] = qtRender_level(QT_NTH_CHILD(qt,0),v0,a,c,sm,lvl-1);
# Line 203 | Line 295 | int lvl;
295      rc[2] = qtRender_level(QT_NTH_CHILD(qt,2),c,b,v2,sm,lvl-1);
296      rc[3] = qtRender_level(QT_NTH_CHILD(qt,3),b,c,a,sm,lvl-1);
297    }
298 <  if (ra == NULL)
298 >  if (QT_IS_EMPTY(le->qt))
299    {                                     /* let's make some data! */
300      int rgbs[3];
301      double distsum;
302 <    int i;
211 <    register int n;
302 >    register int i, n;
303                                          /* average our triangle vertices */
304      rgbs[0] = rgbs[1] = rgbs[2] = 0;
305      distsum = 0.; n = 0;
306      if(QT_IS_TREE(qt))
307      {                                   /* from subtree */
308        for (i = 4; i--; )
309 <        if ((ra = rc[i]) != NULL)
309 >        if (rc[i] != NULL)
310          {
311 <          rgbs[0] += ra->rgb[0]; rgbs[1] += ra->rgb[1]; rgbs[2] += ra->rgb[2];
312 <          distsum += ra->dist; n++;
311 >          rgbs[0] += rc[i]->rgb[0]; rgbs[1] += rc[i]->rgb[1];
312 >          rgbs[2] += rc[i]->rgb[2]; distsum += rc[i]->dist; n++;
313          }
314      }
315      else
316      {                                   /* from triangle set */
317 <      OBJECT os[QT_MAX_SET+1];
317 >      OBJECT *os;
318        int s0, s1, s2;
319  
320 <      qtgetset(os,qt);
320 >      os = qtqueryset(qt);
321        for (n = os[0]; n; n--)
322        {
323 <        qtTri_from_id(os[n],a,b,c,NULL,NULL,NULL,&s0,&s1,&s2);
323 >        tri = SM_NTH_TRI(sm,os[n]);
324 >        s0 = T_NTH_V(tri,0);
325 >        s1 = T_NTH_V(tri,1);
326 >        s2 = T_NTH_V(tri,2);
327 >        VCOPY(a,SM_NTH_WV(sm,s0));
328 >        VCOPY(b,SM_NTH_WV(sm,s1));
329 >        VCOPY(c,SM_NTH_WV(sm,s2));            
330          distsum += SM_BG_SAMPLE(sm,s0) ? dev_zmax
331                                  : sqrt(dist2(a,SM_VIEW_CENTER(sm)));
332          distsum += SM_BG_SAMPLE(sm,s1) ? dev_zmax
# Line 247 | Line 344 | int lvl;
344      }
345      if (!n)
346        return(NULL);
347 <    if ((ra = (QTRAVG *)malloc(sizeof(QTRAVG))) == NULL)
348 <      goto nomemory;
349 <    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;
347 >    le->qt = qt;
348 >    le->av.rgb[0] = rgbs[0]/n; le->av.rgb[1] = rgbs[1]/n;
349 >    le->av.rgb[2] = rgbs[2]/n; le->av.dist = distsum/(double)n;
350    }
351    if (lvl == 0 || (lvl > 0 && QT_IS_LEAF(qt)))
352    {                             /* render this node */
353                                          /* compute pseudo vertices */
354      VCOPY(a,v0); VCOPY(b,v1); VCOPY(c,v2);
355      normalize(a); normalize(b); normalize(c);
356 <    VSUM(a,SM_VIEW_CENTER(sm),a,ra->dist);
357 <    VSUM(b,SM_VIEW_CENTER(sm),b,ra->dist);
358 <    VSUM(c,SM_VIEW_CENTER(sm),c,ra->dist);
356 >    VSUM(a,SM_VIEW_CENTER(sm),a,le->av.dist);
357 >    VSUM(b,SM_VIEW_CENTER(sm),b,le->av.dist);
358 >    VSUM(c,SM_VIEW_CENTER(sm),c,le->av.dist);
359                                          /* draw triangle */
360 <    glColor3ub(ra->rgb[0],ra->rgb[1],ra->rgb[2]);
360 >    glColor3ub(le->av.rgb[0],le->av.rgb[1],le->av.rgb[2]);
361      /* NOTE: Triangle vertex order may change */
362      glVertex3d(c[0],c[1],c[2]);
363      glVertex3d(b[0],b[1],b[2]);
364      glVertex3d(a[0],a[1],a[2]);
365    }
366 <  return(ra);
273 < nomemory:
274 <  error(SYSTEM, "out of memory in qtRender_level");
366 >  return(&le->av);
367   }
368  
369  
# Line 541 | Line 633 | T_DEPTH *td;
633          continue;
634      }
635      tri = SM_NTH_TRI(sm,t_id);
636 + #ifdef DEBUG
637 +    if(i >= smNew_tri_cnt)
638 +    {
639 +      eputs("smDepth_sort_tris():More tris than reported by smNew_tri_cnt\n");
640 +      break;
641 +    }
642 + #endif
643      td[i].tri = t_id;
644      min_d = -1;
645      for(j=0;j < 3;j++)
# Line 603 | Line 702 | int clr;
702       smRender_bg_tri(sm,pop_list(&bglist),vp,d,clr);
703    glEnd();
704  
705 <  glEnable(GL_DEPTH_TEST);
705 >
706    glBegin(GL_TRIANGLES);
707    i=0;
708    while(td[i].tri != -1)
# Line 709 | Line 808 | smUpdate(view,qual)
808    {
809      smClean_notify = FALSE;
810      smNew_tri_cnt = 0;
811 <    lu_done(&qtr_tab);
811 >    smClear_flags(smMesh,T_NEW_FLAG);
812 >    qtCache_init(0);
813    }
814  
815   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines