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.14 by gwlarson, Fri Mar 5 16:33:32 1999 UTC vs.
Revision 3.18 by schorsch, Mon Jul 21 22:30:18 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ SGI";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * sm_ogl.c
6   *
7   *  Rendering routines for triangle mesh representation utilizing OpenGL
8 < */
8 > *
9 > * smClean(tmflag)      : display has been wiped clean
10 > *     int tmflag;
11 > * Called after display has been effectively cleared, meaning that all
12 > * geometry must be resent down the pipeline in the next call to smUpdate().
13 > * If tmflag is set, tone-mapping should be performed
14 > *
15 > * smUpdate(vp, qua)    : update OpenGL output geometry for view vp
16 > * VIEW *vp;            : desired view
17 > * int  qua;            : quality level (percentage on linear time scale)
18 > *
19 > * Draw new geometric representation using OpenGL calls.  Assume that the
20 > * view has already been set up and the correct frame buffer has been
21 > * selected for drawing.  The quality level is on a linear scale, where 100%
22 > * is full (final) quality.  It is not necessary to redraw geometry that has
23 > * been output since the last call to smClean().  (The last view drawn will
24 > * be vp==&odev.v each time.)
25 > */
26   #include "standard.h"
27  
28   #include <GL/gl.h>
# Line 16 | Line 30 | static char SCCSid[] = "$SunId$ SGI";
30   #include "sm_flag.h"
31   #include "sm_list.h"
32   #include "sm_geom.h"
19 #include "sm_qtree.h"
20 #include "sm_stree.h"
33   #include "sm.h"
34  
35 < static int smClean_notify = TRUE;    /*If true:Do full redraw on next update*/
36 < static int smCompute_mapping = TRUE;/*If true:re-tonemap on next update */
37 < static int smIncremental = FALSE;    /*If true: there has been incremental
38 <                                       rendering since last full draw */
35 > int smClean_notify = TRUE;           /*If TRUE:Do full redraw on next update*/
36 > static int smCompute_mapping = TRUE; /*If TRUE:re-tonemap on next update */
37 > static int smIncremental = FALSE;    /*If TRUE: there has been incremental
38 >                                        rendering since last full draw */
39 > #define NEW_TRI_CNT 1000             /* Default number of tris to allocate
40 >                                        space to sort for incremental update*/
41   #define SM_RENDER_FG 0               /* Render foreground tris only*/
42   #define SM_RENDER_BG 1               /* Render background tris only */
43 < #define SM_RENDER_MIXED 4               /* Render mixed tris only */
44 < #define SM_RENDER_CULL 8          /* Perform view frustum culling */
45 < #define BASE 1
32 < #define DIR 2
43 > #define SM_RENDER_CULL 8             /* Perform view frustum culling */
44 > #define BASE 1                       /* Indicates base triangle */
45 > #define DIR 2                        /* Indicates triangle w/directional pts*/
46   /* FOR DISPLAY LIST RENDERING: **********************************************/
47 < #define  SM_DL_LEVELS 2 /* # of levels down to create display lists */
48 < #define SM_DL_LISTS   42  /* # of qtree nodes in tree at above level:
49 <                           should be 2*(4^(SM_DL_LEVELS+1)-1)/(4-1) */
47 > #define  SM_DL_LEVELS 2     /* # of levels down to create display lists */
48 > #define SM_DL_LISTS   42    /* # of qtree nodes in tree at above level:
49 >                               should be 2*(4^(SM_DL_LEVELS+1)-1)/(4-1) */
50   static GLuint Display_lists[SM_DL_LISTS][2] = {0};
51   /****************************************************************************/
52  
# Line 59 | Line 72 | typedef struct _T_DEPTH {
72   }T_DEPTH;
73   /**********************************************************************/
74  
62
75   /*
76    * smClean(tmflag)     : display has been wiped clean
77    *     int tmflag;
# Line 71 | Line 83 | smClean(tmflag)
83     int tmflag;
84   {
85      smClean_notify = TRUE;
86 <    if(tmflag)
75 <       smCompute_mapping = TRUE;
86 >    smCompute_mapping = tmflag;
87   }
88  
89   int
90   qtCache_init(nel)               /* initialize for at least nel elements */
91   int     nel;
92   {
93 <        static int  hsiztab[] = {
94 <                8191, 16381, 32749, 65521, 131071, 262139, 524287, 1048573, 0
95 <        };
96 <        register int  i;
93 >    static int  hsiztab[] = {
94 >        8191, 16381, 32749, 65521, 131071, 262139, 524287, 1048573, 0
95 >    };
96 >    register int  i;
97  
98 <        if (nel <= 0) {                 /* call to free table */
99 <                if (qt_hsiz) {
100 <                        free((char *)qt_htbl);
101 <                        qt_htbl = NULL;
102 <                        qt_hsiz = 0;
92 <                }
93 <                return(0);
98 >    if (nel <= 0) {                     /* call to free table */
99 >        if (qt_hsiz) {
100 >            free((void *)qt_htbl);
101 >            qt_htbl = NULL;
102 >            qt_hsiz = 0;
103          }
104 <        nel += nel>>1;                  /* 66% occupancy */
105 <        for (i = 0; hsiztab[i]; i++)
106 <                if (hsiztab[i] > nel)
107 <                        break;
108 <        if (!(qt_hsiz = hsiztab[i]))
109 <                qt_hsiz = nel*2 + 1;            /* not always prime */
110 <        qt_htbl = (QT_LUENT *)calloc(qt_hsiz, sizeof(QT_LUENT));
111 <        if (qt_htbl == NULL)
112 <                qt_hsiz = 0;
113 <        for (i = qt_hsiz; i--; )
114 <                qt_htbl[i].qt = EMPTY;
115 <        return(qt_hsiz);
104 >        return(0);
105 >    }
106 >    nel += nel>>1;                      /* 66% occupancy */
107 >    for (i = 0; hsiztab[i]; i++)
108 >       if (hsiztab[i] > nel)
109 >          break;
110 >    if (!(qt_hsiz = hsiztab[i]))
111 >       qt_hsiz = nel*2 + 1;             /* not always prime */
112 >    qt_htbl = (QT_LUENT *)calloc(qt_hsiz, sizeof(QT_LUENT));
113 >    if (qt_htbl == NULL)
114 >       qt_hsiz = 0;
115 >    for (i = qt_hsiz; i--; )
116 >       qt_htbl[i].qt = EMPTY;
117 >    return(qt_hsiz);
118   }
119  
120   QT_LUENT *
121   qtCache_find(qt)                /* find a quadtree table entry */
122   QUADTREE qt;
123   {
124 <        int     i, n;
125 <        register int    ndx;
126 <        register QT_LUENT       *le;
124 >    int i, n;
125 >    register int        ndx;
126 >    register QT_LUENT   *le;
127  
128 <        if (qt_hsiz == 0 && !qtCache_init(1))
129 <                return(NULL);
128 >    if (qt_hsiz == 0 && !qtCache_init(1))
129 >       return(NULL);
130   tryagain:                               /* hash table lookup */
131 <        ndx = (unsigned long)qt % qt_hsiz;
132 <        for (i = 0, n = 1; i < qt_hsiz; i++, n += 2) {
133 <                le = &qt_htbl[ndx];
134 <                if (QT_IS_EMPTY(le->qt) || le->qt == qt)
135 <                        return(le);
136 <                if ((ndx += n) >= qt_hsiz)      /* this happens rarely */
137 <                        ndx = ndx % qt_hsiz;
138 <        }
139 <                                        /* table is full, reallocate */
140 <        le = qt_htbl;
141 <        ndx = qt_hsiz;
142 <        if (!qtCache_init(ndx+1)) {     /* no more memory! */
143 <                qt_htbl = le;
144 <                qt_hsiz = ndx;
145 <                return(NULL);
146 <        }
131 >    ndx = (unsigned long)qt % qt_hsiz;
132 >    for (i = 0, n = 1; i < qt_hsiz; i++, n += 2) {
133 >        le = &qt_htbl[ndx];
134 >        if (QT_IS_EMPTY(le->qt) || le->qt == qt)
135 >           return(le);
136 >        if ((ndx += n) >= qt_hsiz)      /* this happens rarely */
137 >           ndx = ndx % qt_hsiz;
138 >    }
139 >    /* table is full, reallocate */
140 >    le = qt_htbl;
141 >    ndx = qt_hsiz;
142 >    if (!qtCache_init(ndx+1)) { /* no more memory! */
143 >        qt_htbl = le;
144 >        qt_hsiz = ndx;
145 >        return(NULL);
146 >    }
147                                          /* copy old table to new and free */
148 <        while (ndx--)
149 <                if (!QT_IS_EMPTY(le[ndx].qt))
150 <                        copystruct(qtCache_find(le[ndx].qt), &le[ndx]);
151 <        free((char *)le);
152 <        goto tryagain;                  /* should happen only once! */
148 >    while (ndx--)
149 >       if (!QT_IS_EMPTY(le[ndx].qt))
150 >          *qtCache_find(le[ndx].qt) = le[ndx];
151 >    free((void *)le);
152 >    goto tryagain;                      /* should happen only once! */
153   }
154  
155   stCount_level_leaves(lcnt, qt)  /* count quadtree leaf nodes at each level */
# Line 160 | Line 171 | register QUADTREE qt;
171        lcnt[0]++;
172   }
173  
163
174   QTRAVG *
175   qtRender_level(qt,v0,v1,v2,sm,lvl)
176   QUADTREE qt;
# Line 209 | Line 219 | int lvl;
219      }
220      else
221      {                                   /* from triangle set */
222 <      OBJECT *os;
223 <      int s0, s1, s2;
224 <      
222 >      S_ID *os;
223 >      S_ID s0, s1, s2,s_id;
224 >      int t_id;
225 >      TRI *tri,*t;
226 >
227        os = qtqueryset(qt);
228        for (i = os[0]; i; i--)
229        {
230 <        if(SM_IS_NTH_T_BASE(sm,os[i]))
231 <           continue;
232 <        tri = SM_NTH_TRI(sm,os[i]);
233 <        if(!T_IS_VALID(tri))
234 <          continue;
235 <        n++;
236 <        s0 = T_NTH_V(tri,0);
237 <        s1 = T_NTH_V(tri,1);
238 <        s2 = T_NTH_V(tri,2);
239 <        VCOPY(a,SM_NTH_WV(sm,s0));
240 <        VCOPY(b,SM_NTH_WV(sm,s1));
241 <        VCOPY(c,SM_NTH_WV(sm,s2));            
242 <        distsum += SM_BG_SAMPLE(sm,s0) ? dev_zmax
230 >        s_id = os[i];
231 >        t_id = SM_NTH_VERT(smMesh,s_id);
232 >        tri = t = SM_NTH_TRI(smMesh,t_id);
233 >        do
234 >        {
235 >          if(!SM_IS_NTH_T_BASE(sm,t_id))
236 >          {
237 >            n++;
238 >            s0 = T_NTH_V(t,0);
239 >            s1 = T_NTH_V(t,1);
240 >            s2 = T_NTH_V(t,2);
241 >            VCOPY(a,SM_NTH_WV(sm,s0));
242 >            VCOPY(b,SM_NTH_WV(sm,s1));
243 >            VCOPY(c,SM_NTH_WV(sm,s2));        
244 >            distsum += SM_BG_SAMPLE(sm,s0) ? dev_zmax
245                                  : sqrt(dist2(a,SM_VIEW_CENTER(sm)));
246 <        distsum += SM_BG_SAMPLE(sm,s1) ? dev_zmax
247 <                                : sqrt(dist2(b,SM_VIEW_CENTER(sm)));
248 <        distsum += SM_BG_SAMPLE(sm,s2) ? dev_zmax
246 >            distsum += SM_BG_SAMPLE(sm,s1) ? dev_zmax
247 >                                : sqrt(dist2(b,SM_VIEW_CENTER(sm)));
248 >            distsum += SM_BG_SAMPLE(sm,s2) ? dev_zmax
249                                  : sqrt(dist2(c,SM_VIEW_CENTER(sm)));
250 <        rgbs[0] += SM_NTH_RGB(sm,s0)[0] + SM_NTH_RGB(sm,s1)[0]
251 <                  + SM_NTH_RGB(sm,s2)[0];
252 <        rgbs[1] += SM_NTH_RGB(sm,s0)[1] + SM_NTH_RGB(sm,s1)[1]
253 <                  + SM_NTH_RGB(sm,s2)[1];
254 <        rgbs[2] += SM_NTH_RGB(sm,s0)[2] + SM_NTH_RGB(sm,s1)[2]
255 <                  + SM_NTH_RGB(sm,s2)[2];
250 >            rgbs[0] += SM_NTH_RGB(sm,s0)[0] + SM_NTH_RGB(sm,s1)[0]
251 >              + SM_NTH_RGB(sm,s2)[0];
252 >            rgbs[1] += SM_NTH_RGB(sm,s0)[1] + SM_NTH_RGB(sm,s1)[1]
253 >              + SM_NTH_RGB(sm,s2)[1];
254 >            rgbs[2] += SM_NTH_RGB(sm,s0)[2] + SM_NTH_RGB(sm,s1)[2]
255 >              + SM_NTH_RGB(sm,s2)[2];
256 >          }
257 >
258 >          t_id = smTri_next_ccw_nbr(smMesh,t,s_id);
259 >          t = SM_NTH_TRI(smMesh,t_id);
260 >
261 >        }while(t != tri);
262        }
263        n *= 3;
264      }
# Line 275 | Line 295 | int lvl;
295    int i;
296    FVECT t0,t1,t2;
297    STREE *st;
278
298    
299    if (lvl < 0)
300      return;
# Line 314 | Line 333 | VIEW *view;
333    int i, n,ntarget;
334    int lvlcnt[QT_MAX_LEVELS];
335    STREE *st;
336 <  int4 *active_flag;
336 >  int32 *active_flag;
337  
338    if (qual <= 0)
339      return;
# Line 346 | Line 365 | VIEW *view;
365    smRender_approx_stree_level(sm,i);
366   }
367  
349 #define render_tri(v0,v1,v2,rgb0,rgb1,rgb2) \
350  {glColor3ub(rgb0[0],rgb0[1],rgb0[2]);  glVertex3fv(v0); \
351  glColor3ub(rgb1[0],rgb1[1],rgb1[2]);  glVertex3fv(v1); \
352  glColor3ub(rgb2[0],rgb2[1],rgb2[2]);  glVertex3fv(v2);}
368  
369 + #define GLVERTEX3V(v) glVertex3fv(v)
370  
355 render_bg_tri(v0,v1,v2,rgb0,rgb1,rgb2,vp,vc,d)
356 float v0[3],v1[3],v2[3];
357 BYTE rgb0[3],rgb1[3],rgb2[3];
358 FVECT vp,vc;
359 double d;
360 {
361   double p[3];
362  
363   glColor3ub(rgb0[0],rgb0[1],rgb0[2]);
364   VSUB(p,v0,vc);
365   if(dev_zmin >= 0.99)
366   {
367     p[0] *= d;
368     p[1] *= d;
369     p[2] *= d;
370   }
371   VADD(p,p,vp);
372   glVertex3dv(p);
373
374   glColor3ub(rgb1[0],rgb1[1],rgb1[2]);
375   VSUB(p,v1,vc);
376   if(dev_zmin >= 0.99)
377   {
378     p[0] *= d;
379     p[1] *= d;
380     p[2] *= d;
381   }
382   VADD(p,p,vp);
383   glVertex3dv(p);
384
385
386   glColor3ub(rgb2[0],rgb2[1],rgb2[2]);
387   VSUB(p,v2,vc);
388   if(dev_zmin >= 0.99)
389   {
390     p[0] *= d;
391     p[1] *= d;
392     p[2] *= d;
393    VADD(p,p,vp);
394    glVertex3dv(p);
395   }
396 }
371  
372 + #define render_tri(v0,v1,v2,rgb0,rgb1,rgb2) \
373 +  {glColor3ub(rgb0[0],rgb0[1],rgb0[2]); GLVERTEX3V(v0); \
374 +  glColor3ub(rgb1[0],rgb1[1],rgb1[2]);  GLVERTEX3V(v1); \
375 +  glColor3ub(rgb2[0],rgb2[1],rgb2[2]);  GLVERTEX3V(v2);}
376  
377   /*
378   * render_mixed_tri(v0,v1,v2,rgb0,rgb1,rgb2,b0,b1,b2)
379 < *  float v0[3],v1[3],v2[3];      : triangle vertex coordinates
379 > *  SFLOAT v0[3],v1[3],v2[3];      : triangle vertex coordinates
380   *  BYTE rgb0[3],rgb1[3],rgb2[3]; : vertex RGBs
381   *  int b0,b1,b2;                 : background or base vertex flag
382   *  
383 < *  render foreground or base vertex color as average of the background
384 < *  vertex RGBs.
383 > *  For triangles with one or more base or directional vertices.
384 > *  render base vertex color as average of the background  and foreground
385 > *  vertex RGBs. The coordinates for a fg vertex are calculated by
386 > *  subtracting off the current view,normalizing, then scaling to fit
387 > * into the current frustum.
388   */
389   render_mixed_tri(v0,v1,v2,rgb0,rgb1,rgb2,vp,vc,bg0,bg1,bg2)
390 < float v0[3],v1[3],v2[3];
390 > SFLOAT v0[3],v1[3],v2[3];
391   BYTE rgb0[3],rgb1[3],rgb2[3];
392   FVECT vp,vc;
393   int bg0,bg1,bg2;
394   {
395    double d,p[3];
396 <  int j,cnt,rgb[3],base;
396 >  int j,cnt,rgb[3];
397    
398 <  base = bg0==BASE || bg1==BASE || bg2==BASE;
399 <
400 <  if(base)
398 >  /* Average color from bg vertices */
399 >  cnt = 0;
400 >  if(bg0 == BASE || bg1==BASE || bg2 == BASE)
401    {
421    cnt = 0;
402      rgb[0] = rgb[1] = rgb[2] = 0;
403      if(bg0 != BASE)
404 <    {
405 <      IADDV3(rgb,rgb0);
406 <      cnt++;
407 <    }
408 <    if(bg1 !=BASE)
409 <    {
410 <      IADDV3(rgb,rgb1);
411 <      cnt++;
412 <    }
404 >      {
405 >        IADDV3(rgb,rgb0);
406 >        cnt++;
407 >      }
408 >    if(bg1 != BASE)
409 >      {
410 >        IADDV3(rgb,rgb1);
411 >        cnt++;
412 >      }
413      if(bg2 != BASE)
414 <    {
415 <      IADDV3(rgb,rgb2);
416 <      cnt++;
417 <    }
414 >      {
415 >        IADDV3(rgb,rgb2);
416 >        cnt++;
417 >      }
418      IDIVV3(rgb,cnt);
419    }
420 <
421 <  if(bg0== BASE)
442 <    glColor3ub(rgb[0],rgb[1],rgb[2]);
420 >  if(bg0 == BASE)
421 >    glColor3i(rgb[0],rgb[1],rgb[2]);
422    else
423      glColor3ub(rgb0[0],rgb0[1],rgb0[2]);
424  
# Line 451 | Line 430 | int bg0,bg1,bg2;
430      glVertex3dv(p);
431    }
432    else
433 <    glVertex3fv(v0);
433 >    GLVERTEX3V(v0);
434  
435 <  if(bg1== BASE)
436 <    glColor3ub(rgb[0],rgb[1],rgb[2]);
435 >  if(bg1 == BASE)
436 >    glColor3i(rgb[0],rgb[1],rgb[2]);
437    else
438      glColor3ub(rgb1[0],rgb1[1],rgb1[2]);
439  
# Line 466 | Line 445 | int bg0,bg1,bg2;
445      glVertex3dv(p);
446    }
447    else
448 <    glVertex3fv(v1);
448 >    GLVERTEX3V(v1);
449  
450 <  if(bg2== BASE)
451 <    glColor3ub(rgb[0],rgb[1],rgb[2]);
450 >  if(bg2 == BASE)
451 >    glColor3i(rgb[0],rgb[1],rgb[2]);
452    else
453      glColor3ub(rgb2[0],rgb2[1],rgb2[2]);
454  
# Line 481 | Line 460 | int bg0,bg1,bg2;
460      glVertex3dv(p);
461    }
462    else
463 <    glVertex3fv(v2);
463 >    GLVERTEX3V(v2);
464   }
465  
466   /*
467   * smRender_bg_tris(sm,vp,t_flag,bg_flag,wp,rgb)
468   * SM *sm;                         : mesh
469   * FVECT vp;                       : current viewpoint
470 < * int4  *t_flag,*bg_flag;         : triangle flags: t_flag is generic,
470 > * int32  *t_flag,*bg_flag;         : triangle flags: t_flag is generic,
471   *                                   and bg_flag indicates if background tri;
472 < * float (*wp)[3];BYTE  (*rgb)[3]; : arrays of sample points and RGB colors
472 > * SFLOAT (*wp)[3];BYTE  (*rgb)[3]; : arrays of sample points and RGB colors
473   *
474 < * Sequentially gos through triangle list and renders all valid tris who
474 > * Sequentially traverses triangle list and renders all valid tris who
475   * have t_flag set, and bg_flag set.
476   */
477  
478   smRender_bg_tris(sm,vp,t_flag,bg_flag,wp,rgb)
479   SM *sm;
480   FVECT vp;
481 < int4 *t_flag,*bg_flag;
482 < float (*wp)[3];
481 > int32 *t_flag,*bg_flag;
482 > SFLOAT (*wp)[3];
483   BYTE  (*rgb)[3];
484   {
485    double d;
# Line 542 | Line 521 | BYTE  (*rgb)[3];
521                  rgb[v2_id])
522             else
523               render_mixed_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],
524 <                      rgb[v1_id],rgb[v2_id],vp,SM_VIEW_CENTER(sm),bg0,bg1,bg2);
524 >              rgb[v1_id],rgb[v2_id],vp,SM_VIEW_CENTER(sm),bg0,bg1,bg2);
525           }
526    glEnd();
527  
# Line 550 | Line 529 | BYTE  (*rgb)[3];
529  
530   }
531   /*
532 + * smRender_new_bg_tris(sm,vp,new_flag,active_flag,bg_flag,wp,rgb)
533 + * SM *sm;                         : mesh
534 + * FVECT vp;                       : current viewpoint
535 + * int32  *new_flag,*active,*bg_flag; : triangle flags: idicates if tri is,
536 + *                                   new,active,bg_flag
537 + * SFLOAT (*wp)[3];BYTE  (*rgb)[3]; : arrays of sample points and RGB colors
538 + *
539 + * Sequentially traverses triangle list and renders all valid tris who
540 + * have new_flag set and active_flag and bg_flag set.
541 + */
542 + smRender_new_bg_tris(sm,vp,new_flag,active_flag,bg_flag,wp,rgb)
543 + SM *sm;
544 + FVECT vp;
545 + int32 *new_flag,*active_flag,*bg_flag;
546 + SFLOAT (*wp)[3];
547 + BYTE  (*rgb)[3];
548 + {
549 +  double d;
550 +  int v0_id,v1_id,v2_id;
551 +  int i,n,bg0,bg1,bg2;
552 +  TRI *tri;
553 +
554 +  glMatrixMode(GL_MODELVIEW);
555 +
556 +  glPushMatrix();
557 +  glTranslated(vp[0],vp[1],vp[2]);
558 +  /* The points are a distance of 1 away from the origin: if necessary scale
559 +     so that they fit in frustum and are therefore not clipped away
560 +   */
561 +  if(dev_zmin >= 0.99)
562 +  {
563 +    d = (dev_zmin+dev_zmax)/2.0;
564 +    glScaled(d,d,d);
565 +  }
566 +  /* move relative to the new view */
567 +  /* move points to unit sphere at origin */
568 +  glTranslated(-SM_VIEW_CENTER(sm)[0],-SM_VIEW_CENTER(sm)[1],
569 +               -SM_VIEW_CENTER(sm)[2]);
570 +  glBegin(GL_TRIANGLES);
571 +  for(n=((SM_NUM_TRI(sm)+31)>>5) +1; --n;)
572 +    if(new_flag[n] & active_flag[n] & bg_flag[n])
573 +      for(i=0; i < 32; i++)
574 +        if(new_flag[n] & active_flag[n] & bg_flag[n] & (1L << i))
575 +         {
576 +           tri = SM_NTH_TRI(sm,(n<<5)+i);
577 +           v0_id = T_NTH_V(tri,0);
578 +           v1_id = T_NTH_V(tri,1);
579 +           v2_id = T_NTH_V(tri,2);
580 +           bg0 = SM_DIR_ID(sm,v0_id)?DIR:SM_BASE_ID(sm,v0_id)?BASE:0;
581 +           bg1 = SM_DIR_ID(sm,v1_id)?DIR:SM_BASE_ID(sm,v1_id)?BASE:0;
582 +           bg2 = SM_DIR_ID(sm,v2_id)?DIR:SM_BASE_ID(sm,v2_id)?BASE:0;
583 +           if(bg0==DIR && bg1==DIR && bg2==DIR)
584 +             render_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
585 +                rgb[v2_id])
586 +           else
587 +             render_mixed_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],
588 +              rgb[v1_id],rgb[v2_id],vp,SM_VIEW_CENTER(sm),bg0,bg1,bg2);
589 +         }
590 +  glEnd();
591 +
592 +  glPopMatrix();
593 +
594 + }
595 +
596 + /*
597   * render_base_tri(v0,v1,v2,rgb0,rgb1,rgb2,vp,b0,b1,b2)
598 < *  float v0[3],v1[3],v2[3];       : triangle vertex coordinates
598 > *  SFLOAT v0[3],v1[3],v2[3];       : triangle vertex coordinates
599   *  BYTE rgb0[3],rgb1[3],rgb2[3];  : vertex RGBs
600   *  FVECT vp;                      : current viewpoint
601   *  int b0,b1,b2;                  : vertex base flag
# Line 561 | Line 605 | BYTE  (*rgb)[3];
605   *  the average distance to the non-base vertices
606   */
607   render_base_tri(v0,v1,v2,rgb0,rgb1,rgb2,vp,b0,b1,b2)
608 < float v0[3],v1[3],v2[3];
608 > SFLOAT v0[3],v1[3],v2[3];
609   BYTE rgb0[3],rgb1[3],rgb2[3];
610   FVECT vp;
611   int b0,b1,b2;
# Line 574 | Line 618 | int b0,b1,b2;
618    cnt = 0;
619    rgb[0] = rgb[1] = rgb[2] = 0;
620    d = 0.0;
621 <
621 >  /* If all vertices are base: don't render */
622    if(b0&&b1&&b2)
623      return;
624    /* First calculate color and coordinates
# Line 612 | Line 656 | int b0,b1,b2;
656    else
657    {
658      glColor3ub(rgb0[0],rgb0[1],rgb0[2]);
659 <    glVertex3fv(v0);
659 >    GLVERTEX3V(v0);
660    }
661    if(b1)
662    {
# Line 625 | Line 669 | int b0,b1,b2;
669    else
670    {
671      glColor3ub(rgb1[0],rgb1[1],rgb1[2]);
672 <    glVertex3fv(v1);
672 >    GLVERTEX3V(v1);
673    }
674    if(b2)
675    {
# Line 638 | Line 682 | int b0,b1,b2;
682    else
683    {
684      glColor3ub(rgb2[0],rgb2[1],rgb2[2]);
685 <    glVertex3fv(v2);
685 >    GLVERTEX3V(v2);
686    }
687   }
688   /*
689   * smRender_fg_tris(sm,vp,t_flag,bg_flag,wp,rgb)
690   * SM *sm;                        : mesh
691   * FVECT vp;                      : current viewpoint
692 < * int4  *t_flag,*bg_flag;        : triangle flags: t_flag is generic,bg_flag
692 > * int32  *t_flag,*bg_flag;        : triangle flags: t_flag is generic,bg_flag
693   *                                  indicates if background tri;
694 < * float (*wp)[3];BYTE (*rgb)[3]; : arrays of sample points and RGB colors
694 > * SFLOAT (*wp)[3];BYTE (*rgb)[3]; : arrays of sample points and RGB colors
695   *
696   * Sequentially gos through triangle list and renders all valid tris who
697   * have t_flag set, and NOT bg_flag set.
# Line 655 | Line 699 | int b0,b1,b2;
699   smRender_fg_tris(sm,vp,t_flag,bg_flag,wp,rgb)
700   SM *sm;
701   FVECT vp;
702 < int4  *t_flag,*bg_flag;
703 < float (*wp)[3];
702 > int32  *t_flag,*bg_flag;
703 > SFLOAT (*wp)[3];
704   BYTE  (*rgb)[3];
705   {
706    TRI *tri;
707    int i,n,b0,b1,b2;
708 <  int v0_id,v1_id,v2_id;
708 >  S_ID v0_id,v1_id,v2_id;
709    
710    glBegin(GL_TRIANGLES);
711    for(n=((SM_NUM_TRI(sm)+31)>>5) +1; --n;)
# Line 682 | Line 726 | BYTE  (*rgb)[3];
726             else
727               render_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
728                          rgb[v2_id])
729 +
730           }
731    glEnd();
732  
733   }
734  
735 + /*
736 + * smRender_new_fg_tris(sm,vp,new_flag,active_flag,bg_flag,wp,rgb)
737 + * SM *sm;                        : mesh
738 + * FVECT vp;                      : current viewpoint
739 + * int32  *new_flag,*active_flag,*bg_flag; : triangle flags: indicate if
740 + *                                tri is new,active,background
741 + * SFLOAT (*wp)[3];BYTE (*rgb)[3]; : arrays of sample points and RGB colors
742 + *
743 + * Sequentially gos through triangle list and renders all valid tris who
744 + * have new_flag and active_flag set, and NOT bg_flag set.
745 + */
746 + smRender_new_fg_tris(sm,vp,new_flag,active_flag,bg_flag,wp,rgb)
747 + SM *sm;
748 + FVECT vp;
749 + int32  *new_flag,*active_flag,*bg_flag;
750 + SFLOAT (*wp)[3];
751 + BYTE  (*rgb)[3];
752 + {
753 +  TRI *tri;
754 +  int i,n,b0,b1,b2;
755 +  S_ID v0_id,v1_id,v2_id;
756 +  
757 +  glBegin(GL_TRIANGLES);
758 +  for(n=((SM_NUM_TRI(sm)+31)>>5) +1; --n;)
759 +    if(new_flag[n] & active_flag[n])
760 +      for(i=0; i < 32; i++)
761 +        if(new_flag[n] & active_flag[n] & (1L << i) & ~bg_flag[n])
762 +         {
763 +           tri = SM_NTH_TRI(sm,(n<<5)+i);
764 +           v0_id = T_NTH_V(tri,0);
765 +           v1_id = T_NTH_V(tri,1);
766 +           v2_id = T_NTH_V(tri,2);
767 +           b0 = SM_BASE_ID(sm,v0_id);
768 +           b1 = SM_BASE_ID(sm,v1_id);
769 +           b2 = SM_BASE_ID(sm,v2_id);
770 +           if(b0 || b1 || b2)
771 +             render_base_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],
772 +             rgb[v1_id],rgb[v2_id],SM_VIEW_CENTER(sm),b0,b1,b2);
773 +           else
774 +             render_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
775 +                        rgb[v2_id])
776 +         }
777 +  glEnd();
778  
779 + }
780 +
781 + /* Test for qsort to depth sort triangles */
782   int
783   compare_tri_depths(T_DEPTH *td1,T_DEPTH *td2)
784   {
# Line 699 | Line 790 | compare_tri_depths(T_DEPTH *td1,T_DEPTH *td2)
790    if(d < 0.0)
791      return(-1);
792    return(0);
702
793   }
794  
705 #ifdef DEBUG
706 #define freebuf(b)  tempbuf(-1)
707 #endif
795  
709 char *
710 tempbuf(len)                    /* get a temporary buffer */
711 unsigned  len;
712 {
713  extern char  *malloc(), *realloc();
714  static char  *tempbuf = NULL;
715  static unsigned  tempbuflen = 0;
716
717 #ifdef DEBUG
718        static int in_use=FALSE;
719
720        if(len == -1)
721          {
722            in_use = FALSE;
723            return(NULL);
724          }
725        if(in_use)
726        {
727            eputs("Buffer in use:cannot allocate:tempbuf()\n");
728            return(NULL);
729        }
730 #endif
731        if (len > tempbuflen) {
732                if (tempbuflen > 0)
733                        tempbuf = realloc(tempbuf, len);
734                else
735                        tempbuf = malloc(len);
736                tempbuflen = tempbuf==NULL ? 0 : len;
737        }
738 #ifdef DEBUG
739        in_use = TRUE;
740 #endif
741        return(tempbuf);
742 }
743
796   /*
797   * smOrder_new_tris(sm,vp,td)
798   * SM *sm;      : mesh
# Line 750 | Line 802 | unsigned  len;
802   * Creates list of all new tris, with their distance from the current
803   * viewpoint, and sorts the list based on this distance
804   */
805 < smOrder_new_tris(sm,vp,td)
805 > T_DEPTH
806 > *smOrder_new_tris(sm,vp)
807   SM *sm;
808   FVECT vp;
756 T_DEPTH *td;
809   {
810 <  int n,i,j,tcnt,v;
810 >  T_DEPTH *td;
811 >  int n,i,j,tcnt,v,size;
812    TRI *tri;
813    double d,min_d;
814    FVECT diff;
815 <  int4 *new_flag,*bg_flag;
815 >  int32 *new_flag,*bg_flag,*active_flag;
816 >  
817 > td = (T_DEPTH *)tempbuf(NEW_TRI_CNT*sizeof(T_DEPTH),FALSE);
818 > size = NEW_TRI_CNT;
819  
820    tcnt=0;
821    new_flag = SM_NTH_FLAGS(sm,T_NEW_FLAG);
822    bg_flag = SM_NTH_FLAGS(sm,T_BG_FLAG);
823 +  active_flag = SM_NTH_FLAGS(sm,T_ACTIVE_FLAG);
824    for(n=((SM_NUM_TRI(sm)+31)>>5) +1; --n;)
825 <    if(new_flag[n] & ~bg_flag[n])
825 >    if(active_flag[n] & new_flag[n] & ~bg_flag[n])
826        for(i=0; i < 32; i++)
827 <        if(new_flag[n] & (1L << i) & ~bg_flag[n])
827 >        if(active_flag[n] & new_flag[n] & (1L << i) & ~bg_flag[n])
828           {
829             tri = SM_NTH_TRI(sm,(n<<5)+i);
830 +           if(tcnt+1 >= size)
831 +           {
832 +             size += 100;
833 +             td = (T_DEPTH *)tempbuf(size*sizeof(T_DEPTH),TRUE);
834 +           }
835             td[tcnt].tri = (n << 5)+i;
836             min_d = -1;
837             for(j=0;j < 3;j++)
# Line 785 | Line 847 | T_DEPTH *td;
847    td[tcnt].tri = -1;
848    if(tcnt)
849        qsort((void *)td,tcnt,sizeof(T_DEPTH),compare_tri_depths);
850 +  return(td);
851   }
852  
853   /*
# Line 826 | Line 889 | smRender_inc(sm,vp)
889   SM *sm;
890   FVECT vp;
891   {
892 <  int i,n,v0_id,v1_id,v2_id,b0,b1,b2;
892 >  S_ID v0_id,v1_id,v2_id;
893 >  int i,n,b0,b1,b2;
894    TRI *tri;
895 <  float (*wp)[3];
895 >  SFLOAT (*wp)[3];
896    BYTE  (*rgb)[3];
897 <  int4  *new_flag,*bg_flag;
897 >  int32  *new_flag,*bg_flag,*active_flag;
898    T_DEPTH *td = NULL;
899  
836  smUpdate_tm(sm);
900  
901 <  /* For all of the NEW triangles (since last update): assume
902 <     ACTIVE. Go through and sort on depth value (from vp). Turn
901 >  /* For all of the NEW and ACTIVE triangles (since last update):
902 >     Go through and sort on depth value (from vp). Turn
903       Depth Buffer test off and render back-front
904 <     */
904 >   */
905 >
906 >  /* Must depth sort if current view point is not same as canonical */
907    if(!EQUAL_VEC3(SM_VIEW_CENTER(sm),vp))
908 <  {
844 <    /* Must depth sort if view points do not coincide */
845 <    td = (T_DEPTH *)tempbuf(smNew_tri_cnt*sizeof(T_DEPTH));
846 <    if(td)
847 <      smOrder_new_tris(sm,vp,td);
848 < #ifdef DEBUG
849 <    else
850 <        eputs("Cant create list:wont depth sort:smUpdate_incremental\n");
851 < #endif
852 <  }
908 >    td =  smOrder_new_tris(sm,vp);
909    wp = SM_WP(sm);
910    rgb =SM_RGB(sm);
911    new_flag = SM_NTH_FLAGS(sm,T_NEW_FLAG);
912 +  active_flag = SM_NTH_FLAGS(sm,T_ACTIVE_FLAG);
913    bg_flag = SM_NTH_FLAGS(sm,T_BG_FLAG);
914    /* Turn Depth Test off -- using Painter's algorithm */
915    glPushAttrib(GL_DEPTH_BUFFER_BIT);
916    glDepthFunc(GL_ALWAYS);
917  
918 <  smRender_bg_tris(sm,vp,new_flag,bg_flag,wp,rgb);
918 >  smRender_new_bg_tris(sm,vp,new_flag,active_flag,bg_flag,wp,rgb);
919    if(!td)
920 <    smRender_fg_tris(sm,vp,new_flag,bg_flag,wp,rgb);
920 >    smRender_new_fg_tris(sm,vp,new_flag,active_flag,bg_flag,wp,rgb);
921    else
922    {
923      glBegin(GL_TRIANGLES);
# Line 895 | Line 952 | FVECT vp;
952   *  SM *sm;              : mesh
953   *  QUADTREE qt;         : quadtree base node
954   *  FVECT vp;            : current viewpoint
955 < *  float (*wp)[3];      : array of sample points
955 > *  SFLOAT (*wp)[3];      : array of sample points
956   *  BYTE (*rgb)[3];      : array of RGB values for samples
957   *  int i,level_i,level,max_level,leaf_cnt;
958 < *                       : variables to keep track of where
958 > *          : variables to keep track of where
959   *         we are in the quadtree traversal in order to map nodes to
960   *         corresponding array locations, where nodes are stored in breadth-
961   *         first order. i is the index of the current node,level_i is the
# Line 917 | Line 974 | smRender_qtree_dl(sm,qt,vp,wp,rgb,i,level_i,level,max_
974   SM *sm;
975   QUADTREE qt;
976   FVECT vp;
977 < float (*wp)[3];
977 > SFLOAT (*wp)[3];
978   BYTE  (*rgb)[3];
979   int i,level_i,level,max_level,leaf_cnt;
980   int which;
# Line 971 | Line 1028 | int which;
1028   *  SM *sm;             : mesh
1029   *  QUADTREE qt;        : quadtree base node
1030   *  FVECT vp;           : current viewpoint
1031 < *  float (*wp)[3]      : array of sample points
1031 > *  SFLOAT (*wp)[3]      : array of sample points
1032   *  BYTE (*rgb)[3]      : array of RGB values for samples
1033   *  int which;          : flag indicates whether to render fg or bg tris
1034   *  int cull;           : if true, only traverse active (flagged) nodes
# Line 981 | Line 1038 | smRender_qtree(sm,qt,vp,wp,rgb,which,cull)
1038   SM *sm;
1039   QUADTREE qt;
1040   FVECT vp;
1041 < float (*wp)[3];
1041 > SFLOAT (*wp)[3];
1042   BYTE  (*rgb)[3];
1043   int which,cull;
1044   {
# Line 992 | Line 1049 | int which,cull;
1049  
1050    if(QT_IS_LEAF(qt))
1051    {
1052 <    TRI *t;
1053 <    OBJECT *optr;
1054 <    int t_id,v0_id,v1_id,v2_id,bg0,bg1,bg2;
1052 >    TRI *t,*tri;
1053 >    S_ID *optr,s_id,v0_id,v1_id,v2_id;
1054 >    int bg0,bg1,bg2,t_id;
1055  
1056      if(cull && !QT_LEAF_IS_FLAG(qt))
1057        return;
1058  
1059      optr = qtqueryset(qt);
1060 <    for (i = QT_SET_CNT(optr),optr = QT_SET_PTR(optr);i > 0; i--)
1060 >    for (i = QT_SET_CNT(optr);i > 0; i--)
1061      {
1062 <      t_id = QT_SET_NEXT_ELEM(optr);
1063 <      t = SM_NTH_TRI(sm,t_id);
1064 <      if(!T_IS_VALID(t) || (cull &&!SM_IS_NTH_T_ACTIVE(sm,t_id)) ||
1065 <         SM_IS_NTH_T_NEW(sm,t_id))
1009 <        continue;
1010 <      
1011 <      bg0 = SM_IS_NTH_T_BG(sm,t_id);
1012 <      if((which== SM_RENDER_FG && bg0) || (which== SM_RENDER_BG && !bg0))
1013 <        continue;
1014 <
1015 <      v0_id = T_NTH_V(t,0);
1016 <      v1_id = T_NTH_V(t,1);
1017 <      v2_id = T_NTH_V(t,2);
1018 <      if(bg0)
1062 >      s_id = QT_SET_NEXT_ELEM(optr);
1063 >      t_id = SM_NTH_VERT(smMesh,s_id);
1064 >      tri = t = SM_NTH_TRI(smMesh,t_id);
1065 >      do
1066        {
1067 <        bg0 = SM_DIR_ID(sm,v0_id)?DIR:SM_BASE_ID(sm,v0_id)?BASE:0;
1068 <        bg1 = SM_DIR_ID(sm,v1_id)?DIR:SM_BASE_ID(sm,v1_id)?BASE:0;
1069 <        bg2 = SM_DIR_ID(sm,v2_id)?DIR:SM_BASE_ID(sm,v2_id)?BASE:0;
1070 <        SM_SET_NTH_T_NEW(sm,t_id);  
1071 <        if(bg0==DIR && bg1==DIR && bg2==DIR)
1072 <          render_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
1073 <                  rgb[v2_id])
1074 <         else
1075 <           render_mixed_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],
1076 <                 rgb[v1_id],rgb[v2_id],vp,SM_VIEW_CENTER(sm),bg0,bg1,bg2);
1077 <      }
1078 <      else
1079 <      {
1080 <        SM_SET_NTH_T_NEW(sm,t_id);  
1081 <        bg0 = SM_BASE_ID(sm,v0_id);
1082 <        bg1 = SM_BASE_ID(sm,v1_id);
1083 <        bg2 = SM_BASE_ID(sm,v2_id);
1084 <        if(bg0 || bg1 || bg2)
1085 <          render_base_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],
1086 <             rgb[v1_id],rgb[v2_id],SM_VIEW_CENTER(sm),bg0,bg1,bg2);
1087 <        else
1088 <          render_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
1089 <                   rgb[v2_id])
1090 <      }
1067 >       if((!cull || SM_IS_NTH_T_ACTIVE(sm,t_id)) && !SM_IS_NTH_T_NEW(sm,t_id))
1068 >       {
1069 >          bg0 = SM_IS_NTH_T_BG(sm,t_id);
1070 >          if((which == SM_RENDER_FG && !bg0) || (which== SM_RENDER_BG && bg0))
1071 >          {
1072 >            v0_id = T_NTH_V(t,0);
1073 >            v1_id = T_NTH_V(t,1);
1074 >            v2_id = T_NTH_V(t,2);
1075 >            if(bg0)
1076 >            {
1077 >              bg0 = SM_DIR_ID(sm,v0_id)?DIR:SM_BASE_ID(sm,v0_id)?BASE:0;
1078 >              bg1 = SM_DIR_ID(sm,v1_id)?DIR:SM_BASE_ID(sm,v1_id)?BASE:0;
1079 >              bg2 = SM_DIR_ID(sm,v2_id)?DIR:SM_BASE_ID(sm,v2_id)?BASE:0;
1080 >              SM_SET_NTH_T_NEW(sm,t_id);  
1081 >              if(bg0==DIR && bg1==DIR && bg2==DIR)
1082 >                render_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
1083 >                         rgb[v2_id])
1084 >              else
1085 >                render_mixed_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],
1086 >                    rgb[v1_id],rgb[v2_id],vp,SM_VIEW_CENTER(sm),bg0,bg1,bg2);
1087 >            }
1088 >            else
1089 >            {
1090 >              SM_SET_NTH_T_NEW(sm,t_id);  
1091 >              bg0 = SM_BASE_ID(sm,v0_id);
1092 >              bg1 = SM_BASE_ID(sm,v1_id);
1093 >              bg2 = SM_BASE_ID(sm,v2_id);
1094 >              if(bg0 || bg1 || bg2)
1095 >                render_base_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],
1096 >                        rgb[v1_id],rgb[v2_id],SM_VIEW_CENTER(sm),bg0,bg1,bg2);
1097 >              else
1098 >                render_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
1099 >                           rgb[v2_id])
1100 >            }
1101 >          }
1102 >       }
1103 >       t_id = smTri_next_ccw_nbr(smMesh,t,s_id);
1104 >       t = SM_NTH_TRI(smMesh,t_id);
1105 >      }while(t!=tri);
1106      }
1107    }
1108    else
# Line 1049 | Line 1111 | int which,cull;
1111          smRender_qtree(sm,QT_NTH_CHILD(qt,i),vp,wp,rgb,which,cull);
1112   }
1113  
1114 +
1115   /*
1116   * smRender_mesh(sm,view,cull) : Render mesh Triangles
1117   *   SM *sm;                   : mesh
# Line 1065 | Line 1128 | SM *sm;
1128   VIEW *view;
1129   int cull;
1130   {
1131 <  float (*wp)[3];
1131 >  SFLOAT (*wp)[3];
1132    BYTE  (*rgb)[3];
1133    int i;
1134    STREE *st= SM_LOCATOR(sm);
1135  
1073  smUpdate_tm(sm);
1074
1136    wp = SM_WP(sm);
1137    rgb =SM_RGB(sm);
1138  
# Line 1080 | Line 1141 | int cull;
1141    if(cull)
1142      smCull(sm,view,SM_ALL_LEVELS);
1143  
1083
1144    glPushAttrib(GL_DEPTH_BUFFER_BIT);
1145    glDisable(GL_DEPTH_TEST);
1146    
# Line 1089 | Line 1149 | int cull;
1149    /* move relative to the new view */
1150    glTranslated(view->vp[0],view->vp[1],view->vp[2]);
1151  
1092
1152    /* The points are a distance of 1 away from the origin: if necessary
1153       scale so that they fit in frustum and are therefore not clipped away
1154       */
# Line 1130 | Line 1189 | smRender_mesh_dl(sm,view)
1189   SM *sm;
1190   VIEW *view;
1191   {
1192 <  float (*wp)[3];
1192 >  SFLOAT (*wp)[3];
1193    BYTE  (*rgb)[3];
1194    STREE *st;
1195    int i;
# Line 1149 | Line 1208 | VIEW *view;
1208  
1209      return;
1210    }    
1211 +  smClear_flags(sm,T_NEW_FLAG);
1212 +
1213    smCull(sm,view,SM_DL_LEVELS);
1214  
1215    st = SM_LOCATOR(sm);
# Line 1207 | Line 1268 | SM *sm;
1268   VIEW *view;
1269   int render_flag;
1270   {
1271 <  int4  *active_flag,*bg_flag;
1272 <  float (*wp)[3];
1271 >  int32  *active_flag,*bg_flag;
1272 >  SFLOAT (*wp)[3];
1273    BYTE  (*rgb)[3];
1274  
1275    wp = SM_WP(sm);
1276 <  rgb =SM_RGB(sm);
1276 >  rgb = SM_RGB(sm);
1277    active_flag = SM_NTH_FLAGS(sm,T_ACTIVE_FLAG);
1278    bg_flag = SM_NTH_FLAGS(sm,T_BG_FLAG);
1279  
# Line 1366 | Line 1427 | SM *sm;
1427   VIEW *view;
1428   int qual;
1429   {
1369
1370  /* Recompute tone mapping if specified */
1371  if( qual >= MAXQUALITY && smCompute_mapping)
1372    smUpdate_tm(sm);
1373
1430    /* Unless quality > MAXQUALITY, render using display lists */
1431    if(qual <= MAXQUALITY)
1432    {
1433      /* If quality above threshold: render mesh*/
1434 <    if(qual > (MAXQUALITY*2/4))
1434 >    if(qual > (MAXQUALITY*2/4) )
1435        /* render stree using display lists */
1436        smRender_mesh_dl(sm,view);
1437      else
1438 +    {
1439        /* If quality below threshold, use approximate rendering */
1440        smRender_approx(sm,qual,view);
1441 +    }
1442    }
1443    else
1444 <      /* render stree without display lists */
1444 >  {
1445 >    /* render stree without display lists */
1446        smRender_mesh(sm,view,TRUE);
1447 +  }
1448   }
1449  
1450  
# Line 1404 | Line 1464 | smUpdate(view,qual)
1464     VIEW *view;
1465     int qual;
1466   {
1467 +  
1468    /* Is there anything to render? */
1469    if(!smMesh || SM_NUM_TRI(smMesh)<=0)
1470      return;
1471 <
1471 >  
1472    /* Is viewer MOVING?*/
1473    if(qual < MAXQUALITY)
1474    {
1475 +    if(smIncremental)
1476 +      smUpdate_tm(smMesh);
1477 +
1478      /* Render mesh using display lists */
1479      smRender(smMesh,view,qual);
1480      return;
1481    }
1418
1482    /* Viewer is STATIONARY */
1420
1483    /* Has view moved epsilon from canonical view? (epsilon= percentage
1484       (SM_VIEW_FRAC) of running average of the distance of the sample points
1485       from the canonical view */
1486    if(DIST(view->vp,SM_VIEW_CENTER(smMesh)) > SM_ALLOWED_VIEW_CHANGE(smMesh))
1487    {
1488      /* Must rebuild mesh with current view as new canonical view  */
1489 <    smRebuild_mesh(smMesh,view);
1489 >    smRebuild(smMesh,view);
1490      /* Existing display lists and tonemapping are no longer valid */
1491      clear_display_lists();
1492 <    smCompute_mapping = TRUE;
1492 >    smCompute_mapping = FALSE;
1493 >    smUpdate_tm(smMesh);
1494      /* Render all the triangles in the new mesh */
1495      smRender(smMesh,view,qual+1);
1496    }
# Line 1435 | Line 1498 | smUpdate(view,qual)
1498      /* Has a complete redraw been requested ?*/
1499      if(smClean_notify)
1500      {
1501 +      if(smIncremental)
1502 +        smUpdate_tm(smMesh);
1503        smIncremental = FALSE;
1504        smRender(smMesh,view,qual);
1505      }
1506      else
1507      {
1508 <      /* Viewer fixed and receiving new samples for the same view */
1444 <      if(!smNew_tri_cnt)
1445 <        return;
1446 <
1508 >      smUpdate_tm(smMesh);
1509        /* If number of new triangles relatively small: do incremental update */
1510 <      if(smNew_tri_cnt < SM_SAMPLE_TRIS(smMesh)*SM_INC_PERCENT)
1511 <        {
1512 <          /* Mark Existing display lists in frustum invalid */
1513 <          if(!smIncremental)
1514 <          {
1515 <            smInvalidate_view(smMesh,view);
1516 <            smIncremental = TRUE;
1455 <          }
1456 <          smRender_inc(smMesh,view->vp);
1457 <        }
1458 <      else
1459 <        /* Otherwise render all of the active triangles */
1460 <          smRender(smMesh,view,qual+1);
1510 >      /* Mark Existing display lists in frustum invalid */
1511 >      if(!smIncremental)
1512 >      {
1513 >        smInvalidate_view(smMesh,view);
1514 >        smIncremental = TRUE;
1515 >      }
1516 >      smRender_inc(smMesh,view->vp);
1517    }
1518    /* This is our final update iff qual==MAXQUALITY and view==&odev.v */
1519    if( (qual >= MAXQUALITY) && (view == &(odev.v)))
1520    {
1521      /* reset rendering flags */
1522      smClean_notify = FALSE;
1523 <    smNew_tri_cnt = 0;
1524 <    smClear_flags(smMesh,T_NEW_FLAG);
1523 >    if(smIncremental)
1524 >      smClear_flags(smMesh,T_NEW_FLAG);
1525      qtCache_init(0);
1526    }
1527  
1528   }
1529 +
1530 +
1531 +
1532 +
1533 +
1534 +
1535 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines