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.11 by gwlarson, Wed Dec 30 13:44:16 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_flag.h"
20   #include "sm_list.h"
21   #include "sm_geom.h"
22 + #include "sm_qtree.h"
23 + #include "sm_stree.h"
24   #include "sm.h"
23 #include "lookup.h"
25  
26   #ifdef TEST_DRIVER
27   #include "sm_draw.h"
# Line 29 | Line 30 | MAKE STATIC LATER: ui.c using for now;
30   */
31   char smClean_notify = TRUE;
32   #else
33 < static char smClean_notify = TRUE;
33 > static int smClean_notify = TRUE;
34   #endif
35  
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
36   typedef struct {
42        BYTE    rgb[3];         /* average color */
37          float   dist;           /* average distance */
38 +        BYTE    rgb[3];         /* average color */
39   } QTRAVG;               /* average quadtree value */
40  
41 + typedef struct {
42 +        QUADTREE        qt;     /* quadtree node (key & hash value) */
43 +        QTRAVG          av;     /* node average */
44 + } QT_LUENT;             /* lookup table entry */
45  
46 < unsigned long
47 < qthash(qtc)                     /* hash a quadtree node value */
49 < char *qtc;
50 < {
51 <    register unsigned long qt = qtc;
46 > static QT_LUENT *qt_htbl = NULL;        /* quadtree cache */
47 > static int      qt_hsiz = 0;            /* quadtree cache size */
48  
53    return(qt>>10 ^ qt<<5);
54 }
49  
50 < int
51 < qtcmp(qt1, qt2)
52 < char *qt1, *qt2;
50 > /*
51 >  * smClean()           : display has been wiped clean
52 >  *
53 >  * Called after display has been effectively cleared, meaning that all
54 >  * geometry must be resent down the pipeline in the next call to smUpdate().
55 >  */
56 > smClean()
57   {
58 <    return(qt1 - qt2);
58 >    smClean_notify = TRUE;
59   }
60  
63
61   int
62 < mark_active_tris(qtptr,arg)
63 < QUADTREE *qtptr;
67 < char *arg;
62 > qtCache_init(nel)               /* initialize for at least nel elements */
63 > int     nel;
64   {
65 <  QUADTREE qt = *qtptr;
66 <  OBJECT os[QT_MAX_SET+1],*optr;
67 <  register int i,t_id;
65 >        static int  hsiztab[] = {
66 >                8191, 16381, 32749, 65521, 131071, 262139, 524287, 1048573, 0
67 >        };
68 >        register int  i;
69  
70 <  if (!QT_IS_LEAF(qt))
71 <    return(TRUE);
72 <  /* For each triangle in the set, set the which flag*/
73 <  qtgetset(os,qt);
74 <
75 <  for (i = QT_SET_CNT(os), optr = QT_SET_PTR(os); i > 0; i--)
76 <  {
77 <    t_id = QT_SET_NEXT_ELEM(optr);
78 <    /* Set the render flag */
79 <    if(SM_IS_NTH_T_BASE(smMesh,t_id))
80 <        continue;
81 <    SM_SET_NTH_T_ACTIVE(smMesh,t_id);
82 <    /* FOR NOW:Also set the LRU clock bit: MAY WANT TO CHANGE: */      
83 <    SM_SET_NTH_T_LRU(smMesh,t_id);
84 <  }
85 <  return(TRUE);
70 >        if (nel <= 0) {                 /* call to free table */
71 >                if (qt_hsiz) {
72 >                        free((char *)qt_htbl);
73 >                        qt_htbl = NULL;
74 >                        qt_hsiz = 0;
75 >                }
76 >                return(0);
77 >        }
78 >        nel += nel>>1;                  /* 66% occupancy */
79 >        for (i = 0; hsiztab[i]; i++)
80 >                if (hsiztab[i] > nel)
81 >                        break;
82 >        if (!(qt_hsiz = hsiztab[i]))
83 >                qt_hsiz = nel*2 + 1;            /* not always prime */
84 >        qt_htbl = (QT_LUENT *)calloc(qt_hsiz, sizeof(QT_LUENT));
85 >        if (qt_htbl == NULL)
86 >                qt_hsiz = 0;
87 >        for (i = qt_hsiz; i--; )
88 >                qt_htbl[i].qt = EMPTY;
89 >        return(qt_hsiz);
90   }
91  
92 < mark_tris_in_frustum(view)
93 < VIEW *view;
92 > QT_LUENT *
93 > qtCache_find(qt)                /* find a quadtree table entry */
94 > QUADTREE qt;
95   {
96 <    FVECT nr[4],far[4];
96 >        int     i, n;
97 >        register int    ndx;
98 >        register QT_LUENT       *le;
99  
100 <    /* Mark triangles in approx. view frustum as being active:set
101 <       LRU counter: for use in discarding samples when out
102 <       of space
103 <       Radiance often has no far clipping plane: but driver will set
104 <       dev_zmin,dev_zmax to satisfy OGL
105 <    */
106 <
107 <    /* First clear all the quadtree node and triangle active flags */
108 <    qtClearAllFlags();
109 <    smClear_flags(smMesh,T_ACTIVE_FLAG);
110 <
111 <    /* calculate the world space coordinates of the view frustum */
112 <    calculate_view_frustum(view->vp,view->hvec,view->vvec,view->horiz,
113 <                           view->vert, dev_zmin,dev_zmax,nr,far);
114 <
115 <    /* Project the view frustum onto the spherical quadtree */
116 <    /* For every cell intersected by the projection of the faces
117 <       of the frustum: mark all triangles in the cell as ACTIVE-
118 <       Also set the triangles LRU clock counter
119 <       */
120 <    /* Near face triangles */
121 <    smLocator_apply_func(smMesh,nr[0],nr[2],nr[3],mark_active_tris,NULL);
122 <    smLocator_apply_func(smMesh,nr[2],nr[0],nr[1],mark_active_tris,NULL);
123 <    /* Right face triangles */
124 <    smLocator_apply_func(smMesh,nr[0],far[3],far[0],mark_active_tris,NULL);
121 <    smLocator_apply_func(smMesh,far[3],nr[0],nr[3],mark_active_tris,NULL);
122 <    /* Left face triangles */
123 <    smLocator_apply_func(smMesh,nr[1],far[2],nr[2],mark_active_tris,NULL);
124 <    smLocator_apply_func(smMesh,far[2],nr[1],far[1],mark_active_tris,NULL);
125 <    /* Top face triangles */
126 <    smLocator_apply_func(smMesh,nr[0],far[0],nr[1],mark_active_tris,NULL);
127 <    smLocator_apply_func(smMesh,nr[1],far[0],far[1],mark_active_tris,NULL);
128 <    /* Bottom face triangles */
129 <    smLocator_apply_func(smMesh,nr[3],nr[2],far[3],mark_active_tris,NULL);
130 <    smLocator_apply_func(smMesh,nr[2],far[2],far[3],mark_active_tris,NULL);
131 <    /* Far face triangles */
132 <    smLocator_apply_func(smMesh,far[0],far[2],far[1],mark_active_tris,NULL);
133 <    smLocator_apply_func(smMesh,far[2],far[0],far[3],mark_active_tris,NULL);
134 <
135 < #ifdef TEST_DRIVER
136 <    VCOPY(FrustumFar[0],far[0]);
137 <    VCOPY(FrustumFar[1],far[1]);
138 <    VCOPY(FrustumFar[2],far[2]);
139 <    VCOPY(FrustumFar[3],far[3]);
140 <    VCOPY(FrustumNear[0],nr[0]);
141 <    VCOPY(FrustumNear[1],nr[1]);
142 <    VCOPY(FrustumNear[2],nr[2]);
143 <    VCOPY(FrustumNear[3],nr[3]);
144 < #endif
100 >        if (qt_hsiz == 0 && !qtCache_init(1))
101 >                return(NULL);
102 > tryagain:                               /* hash table lookup */
103 >        ndx = (unsigned long)qt % qt_hsiz;
104 >        for (i = 0, n = 1; i < qt_hsiz; i++, n += 2) {
105 >                le = &qt_htbl[ndx];
106 >                if (QT_IS_EMPTY(le->qt) || le->qt == qt)
107 >                        return(le);
108 >                if ((ndx += n) >= qt_hsiz)      /* this happens rarely */
109 >                        ndx = ndx % qt_hsiz;
110 >        }
111 >                                        /* table is full, reallocate */
112 >        le = qt_htbl;
113 >        ndx = qt_hsiz;
114 >        if (!qtCache_init(ndx+1)) {     /* no more memory! */
115 >                qt_htbl = le;
116 >                qt_hsiz = ndx;
117 >                return(NULL);
118 >        }
119 >                                        /* copy old table to new and free */
120 >        while (ndx--)
121 >                if (!QT_IS_EMPTY(le[ndx].qt))
122 >                        copystruct(qtCache_find(le[ndx].qt), &le[ndx]);
123 >        free((char *)le);
124 >        goto tryagain;                  /* should happen only once! */
125   }
126  
147 /*
148 * smClean()            : display has been wiped clean
149 *
150 * Called after display has been effectively cleared, meaning that all
151 * geometry must be resent down the pipeline in the next call to smUpdate().
152 */
153 smClean()
154 {
155    smClean_notify = TRUE;
156 }
157
158
127   stCount_level_leaves(lcnt, qt)  /* count quadtree leaf nodes at each level */
128   int lcnt[];
129   register QUADTREE qt;
# Line 171 | Line 139 | register QUADTREE qt;
139      stCount_level_leaves(lcnt+1, QT_NTH_CHILD(qt,3));
140    }
141    else
142 <    lcnt[0]++;
142 >    if(QT_LEAF_IS_FLAG(qt))
143 >      lcnt[0]++;
144   }
145  
146  
# Line 183 | Line 152 | SM *sm;
152   int lvl;
153   {
154    FVECT a,b,c;
155 <  LUENT *le;
155 >  register QT_LUENT *le;
156    QTRAVG *rc[4];
157 <  register QTRAVG *ra;
157 >  TRI *tri;
158    
159    if (QT_IS_EMPTY(qt))                          /* empty leaf node */
160      return(NULL);
161    if (QT_IS_TREE(qt) && !QT_IS_FLAG(qt))        /* not in our frustum */
162      return(NULL);
163 +  if(QT_IS_LEAF(qt)  && !QT_LEAF_IS_FLAG(qt))   /* not in our frustum */
164 +    return(NULL);
165                                          /* else look up node */
166 <  if ((le = lu_find(&qtr_tab,(char *)qt)) == NULL)
167 <    goto nomemory;
168 <  ra = (QTRAVG *)le->data;
198 <  if (QT_IS_TREE(qt) && (ra == NULL || lvl > 0))
166 >  if ((le = qtCache_find(qt)) == NULL)
167 >    error(SYSTEM, "out of memory in qtRender_level");
168 >  if (QT_IS_TREE(qt) && (QT_IS_EMPTY(le->qt) || lvl > 0))
169    {                                     /* compute children */
170      qtSubdivide_tri(v0,v1,v2,a,b,c);
171 <    rc[0] = qtRender_level(QT_NTH_CHILD(qt,0),v0,a,c,sm,lvl-1);
172 <    rc[1] = qtRender_level(QT_NTH_CHILD(qt,1),a,v1,b,sm,lvl-1);
173 <    rc[2] = qtRender_level(QT_NTH_CHILD(qt,2),c,b,v2,sm,lvl-1);
174 <    rc[3] = qtRender_level(QT_NTH_CHILD(qt,3),b,c,a,sm,lvl-1);
171 >    rc[0] = qtRender_level(QT_NTH_CHILD(qt,0),v0,c,b,sm,lvl-1);
172 >    rc[1] = qtRender_level(QT_NTH_CHILD(qt,1),c,v1,a,sm,lvl-1);
173 >    rc[2] = qtRender_level(QT_NTH_CHILD(qt,2),b,a,v2,sm,lvl-1);
174 >    rc[3] = qtRender_level(QT_NTH_CHILD(qt,3),a,b,c,sm,lvl-1);
175    }
176 <  if (ra == NULL)
176 >  if (QT_IS_EMPTY(le->qt))
177    {                                     /* let's make some data! */
178      int rgbs[3];
179      double distsum;
180 <    int i;
211 <    register int n;
180 >    register int i, n;
181                                          /* average our triangle vertices */
182      rgbs[0] = rgbs[1] = rgbs[2] = 0;
183      distsum = 0.; n = 0;
184      if(QT_IS_TREE(qt))
185      {                                   /* from subtree */
186        for (i = 4; i--; )
187 <        if ((ra = rc[i]) != NULL)
187 >        if (rc[i] != NULL)
188          {
189 <          rgbs[0] += ra->rgb[0]; rgbs[1] += ra->rgb[1]; rgbs[2] += ra->rgb[2];
190 <          distsum += ra->dist; n++;
189 >          rgbs[0] += rc[i]->rgb[0]; rgbs[1] += rc[i]->rgb[1];
190 >          rgbs[2] += rc[i]->rgb[2]; distsum += rc[i]->dist; n++;
191          }
192      }
193      else
194      {                                   /* from triangle set */
195 <      OBJECT os[QT_MAX_SET+1];
195 >      OBJECT *os;
196        int s0, s1, s2;
197 <
198 <      qtgetset(os,qt);
199 <      for (n = os[0]; n; n--)
197 >      
198 >      os = qtqueryset(qt);
199 >      for (i = os[0]; i; i--)
200        {
201 <        qtTri_from_id(os[n],a,b,c,NULL,NULL,NULL,&s0,&s1,&s2);
201 >        if(SM_IS_NTH_T_BASE(sm,os[i]))
202 >           continue;
203 >        tri = SM_NTH_TRI(sm,os[i]);
204 >        if(!T_IS_VALID(tri))
205 >          continue;
206 >        n++;
207 >        s0 = T_NTH_V(tri,0);
208 >        s1 = T_NTH_V(tri,1);
209 >        s2 = T_NTH_V(tri,2);
210 >        VCOPY(a,SM_NTH_WV(sm,s0));
211 >        VCOPY(b,SM_NTH_WV(sm,s1));
212 >        VCOPY(c,SM_NTH_WV(sm,s2));            
213          distsum += SM_BG_SAMPLE(sm,s0) ? dev_zmax
214                                  : sqrt(dist2(a,SM_VIEW_CENTER(sm)));
215          distsum += SM_BG_SAMPLE(sm,s1) ? dev_zmax
# Line 243 | Line 223 | int lvl;
223          rgbs[2] += SM_NTH_RGB(sm,s0)[2] + SM_NTH_RGB(sm,s1)[2]
224                    + SM_NTH_RGB(sm,s2)[2];
225        }
226 <      n = 3*os[0];
226 >      n *= 3;
227      }
228      if (!n)
229        return(NULL);
230 <    if ((ra = (QTRAVG *)malloc(sizeof(QTRAVG))) == NULL)
231 <      goto nomemory;
232 <    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;
230 >    le->qt = qt;
231 >    le->av.rgb[0] = rgbs[0]/n; le->av.rgb[1] = rgbs[1]/n;
232 >    le->av.rgb[2] = rgbs[2]/n; le->av.dist = distsum/(double)n;
233    }
234    if (lvl == 0 || (lvl > 0 && QT_IS_LEAF(qt)))
235    {                             /* render this node */
236                                          /* compute pseudo vertices */
237      VCOPY(a,v0); VCOPY(b,v1); VCOPY(c,v2);
238      normalize(a); normalize(b); normalize(c);
239 <    VSUM(a,SM_VIEW_CENTER(sm),a,ra->dist);
240 <    VSUM(b,SM_VIEW_CENTER(sm),b,ra->dist);
241 <    VSUM(c,SM_VIEW_CENTER(sm),c,ra->dist);
239 >    VSUM(a,SM_VIEW_CENTER(sm),a,le->av.dist);
240 >    VSUM(b,SM_VIEW_CENTER(sm),b,le->av.dist);
241 >    VSUM(c,SM_VIEW_CENTER(sm),c,le->av.dist);
242                                          /* draw triangle */
243 <    glColor3ub(ra->rgb[0],ra->rgb[1],ra->rgb[2]);
267 <    /* NOTE: Triangle vertex order may change */
268 <    glVertex3d(c[0],c[1],c[2]);
269 <    glVertex3d(b[0],b[1],b[2]);
243 >    glColor3ub(le->av.rgb[0],le->av.rgb[1],le->av.rgb[2]);
244      glVertex3d(a[0],a[1],a[2]);
245 +    glVertex3d(b[0],b[1],b[2]);
246 +    glVertex3d(c[0],c[1],c[2]);
247 +
248    }
249 <  return(ra);
273 < nomemory:
274 <  error(SYSTEM, "out of memory in qtRender_level");
249 >  return(&le->av);
250   }
251  
252  
# Line 279 | Line 254 | smRender_stree_level(sm,lvl)
254   SM *sm;
255   int lvl;
256   {
257 <  QUADTREE root;
257 >  QUADTREE qt;
258    int i;
259    FVECT t0,t1,t2;
260 +  STREE *st;
261  
262 <  if (lvl < 1)
262 >  
263 >  if (lvl < 0)
264      return;
265 +  st = SM_LOCATOR(sm);
266    glPushAttrib(GL_LIGHTING_BIT);
267    glShadeModel(GL_FLAT);
268    glBegin(GL_TRIANGLES);
269 <  for(i=0; i < 4; i++)
269 >  for(i=0; i < ST_NUM_ROOT_NODES; i++)
270    {
271 <    root = ST_NTH_ROOT(SM_LOCATOR(sm),i);
272 <    stNth_base_verts(SM_LOCATOR(sm),i,t0,t1,t2);
273 <    qtRender_level(root,t0,t1,t2,sm,lvl-1);
271 >    qt = ST_ROOT_QT(st,i);
272 >    qtRender_level(qt,ST_NTH_V(st,i,0),ST_NTH_V(st,i,1),ST_NTH_V(st,i,2),
273 >                   sm,lvl);
274    }
275    glEnd();
276    glPopAttrib();
# Line 305 | Line 283 | int qual;
283   {
284    int i, ntarget;
285    int lvlcnt[QT_MAX_LEVELS];
286 +  STREE *st;
287  
288    if (qual <= 0)
289      return;
# Line 317 | Line 296 | int qual;
296      return;
297    for (i = QT_MAX_LEVELS; i--; )
298      lvlcnt[i] = 0;
299 <  stCount_level_leaves(lvlcnt, SM_LOCATOR(sm)->root);
299 >  
300 >  st = SM_LOCATOR(sm);
301 >  for(i=0; i < ST_NUM_ROOT_NODES;i++)
302 >    stCount_level_leaves(lvlcnt, ST_ROOT_QT(st,i));
303 >  
304    for (ntarget -= lvlcnt[i=0]; i < QT_MAX_LEVELS-1; ntarget -= lvlcnt[++i])
305      if (ntarget < lvlcnt[i+1])
306        break;
# Line 337 | Line 320 | int clr;
320    int j;
321  
322    tri = SM_NTH_TRI(sm,i);
323 <  if (clr) SM_CLEAR_NTH_T_NEW(sm,i);
324 <
342 <  /* NOTE:Triangles are defined clockwise:historical relative to spherical
343 <     tris: could change
344 <     */
345 <  for(j=2; j>= 0; j--)
323 >  if (clr) SM_CLR_NTH_T_NEW(sm,i);
324 >  for(j=0; j <= 2; j++)
325    {
326   #ifdef DEBUG
327      if(SM_BG_SAMPLE(sm,T_NTH_V(tri,j)))
# Line 368 | Line 347 | int clr;
347    int rgb[3];
348  
349    tri = SM_NTH_TRI(sm,i);
350 <  if (clr) SM_CLEAR_NTH_T_NEW(sm,i);
350 >  if (clr) SM_CLR_NTH_T_NEW(sm,i);
351  
352    /* NOTE:Triangles are defined clockwise:historical relative to spherical
353       tris: could change
# Line 393 | Line 372 | int clr;
372      rgb[0]/=cnt; rgb[1]/=cnt; rgb[2]/=cnt;
373      d /= (double)cnt;
374    }
375 <  for(j=2; j>= 0; j--)
375 >  for(j=0; j <= 2; j++)
376    {
377      if(SM_BG_SAMPLE(sm,ids[j]))
378      {
# Line 426 | Line 405 | int clr;
405    TRI *tri;
406    
407    tri = SM_NTH_TRI(sm,i);
408 <  if (clr) SM_CLEAR_NTH_T_NEW(sm,i);
408 >  if (clr) SM_CLR_NTH_T_NEW(sm,i);
409  
410    /* NOTE:Triangles are defined clockwise:historical relative to spherical
411       tris: could change
412       */
413 <  for(j=2; j>= 0; j--)
413 >  for(j=0; j <= 2; j++)
414    {
415        id = T_NTH_V(tri,j);
416        glColor3ub(SM_NTH_RGB(sm,id)[0],SM_NTH_RGB(sm,id)[1],
# Line 462 | Line 441 | int clr;
441    glPushAttrib(GL_DEPTH_BUFFER_BIT);
442    
443    /* First draw background polygons */
465
444    glDisable(GL_DEPTH_TEST);
445    glBegin(GL_TRIANGLES);
446    SM_FOR_ALL_ACTIVE_BG_TRIS(sm,i)
447       smRender_bg_tri(sm,i,vp,d,clr);
448    glEnd();
471  
449    glEnable(GL_DEPTH_TEST);
450    glBegin(GL_TRIANGLES);
451    SM_FOR_ALL_ACTIVE_FG_TRIS(sm,i)
452    {
453        if(!SM_MIXED_TRI(sm,i))
454          smRender_tri(sm,i,vp,clr);
455 <     else
455 >   else
456          smRender_mixed_tri(sm,i,vp,clr);
457    }
458    glEnd();
# Line 494 | Line 471 | int i;
471  
472    tri = SM_NTH_TRI(sm,i);
473  
474 <  /* Triangles are defined clockwise:historical relative to spherical
498 <     tris: could change
499 <     */
500 <  for(j=2; j >=0; j--)
474 >  for(j=0; j <= 2; j++)
475    {
476      VCOPY(ptr,SM_NTH_WV(sm,T_NTH_V(tri,j)));
477      glVertex3d(ptr[0],ptr[1],ptr[2]);
# Line 541 | Line 515 | T_DEPTH *td;
515          continue;
516      }
517      tri = SM_NTH_TRI(sm,t_id);
518 + #ifdef DEBUG
519 +    if(i >= smNew_tri_cnt)
520 +    {
521 +      eputs("smDepth_sort_tris():More tris than reported by smNew_tri_cnt\n");
522 +      break;
523 +    }
524 + #endif
525      td[i].tri = t_id;
526      min_d = -1;
527      for(j=0;j < 3;j++)
# Line 594 | Line 575 | int clr;
575  
576    /* Turn Depth Test off -- using Painter's algorithm */
577    glPushAttrib(GL_DEPTH_BUFFER_BIT);
578 <  glDisable(GL_DEPTH_TEST);
578 >  glDepthFunc(GL_ALWAYS);
579    d = (dev_zmin+dev_zmax)/2.0;
580    /* Now render back-to front */
581    /* First render bg triangles */
# Line 603 | Line 584 | int clr;
584       smRender_bg_tri(sm,pop_list(&bglist),vp,d,clr);
585    glEnd();
586  
587 <  glEnable(GL_DEPTH_TEST);
587 >
588    glBegin(GL_TRIANGLES);
589    i=0;
590    while(td[i].tri != -1)
# Line 641 | Line 622 | smUpdate(view,qual)
622       epsilon is calculated as running avg of distance of sample points
623       from canonical view: m = 1/(AVG(1/r)): some fraction of this
624     */
625 +
626 +  if(!smMesh)
627 +    return;
628 +
629 +
630 +
631    d = DIST(view->vp,SM_VIEW_CENTER(smMesh));
632    if(qual >= 100 && d > SM_ALLOWED_VIEW_CHANGE(smMesh))
633    {
634        /* Re-build the mesh */
635   #ifdef TEST_DRIVER
636      odev.v = *view;
637 < #endif    
638 <      smRebuild_mesh(smMesh,view->vp);
637 > #endif  
638 >      mark_tris_in_frustum(view);
639 >      smRebuild_mesh(smMesh,view);
640    }
641    /* This is our final update iff qual==100 and view==&odev.v */
642    last_update = qual>=100 && view==&(odev.v);
643    /* Check if we should draw ALL triangles in current frustum */
644 <  if(smClean_notify || smNew_tri_cnt > SM_NUM_TRIS(smMesh)*SM_INC_PERCENT)
644 >  if(smClean_notify || smNew_tri_cnt > SM_SAMPLE_TRIS(smMesh)*SM_INC_PERCENT)
645    {
646   #ifdef TEST_DRIVER
647      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
648   #else
649 <    if (SM_TONE_MAP(smMesh) < SM_NUM_SAMP(smMesh))
649 >    if ( SM_TONE_MAP(smMesh) < SM_NUM_SAMP(smMesh))
650      {
651         tmClearHisto();
652         tmAddHisto(SM_BRT(smMesh),SM_NUM_SAMP(smMesh),1);
653 <       if(tmComputeMapping(0.,0.,0.) != TM_E_OK ||
654 <                   tmMapPixels(SM_RGB(smMesh),SM_BRT(smMesh),SM_CHR(smMesh),
655 <                                SM_NUM_SAMP(smMesh)) != TM_E_OK)
668 <            return;
653 >       tmComputeMapping(0.,0.,0.);
654 >       tmMapPixels(SM_RGB(smMesh),SM_BRT(smMesh),SM_CHR(smMesh),
655 >                   SM_NUM_SAMP(smMesh));
656      }
657   #endif
658      mark_tris_in_frustum(view);
# Line 680 | Line 667 | smUpdate(view,qual)
667    }
668    /* Do an incremental update instead */
669    else
670 <  {  
671 <    if(!smNew_tri_cnt)
670 >  {
671 >      if(!smNew_tri_cnt)
672        return;
673   #ifdef TEST_DRIVER
674      glDrawBuffer(GL_FRONT);
# Line 694 | Line 681 | smUpdate(view,qual)
681          if(tmComputeMapping(0.,0.,0.) != TM_E_OK)
682             return;
683      }
684 <    if(tmMapPixels(SM_NTH_RGB(smMesh,t),&SM_NTH_BRT(smMesh,t),
685 <                   SM_NTH_CHR(smMesh,t), SM_NUM_SAMP(smMesh)-t) != TM_E_OK)
686 <          return;
684 >    tmMapPixels(SM_NTH_RGB(smMesh,t),&SM_NTH_BRT(smMesh,t),
685 >                   SM_NTH_CHR(smMesh,t), SM_NUM_SAMP(smMesh)-t);
686 >        
687   #endif    
688      smUpdate_Rendered_mesh(smMesh,view->vp,last_update);
689      
# Line 704 | Line 691 | smUpdate(view,qual)
691      glDrawBuffer(GL_BACK);
692   #endif
693    }
694 +
695    SM_TONE_MAP(smMesh) = SM_NUM_SAMP(smMesh);
696 +
697    if (last_update)
698    {
699      smClean_notify = FALSE;
700      smNew_tri_cnt = 0;
701 <    lu_done(&qtr_tab);
701 >    smClear_flags(smMesh,T_NEW_FLAG);
702 >    qtCache_init(0);
703    }
704  
705   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines