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.9 by gwlarson, Wed Nov 11 12:05:39 1998 UTC vs.
Revision 3.13 by gwlarson, Sun Jan 10 10:27:48 1999 UTC

# Line 47 | Line 47 | static QT_LUENT        *qt_htbl = NULL;        /* quadtree cache */
47   static int      qt_hsiz = 0;            /* quadtree cache size */
48  
49  
50 + typedef struct _T_DEPTH {
51 +  int tri;
52 +  double depth;
53 + }T_DEPTH;
54  
55 < mark_active_tris(qtptr,fptr)
56 < QUADTREE *qtptr;
57 < int *fptr;
55 > /*
56 >  * smClean(tmflag)     : display has been wiped clean
57 >  *     int tmflag;
58 >  * Called after display has been effectively cleared, meaning that all
59 >  * geometry must be resent down the pipeline in the next call to smUpdate().
60 >  * If tmflag is set, tone-mapping should be performed
61 >  */
62 > smClean(tmflag)
63 >   int tmflag;
64   {
55  QUADTREE qt = *qtptr;
56  OBJECT *os,*optr;
57  register int i,t_id;
58  TRI *tri;
59
60  if(!QT_FLAG_FILL_TRI(*fptr))
61     (*fptr)++;
62  if(QT_IS_EMPTY(qt) || QT_LEAF_IS_FLAG(qt))
63    return;
64
65  /* For each triangle in the set, set the which flag*/
66  os = qtqueryset(qt);
67
68  for (i = QT_SET_CNT(os), optr = QT_SET_PTR(os); i > 0; i--)
69  {
70    t_id = QT_SET_NEXT_ELEM(optr);
71    /* Set the render flag */
72    tri = SM_NTH_TRI(smMesh,t_id);
73    if(!T_IS_VALID(tri) || SM_IS_NTH_T_BASE(smMesh,t_id))
74        continue;
75    SM_SET_NTH_T_ACTIVE(smMesh,t_id);
76    /* Set the Active bits of the Vertices */
77    S_SET_FLAG(T_NTH_V(tri,0));
78    S_SET_FLAG(T_NTH_V(tri,1));
79    S_SET_FLAG(T_NTH_V(tri,2));
80
81  }
82 }
83
84 #define mark_active_interior mark_active_tris
85
86 mark_tris_in_frustum(view)
87 VIEW *view;
88 {
89    FVECT nr[4],far[4];
90    FPEQ peq;
91    int debug=0;
92    /* Mark triangles in approx. view frustum as being active:set
93       LRU counter: for use in discarding samples when out
94       of space
95       Radiance often has no far clipping plane: but driver will set
96       dev_zmin,dev_zmax to satisfy OGL
97    */
98
99    /* First clear all the quadtree node and triangle active flags */
100    qtClearAllFlags();
101    smClear_flags(smMesh,T_ACTIVE_FLAG);
102    /* Clear all of the active sample flags*/
103    sClear_all_flags(SM_SAMP(smMesh));
104
105
106    /* calculate the world space coordinates of the view frustum */
107    calculate_view_frustum(view->vp,view->hvec,view->vvec,view->horiz,
108                           view->vert, dev_zmin,dev_zmax,nr,far);
109
110 #ifdef TEST_DRIVER
111    VCOPY(FrustumFar[0],far[0]);
112    VCOPY(FrustumFar[1],far[1]);
113    VCOPY(FrustumFar[2],far[2]);
114    VCOPY(FrustumFar[3],far[3]);
115    VCOPY(FrustumNear[0],nr[0]);
116    VCOPY(FrustumNear[1],nr[1]);
117    VCOPY(FrustumNear[2],nr[2]);
118    VCOPY(FrustumNear[3],nr[3]);
119 #endif
120    /* Project the view frustum onto the spherical quadtree */
121    /* For every cell intersected by the projection of the faces
122
123       of the frustum: mark all triangles in the cell as ACTIVE-
124       Also set the triangles LRU clock counter
125       */
126    
127    if(EQUAL_VEC3(view->vp,SM_VIEW_CENTER(smMesh)))
128    {/* Near face triangles */
129
130      smLocator_apply_func(smMesh,nr[0],nr[2],nr[3],mark_active_tris,
131                         mark_active_interior,NULL);
132      smLocator_apply_func(smMesh,nr[2],nr[0],nr[1],mark_active_tris,
133                         mark_active_interior,NULL);
134      return;
135    }
136
137    /* Test the view against the planes: and swap orientation if inside:*/
138    tri_plane_equation(nr[0],nr[2],nr[3], &peq,FALSE);
139    if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0)
140    {/* Near face triangles */
141      smLocator_apply_func(smMesh,nr[3],nr[2],nr[0],mark_active_tris,
142                           mark_active_interior,NULL);
143      smLocator_apply_func(smMesh,nr[1],nr[0],nr[2],mark_active_tris,
144                         mark_active_interior,NULL);
145    }
146    else
147    {/* Near face triangles */
148      smLocator_apply_func(smMesh,nr[0],nr[2],nr[3],mark_active_tris,
149                           mark_active_interior,NULL);
150      smLocator_apply_func(smMesh,nr[2],nr[0],nr[1],mark_active_tris,
151                         mark_active_interior,NULL);
152    }
153    tri_plane_equation(nr[0],far[3],far[0], &peq,FALSE);
154    if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0)
155    { /* Right face triangles */
156      smLocator_apply_func(smMesh,far[0],far[3],nr[0],mark_active_tris,
157                           mark_active_interior,NULL);
158      smLocator_apply_func(smMesh,nr[3],nr[0],far[3],mark_active_tris,
159                           mark_active_interior,NULL);
160    }
161    else
162    {/* Right face triangles */
163      smLocator_apply_func(smMesh,nr[0],far[3],far[0],mark_active_tris,
164                           mark_active_interior,NULL);
165      smLocator_apply_func(smMesh,far[3],nr[0],nr[3],mark_active_tris,
166                           mark_active_interior,NULL);
167    }
168
169    tri_plane_equation(nr[1],far[2],nr[2], &peq,FALSE);
170    if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0)
171    { /* Left face triangles */
172      smLocator_apply_func(smMesh,nr[2],far[2],nr[1],mark_active_tris,
173                           mark_active_interior,NULL);
174      smLocator_apply_func(smMesh,far[1],nr[1],far[2],mark_active_tris,
175                           mark_active_interior,NULL);  
176    }
177    else
178    { /* Left face triangles */
179      smLocator_apply_func(smMesh,nr[1],far[2],nr[2],mark_active_tris,
180                           mark_active_interior,NULL);
181      smLocator_apply_func(smMesh,far[2],nr[1],far[1],mark_active_tris,
182                   mark_active_interior,NULL);
183
184    }
185    tri_plane_equation(nr[0],far[0],nr[1], &peq,FALSE);
186    if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0)
187    {/* Top face triangles */
188      smLocator_apply_func(smMesh,nr[1],far[0],nr[0],mark_active_tris,
189                           mark_active_interior,NULL);
190      smLocator_apply_func(smMesh,far[1],far[0],nr[1],mark_active_tris,
191                           mark_active_interior,NULL);
192    }
193    else
194    {/* Top face triangles */
195      smLocator_apply_func(smMesh,nr[0],far[0],nr[1],mark_active_tris,
196                           mark_active_interior,NULL);
197      smLocator_apply_func(smMesh,nr[1],far[0],far[1],mark_active_tris,
198                           mark_active_interior,NULL);
199    }
200    tri_plane_equation(nr[3],nr[2],far[3], &peq,FALSE);
201    if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0)
202    {/* Bottom face triangles */
203      smLocator_apply_func(smMesh,far[3],nr[2],nr[3],mark_active_tris,
204                           mark_active_interior,NULL);
205      smLocator_apply_func(smMesh,far[3],far[2],nr[2],mark_active_tris,
206                           mark_active_interior,NULL);
207    }
208    else
209    { /* Bottom face triangles */
210      smLocator_apply_func(smMesh,nr[3],nr[2],far[3],mark_active_tris,
211                           mark_active_interior,NULL);
212      smLocator_apply_func(smMesh,nr[2],far[2],far[3],mark_active_tris,
213                           mark_active_interior,NULL);
214    }
215     tri_plane_equation(far[2],far[0],far[1], &peq,FALSE);
216    if(PT_ON_PLANE(SM_VIEW_CENTER(smMesh),peq) < 0.0)
217    {/* Far face triangles */
218      smLocator_apply_func(smMesh,far[0],far[2],far[1],mark_active_tris,
219                           mark_active_interior,NULL);
220      smLocator_apply_func(smMesh,far[2],far[0],far[3],mark_active_tris,
221                           mark_active_interior,NULL);
222    }
223    else
224    {/* Far face triangles */
225      smLocator_apply_func(smMesh,far[1],far[2],far[0],mark_active_tris,
226                           mark_active_interior,NULL);
227      smLocator_apply_func(smMesh,far[3],far[0],far[2],mark_active_tris,
228                           mark_active_interior,NULL);
229    }
230
231 }
232
233 /*
234 * smClean()            : display has been wiped clean
235 *
236 * Called after display has been effectively cleared, meaning that all
237 * geometry must be resent down the pipeline in the next call to smUpdate().
238 */
239 smClean()
240 {
65      smClean_notify = TRUE;
66 +    if(tmflag)
67 +       SM_TONE_MAP(smMesh) = 0;
68   }
69  
70   int
# Line 322 | Line 148 | register QUADTREE qt;
148      stCount_level_leaves(lcnt+1, QT_NTH_CHILD(qt,3));
149    }
150    else
151 <    lcnt[0]++;
151 >    if(QT_LEAF_IS_FLAG(qt))
152 >      lcnt[0]++;
153   }
154  
155  
# Line 342 | Line 169 | int lvl;
169      return(NULL);
170    if (QT_IS_TREE(qt) && !QT_IS_FLAG(qt))        /* not in our frustum */
171      return(NULL);
172 +  if(QT_IS_LEAF(qt)  && !QT_LEAF_IS_FLAG(qt))   /* not in our frustum */
173 +    return(NULL);
174                                          /* else look up node */
175    if ((le = qtCache_find(qt)) == NULL)
176      error(SYSTEM, "out of memory in qtRender_level");
177    if (QT_IS_TREE(qt) && (QT_IS_EMPTY(le->qt) || lvl > 0))
178    {                                     /* compute children */
179      qtSubdivide_tri(v0,v1,v2,a,b,c);
180 <    rc[0] = qtRender_level(QT_NTH_CHILD(qt,0),v0,a,c,sm,lvl-1);
181 <    rc[1] = qtRender_level(QT_NTH_CHILD(qt,1),a,v1,b,sm,lvl-1);
182 <    rc[2] = qtRender_level(QT_NTH_CHILD(qt,2),c,b,v2,sm,lvl-1);
183 <    rc[3] = qtRender_level(QT_NTH_CHILD(qt,3),b,c,a,sm,lvl-1);
180 >    rc[0] = qtRender_level(QT_NTH_CHILD(qt,0),v0,c,b,sm,lvl-1);
181 >    rc[1] = qtRender_level(QT_NTH_CHILD(qt,1),c,v1,a,sm,lvl-1);
182 >    rc[2] = qtRender_level(QT_NTH_CHILD(qt,2),b,a,v2,sm,lvl-1);
183 >    rc[3] = qtRender_level(QT_NTH_CHILD(qt,3),a,b,c,sm,lvl-1);
184    }
185    if (QT_IS_EMPTY(le->qt))
186    {                                     /* let's make some data! */
# Line 374 | Line 203 | int lvl;
203      {                                   /* from triangle set */
204        OBJECT *os;
205        int s0, s1, s2;
206 <
206 >      
207        os = qtqueryset(qt);
208 <      for (n = os[0]; n; n--)
208 >      for (i = os[0]; i; i--)
209        {
210 <        if(SM_IS_NTH_T_BASE(sm,os[n]))
210 >        if(SM_IS_NTH_T_BASE(sm,os[i]))
211             continue;
212 <        tri = SM_NTH_TRI(sm,os[n]);
212 >        tri = SM_NTH_TRI(sm,os[i]);
213          if(!T_IS_VALID(tri))
214            continue;
215 <        
215 >        n++;
216          s0 = T_NTH_V(tri,0);
217          s1 = T_NTH_V(tri,1);
218          s2 = T_NTH_V(tri,2);
# Line 403 | Line 232 | int lvl;
232          rgbs[2] += SM_NTH_RGB(sm,s0)[2] + SM_NTH_RGB(sm,s1)[2]
233                    + SM_NTH_RGB(sm,s2)[2];
234        }
235 <      n = 3*os[0];
235 >      n *= 3;
236      }
237      if (!n)
238        return(NULL);
# Line 434 | Line 263 | smRender_stree_level(sm,lvl)
263   SM *sm;
264   int lvl;
265   {
266 <  QUADTREE root;
266 >  QUADTREE qt;
267    int i;
268    FVECT t0,t1,t2;
269    STREE *st;
270  
271    
272 <  if (lvl < 1)
272 >  if (lvl < 0)
273      return;
274    st = SM_LOCATOR(sm);
275    glPushAttrib(GL_LIGHTING_BIT);
# Line 448 | Line 277 | int lvl;
277    glBegin(GL_TRIANGLES);
278    for(i=0; i < ST_NUM_ROOT_NODES; i++)
279    {
280 <    root = ST_NTH_ROOT(st,i);
281 <    qtRender_level(root,ST_NTH_V(st,i,0),ST_NTH_V(st,i,1),ST_NTH_V(st,i,2),
282 <                   sm,lvl-1);
280 >    qt = ST_ROOT_QT(st,i);
281 >    qtRender_level(qt,ST_NTH_V(st,i,0),ST_NTH_V(st,i,1),ST_NTH_V(st,i,2),
282 >                   sm,lvl);
283    }
284    glEnd();
285    glPopAttrib();
# Line 461 | Line 290 | smRender_stree(sm, qual)       /* render some quadtree trian
290   SM *sm;
291   int qual;
292   {
293 <  int i, ntarget;
293 >  int i, n,ntarget;
294    int lvlcnt[QT_MAX_LEVELS];
295 <
295 >  STREE *st;
296 >  int4 *active_flag;
297    if (qual <= 0)
298      return;
299                                  /* compute rendering target */
300    ntarget = 0;
301 <  SM_FOR_ALL_ACTIVE_TRIS(sm,i)
302 <    ntarget++;
303 <  ntarget = ntarget*qual/100;
301 >
302 >  active_flag = SM_NTH_FLAGS(sm,T_ACTIVE_FLAG);
303 >  for(n=((SM_NUM_TRI(sm)+31)>>5) +1; --n;)
304 >    if(active_flag[n])
305 >      for(i=0; i < 32; i++)
306 >        if(active_flag[n] & (1L << i))
307 >          ntarget++;
308 >
309 >  ntarget = ntarget*qual/MAXQUALITY;
310    if (!ntarget)
311      return;
312    for (i = QT_MAX_LEVELS; i--; )
313      lvlcnt[i] = 0;
314 <  stCount_level_leaves(lvlcnt, ST_TOP_ROOT(SM_LOCATOR(sm)));
315 <  stCount_level_leaves(lvlcnt, ST_BOTTOM_ROOT(SM_LOCATOR(sm)));  
314 >  
315 >  st = SM_LOCATOR(sm);
316 >  for(i=0; i < ST_NUM_ROOT_NODES;i++)
317 >    stCount_level_leaves(lvlcnt, ST_ROOT_QT(st,i));
318 >  
319    for (ntarget -= lvlcnt[i=0]; i < QT_MAX_LEVELS-1; ntarget -= lvlcnt[++i])
320      if (ntarget < lvlcnt[i+1])
321        break;
# Line 485 | Line 324 | int qual;
324   }
325  
326  
488 smRender_tri(sm,i,vp,clr)
489 SM *sm;
490 int i;
491 FVECT vp;
492 int clr;
493 {
494  TRI *tri;
495  double ptr[3];
496  int j;
327  
328 <  tri = SM_NTH_TRI(sm,i);
329 <  if (clr) SM_CLR_NTH_T_NEW(sm,i);
330 <  for(j=0; j <= 2; j++)
331 <  {
502 < #ifdef DEBUG
503 <    if(SM_BG_SAMPLE(sm,T_NTH_V(tri,j)))
504 <      eputs("SmRenderTri(): shouldnt have bg samples\n");
505 < #endif
506 <    glColor3ub(SM_NTH_RGB(sm,T_NTH_V(tri,j))[0],
507 <               SM_NTH_RGB(sm,T_NTH_V(tri,j))[1],
508 <               SM_NTH_RGB(sm,T_NTH_V(tri,j))[2]);
509 <    VCOPY(ptr,SM_T_NTH_WV(sm,tri,j));
510 <    glVertex3d(ptr[0],ptr[1],ptr[2]);
511 <  }
512 < }
328 > #define render_tri(v0,v1,v2,rgb0,rgb1,rgb2) \
329 >  {glColor3ub(rgb0[0],rgb0[1],rgb0[2]);  glVertex3fv(v0); \
330 >  glColor3ub(rgb1[0],rgb1[1],rgb1[2]);  glVertex3fv(v1); \
331 >  glColor3ub(rgb2[0],rgb2[1],rgb2[2]);  glVertex3fv(v2);} \
332  
333 < smRender_mixed_tri(sm,i,vp,clr)
334 < SM *sm;
335 < int i;
336 < FVECT vp;
337 < int clr;
333 > render_mixed_tri(v0,v1,v2,rgb0,rgb1,rgb2,bg0,bg1,bg2,vp,vc)
334 > float v0[3],v1[3],v2[3];
335 > BYTE rgb0[3],rgb1[3],rgb2[3];
336 > int bg0,bg1,bg2;
337 > FVECT vp,vc;
338   {
520  TRI *tri;
339    double p[3],d;
340    int j,ids[3],cnt;
341    int rgb[3];
342  
525  tri = SM_NTH_TRI(sm,i);
526  if (clr) SM_CLR_NTH_T_NEW(sm,i);
527
343    /* NOTE:Triangles are defined clockwise:historical relative to spherical
344       tris: could change
345       */
346 +  if(bg0 && bg1 && bg2)
347 +    return;
348 +
349    cnt = 0;
350    d = 0.0;
351    rgb[0] = rgb[1] = rgb[2] = 0;
352 <  for(j=0;j < 3;j++)
352 >
353 >  if(!bg0)
354    {
355 <      ids[j] = T_NTH_V(tri,j);
356 <      if(!SM_BG_SAMPLE(sm,ids[j]))
357 <      {
358 <          rgb[0] += SM_NTH_RGB(sm,ids[j])[0];
359 <          rgb[1] += SM_NTH_RGB(sm,ids[j])[1];
541 <          rgb[2] += SM_NTH_RGB(sm,ids[j])[2];
542 <          cnt++;
543 <          d += DIST(vp,SM_NTH_WV(sm,ids[j]));
544 <      }
355 >    rgb[0] += rgb0[0];
356 >    rgb[1] += rgb0[1];
357 >    rgb[2] += rgb0[2];
358 >    cnt++;
359 >    d += DIST(vp,v0);
360    }
361 +  if(!bg1)
362 +  {
363 +    rgb[0] += rgb1[0];
364 +    rgb[1] += rgb1[1];
365 +    rgb[2] += rgb1[2];
366 +    cnt++;
367 +    d += DIST(vp,v1);
368 +  }
369 +  if(!bg2)
370 +  {
371 +    rgb[0] += rgb2[0];
372 +    rgb[1] += rgb2[1];
373 +    rgb[2] += rgb2[2];
374 +    cnt++;
375 +    d += DIST(vp,v2);
376 +  }
377    if(cnt > 1)
378    {
379      rgb[0]/=cnt; rgb[1]/=cnt; rgb[2]/=cnt;
380      d /= (double)cnt;
381    }
382 <  for(j=0; j <= 2; j++)
382 >  if(bg0)
383    {
384 <    if(SM_BG_SAMPLE(sm,ids[j]))
385 <    {
386 <        glColor3ub(rgb[0],rgb[1],rgb[2]);
387 <        VSUB(p,SM_NTH_WV(sm,ids[j]),SM_VIEW_CENTER(sm));
388 <        p[0] *= d;
389 <        p[1] *= d;
390 <        p[2] *= d;
391 <        VADD(p,p,SM_VIEW_CENTER(sm));
392 <    }
393 <    else
394 <    {
395 <        glColor3ub(SM_NTH_RGB(sm,ids[j])[0],SM_NTH_RGB(sm,ids[j])[1],
565 <                   SM_NTH_RGB(sm,ids[j])[2]);
566 <        VCOPY(p,SM_NTH_WV(sm,ids[j]));
567 <    }
568 <    glVertex3d(p[0],p[1],p[2]);
384 >    glColor3ub(rgb[0],rgb[1],rgb[2]);
385 >    VSUB(p,v0,vc);
386 >    p[0] *= d;
387 >    p[1] *= d;
388 >    p[2] *= d;
389 >    VADD(p,p,vc);
390 >    glVertex3dv(p);
391 >  }
392 >  else
393 >  {
394 >    glColor3ub(rgb0[0],rgb0[1],rgb0[2]);
395 >    glVertex3fv(v0);
396     }
397 +  if(bg1)
398 +  {
399 +    glColor3ub(rgb[0],rgb[1],rgb[2]);
400 +    VSUB(p,v1,vc);
401 +    p[0] *= d;
402 +    p[1] *= d;
403 +    p[2] *= d;
404 +    VADD(p,p,vc);
405 +    glVertex3dv(p);
406 +  }
407 +  else
408 +  {
409 +    glColor3ub(rgb1[0],rgb1[1],rgb1[2]);
410 +    glVertex3fv(v1);
411 +   }
412 +  if(bg2)
413 +  {
414 +    glColor3ub(rgb[0],rgb[1],rgb[2]);
415 +    VSUB(p,v2,vc);
416 +    p[0] *= d;
417 +    p[1] *= d;
418 +    p[2] *= d;
419 +    VADD(p,p,vc);
420 +    glVertex3dv(p);
421 +  }
422 +  else
423 +  {
424 +    glColor3ub(rgb2[0],rgb2[1],rgb2[2]);
425 +    glVertex3fv(v2);
426 +   }
427 +
428   }
429  
430 < smRender_bg_tri(sm,i,vp,d,clr)
431 < SM *sm;
432 < int i;
433 < FVECT vp;
430 > render_bg_tri(v0,v1,v2,rgb0,rgb1,rgb2,vp,vc,d)
431 > float v0[3],v1[3],v2[3];
432 > BYTE rgb0[3],rgb1[3],rgb2[3];
433 > FVECT vp,vc;
434   double d;
577 int clr;
435   {
436    double p[3];
580  int j,id;
581  TRI *tri;
437    
438 <  tri = SM_NTH_TRI(sm,i);
439 <  if (clr) SM_CLR_NTH_T_NEW(sm,i);
438 >  glColor3ub(rgb0[0],rgb0[1],rgb0[2]);
439 >  VSUB(p,v0,vc);
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 >  glVertex3dv(p);
448  
449 <  /* NOTE:Triangles are defined clockwise:historical relative to spherical
450 <     tris: could change
451 <     */
589 <  for(j=0; j <= 2; j++)
449 >  glColor3ub(rgb1[0],rgb1[1],rgb1[2]);
450 >  VSUB(p,v1,vc);
451 >  if(dev_zmin >= 0.99)
452    {
453 <      id = T_NTH_V(tri,j);
454 <      glColor3ub(SM_NTH_RGB(sm,id)[0],SM_NTH_RGB(sm,id)[1],
455 <                 SM_NTH_RGB(sm,id)[2]);
594 <      VSUB(p,SM_NTH_WV(sm,id),SM_VIEW_CENTER(sm));
595 <      if(dev_zmin >= 0.99)
596 <       {
597 <           p[0] *= d;
598 <           p[1] *= d;
599 <           p[2] *= d;
600 <       }
601 <      VADD(p,p,vp);
602 <      glVertex3d(p[0],p[1],p[2]);
453 >    p[0] *= d;
454 >    p[1] *= d;
455 >    p[2] *= d;
456    }
457 +  VADD(p,p,vp);
458 +  glVertex3dv(p);
459 +
460 +
461 +  glColor3ub(rgb2[0],rgb2[1],rgb2[2]);
462 +  VSUB(p,v2,vc);
463 +  if(dev_zmin >= 0.99)
464 +  {
465 +    p[0] *= d;
466 +    p[1] *= d;
467 +    p[2] *= d;
468 +  }
469 +  VADD(p,p,vp);
470 +  glVertex3dv(p);
471 +
472   }
473  
474 < smRender_mesh(sm,vp,clr)
474 > smRender_mesh(sm,vp)
475   SM *sm;
476   FVECT vp;
609 int clr;
477   {
478 <  int i;
478 >  int i,n,bg0,bg1,bg2;
479 >  double d;
480 >  int v0_id,v1_id,v2_id;
481    TRI *tri;
482 <  double ptr[3],d;
483 <  int j;
482 >  float (*wp)[3];
483 >  BYTE  (*rgb)[3];
484 >  int4  *active_flag,*bg_flag;
485  
486 +  wp = SM_WP(sm);
487 +  rgb =SM_RGB(sm);
488    d = (dev_zmin+dev_zmax)/2.0;
489    glPushAttrib(GL_DEPTH_BUFFER_BIT);
490    
491    /* First draw background polygons */
492    glDisable(GL_DEPTH_TEST);
493    glBegin(GL_TRIANGLES);
494 <  SM_FOR_ALL_ACTIVE_BG_TRIS(sm,i)
495 <     smRender_bg_tri(sm,i,vp,d,clr);
494 >
495 >  active_flag = SM_NTH_FLAGS(sm,T_ACTIVE_FLAG);
496 >  bg_flag = SM_NTH_FLAGS(sm,T_BG_FLAG);
497 >  for(n=((SM_NUM_TRI(sm)+31)>>5) +1; --n;)
498 >    if(active_flag[n] & bg_flag[n])
499 >      for(i=0; i < 32; i++)
500 >        if(active_flag[n] & bg_flag[n] & (1L << i))
501 >         {
502 >           tri = SM_NTH_TRI(sm,(n<<5)+i);
503 >           v0_id = T_NTH_V(tri,0);
504 >           v1_id = T_NTH_V(tri,1);
505 >           v2_id = T_NTH_V(tri,2);
506 >           render_bg_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
507 >                         rgb[v2_id],vp,SM_VIEW_CENTER(sm),d);
508 >         }
509    glEnd();
510 +
511    glEnable(GL_DEPTH_TEST);
512    glBegin(GL_TRIANGLES);
513 <  SM_FOR_ALL_ACTIVE_FG_TRIS(sm,i)
514 <  {
515 <      if(!SM_MIXED_TRI(sm,i))
516 <        smRender_tri(sm,i,vp,clr);
517 <   else
518 <        smRender_mixed_tri(sm,i,vp,clr);
519 <  }
513 >  for(n=((SM_NUM_TRI(sm)+31)>>5) +1; --n;)
514 >    if(active_flag[n])
515 >      for(i=0; i < 32; i++)
516 >        if((active_flag[n] & (1L << i)) && !(bg_flag[n] & (1L << i)))
517 >         {
518 >           tri = SM_NTH_TRI(sm,(n<<5)+i);
519 >           v0_id = T_NTH_V(tri,0);
520 >           v1_id = T_NTH_V(tri,1);
521 >           v2_id = T_NTH_V(tri,2);
522 >           bg0 = SM_DIR_ID(sm,v0_id) || SM_BASE_ID(sm,v0_id);
523 >           bg1 = SM_DIR_ID(sm,v1_id) || SM_BASE_ID(sm,v1_id);
524 >           bg2 = SM_DIR_ID(sm,v2_id) || SM_BASE_ID(sm,v2_id);
525 >           if(!(bg0 || bg1 || bg2))
526 >             render_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
527 >                        rgb[v2_id])
528 >               else
529 >                 render_mixed_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],
530 >                  rgb[v1_id],rgb[v2_id],bg0,bg1,bg2,vp,SM_VIEW_CENTER(sm));
531 >         }
532    glEnd();
533  
534    glPopAttrib();
535   }
536  
639 smRender_tri_edges(sm,i)
640 SM *sm;
641 int i;
642 {
643  TRI *tri;
644  int j;
645  double ptr[3];
646
647
648  tri = SM_NTH_TRI(sm,i);
649
650  for(j=0; j <= 2; j++)
651  {
652    VCOPY(ptr,SM_NTH_WV(sm,T_NTH_V(tri,j)));
653    glVertex3d(ptr[0],ptr[1],ptr[2]);
654    VCOPY(ptr,SM_NTH_WV(sm,T_NTH_V(tri,(j+1)%3)));
655    glVertex3d(ptr[0],ptr[1],ptr[2]);
656  }
657 }
658
537   int
538   compare_tri_depths(T_DEPTH *td1,T_DEPTH *td2)
539   {
# Line 669 | Line 547 | compare_tri_depths(T_DEPTH *td1,T_DEPTH *td2)
547      return(-1);
548    
549    return(0);
550 +
551   }
552  
553 < LIST
554 < *smDepth_sort_tris(sm,vp,td)
553 > #ifdef DEBUG
554 > #define freebuf(b)  tempbuf(-1)
555 > #endif
556 >
557 >
558 > char *
559 > tempbuf(len)                    /* get a temporary buffer */
560 > unsigned  len;
561 > {
562 >        extern char  *malloc(), *realloc();
563 >        static char  *tempbuf = NULL;
564 >        static unsigned  tempbuflen = 0;
565 >
566 > #ifdef DEBUG
567 >        static int in_use=FALSE;
568 >
569 >        if(len == -1)
570 >          {
571 >            in_use = FALSE;
572 >            return(NULL);
573 >          }
574 >        if(in_use)
575 >        {
576 >            eputs("Buffer in use:cannot allocate:tempbuf()\n");
577 >            return(NULL);
578 >        }
579 > #endif
580 >        if (len > tempbuflen) {
581 >                if (tempbuflen > 0)
582 >                        tempbuf = realloc(tempbuf, len);
583 >                else
584 >                        tempbuf = malloc(len);
585 >                tempbuflen = tempbuf==NULL ? 0 : len;
586 >        }
587 > #ifdef DEBUG
588 >        in_use = TRUE;
589 > #endif
590 >        return(tempbuf);
591 > }
592 >
593 > smOrder_new_tris(sm,vp,td)
594   SM *sm;
595   FVECT vp;
596   T_DEPTH *td;
597   {
598 <  int i,j,t_id,v;
598 >  int n,i,j,tcnt,v;
599    TRI *tri;
600    double d,min_d;
601 <  LIST *tlist=NULL;
601 >  FVECT diff;
602 >  int4 *new_flag,*bg_flag;
603  
604 <  i = 0;
605 <  SM_FOR_ALL_NEW_TRIS(sm,t_id)
606 <  {
607 <    if(SM_BG_TRI(sm,t_id))
608 <    {
609 <        tlist = push_data(tlist,t_id);
610 <        continue;
611 <    }
612 <    tri = SM_NTH_TRI(sm,t_id);
613 < #ifdef DEBUG
614 <    if(i >= smNew_tri_cnt)
615 <    {
616 <      eputs("smDepth_sort_tris():More tris than reported by smNew_tri_cnt\n");
617 <      break;
618 <    }
619 < #endif
620 <    td[i].tri = t_id;
621 <    min_d = -1;
622 <    for(j=0;j < 3;j++)
623 <    {
624 <        v = T_NTH_V(tri,j);
625 <        if(!SM_BG_SAMPLE(sm,v))
626 <        {
708 <            d = DIST(vp,SM_NTH_WV(sm,v));
709 <            if(min_d == -1 || d < min_d)
710 <               min_d = d;
711 <        }
712 <    }
713 <    td[i].depth = min_d;
714 <    i++;
604 >  tcnt=0;
605 >  new_flag = SM_NTH_FLAGS(sm,T_NEW_FLAG);
606 >  bg_flag = SM_NTH_FLAGS(sm,T_BG_FLAG);
607 >  for(n=((SM_NUM_TRI(sm)+31)>>5) +1; --n;)
608 >    if(new_flag[n] & ~bg_flag[n])
609 >      for(i=0; i < 32; i++)
610 >        if(new_flag[n] & (1L << i) & ~bg_flag[n])
611 >         {
612 >           tri = SM_NTH_TRI(sm,(n<<5)+i);
613 >           td[tcnt].tri = (n << 5)+i;
614 >           min_d = -1;
615 >           for(j=0;j < 3;j++)
616 >             {
617 >               v = T_NTH_V(tri,j);
618 >               if(!SM_BG_SAMPLE(sm,v))
619 >                 {
620 >                   VSUB(diff,SM_NTH_WV(sm,v),vp);
621 >                   d = DOT(diff,diff);
622 >                   if(min_d == -1 || d < min_d)
623 >                     min_d = d;
624 >                 }
625 >             }
626 >           td[tcnt++].depth = min_d;
627    }
628 <  td[i].tri = -1;
629 <  if(i)
630 <     qsort((void *)td,i,sizeof(T_DEPTH),compare_tri_depths);
719 <  return(tlist);
628 >  td[tcnt].tri = -1;
629 >  if(tcnt)
630 >      qsort((void *)td,tcnt,sizeof(T_DEPTH),compare_tri_depths);
631   }
632  
633  
# Line 725 | Line 636 | SM *sm;
636   FVECT vp;
637   int clr;
638   {
639 <  static T_DEPTH *td= NULL;
729 <  static int tsize = 0;
730 <  int i;
639 >  int i,n,v0_id,v1_id,v2_id,bg0,bg1,bg2;
640    GLint depth_test;
641    double d;
642 <  LIST *bglist;
642 >  TRI *tri;
643 >  float (*wp)[3];
644 >  BYTE  (*rgb)[3];
645 >  int4  *new_flag,*bg_flag;
646 >  T_DEPTH *td = NULL;
647    /* For all of the NEW triangles (since last update): assume
648       ACTIVE. Go through and sort on depth value (from vp). Turn
649       Depth Buffer test off and render back-front
650       */
651 <  /* NOTE: could malloc each time or hard code */
739 <  if(smNew_tri_cnt > tsize)
651 >  if(!EQUAL_VEC3(SM_VIEW_CENTER(sm),vp))
652    {
653 <    if(td)
654 <      free((char *)td);
655 <    td = (T_DEPTH *)malloc(smNew_tri_cnt*sizeof(T_DEPTH));
656 <    tsize = smNew_tri_cnt;
653 >    /* Must depth sort if view points do not coincide */
654 >    td = (T_DEPTH *)tempbuf(smNew_tri_cnt*sizeof(T_DEPTH));
655 > #ifdef DEBUG
656 >    if(!td)
657 >        eputs("Cant create list:wont depth sort:smUpdate_rendered_mesh\n");
658 > #endif
659 >    smOrder_new_tris(sm,vp,td);
660    }
661 <  if(!td)
662 <  {
748 <    error(SYSTEM,"smUpdate_Rendered_mesh:Cannot allocate memory\n");
749 <  }
750 <  bglist = smDepth_sort_tris(sm,vp,td);
751 <
661 >  wp = SM_WP(sm);
662 >  rgb =SM_RGB(sm);
663    /* Turn Depth Test off -- using Painter's algorithm */
664    glPushAttrib(GL_DEPTH_BUFFER_BIT);
665    glDepthFunc(GL_ALWAYS);
666    d = (dev_zmin+dev_zmax)/2.0;
667 +
668    /* Now render back-to front */
669    /* First render bg triangles */
670 +  new_flag = SM_NTH_FLAGS(sm,T_NEW_FLAG);
671 +  bg_flag = SM_NTH_FLAGS(sm,T_BG_FLAG);
672    glBegin(GL_TRIANGLES);
673 <  while(bglist)
674 <     smRender_bg_tri(sm,pop_list(&bglist),vp,d,clr);
673 >  for(n=((SM_NUM_TRI(sm)+31)>>5) +1; --n;)
674 >    if(new_flag[n] & bg_flag[n])
675 >      for(i=0; i < 32; i++)
676 >        if(new_flag[n] & (1L << i) & bg_flag[n] )
677 >         {
678 >           tri = SM_NTH_TRI(sm,(n<<5)+i);
679 >           v0_id = T_NTH_V(tri,0);
680 >           v1_id = T_NTH_V(tri,1);
681 >           v2_id = T_NTH_V(tri,2);
682 >           render_bg_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
683 >                         rgb[v2_id],vp,SM_VIEW_CENTER(sm),d);
684 >         }
685    glEnd();
686  
687  
688    glBegin(GL_TRIANGLES);
689 <  i=0;
690 <  while(td[i].tri != -1)
691 <     if(!SM_MIXED_TRI(sm,td[i].tri))
692 <        smRender_tri(sm,td[i++].tri,vp,clr);
693 <     else
694 <        smRender_mixed_tri(sm,td[i++].tri,vp,clr);
689 >  if(!td)
690 >  {
691 >    for(n=((SM_NUM_TRI(sm)+31)>>5) +1; --n;)
692 >     if(new_flag[n] & ~bg_flag[n])
693 >      for(i=0; i < 32; i++)
694 >        if(new_flag[n] & (1L << i) & ~bg_flag[n])
695 >         {
696 >           tri = SM_NTH_TRI(sm,(n<<5)+i);
697 >           /* Dont need to check for valid tri because flags are
698 >              cleared on delete
699 >            */
700 >           v0_id = T_NTH_V(tri,0);
701 >           v1_id = T_NTH_V(tri,1);
702 >           v2_id = T_NTH_V(tri,2);
703 >           bg0 = SM_DIR_ID(sm,v0_id) || SM_BASE_ID(sm,v0_id);
704 >           bg1 = SM_DIR_ID(sm,v1_id) || SM_BASE_ID(sm,v1_id);
705 >           bg2 = SM_DIR_ID(sm,v2_id) || SM_BASE_ID(sm,v2_id);
706 >           if(!(bg0 || bg1 || bg2))
707 >             render_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
708 >                        rgb[v2_id])
709 >           else
710 >             render_mixed_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],
711 >                              rgb[v1_id],rgb[v2_id],bg0,bg1,bg2,vp,
712 >                              SM_VIEW_CENTER(sm));
713 >         }
714 >  }
715 >  else
716 >  {
717 >    for(i=0; td[i].tri != -1;i++)
718 >    {
719 >      tri = SM_NTH_TRI(sm,td[i].tri);
720 >      /* Dont need to check for valid tri because flags are
721 >         cleared on delete
722 >         */
723 >      v0_id = T_NTH_V(tri,0);
724 >      v1_id = T_NTH_V(tri,1);
725 >      v2_id = T_NTH_V(tri,2);
726 >      bg0 = SM_DIR_ID(sm,v0_id) || SM_BASE_ID(sm,v0_id);
727 >      bg1 = SM_DIR_ID(sm,v1_id) || SM_BASE_ID(sm,v1_id);
728 >      bg2 = SM_DIR_ID(sm,v2_id) || SM_BASE_ID(sm,v2_id);
729 >      if(!(bg0 || bg1 || bg2))
730 >        render_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],rgb[v1_id],
731 >                   rgb[v2_id])
732 >          else
733 >            render_mixed_tri(wp[v0_id],wp[v1_id],wp[v2_id],rgb[v0_id],
734 >                             rgb[v1_id],rgb[v2_id],bg0,bg1,bg2,vp,
735 >                             SM_VIEW_CENTER(sm));
736 >    }
737 > #ifdef DEBUG
738 >    freebuf(td);
739 > #endif
740 >  }
741    glEnd();
742  
743    /* Restore Depth Test */
# Line 791 | Line 761 | smUpdate(view,qual)
761     int qual;
762   {
763    double d;
764 <  int last_update;
795 <  int t;
764 >  int last_update,t;
765  
766 +  if(!smMesh)
767 +    return;
768 +
769    /* If view has moved beyond epsilon from canonical: must rebuild -
770       epsilon is calculated as running avg of distance of sample points
771       from canonical view: m = 1/(AVG(1/r)): some fraction of this
772     */
801
802  if(!smMesh)
803    return;
773    d = DIST(view->vp,SM_VIEW_CENTER(smMesh));
774 <  if(qual >= 100 && d > SM_ALLOWED_VIEW_CHANGE(smMesh))
774 >  if(qual >= MAXQUALITY  && d > SM_ALLOWED_VIEW_CHANGE(smMesh))
775    {
776        /* Re-build the mesh */
777   #ifdef TEST_DRIVER
# Line 810 | Line 779 | smUpdate(view,qual)
779   #endif  
780        mark_tris_in_frustum(view);
781        smRebuild_mesh(smMesh,view);
782 +      smClean_notify = TRUE;
783    }
784 <  /* This is our final update iff qual==100 and view==&odev.v */
785 <  last_update = qual>=100 && view==&(odev.v);
784 >  /* This is our final update iff qual==MAXQUALITY and view==&odev.v */
785 >  last_update = qual>=MAXQUALITY && view==&(odev.v);
786    /* Check if we should draw ALL triangles in current frustum */
787 <  if(smClean_notify || smNew_tri_cnt > SM_SAMPLE_TRIS(smMesh)*SM_INC_PERCENT)
787 >  if(smClean_notify || smNew_tri_cnt>SM_SAMPLE_TRIS(smMesh)*SM_INC_PERCENT)
788    {
789   #ifdef TEST_DRIVER
790      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
791   #else
792 <    if ( SM_TONE_MAP(smMesh) < SM_NUM_SAMP(smMesh))
792 >    if (SM_TONE_MAP(smMesh) < SM_NUM_SAMP(smMesh))
793      {
794         tmClearHisto();
795         tmAddHisto(SM_BRT(smMesh),SM_NUM_SAMP(smMesh),1);
796 <       if(tmComputeMapping(0.,0.,0.) != TM_E_OK ||
797 <                   tmMapPixels(SM_RGB(smMesh),SM_BRT(smMesh),SM_CHR(smMesh),
798 <                                SM_NUM_SAMP(smMesh)) != TM_E_OK)
799 <            return;
796 >       if(tmComputeMapping(0.,0.,0.) != TM_E_OK)
797 >         return;
798 >       tmMapPixels(SM_RGB(smMesh),SM_BRT(smMesh),SM_CHR(smMesh),
799 >                   SM_NUM_SAMP(smMesh));
800      }
801   #endif
802      mark_tris_in_frustum(view);
803 <    if (qual <= 75)
803 >    if (qual <= (MAXQUALITY*3/4))
804          smRender_stree(smMesh,qual);
805      else
806 <        smRender_mesh(smMesh,view->vp,last_update);
806 >        smRender_mesh(smMesh,view->vp);
807   #ifdef TEST_DRIVER
808      glFlush();
809      glutSwapBuffers();
# Line 855 | Line 825 | smUpdate(view,qual)
825          if(tmComputeMapping(0.,0.,0.) != TM_E_OK)
826             return;
827      }
828 <    if(tmMapPixels(SM_NTH_RGB(smMesh,t),&SM_NTH_BRT(smMesh,t),
829 <                   SM_NTH_CHR(smMesh,t), SM_NUM_SAMP(smMesh)-t) != TM_E_OK)
830 <          return;
828 >      tmMapPixels(SM_NTH_RGB(smMesh,t),&SM_NTH_BRT(smMesh,t),
829 >                   SM_NTH_CHR(smMesh,t), SM_NUM_SAMP(smMesh)-t);
830 >        
831   #endif    
832      smUpdate_Rendered_mesh(smMesh,view->vp,last_update);
833      
# Line 877 | Line 847 | smUpdate(view,qual)
847    }
848  
849   }
850 +
851 +
852 +
853 +
854 +
855 +
856 +
857 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines