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.2 by gwlarson, Thu Aug 20 16:47:21 1998 UTC vs.
Revision 3.3 by gwlarson, Thu Sep 3 08:14:29 1998 UTC

# Line 17 | Line 17 | static char SCCSid[] = "$SunId$ SGI";
17   #include <glut.h>
18   #endif
19   #include "object.h"
20 + #include "sm_list.h"
21   #include "sm_geom.h"
22   #include "sm.h"
23 + #include "lookup.h"
24  
25   #ifdef TEST_DRIVER
26   #include "sm_draw.h"
# Line 30 | Line 32 | char smClean_notify = TRUE;
32   static char smClean_notify = TRUE;
33   #endif
34  
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 +
41 + typedef struct {
42 +        BYTE    rgb[3];         /* average color */
43 +        float   dist;           /* average distance */
44 + } QTRAVG;               /* average quadtree value */
45 +
46 +
47 + unsigned long
48 + qthash(qtc)                     /* hash a quadtree node value */
49 + char *qtc;
50 + {
51 +    register unsigned long qt = qtc;
52 +
53 +    return(qt>>10 ^ qt<<5);
54 + }
55 +
56   int
57 + qtcmp(qt1, qt2)
58 + char *qt1, *qt2;
59 + {
60 +    return(qt1 - qt2);
61 + }
62 +
63 +
64 + int
65   mark_active_tris(qtptr,arg)
66   QUADTREE *qtptr;
67   char *arg;
68   {
69 <  OBJECT os[MAXSET+1],*optr;
70 <  int i,t_id;
71 <  SM *sm;
69 >  QUADTREE qt = *qtptr;
70 >  OBJECT os[QT_MAX_SET+1],*optr;
71 >  register int i,t_id;
72  
73 <
74 <  sm = (SM *)arg;
44 <
73 >  if (!QT_IS_LEAF(qt))
74 >    return(TRUE);
75    /* For each triangle in the set, set the which flag*/
76 <  if(QT_IS_EMPTY(*qtptr))
47 <  {
48 <      return(FALSE);
49 <  }
50 <  else
51 <  {
52 <    qtgetset(os,*qtptr);
76 >  qtgetset(os,qt);
77  
78 <    for (i = QT_SET_CNT(os),optr = QT_SET_PTR(os); i > 0; i--)
79 <    {
80 <      t_id = QT_SET_NEXT_ELEM(optr);
81 <      /* Set the render flag */
82 <      if(SM_IS_NTH_T_BASE(sm,t_id))
78 >  for (i = QT_SET_CNT(os), optr = QT_SET_PTR(os); i > 0; i--)
79 >  {
80 >    t_id = QT_SET_NEXT_ELEM(optr);
81 >    /* Set the render flag */
82 >    if(SM_IS_NTH_T_BASE(smMesh,t_id))
83          continue;
84 <      SM_SET_NTH_T_ACTIVE(sm,t_id);
85 <      /* FOR NOW:Also set the LRU clock bit: MAY WANT TO CHANGE: */      
86 <      SM_SET_NTH_T_LRU(sm,t_id);
63 <    }
84 >    SM_SET_NTH_T_ACTIVE(smMesh,t_id);
85 >    /* FOR NOW:Also set the LRU clock bit: MAY WANT TO CHANGE: */      
86 >    SM_SET_NTH_T_LRU(smMesh,t_id);
87    }
88    return(TRUE);
89   }
90  
91 <
92 < smMark_tris_in_frustum(sm,vp)
70 < SM *sm;
71 < VIEW *vp;
91 > mark_tris_in_frustum(view)
92 > VIEW *view;
93   {
94      FVECT nr[4],far[4];
95  
# Line 79 | Line 100 | VIEW *vp;
100         dev_zmin,dev_zmax to satisfy OGL
101      */
102  
103 <    /* First clear all the triangle active flags */
104 <    smClear_flags(sm,T_ACTIVE_FLAG);
103 >    /* First clear all the quadtree node and triangle active flags */
104 >    qtClearAllFlags();
105 >    smClear_flags(smMesh,T_ACTIVE_FLAG);
106  
107      /* calculate the world space coordinates of the view frustum */
108 <    calculate_view_frustum(vp->vp,vp->hvec,vp->vvec,vp->horiz,vp->vert,
109 <                           dev_zmin,dev_zmax,nr,far);
108 >    calculate_view_frustum(view->vp,view->hvec,view->vvec,view->horiz,
109 >                           view->vert, dev_zmin,dev_zmax,nr,far);
110  
111      /* Project the view frustum onto the spherical quadtree */
112      /* For every cell intersected by the projection of the faces
113         of the frustum: mark all triangles in the cell as ACTIVE-
114         Also set the triangles LRU clock counter
115         */
94    /* Need to do tonemap call */
116      /* Near face triangles */
117 <    smLocator_apply_func(sm,nr[0],nr[2],nr[3],mark_active_tris,(char *)(sm));
118 <    smLocator_apply_func(sm,nr[2],nr[0],nr[1],mark_active_tris,(char *)(sm));
117 >    smLocator_apply_func(smMesh,nr[0],nr[2],nr[3],mark_active_tris,NULL);
118 >    smLocator_apply_func(smMesh,nr[2],nr[0],nr[1],mark_active_tris,NULL);
119      /* Right face triangles */
120 <    smLocator_apply_func(sm,nr[0],far[3],far[0],mark_active_tris,(char *)(sm));
121 <    smLocator_apply_func(sm,far[3],nr[0],nr[3],mark_active_tris,(char *)(sm));
120 >    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(sm,nr[1],far[2],nr[2],mark_active_tris,(char *)(sm));
124 <    smLocator_apply_func(sm,far[2],nr[1],far[1],mark_active_tris,(char *)(sm));
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(sm,nr[0],far[0],nr[1],mark_active_tris,(char *)(sm));
127 <    smLocator_apply_func(sm,nr[1],far[0],far[1],mark_active_tris,(char *)(sm));
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(sm,nr[3],nr[2],far[3],mark_active_tris,(char *)(sm));
130 <    smLocator_apply_func(sm,nr[2],far[2],far[3],mark_active_tris,(char *)(sm));
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(sm,far[0],far[2],far[1],mark_active_tris,(char *)(sm));
133 <   smLocator_apply_func(sm,far[2],far[0],far[3],mark_active_tris,(char *)(sm));
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]);
# Line 131 | Line 152 | VIEW *vp;
152   */
153   smClean()
154   {
134  /* Mark all triangles in the frustum as active */
135    if(!smMesh || SM_NUM_TRIS(smMesh)==0)
136       return;
137    
138 #ifdef TEST_DRIVER
139    smMark_tris_in_frustum(smMesh,&Current_View);
140 #else
141    smMark_tris_in_frustum(smMesh,&(odev.v));
142 #endif
155      smClean_notify = TRUE;
156   }
157  
158  
159 < smRender_tri(sm,i,vp)
159 > stCount_level_leaves(lcnt, qt)  /* count quadtree leaf nodes at each level */
160 > int lcnt[];
161 > register QUADTREE qt;
162 > {
163 >  if (QT_IS_EMPTY(qt))
164 >    return;
165 >  if (QT_IS_TREE(qt)) {
166 >    if (!QT_IS_FLAG(qt))        /* not in our frustum */
167 >      return;
168 >    stCount_level_leaves(lcnt+1, QT_NTH_CHILD(qt,0));
169 >    stCount_level_leaves(lcnt+1, QT_NTH_CHILD(qt,1));
170 >    stCount_level_leaves(lcnt+1, QT_NTH_CHILD(qt,2));
171 >    stCount_level_leaves(lcnt+1, QT_NTH_CHILD(qt,3));
172 >  }
173 >  else
174 >    lcnt[0]++;
175 > }
176 >
177 >
178 > QTRAVG *
179 > qtRender_level(qt,v0,v1,v2,sm,lvl)
180 > QUADTREE qt;
181 > FVECT v0,v1,v2;
182   SM *sm;
183 + int lvl;
184 + {
185 +  FVECT a,b,c;
186 +  LUENT *le;
187 +  QTRAVG *rc[4];
188 +  register QTRAVG *ra;
189 +  
190 +  if (QT_IS_EMPTY(qt))                          /* empty leaf node */
191 +    return(NULL);
192 +  if (QT_IS_TREE(qt) && !QT_IS_FLAG(qt))        /* not in our frustum */
193 +    return(NULL);
194 +                                        /* else look up node */
195 +  if ((le = lu_find(&qtr_tab,(char *)qt)) == NULL)
196 +    goto nomemory;
197 +  ra = (QTRAVG *)le->data;
198 +  if (QT_IS_TREE(qt) && (ra == NULL || lvl > 0))
199 +  {                                     /* compute children */
200 +    qtSubdivide_tri(v0,v1,v2,a,b,c);
201 +    rc[0] = qtRender_level(QT_NTH_CHILD(qt,0),v0,a,c,sm,lvl-1);
202 +    rc[1] = qtRender_level(QT_NTH_CHILD(qt,1),a,v1,b,sm,lvl-1);
203 +    rc[2] = qtRender_level(QT_NTH_CHILD(qt,2),c,b,v2,sm,lvl-1);
204 +    rc[3] = qtRender_level(QT_NTH_CHILD(qt,3),b,c,a,sm,lvl-1);
205 +  }
206 +  if (ra == NULL)
207 +  {                                     /* let's make some data! */
208 +    int rgbs[3];
209 +    double distsum;
210 +    int i;
211 +    register int n;
212 +                                        /* average our triangle vertices */
213 +    rgbs[0] = rgbs[1] = rgbs[2] = 0;
214 +    distsum = 0.; n = 0;
215 +    if(QT_IS_TREE(qt))
216 +    {                                   /* from subtree */
217 +      for (i = 4; i--; )
218 +        if ((ra = rc[i]) != NULL)
219 +        {
220 +          rgbs[0] += ra->rgb[0]; rgbs[1] += ra->rgb[1]; rgbs[2] += ra->rgb[2];
221 +          distsum += ra->dist; n++;
222 +        }
223 +    }
224 +    else
225 +    {                                   /* from triangle set */
226 +      OBJECT os[QT_MAX_SET+1];
227 +      int s0, s1, s2;
228 +
229 +      qtgetset(os,qt);
230 +      for (n = os[0]; n; n--)
231 +      {
232 +        qtTri_from_id(os[n],a,b,c,NULL,NULL,NULL,&s0,&s1,&s2);
233 +        distsum += SM_BG_SAMPLE(sm,s0) ? dev_zmax
234 +                                : sqrt(dist2(a,SM_VIEW_CENTER(sm)));
235 +        distsum += SM_BG_SAMPLE(sm,s1) ? dev_zmax
236 +                                : sqrt(dist2(b,SM_VIEW_CENTER(sm)));
237 +        distsum += SM_BG_SAMPLE(sm,s2) ? dev_zmax
238 +                                : sqrt(dist2(c,SM_VIEW_CENTER(sm)));
239 +        rgbs[0] += SM_NTH_RGB(sm,s0)[0] + SM_NTH_RGB(sm,s1)[0]
240 +                  + SM_NTH_RGB(sm,s2)[0];
241 +        rgbs[1] += SM_NTH_RGB(sm,s0)[1] + SM_NTH_RGB(sm,s1)[1]
242 +                  + SM_NTH_RGB(sm,s2)[1];
243 +        rgbs[2] += SM_NTH_RGB(sm,s0)[2] + SM_NTH_RGB(sm,s1)[2]
244 +                  + SM_NTH_RGB(sm,s2)[2];
245 +      }
246 +      n = 3*os[0];
247 +    }
248 +    if (!n)
249 +      return(NULL);
250 +    if ((ra = (QTRAVG *)malloc(sizeof(QTRAVG))) == NULL)
251 +      goto nomemory;
252 +    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;
256 +  }
257 +  if (lvl == 0 || (lvl > 0 && QT_IS_LEAF(qt)))
258 +  {                             /* render this node */
259 +                                        /* compute pseudo vertices */
260 +    VCOPY(a,v0); VCOPY(b,v1); VCOPY(c,v2);
261 +    normalize(a); normalize(b); normalize(c);
262 +    VSUM(a,SM_VIEW_CENTER(sm),a,ra->dist);
263 +    VSUM(b,SM_VIEW_CENTER(sm),b,ra->dist);
264 +    VSUM(c,SM_VIEW_CENTER(sm),c,ra->dist);
265 +                                        /* draw triangle */
266 +    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]);
270 +    glVertex3d(a[0],a[1],a[2]);
271 +  }
272 +  return(ra);
273 + nomemory:
274 +  error(SYSTEM, "out of memory in qtRender_level");
275 + }
276 +
277 +
278 + smRender_stree_level(sm,lvl)
279 + SM *sm;
280 + int lvl;
281 + {
282 +  QUADTREE root;
283 +  int i;
284 +  FVECT t0,t1,t2;
285 +
286 +  if (lvl < 1)
287 +    return;
288 +  glPushAttrib(GL_LIGHTING_BIT);
289 +  glShadeModel(GL_FLAT);
290 +  glBegin(GL_TRIANGLES);
291 +  for(i=0; i < 4; i++)
292 +  {
293 +    root = ST_NTH_ROOT(SM_LOCATOR(sm),i);
294 +    stNth_base_verts(SM_LOCATOR(sm),i,t0,t1,t2);
295 +    qtRender_level(root,t0,t1,t2,sm,lvl-1);
296 +  }
297 +  glEnd();
298 +  glPopAttrib();
299 + }
300 +
301 +
302 + smRender_stree(sm, qual)        /* render some quadtree triangles */
303 + SM *sm;
304 + int qual;
305 + {
306 +  int i, ntarget;
307 +  int lvlcnt[QT_MAX_LEVELS];
308 +
309 +  if (qual <= 0)
310 +    return;
311 +                                /* compute rendering target */
312 +  ntarget = 0;
313 +  SM_FOR_ALL_ACTIVE_TRIS(sm,i)
314 +    ntarget++;
315 +  ntarget = ntarget*qual/100;
316 +  if (!ntarget)
317 +    return;
318 +  for (i = QT_MAX_LEVELS; i--; )
319 +    lvlcnt[i] = 0;
320 +  stCount_level_leaves(lvlcnt, SM_LOCATOR(sm)->root);
321 +  for (ntarget -= lvlcnt[i=0]; i < QT_MAX_LEVELS-1; ntarget -= lvlcnt[++i])
322 +    if (ntarget < lvlcnt[i+1])
323 +      break;
324 +                                /* compute and render target level */
325 +  smRender_stree_level(sm,i);
326 + }
327 +
328 +
329 + smRender_tri(sm,i,vp,clr)
330 + SM *sm;
331   int i;
332   FVECT vp;
333 + int clr;
334   {
335    TRI *tri;
336    double ptr[3];
337    int j;
338  
339    tri = SM_NTH_TRI(sm,i);
340 <  SM_CLEAR_NTH_T_NEW(sm,i);
341 <  if(smNew_tri_cnt)
159 <     smNew_tri_cnt--;
340 >  if (clr) SM_CLEAR_NTH_T_NEW(sm,i);
341 >
342    /* NOTE:Triangles are defined clockwise:historical relative to spherical
343       tris: could change
344       */
# Line 174 | Line 356 | FVECT vp;
356    }
357   }
358  
359 < /* NOTE SEEMS BAD TO PENALIZE POLYGONS INFRONT BY LETTING
178 < ADJACENT TRIANGLES TO BG be BG
179 < */
180 < smRender_bg_tri(sm,i,vp,d)
359 > smRender_mixed_tri(sm,i,vp,clr)
360   SM *sm;
361   int i;
362   FVECT vp;
363 < double d;
363 > int clr;
364   {
365    TRI *tri;
366 <  FVECT p;
366 >  double p[3],d;
367    int j,ids[3],cnt;
368    int rgb[3];
369  
191
370    tri = SM_NTH_TRI(sm,i);
371 <  SM_CLEAR_NTH_T_NEW(sm,i);
372 <  if(smNew_tri_cnt)
195 <     smNew_tri_cnt--;
371 >  if (clr) SM_CLEAR_NTH_T_NEW(sm,i);
372 >
373    /* NOTE:Triangles are defined clockwise:historical relative to spherical
374       tris: could change
375       */
376    cnt = 0;
377 +  d = 0.0;
378    rgb[0] = rgb[1] = rgb[2] = 0;
379 <  for(j=0;j<3;j++)
379 >  for(j=0;j < 3;j++)
380    {
381 <    ids[j] = T_NTH_V(tri,j);
382 <    if(SM_BG_SAMPLE(sm,ids[j]))
383 <    {
384 <      rgb[0] += SM_NTH_RGB(sm,ids[j])[0];
385 <      rgb[1] += SM_NTH_RGB(sm,ids[j])[1];
386 <      rgb[2] += SM_NTH_RGB(sm,ids[j])[2];
387 <      cnt++;
388 <    }
381 >      ids[j] = T_NTH_V(tri,j);
382 >      if(!SM_BG_SAMPLE(sm,ids[j]))
383 >      {
384 >          rgb[0] += SM_NTH_RGB(sm,ids[j])[0];
385 >          rgb[1] += SM_NTH_RGB(sm,ids[j])[1];
386 >          rgb[2] += SM_NTH_RGB(sm,ids[j])[2];
387 >          cnt++;
388 >          d += DIST(vp,SM_NTH_WV(sm,ids[j]));
389 >      }
390    }
391 <  if(cnt)
391 >  if(cnt > 1)
392    {
393      rgb[0]/=cnt; rgb[1]/=cnt; rgb[2]/=cnt;
394 +    d /= (double)cnt;
395    }
396    for(j=2; j>= 0; j--)
397    {
398      if(SM_BG_SAMPLE(sm,ids[j]))
399 <      glColor3ub(SM_NTH_RGB(sm,ids[j])[0],SM_NTH_RGB(sm,ids[j])[1],
400 <                 SM_NTH_RGB(sm,ids[j])[2]);
399 >    {
400 >        glColor3ub(rgb[0],rgb[1],rgb[2]);
401 >        VSUB(p,SM_NTH_WV(sm,ids[j]),SM_VIEW_CENTER(sm));
402 >        p[0] *= d;
403 >        p[1] *= d;
404 >        p[2] *= d;
405 >        VADD(p,p,SM_VIEW_CENTER(sm));
406 >    }
407      else
222      glColor3ub(rgb[0],rgb[1],rgb[2]);
223    if(SM_BG_SAMPLE(sm,ids[j]))
224      VSUB(p,SM_NTH_WV(sm,ids[j]),SM_VIEW_CENTER(sm));
225    else
226      smDir(sm,p,ids[j]);
227    if(dev_zmin > 1.0)
408      {
409 <      p[0] *= d;
410 <      p[1] *= d;
411 <      p[2] *= d;
409 >        glColor3ub(SM_NTH_RGB(sm,ids[j])[0],SM_NTH_RGB(sm,ids[j])[1],
410 >                   SM_NTH_RGB(sm,ids[j])[2]);
411 >        VCOPY(p,SM_NTH_WV(sm,ids[j]));
412      }
233    VADD(p,p,vp);
413      glVertex3d(p[0],p[1],p[2]);
414 +   }
415 + }
416 +
417 + smRender_bg_tri(sm,i,vp,d,clr)
418 + SM *sm;
419 + int i;
420 + FVECT vp;
421 + double d;
422 + int clr;
423 + {
424 +  double p[3];
425 +  int j,id;
426 +  TRI *tri;
427 +  
428 +  tri = SM_NTH_TRI(sm,i);
429 +  if (clr) SM_CLEAR_NTH_T_NEW(sm,i);
430 +
431 +  /* NOTE:Triangles are defined clockwise:historical relative to spherical
432 +     tris: could change
433 +     */
434 +  for(j=2; j>= 0; j--)
435 +  {
436 +      id = T_NTH_V(tri,j);
437 +      glColor3ub(SM_NTH_RGB(sm,id)[0],SM_NTH_RGB(sm,id)[1],
438 +                 SM_NTH_RGB(sm,id)[2]);
439 +      VSUB(p,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm));
440 +      if(dev_zmin >= 0.99)
441 +       {
442 +           p[0] *= d;
443 +           p[1] *= d;
444 +           p[2] *= d;
445 +       }
446 +      VADD(p,p,vp);
447 +      glVertex3d(p[0],p[1],p[2]);
448    }
449   }
450  
451 < smRender_mesh(sm,vp)
451 > smRender_mesh(sm,vp,clr)
452   SM *sm;
453   FVECT vp;
454 + int clr;
455   {
456    int i;
457    TRI *tri;
# Line 252 | Line 466 | FVECT vp;
466    glDisable(GL_DEPTH_TEST);
467    glBegin(GL_TRIANGLES);
468    SM_FOR_ALL_ACTIVE_BG_TRIS(sm,i)
469 <    smRender_bg_tri(sm,i,vp,d);
469 >     smRender_bg_tri(sm,i,vp,d,clr);
470    glEnd();
471    
472    glEnable(GL_DEPTH_TEST);
473    glBegin(GL_TRIANGLES);
474    SM_FOR_ALL_ACTIVE_FG_TRIS(sm,i)
475 <    smRender_tri(sm,i,vp);
475 >  {
476 >      if(!SM_MIXED_TRI(sm,i))
477 >        smRender_tri(sm,i,vp,clr);
478 >     else
479 >        smRender_mixed_tri(sm,i,vp,clr);
480 >  }
481    glEnd();
482  
483    glPopAttrib();
484   }
485 +
486   smRender_tri_edges(sm,i)
487   SM *sm;
488   int i;
# Line 301 | Line 521 | compare_tri_depths(T_DEPTH *td1,T_DEPTH *td2)
521    return(0);
522   }
523  
524 < smDepth_sort_tris(sm,vp,td)
524 > LIST
525 > *smDepth_sort_tris(sm,vp,td)
526   SM *sm;
527 < VIEW *vp;
527 > FVECT vp;
528   T_DEPTH *td;
529   {
530 <  int i,j,t_id;
530 >  int i,j,t_id,v;
531    TRI *tri;
532 <  double d[3];
532 >  double d,min_d;
533 >  LIST *tlist=NULL;
534  
535    i = 0;
536    SM_FOR_ALL_NEW_TRIS(sm,t_id)
537    {
538 <    if(i >= smNew_tri_cnt)
538 >    if(SM_BG_TRI(sm,t_id))
539      {
540 < #ifdef DEBUG
541 <        eputs("smDepth_sort_tris(): more new tris then counted\n");
320 < #endif
321 <        break;
540 >        tlist = push_data(tlist,t_id);
541 >        continue;
542      }
543      tri = SM_NTH_TRI(sm,t_id);
544      td[i].tri = t_id;
545 +    min_d = -1;
546      for(j=0;j < 3;j++)
547 <      d[j] = DIST(vp->vp,SM_T_NTH_WV(sm,tri,j));
548 <    td[i].depth = MIN_VEC3(d);
547 >    {
548 >        v = T_NTH_V(tri,j);
549 >        if(!SM_BG_SAMPLE(sm,v))
550 >        {
551 >            d = DIST(vp,SM_NTH_WV(sm,v));
552 >            if(min_d == -1 || d < min_d)
553 >               min_d = d;
554 >        }
555 >    }
556 >    td[i].depth = min_d;
557      i++;
558    }
559 <  qsort((void *)td,smNew_tri_cnt,sizeof(T_DEPTH),compare_tri_depths);
559 >  td[i].tri = -1;
560 >  if(i)
561 >     qsort((void *)td,i,sizeof(T_DEPTH),compare_tri_depths);
562 >  return(tlist);
563   }
564  
565  
566 < smUpdate_Rendered_mesh(sm,vp)
566 > smUpdate_Rendered_mesh(sm,vp,clr)
567   SM *sm;
568 < VIEW *vp;
568 > FVECT vp;
569 > int clr;
570   {
571    static T_DEPTH *td= NULL;
572    static int tsize = 0;
573    int i;
574    GLint depth_test;
575    double d;
576 <
576 >  LIST *bglist;
577    /* For all of the NEW triangles (since last update): assume
578       ACTIVE. Go through and sort on depth value (from vp). Turn
579       Depth Buffer test off and render back-front
# Line 349 | Line 582 | VIEW *vp;
582    if(smNew_tri_cnt > tsize)
583    {
584      if(td)
585 <      free(td);
585 >      free((char *)td);
586      td = (T_DEPTH *)malloc(smNew_tri_cnt*sizeof(T_DEPTH));
587      tsize = smNew_tri_cnt;
588    }
# Line 357 | Line 590 | VIEW *vp;
590    {
591      error(SYSTEM,"smUpdate_Rendered_mesh:Cannot allocate memory\n");
592    }
593 <  smDepth_sort_tris(sm,vp,td);
593 >  bglist = smDepth_sort_tris(sm,vp,td);
594  
595 <  /* Turn Depth Test off */
595 >  /* Turn Depth Test off -- using Painter's algorithm */
596    glPushAttrib(GL_DEPTH_BUFFER_BIT);
597 <  glDepthFunc(GL_ALWAYS);          /* Turn off Depth-painter's algorithm */
365 <
597 >  glDisable(GL_DEPTH_TEST);
598    d = (dev_zmin+dev_zmax)/2.0;
599    /* Now render back-to front */
600    /* First render bg triangles */
369  glDisable(GL_DEPTH_TEST);
601    glBegin(GL_TRIANGLES);
602 <  for(i=0; i< smNew_tri_cnt; i++)
603 <    if(SM_BG_TRI(sm,td[i].tri))
373 <      smRender_bg_tri(sm,td[i].tri,vp,d);
602 >  while(bglist)
603 >     smRender_bg_tri(sm,pop_list(&bglist),vp,d,clr);
604    glEnd();
605  
606    glEnable(GL_DEPTH_TEST);
607    glBegin(GL_TRIANGLES);
608 <  for(i=0; i< smNew_tri_cnt; i++)
609 <    if(!SM_BG_TRI(sm,td[i].tri))
610 <      smRender_tri(sm,td[i].tri,vp);
608 >  i=0;
609 >  while(td[i].tri != -1)
610 >     if(!SM_MIXED_TRI(sm,td[i].tri))
611 >        smRender_tri(sm,td[i++].tri,vp,clr);
612 >     else
613 >        smRender_mixed_tri(sm,td[i++].tri,vp,clr);
614    glEnd();
615  
616    /* Restore Depth Test */
# Line 385 | Line 618 | VIEW *vp;
618   }
619  
620   /*
621 < * smUpdate(vp, qua)    : update OpenGL output geometry for view vp
622 < * VIEW *vp;            : desired view
621 > * smUpdate(view, qua)  : update OpenGL output geometry for view vp
622 > * VIEW *view;          : desired view
623   * int  qual;           : quality level (percentage on linear time scale)
624   *
625   * Draw new geometric representation using OpenGL calls.  Assume that the
626   * view has already been set up and the correct frame buffer has been
627   * selected for drawing.  The quality level is on a linear scale, where 100%
628   * is full (final) quality.  It is not necessary to redraw geometry that has
629 < * been output since the last call to smClean().
629 > * been output since the last call to smClean().  (The last view drawn will
630 > * be view==&odev.v each time.)
631   */
632 < smUpdate(vp,qual)
633 <   VIEW *vp;
632 > smUpdate(view,qual)
633 >   VIEW *view;
634     int qual;
635   {
636    double d;
637 +  int last_update;
638    int t;
639 < #ifdef TEST_DRIVER  
405 <  Current_View = (*vp);
406 < #endif
639 >
640    /* If view has moved beyond epsilon from canonical: must rebuild -
641       epsilon is calculated as running avg of distance of sample points
642 <     from canonical view: m = 1/(SUM1/r): some fraction of this
642 >     from canonical view: m = 1/(AVG(1/r)): some fraction of this
643     */
644 <  d = DIST(vp->vp,SM_VIEW_CENTER(smMesh));
644 >  d = DIST(view->vp,SM_VIEW_CENTER(smMesh));
645    if(qual >= 100 && d > SM_ALLOWED_VIEW_CHANGE(smMesh))
646    {
414      smNew_tri_cnt = 0;
647        /* Re-build the mesh */
648 <      smRebuild_mesh(smMesh,vp);
648 > #ifdef TEST_DRIVER
649 >    odev.v = *view;
650 > #endif    
651 >      smRebuild_mesh(smMesh,view->vp);
652    }
653 <  /* Check if should draw ALL triangles in current frustum */
654 <  if(smClean_notify || (smNew_tri_cnt > SM_NUM_TRIS(smMesh)*SM_INC_PERCENT))
653 >  /* This is our final update iff qual==100 and view==&odev.v */
654 >  last_update = qual>=100 && view==&(odev.v);
655 >  /* Check if we should draw ALL triangles in current frustum */
656 >  if(smClean_notify || smNew_tri_cnt > SM_NUM_TRIS(smMesh)*SM_INC_PERCENT)
657    {
658   #ifdef TEST_DRIVER
659      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
660   #else
661 <    tmClearHisto();
662 <    tmAddHisto(SM_BRT(smMesh),SM_NUM_SAMP(smMesh),1);
663 <    if(tmComputeMapping(0.,0.,0.) != TM_E_OK)
664 <       return;
665 <    if(tmMapPixels(SM_RGB(smMesh),SM_BRT(smMesh),SM_CHR(smMesh),
666 <                   SM_NUM_SAMP(smMesh))!=TM_E_OK)
667 <       return;
661 >    if (SM_TONE_MAP(smMesh) < SM_NUM_SAMP(smMesh))
662 >    {
663 >       tmClearHisto();
664 >       tmAddHisto(SM_BRT(smMesh),SM_NUM_SAMP(smMesh),1);
665 >       if(tmComputeMapping(0.,0.,0.) != TM_E_OK ||
666 >                   tmMapPixels(SM_RGB(smMesh),SM_BRT(smMesh),SM_CHR(smMesh),
667 >                                SM_NUM_SAMP(smMesh)) != TM_E_OK)
668 >            return;
669 >    }
670   #endif
671 <    smRender_mesh(smMesh,vp->vp);
672 <    smClean_notify = FALSE;
671 >    mark_tris_in_frustum(view);
672 >    if (qual <= 75)
673 >        smRender_stree(smMesh,qual);
674 >    else
675 >        smRender_mesh(smMesh,view->vp,last_update);
676   #ifdef TEST_DRIVER
677      glFlush();
678      glutSwapBuffers();
# Line 456 | Line 698 | smUpdate(vp,qual)
698                     SM_NTH_CHR(smMesh,t), SM_NUM_SAMP(smMesh)-t) != TM_E_OK)
699            return;
700   #endif    
701 <    smUpdate_Rendered_mesh(smMesh,vp);
701 >    smUpdate_Rendered_mesh(smMesh,view->vp,last_update);
702      
703   #ifdef TEST_DRIVER
704      glDrawBuffer(GL_BACK);
705   #endif
706    }
707    SM_TONE_MAP(smMesh) = SM_NUM_SAMP(smMesh);
708 < }
708 >  if (last_update)
709 >  {
710 >    smClean_notify = FALSE;
711 >    smNew_tri_cnt = 0;
712 >    lu_done(&qtr_tab);
713 >  }
714  
715 <    /* LATER:If quality < 100 should draw approximation because it indicates
469 <       the user is moving
470 <       */
471 <
472 <
715 > }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines