0022819: Redesign of OpenGl driver
[occt.git] / src / OpenGl / OpenGl_TriangleStrip.cxx
1 // File:      OpenGl_TriangleStrip.cxx
2 // Created:   13 July 2011
3 // Author:    Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
5
6 #include <OpenGl_tgl_all.hxx>
7 #include <GL/gl.h>
8
9 #include <OpenGl_TriangleStrip.hxx>
10
11 #include <OpenGl_telem_util.hxx>
12 #include <OpenGl_TextureBox.hxx>
13
14 #include <OpenGl_AspectFace.hxx>
15 #include <OpenGl_Structure.hxx>
16
17 /*----------------------------------------------------------------------*/
18
19 void draw_degenerates_as_points ( PDS_INTERNAL, tel_point, Tint, const Handle(OpenGl_Workspace) & );
20 void draw_degenerates_as_bboxs  ( PDS_INTERNAL, tel_point, Tint, const Handle(OpenGl_Workspace) & );
21 extern void set_drawable_items  ( GLboolean*, int, const float           );
22
23 /*----------------------------------------------------------------------*/
24
25 void OpenGl_TriangleStrip::draw_tmesh (const Tint front_lighting_model,
26                                       const Aspect_InteriorStyle interior_style,
27                                       const TEL_COLOUR *edge_colour,
28                                       const Handle(OpenGl_Workspace) &AWorkspace) const
29 {
30   Tint              i, newList = 0;
31
32   tel_point pfn = myData.fnormals;
33   tel_colour pfc = myData.fcolours;
34   tel_point pv  = myData.vertices;
35   tel_colour pvc = myData.vcolours;
36   tel_point pvn = myData.vnormals;
37   tel_texture_coord pvt = myData.vtexturecoord;
38
39   if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT ) pvc = pfc = 0;
40
41   if ( AWorkspace->DegenerateModel < 2 && interior_style != Aspect_IS_EMPTY )
42   {
43     if ( front_lighting_model )
44       glEnable(GL_LIGHTING);
45     else
46       glDisable(GL_LIGHTING);
47
48     if ( (AWorkspace->NamedStatus & OPENGL_NS_ANIMATION) == 0 )
49       goto doDraw; /* Disable object display list out of animation */
50     if ( myDS->model != front_lighting_model || !myDS->list || myDS->model == -1 ||
51         ( AWorkspace->DegenerateModel && myDS->skipRatio != AWorkspace->SkipRatio ) )
52     {
53         myDS->skipRatio = AWorkspace->SkipRatio;
54         myDS->model     = front_lighting_model;
55         myDS->degMode   = AWorkspace->DegenerateModel;
56
57         if ( AWorkspace->SkipRatio <= 0.f ) {
58
59           if ( !myDS->list ) myDS->list = glGenLists ( 1 );
60
61           glNewList ( myDS->list, GL_COMPILE_AND_EXECUTE );
62           newList = 1;
63 doDraw:
64           glBegin ( GL_TRIANGLE_STRIP );
65
66           if ( front_lighting_model )
67           {
68             if ( pvt && (AWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0 )
69             {
70               for ( i = 0; i < myData.num_facets + 2; ++i )
71               {
72                 glNormal3fv   ( pvn[ i ].xyz );
73                 glTexCoord2fv ( pvt[ i ].xy  );
74                 glVertex3fv   ( pv [ i ].xyz );
75               }
76             }
77             else
78               for ( i = 0; i < myData.num_facets + 2; ++i )
79               {
80                 glNormal3fv( pvn[ i ].xyz );
81                 glVertex3fv( pv[  i ].xyz );
82               }
83           }
84           else
85           {
86             if ( pvc )
87             {
88               for ( i = 0; i < myData.num_facets + 2; ++i )
89               {
90                 glColor3fv  ( pvc[ i ].rgb );
91                 glVertex3fv ( pv [ i ].xyz );
92               }
93             }
94             else if ( pfc )
95             {
96               glColor3fv  ( pfc[ 0 ].rgb );
97               glVertex3fv ( pv [ 0 ].xyz );
98               glVertex3fv ( pv [ 1 ].xyz );
99               for ( i = 2; i < myData.num_facets + 2; ++i )
100               {
101                 glColor3fv ( pfc[ i - 2 ].rgb );
102                 glVertex3fv( pv [ i     ].xyz );
103               }
104             }
105             else
106               for ( i = 0; i < myData.num_facets + 2; ++i ) glVertex3fv ( pv[ i ].xyz );
107           }
108           glEnd ();
109         }
110         else if ( AWorkspace->SkipRatio < 1.f )
111         {
112           set_drawable_items ( myDS->bDraw, myData.num_facets + 2, AWorkspace->SkipRatio );
113
114           if ( !myDS->dlist ) myDS->dlist = glGenLists ( 1 );
115
116           glNewList ( myDS->dlist, GL_COMPILE_AND_EXECUTE );
117           newList = 1;
118
119           glBegin ( GL_TRIANGLES );
120
121           if ( front_lighting_model )
122           {
123             if ( pvt && (AWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0 )
124             {
125               for ( i = 0; i < myData.num_facets; ++i )
126               {
127                 if ( myDS->bDraw[ i ] )
128                 {
129                   if ( i % 2 )
130                   {
131                     glNormal3fv   ( pvn[ i     ].xyz );
132                     glTexCoord2fv ( pvt[ i     ].xy  );
133                     glVertex3fv   ( pv [ i     ].xyz );
134                     glNormal3fv   ( pvn[ i + 2 ].xyz );
135                     glTexCoord2fv ( pvt[ i + 2 ].xy  );
136                     glVertex3fv   ( pv [ i + 2 ].xyz );
137                     glNormal3fv   ( pvn[ i + 1 ].xyz );
138                     glTexCoord2fv ( pvt[ i + 1 ].xy  );
139                     glVertex3fv   ( pv [ i + 1 ].xyz );
140                   }
141                   else
142                   {
143                     glNormal3fv   ( pvn[ i + 2 ].xyz );
144                     glTexCoord2fv ( pvt[ i + 2 ].xy  );
145                     glVertex3fv   ( pv [ i + 2 ].xyz );
146                     glNormal3fv   ( pvn[ i     ].xyz );
147                     glTexCoord2fv ( pvt[ i     ].xy  );
148                     glVertex3fv   ( pv [ i     ].xyz );
149                     glNormal3fv   ( pvn[ i + 1 ].xyz );
150                     glTexCoord2fv ( pvt[ i + 1 ].xy  );
151                     glVertex3fv   ( pv [ i + 1 ].xyz );
152                   }
153                 }
154               }
155             }
156             else
157             {
158               for ( i = 0; i < myData.num_facets; ++i )
159               {
160                 if ( myDS->bDraw[ i ] )
161                 {
162                   if ( i % 2 )
163                   {
164                     glNormal3fv( pvn[ i     ].xyz );
165                     glVertex3fv( pv[  i     ].xyz );
166                     glNormal3fv( pvn[ i + 2 ].xyz );
167                     glVertex3fv( pv[  i + 2 ].xyz );
168                     glNormal3fv( pvn[ i + 1 ].xyz );
169                     glVertex3fv( pv[  i + 1 ].xyz );
170                   }
171                   else
172                   {
173                     glNormal3fv( pvn[ i + 2 ].xyz );
174                     glVertex3fv( pv[  i + 2 ].xyz );
175                     glNormal3fv( pvn[ i     ].xyz );
176                     glVertex3fv( pv[  i     ].xyz );
177                     glNormal3fv( pvn[ i + 1 ].xyz );
178                     glVertex3fv( pv[  i + 1 ].xyz );
179                   }
180                 }
181               }
182             }
183           }
184           else
185           {
186             if ( pvc )
187             {
188               for ( i = 0; i < myData.num_facets; ++i )
189               {
190                 if ( myDS->bDraw[ i ] )
191                 {
192                   if ( i % 2 )
193                   {
194                     glColor3fv  ( pvc[ i     ].rgb );
195                     glVertex3fv ( pv [ i     ].xyz );
196                     glColor3fv  ( pvc[ i + 2 ].rgb );
197                     glVertex3fv ( pv [ i + 2 ].xyz );
198                     glColor3fv  ( pvc[ i + 1 ].rgb );
199                     glVertex3fv ( pv [ i + 1 ].xyz );
200                   }
201                   else
202                   {
203                     glColor3fv  ( pvc[ i + 2 ].rgb );
204                     glVertex3fv ( pv [ i + 2 ].xyz );
205                     glColor3fv  ( pvc[ i     ].rgb );
206                     glVertex3fv ( pv [ i     ].xyz );
207                     glColor3fv  ( pvc[ i + 1 ].rgb );
208                     glVertex3fv ( pv [ i + 1 ].xyz );
209                   }
210                 }
211               }
212             }
213             else if ( pfc )
214             {
215               for ( i = 0; i < myData.num_facets; ++i )
216               {
217                 if ( myDS->bDraw[ i ] )
218                 {
219                   if ( i % 2 )
220                   {
221                     glColor3fv ( pfc[ i     ].rgb );
222                     glVertex3fv( pv [ i     ].xyz );
223                     glColor3fv ( pfc[ i + 2 ].rgb );
224                     glVertex3fv( pv [ i + 2 ].xyz );
225                     glColor3fv ( pfc[ i + 1 ].rgb );
226                     glVertex3fv( pv [ i + 1 ].xyz );
227                   }
228                   else
229                   {
230                     glColor3fv ( pfc[ i + 2 ].rgb );
231                     glVertex3fv( pv [ i + 2 ].xyz );
232                     glColor3fv ( pfc[ i     ].rgb );
233                     glVertex3fv( pv [ i     ].xyz );
234                     glColor3fv ( pfc[ i + 1 ].rgb );
235                     glVertex3fv( pv [ i + 1 ].xyz );
236                   }
237                 }
238               }
239             }
240             else
241             {
242               for ( i = 0; i < myData.num_facets; ++i )
243               {
244                 if ( myDS->bDraw[ i ] )
245                 {
246                   if ( i % 2 )
247                   {
248                     glVertex3fv ( pv[ i     ].xyz );
249                     glVertex3fv ( pv[ i + 2 ].xyz );
250                     glVertex3fv ( pv[ i + 1 ].xyz );
251                   }
252                   else
253                   {
254                     glVertex3fv ( pv[ i + 2 ].xyz );
255                     glVertex3fv ( pv[ i     ].xyz );
256                     glVertex3fv ( pv[ i + 1 ].xyz );
257                   }
258                 }
259               }
260             }
261           }
262           glEnd ();
263         }
264         else
265         {
266           if ( !myDS->dlist ) myDS->dlist = glGenLists ( 1 );
267
268           glNewList ( myDS->dlist, GL_COMPILE_AND_EXECUTE );
269           newList = 1;
270         }
271         if ( newList ) glEndList ();
272
273         if ( AWorkspace->DegenerateModel ) return;
274       }
275       else
276       {
277         glCallList ( AWorkspace->SkipRatio <= 0.f ? myDS->list : myDS->dlist );
278         if ( AWorkspace->DegenerateModel ) return;
279       }
280   }
281
282   i = 0;
283
284   /* OCC11904 -- Temporarily disable environment mapping */
285   glPushAttrib(GL_ENABLE_BIT);
286   glDisable(GL_TEXTURE_1D);
287   glDisable(GL_TEXTURE_2D);
288
289   switch ( AWorkspace->DegenerateModel )
290   {
291     default:
292       break;
293
294     case 2:  /* XXX_TDM_WIREFRAME */
295       i = 1;
296       break;
297
298     case 3:  /* XXX_TDM_MARKER */
299       draw_degenerates_as_points ( myDS, myData.vertices, myData.num_facets + 2, AWorkspace );
300       glPopAttrib();
301       return;
302
303     case 4:  /* XXX_TDM_BBOX */
304       draw_degenerates_as_bboxs ( myDS, myData.vertices, myData.num_facets + 2, AWorkspace );
305       glPopAttrib();
306       return;
307   }
308
309   draw_edges ( edge_colour, interior_style, i, AWorkspace );
310
311   glPopAttrib();
312 }
313
314 /*----------------------------------------------------------------------*/
315
316 void OpenGl_TriangleStrip::draw_edges (const TEL_COLOUR *edge_colour, const Aspect_InteriorStyle interior_style,
317                                       Tint forceDraw, const Handle(OpenGl_Workspace) &AWorkspace) const
318 {
319   const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace( Standard_True );
320
321   if ( interior_style != Aspect_IS_HIDDENLINE && !forceDraw && aspect_face->Context().Edge == TOff )
322     return;
323
324   glDisable(GL_LIGHTING);
325   const GLboolean texture_on = IsTextureEnabled();
326   if ( texture_on ) DisableTexture();
327
328   // Setup line aspect
329   const OpenGl_AspectLine *aspect_line_old = AWorkspace->SetAspectLine( aspect_face->AspectEdge() );
330   AWorkspace->AspectLine( Standard_True );
331
332   tel_point pv = myData.vertices;
333   Tint i, newList = 0;
334
335   glColor3fv ( edge_colour->rgb );
336   if ( !forceDraw )
337     draw_line_loop ();
338   else
339   {
340     if ( (AWorkspace->NamedStatus & OPENGL_NS_ANIMATION) == 0 )
341       goto doDraw; /* Disable object display list out of animation */
342     if ( myDS->degMode != 2 || myDS->skipRatio != AWorkspace->SkipRatio || !myDS->dlist ) {
343
344       if ( !myDS->dlist ) myDS->dlist = glGenLists ( 1 );
345
346       myDS->degMode   = 2;
347       myDS->skipRatio = AWorkspace->SkipRatio;
348       glNewList ( myDS->dlist, GL_COMPILE_AND_EXECUTE );
349       newList = 1;
350 doDraw:
351       glPushAttrib ( GL_DEPTH_BUFFER_BIT );
352       glDisable ( GL_DEPTH_TEST );
353
354       if ( AWorkspace->SkipRatio <= 0.f )
355
356         draw_line_loop ();
357
358       else if ( AWorkspace->SkipRatio < 1.f ) {
359
360         set_drawable_items ( myDS->bDraw, myData.num_facets + 2, AWorkspace->SkipRatio );
361
362         for ( i = 0; i < myData.num_facets; ++i )
363
364           if ( myDS->bDraw[ i ] ) {
365
366             glBegin ( GL_LINE_LOOP );
367             glVertex3fv ( pv[ i     ].xyz );
368             glVertex3fv ( pv[ i + 1 ].xyz );
369             glVertex3fv ( pv[ i + 2 ].xyz );
370             glEnd();
371
372           }  /* end if */
373
374       }  /* end if */
375
376       glPopAttrib ();
377       if ( newList ) glEndList ();
378
379     } else glCallList ( myDS->dlist );
380
381   }  /* end else */
382
383   // Restore line context
384   AWorkspace->SetAspectLine( aspect_line_old );
385
386   if ( texture_on ) EnableTexture ();
387 }
388
389 void draw_degenerates_as_points ( PDS_INTERNAL pd, tel_point p, Tint n, const Handle(OpenGl_Workspace) &AWorkspace )
390 {
391   int i, newList = 0; 
392
393   glDisable(GL_LIGHTING);
394   if ( (AWorkspace->NamedStatus & OPENGL_NS_ANIMATION) == 0 )
395     goto doDraw; /* Disable object display list out of animation */
396   if ( pd -> degMode != 3 || pd -> skipRatio != AWorkspace->SkipRatio || !pd -> dlist ) {
397
398     if ( !pd -> dlist ) pd -> dlist = glGenLists ( 1 );
399
400     pd -> degMode   = 3;
401     pd -> skipRatio = AWorkspace->SkipRatio;
402     glNewList ( pd -> dlist, GL_COMPILE_AND_EXECUTE );
403     newList = 1;
404
405     if ( AWorkspace->SkipRatio <= 0.f ) {
406 doDraw:
407       glBegin ( GL_POINTS );
408
409       for ( i = 0; i < n; ++i ) glVertex3fv ( p[ i ].xyz );
410
411       glEnd ();
412
413     } else if ( AWorkspace->SkipRatio < 1.f ) {
414
415       set_drawable_items ( pd -> bDraw, n, AWorkspace->SkipRatio );
416
417       glBegin ( GL_POINTS );
418
419       for ( i = 0; i < n; ++i )
420
421         if ( pd -> bDraw[ i ] ) glVertex3fv ( p[ i ].xyz );
422
423       glEnd ();
424
425     }  /* end if */
426     if ( newList ) glEndList ();
427
428   } else glCallList ( pd -> dlist );
429
430 }  /* end draw_degenerates_as_points */
431
432 void draw_degenerates_as_bboxs ( PDS_INTERNAL pd, tel_point p, Tint n, const Handle(OpenGl_Workspace) &AWorkspace )
433 {
434   int     i, newList = 0;
435   GLfloat minp[ 3 ] = { FLT_MAX, FLT_MAX, FLT_MAX };
436   GLfloat maxp[ 3 ] = { FLT_MIN, FLT_MIN, FLT_MIN };
437
438   glDisable(GL_LIGHTING);
439   if ( (AWorkspace->NamedStatus & OPENGL_NS_ANIMATION) == 0 )
440     goto doDraw; /* Disable object display list out of animation */
441   if ( pd -> degMode != 4 || !pd -> dlist ) {
442
443     if ( !pd -> dlist ) pd -> dlist = glGenLists ( 1 );
444
445     pd -> degMode = 4;
446
447     glNewList ( pd -> dlist, GL_COMPILE_AND_EXECUTE );
448     newList = 1; 
449 doDraw:
450     for ( i = 0; i < n; ++i ) {
451
452       TEL_POINT pt = p[ i ];
453
454       if ( pt.xyz[ 0 ] < minp[ 0 ] )
455         minp[ 0 ] = pt.xyz[ 0 ] ;
456       if ( pt.xyz[ 1 ] < minp[ 1 ] )
457         minp[ 1 ] = pt.xyz[ 1 ] ;
458       if ( pt.xyz[ 2 ] < minp[ 2 ] )
459         minp[ 2 ] = pt.xyz[ 2 ] ;
460
461       if ( pt.xyz[ 0 ] > maxp[ 0 ] )
462         maxp[ 0 ] = pt.xyz[ 0 ] ;
463       if ( pt.xyz[ 1 ] > maxp[ 1 ] )
464         maxp[ 1 ] = pt.xyz[ 1 ] ;
465       if ( pt.xyz[ 2 ] > maxp[ 2 ] )
466         maxp[ 2 ] = pt.xyz[ 2 ] ;
467
468     }  /* end for */
469
470     glBegin ( GL_LINE_STRIP );
471
472     glVertex3fv ( minp );
473     glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
474     glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
475     glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
476     glVertex3f ( minp[ 0 ], minp[ 1 ], minp[ 2 ] );
477
478     glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
479     glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
480     glVertex3f ( maxp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
481     glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
482     glVertex3f ( maxp[ 0 ], minp[ 1 ], minp[ 2 ] );
483
484     glVertex3f ( maxp[ 0 ], minp[ 1 ], maxp[ 2 ] );
485     glVertex3f ( minp[ 0 ], minp[ 1 ], maxp[ 2 ] );
486     glVertex3f ( minp[ 0 ], maxp[ 1 ], maxp[ 2 ] );
487     glVertex3fv ( maxp );
488     glVertex3f ( maxp[ 0 ], maxp[ 1 ], minp[ 2 ] );
489     glVertex3f ( minp[ 0 ], maxp[ 1 ], minp[ 2 ] );
490
491     glEnd();
492     if ( newList ) glEndList ();
493
494   } else glCallList ( pd -> dlist );
495
496 }  /* end draw_degenerates_as_bboxs */
497
498 void OpenGl_TriangleStrip::draw_line_loop () const
499 {
500   int i;
501
502   for ( i = 0; i < myData.num_facets; ++i )
503   {
504     glBegin ( GL_LINE_LOOP );
505     glVertex3fv ( myData.vertices[ i     ].xyz );
506     glVertex3fv ( myData.vertices[ i + 1 ].xyz );
507     glVertex3fv ( myData.vertices[ i + 2 ].xyz );
508     glEnd();
509   }
510 }
511
512 /*----------------------------------------------------------------------*/
513
514 OpenGl_TriangleStrip::OpenGl_TriangleStrip (const Graphic3d_Array1OfVertex& AListVertex)
515 {
516   const Standard_Integer nv = AListVertex.Length();
517   TEL_POINT *points = new TEL_POINT[nv];
518   memcpy( points, &AListVertex(AListVertex.Lower()), nv*sizeof(TEL_POINT) );
519
520   Init(nv - 2,points,NULL,NULL,NULL,NULL,NULL);
521 }
522
523 /*----------------------------------------------------------------------*/
524
525 OpenGl_TriangleStrip::OpenGl_TriangleStrip (const Graphic3d_Array1OfVertexN& AListVertex)
526 {
527   const Standard_Integer nv = AListVertex.Length ();
528
529   // Dynamic allocation
530   TEL_POINT *points = new TEL_POINT[nv];
531   TEL_POINT *normals = new TEL_POINT[nv];
532
533   Standard_Integer i = 0, j = AListVertex.Lower();
534   Standard_Real X, Y, Z;
535   for ( ; i < nv; i++, j++)
536   {
537     AListVertex(j).Coord (X, Y, Z);
538     points[i].xyz[0] = float (X);
539     points[i].xyz[1] = float (Y);
540     points[i].xyz[2] = float (Z);
541     AListVertex(j).Normal (X, Y, Z);
542     normals[i].xyz[0] = float (X);
543     normals[i].xyz[1] = float (Y);
544     normals[i].xyz[2] = float (Z);
545   }
546
547   Init(nv - 2,points,normals,NULL,NULL,NULL,NULL);
548 }
549
550 /*----------------------------------------------------------------------*/
551
552 OpenGl_TriangleStrip::OpenGl_TriangleStrip (const Graphic3d_Array1OfVertexNT& AListVertex)
553 {
554   const Standard_Integer nv = AListVertex.Length();
555
556   // Dynamic allocation
557   TEL_POINT *points = new TEL_POINT[nv];
558   TEL_POINT *normals = new TEL_POINT[nv];
559   TEL_TEXTURE_COORD *tcoords = new TEL_TEXTURE_COORD[nv];
560
561   Standard_Integer i = 0, j = AListVertex.Upper();
562   Standard_Real X, Y, Z;
563   for ( ; i < nv; i++, j++)
564   {
565     AListVertex(j).Coord (X, Y, Z);
566     points[i].xyz[0] = float (X);
567     points[i].xyz[1] = float (Y);
568     points[i].xyz[2] = float (Z);
569     AListVertex(j).Normal (X, Y, Z);
570     normals[i].xyz[0] = float (X);
571     normals[i].xyz[1] = float (Y);
572     normals[i].xyz[2] = float (Z);
573     AListVertex(j).TextureCoordinate(X, Y);
574     tcoords[i].xy[0] = float(X);
575     tcoords[i].xy[1] = float(Y);
576   }
577
578   Init(nv - 2,points,normals,NULL,tcoords,NULL,NULL);
579 }
580
581 /*----------------------------------------------------------------------*/
582
583 void OpenGl_TriangleStrip::Init (const Tint ANbFacets, tel_point AVertices,
584                                 tel_point AVNormals, tel_colour AVColors, tel_texture_coord ATCoords,
585                                 tel_point AFNormals, tel_colour AFColors)
586 {
587   myData.num_facets = ANbFacets;
588
589   const Tint nv = ANbFacets + 2;
590
591   Tint i;
592
593   // Store vertices
594   myData.vertices = AVertices;
595
596   // Store or compute (based on vertices) facet normals
597   if (AFNormals)
598   {
599     myData.facet_flag = TEL_FA_NORMAL;
600     myData.fnormals = AFNormals;
601     for( i = 0; i < ANbFacets; i++ )
602       vecnrm( myData.fnormals[i].xyz );
603   }
604   else
605   {
606     myData.facet_flag = TEL_FA_NONE;
607     myData.fnormals = new TEL_POINT[ANbFacets];
608     for( i = 0; i < ANbFacets; i++ )
609     {
610       if( i & 1 ) {
611         TelGetNormal( myData.vertices[i].xyz, myData.vertices[i+2].xyz, myData.vertices[i+1].xyz, myData.fnormals[i].xyz );
612       } else {
613         TelGetNormal( myData.vertices[i].xyz, myData.vertices[i+1].xyz, myData.vertices[i+2].xyz, myData.fnormals[i].xyz );
614       }
615     }
616   }
617
618   // Store or compute (based on facet normals) vertex normals
619   if (AVNormals)
620   {
621     myData.vertex_flag = TEL_VT_NORMAL;
622     myData.vnormals = AVNormals;
623     for( i = 0; i < nv; i++ )
624       vecnrm( myData.vnormals[i].xyz );
625   }
626   else
627   {
628     myData.vertex_flag = TEL_VT_NONE;
629     myData.vnormals = new TEL_POINT[nv];
630     for( i = 2; i < ANbFacets; i++ )
631     {
632       myData.vnormals[i].xyz[0] = ( myData.fnormals[i-2].xyz[0] + myData.fnormals[i-1].xyz[0] + myData.fnormals[i].xyz[0] ) / 3.0F;
633       myData.vnormals[i].xyz[1] = ( myData.fnormals[i-2].xyz[1] + myData.fnormals[i-1].xyz[1] + myData.fnormals[i].xyz[1] ) / 3.0F;
634       myData.vnormals[i].xyz[2] = ( myData.fnormals[i-2].xyz[2] + myData.fnormals[i-1].xyz[2] + myData.fnormals[i].xyz[2] ) / 3.0F;
635     }
636     myData.vnormals[0] = myData.fnormals[0];
637     if( ANbFacets > 1 )
638     {
639       myData.vnormals[1].xyz[0] = ( myData.fnormals[0].xyz[0] + myData.fnormals[1].xyz[0] ) / 2.0F;
640       myData.vnormals[1].xyz[1] = ( myData.fnormals[0].xyz[1] + myData.fnormals[1].xyz[1] ) / 2.0F;
641       myData.vnormals[1].xyz[2] = ( myData.fnormals[0].xyz[2] + myData.fnormals[1].xyz[2] ) / 2.0F;
642     }
643     else
644       myData.vnormals[1] = myData.fnormals[0];
645     // last vertex
646     myData.vnormals[ANbFacets+1] = myData.fnormals[ANbFacets-1];
647     // second last vertex
648     if( ANbFacets > 1 )
649     {
650       myData.vnormals[ANbFacets].xyz[0] = ( myData.fnormals[ANbFacets-1].xyz[0] + myData.fnormals[ANbFacets-2].xyz[0] ) / 2.0F;
651       myData.vnormals[ANbFacets].xyz[1] = ( myData.fnormals[ANbFacets-1].xyz[1] + myData.fnormals[ANbFacets-2].xyz[1] ) / 2.0F;
652       myData.vnormals[ANbFacets].xyz[2] = ( myData.fnormals[ANbFacets-1].xyz[2] + myData.fnormals[ANbFacets-2].xyz[2] ) / 2.0F;
653     }
654   }
655
656   myData.vcolours = AVColors;
657   myData.vtexturecoord = ATCoords;
658   myData.fcolours = AFColors;
659
660   myDS = new DS_INTERNAL();
661   myDS->list      =  0;
662   myDS->dlist     =  0;
663   myDS->degMode   =  0;
664   myDS->model     = -1;
665   myDS->skipRatio =  0.0F;
666   myDS->bDraw = new unsigned char[nv];
667 }
668
669 /*----------------------------------------------------------------------*/
670
671 OpenGl_TriangleStrip::~OpenGl_TriangleStrip ()
672 {
673   if( myData.fnormals )
674     delete[] myData.fnormals;
675   if( myData.fcolours )
676     delete[] myData.fcolours;
677   if( myData.vertices )
678     delete[] myData.vertices;
679   if( myData.vcolours )
680     delete[] myData.vcolours;
681   if( myData.vnormals )
682     delete[] myData.vnormals;
683   if ( myData.vtexturecoord )
684     delete[] myData.vtexturecoord;
685
686   if ( myDS )
687   {
688     if (  GET_GL_CONTEXT() != NULL  )
689     {
690       if ( myDS->list ) glDeleteLists ( myDS->list, 1 );
691       if ( myDS->dlist ) glDeleteLists ( myDS->dlist, 1 );
692     }
693     if ( myDS->bDraw )
694       delete[] myDS->bDraw;
695
696         delete myDS;
697   }
698 }
699
700 /*----------------------------------------------------------------------*/
701
702 void OpenGl_TriangleStrip::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
703 {
704   const OpenGl_AspectFace *aspect_face = AWorkspace->AspectFace( Standard_True );
705
706   Tint front_lighting_model = aspect_face->Context().IntFront.color_mask;
707   const TEL_COLOUR *interior_colour = &aspect_face->Context().IntFront.matcol;
708   const TEL_COLOUR *edge_colour = &aspect_face->AspectEdge()->Color();
709
710   // Use highlight colors
711   if ( AWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT )
712   {                         
713     edge_colour = interior_colour = AWorkspace->HighlightColor;
714     front_lighting_model = 0;
715   }
716
717   glColor3fv( interior_colour->rgb );
718
719   draw_tmesh( front_lighting_model,
720               aspect_face->Context().InteriorStyle,
721               edge_colour,
722               AWorkspace );
723 }
724
725 /*----------------------------------------------------------------------*/