KiCad PCB EDA Suite
clayer_triangles.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
5  * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
31 #include "clayer_triangles.h"
32 #include <wx/debug.h> // For the wxASSERT
33 
34 
35 CLAYER_TRIANGLE_CONTAINER::CLAYER_TRIANGLE_CONTAINER( unsigned int aNrReservedTriangles,
36  bool aReserveNormals )
37 {
38  wxASSERT( aNrReservedTriangles > 0 );
39 
40  m_vertexs.clear();
41  m_normals.clear();
42 
43  m_vertexs.reserve( aNrReservedTriangles * 3 );
44 
45  if( aReserveNormals )
46  m_normals.reserve( aNrReservedTriangles * 3 );
47 }
48 
49 
50 void CLAYER_TRIANGLE_CONTAINER::Reserve_More( unsigned int aNrReservedTriangles,
51  bool aReserveNormals )
52 {
53  m_vertexs.reserve( m_vertexs.size() + aNrReservedTriangles * 3 );
54 
55  if( aReserveNormals )
56  m_normals.reserve( m_normals.size() + aNrReservedTriangles * 3 );
57 }
58 
59 
61  const SFVEC3F &aV2,
62  const SFVEC3F &aV3,
63  const SFVEC3F &aV4 )
64 {
65  m_vertexs.push_back( aV1 );
66  m_vertexs.push_back( aV2 );
67  m_vertexs.push_back( aV3 );
68 
69  m_vertexs.push_back( aV3 );
70  m_vertexs.push_back( aV4 );
71  m_vertexs.push_back( aV1 );
72 }
73 
74 
76  const SFVEC3F &aV2,
77  const SFVEC3F &aV3 )
78 {
79  m_vertexs.push_back( aV1 );
80  m_vertexs.push_back( aV2 );
81  m_vertexs.push_back( aV3 );
82 }
83 
84 
86  const SFVEC3F &aN2,
87  const SFVEC3F &aN3 )
88 {
89  m_normals.push_back( aN1 );
90  m_normals.push_back( aN2 );
91  m_normals.push_back( aN3 );
92 }
93 
95  const SFVEC3F &aN2,
96  const SFVEC3F &aN3,
97  const SFVEC3F &aN4 )
98 {
99  m_normals.push_back( aN1 );
100  m_normals.push_back( aN2 );
101  m_normals.push_back( aN3 );
102 
103  m_normals.push_back( aN3 );
104  m_normals.push_back( aN4 );
105  m_normals.push_back( aN1 );
106 }
107 
108 
109 CLAYER_TRIANGLES::CLAYER_TRIANGLES( unsigned int aNrReservedTriangles )
110 {
111  wxASSERT( aNrReservedTriangles > 0 );
112 
113  m_layer_top_segment_ends = new CLAYER_TRIANGLE_CONTAINER( aNrReservedTriangles,
114  false );
115  m_layer_top_triangles = new CLAYER_TRIANGLE_CONTAINER( aNrReservedTriangles,
116  false );
117  m_layer_middle_contourns_quads = new CLAYER_TRIANGLE_CONTAINER( aNrReservedTriangles,
118  true );
119  m_layer_bot_triangles = new CLAYER_TRIANGLE_CONTAINER( aNrReservedTriangles,
120  false );
121  m_layer_bot_segment_ends = new CLAYER_TRIANGLE_CONTAINER( aNrReservedTriangles,
122  false );
123 }
124 
125 
127 {
130 
131  delete m_layer_top_triangles;
133 
136 
137  delete m_layer_bot_triangles;
139 
142 }
143 
144 
145 void CLAYER_TRIANGLES::AddToMiddleContourns( const std::vector< SFVEC2F > &aContournPoints,
146  float zBot,
147  float zTop,
148  bool aInvertFaceDirection )
149 {
150  if( aContournPoints.size() > 4 )
151  {
152  // Calculate normals of each segment of the contourn
153  std::vector< SFVEC2F > contournNormals;
154 
155  contournNormals.clear();
156  contournNormals.resize( aContournPoints.size() - 1 );
157 
158  if( aInvertFaceDirection )
159  {
160  for( unsigned int i = 0; i < ( aContournPoints.size() - 1 ); ++i )
161  {
162  const SFVEC2F &v0 = aContournPoints[i + 0];
163  const SFVEC2F &v1 = aContournPoints[i + 1];
164 
165  const SFVEC2F n = glm::normalize( v1 - v0 );
166 
167  contournNormals[i] = SFVEC2F( n.y,-n.x );
168  }
169  }
170  else
171  {
172  for( unsigned int i = 0; i < ( aContournPoints.size() - 1 ); ++i )
173  {
174  const SFVEC2F &v0 = aContournPoints[i + 0];
175  const SFVEC2F &v1 = aContournPoints[i + 1];
176 
177  const SFVEC2F n = glm::normalize( v1 - v0 );
178 
179  contournNormals[i] = SFVEC2F( -n.y, n.x );
180  }
181  }
182 
183 
184  if( aInvertFaceDirection )
185  std::swap( zBot, zTop );
186 
187  const unsigned int nContournsToProcess = ( aContournPoints.size() - 1 );
188 
189  for( unsigned int i = 0; i < nContournsToProcess; ++i )
190  {
191  SFVEC2F lastNormal;
192 
193  if( i > 0 )
194  lastNormal = contournNormals[i - 1];
195  else
196  lastNormal = contournNormals[nContournsToProcess - 1];
197 
198  SFVEC2F n0 = contournNormals[i];
199 
200  // Only interpolate the normal if the angle is closer
201  if( glm::dot( n0, lastNormal ) > 0.5f )
202  n0 = glm::normalize( n0 + lastNormal );
203 
204  SFVEC2F nextNormal;
205 
206  if( i < (nContournsToProcess - 1) )
207  nextNormal = contournNormals[i + 1];
208  else
209  nextNormal = contournNormals[0];
210 
211  SFVEC2F n1 = contournNormals[i];
212 
213  if( glm::dot( n1, nextNormal ) > 0.5f )
214  n1 = glm::normalize( n1 + nextNormal );
215 
216  const SFVEC3F n3d0 = SFVEC3F( n0.x, n0.y, 0.0f );
217  const SFVEC3F n3d1 = SFVEC3F( n1.x, n1.y, 0.0f );
218 
219  const SFVEC2F &v0 = aContournPoints[i + 0];
220  const SFVEC2F &v1 = aContournPoints[i + 1];
221 
222  #pragma omp critical
223  {
224  m_layer_middle_contourns_quads->AddQuad( SFVEC3F( v0.x, v0.y, zTop ),
225  SFVEC3F( v1.x, v1.y, zTop ),
226  SFVEC3F( v1.x, v1.y, zBot ),
227  SFVEC3F( v0.x, v0.y, zBot ) );
228 
229  m_layer_middle_contourns_quads->AddNormal( n3d0, n3d1, n3d1, n3d0 );
230  }
231  }
232  }
233 }
234 
235 
237  float zBot,
238  float zTop,
239  double aBiuTo3Du,
240  bool aInvertFaceDirection )
241 {
242  std::vector< SFVEC2F >contournPoints;
243 
244  contournPoints.clear();
245  contournPoints.reserve( outlinePath.PointCount() + 2 );
246 
247  const VECTOR2I &firstV = outlinePath.CPoint( 0 );
248 
249  SFVEC2F lastV = SFVEC2F( firstV.x * aBiuTo3Du,
250  -firstV.y * aBiuTo3Du );
251 
252  contournPoints.push_back( lastV );
253 
254  for( unsigned int i = 1; i < (unsigned int)outlinePath.PointCount(); ++i )
255  {
256  const VECTOR2I & v = outlinePath.CPoint( i );
257 
258  const SFVEC2F vf = SFVEC2F( v.x * aBiuTo3Du,
259  -v.y * aBiuTo3Du );
260 
261  if( vf != lastV ) // Do not add repeated points
262  {
263  lastV = vf;
264  contournPoints.push_back( vf );
265  }
266  }
267 
268  // Add first position fo the list to close the path
269  if( lastV != contournPoints[0] )
270  contournPoints.push_back( contournPoints[0] );
271 
272  AddToMiddleContourns( contournPoints, zBot, zTop, aInvertFaceDirection );
273 }
274 
275 
277  float zBot,
278  float zTop,
279  double aBiuTo3Du,
280  bool aInvertFaceDirection )
281 {
282  wxASSERT( aPolySet.OutlineCount() > 0 );
283 
284  if( aPolySet.OutlineCount() == 0 )
285  return;
286 
287  // Calculate an estimation of points to reserve
288  unsigned int nrContournPointsToReserve = 0;
289 
290  for( int i = 0; i < aPolySet.OutlineCount(); ++i )
291  {
292  const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
293 
294  nrContournPointsToReserve += pathOutline.PointCount();
295 
296  for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
297  {
298  const SHAPE_LINE_CHAIN &hole = aPolySet.CHole( i, h );
299 
300  nrContournPointsToReserve += hole.PointCount();
301  }
302  }
303 
304  // Request to reserve more space
305  m_layer_middle_contourns_quads->Reserve_More( nrContournPointsToReserve * 2,
306  true );
307 
308  #pragma omp parallel for
309  for( signed int i = 0; i < aPolySet.OutlineCount(); ++i )
310  {
311  // Add outline
312  const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
313 
314  AddToMiddleContourns( pathOutline, zBot, zTop, aBiuTo3Du, aInvertFaceDirection );
315 
316  // Add holes for this outline
317  for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
318  {
319  const SHAPE_LINE_CHAIN &hole = aPolySet.CHole( i, h );
320  AddToMiddleContourns( hole, zBot, zTop, aBiuTo3Du, aInvertFaceDirection );
321  }
322  }
323 }
324 
325 
327  GLuint aTextureIndexForSegEnds,
328  float aZBot,
329  float aZTop )
330 {
331  m_zBot = aZBot;
332  m_zTop = aZTop;
333 
339 
340  if( aTextureIndexForSegEnds )
341  {
342  wxASSERT( glIsTexture( aTextureIndexForSegEnds ) );
343 
344  if( glIsTexture( aTextureIndexForSegEnds ) )
345  {
348  true,
349  aTextureIndexForSegEnds );
350 
353  false,
354  aTextureIndexForSegEnds );
355  }
356  }
357 
359  true );
360 
362  false );
363 
364 
365  if( aLayerTriangles.m_layer_middle_contourns_quads->GetVertexSize() > 0 )
366  {
369  }
370 
371  m_draw_it_transparent = false;
372  m_haveTransformation = false;
374  m_zScaleTransformation = 0.0f;
375 }
376 
377 
379 {
380  if( glIsList( m_layer_top_segment_ends ) )
381  glDeleteLists( m_layer_top_segment_ends, 1 );
382 
383  if( glIsList( m_layer_top_triangles ) )
384  glDeleteLists( m_layer_top_triangles, 1 );
385 
386  if( glIsList( m_layer_middle_contourns_quads ) )
387  glDeleteLists( m_layer_middle_contourns_quads, 1 );
388 
389  if( glIsList( m_layer_bot_triangles ) )
390  glDeleteLists( m_layer_bot_triangles, 1 );
391 
392  if( glIsList( m_layer_bot_segment_ends ) )
393  glDeleteLists( m_layer_bot_segment_ends, 1 );
394 
400 }
401 
402 
404 {
406 
407  if( glIsList( m_layer_middle_contourns_quads ) )
408  glCallList( m_layer_middle_contourns_quads );
409 
410  if( glIsList( m_layer_top_triangles ) )
411  glCallList( m_layer_top_triangles );
412 
413  if( glIsList( m_layer_top_segment_ends ) )
414  glCallList( m_layer_top_segment_ends );
415 
417 }
418 
419 
421 {
423 
424  if( glIsList( m_layer_middle_contourns_quads ) )
425  glCallList( m_layer_middle_contourns_quads );
426 
427  if( glIsList( m_layer_bot_triangles ) )
428  glCallList( m_layer_bot_triangles );
429 
430  if( glIsList( m_layer_bot_segment_ends ) )
431  glCallList( m_layer_bot_segment_ends );
432 
434 }
435 
436 
438 {
440 
441  if( glIsList( m_layer_top_triangles ) )
442  glCallList( m_layer_top_triangles );
443 
444  if( glIsList( m_layer_top_segment_ends ) )
445  glCallList( m_layer_top_segment_ends );
446 
448 }
449 
450 
452 {
454 
455  if( glIsList( m_layer_bot_triangles ) )
456  glCallList( m_layer_bot_triangles );
457 
458  if( glIsList( m_layer_bot_segment_ends ) )
459  glCallList( m_layer_bot_segment_ends );
460 
462 }
463 
464 
466 {
468 
469  if( glIsList( m_layer_middle_contourns_quads ) )
470  glCallList( m_layer_middle_contourns_quads );
471 
473 }
474 
475 
476 void CLAYERS_OGL_DISP_LISTS::DrawAll( bool aDrawMiddle ) const
477 {
479 
480  if( aDrawMiddle )
481  if( glIsList( m_layer_middle_contourns_quads ) )
482  glCallList( m_layer_middle_contourns_quads );
483 
484  if( glIsList( m_layer_top_triangles ) )
485  glCallList( m_layer_top_triangles );
486 
487  if( glIsList( m_layer_bot_triangles ) )
488  glCallList( m_layer_bot_triangles );
489 
490  if( glIsList( m_layer_top_segment_ends ) )
491  glCallList( m_layer_top_segment_ends );
492 
493  if( glIsList( m_layer_bot_segment_ends ) )
494  glCallList( m_layer_bot_segment_ends );
495 
497 }
498 
499 
500 void CLAYERS_OGL_DISP_LISTS::DrawAllCameraCulled(float zCameraPos, bool aDrawMiddle ) const
501 {
502  zCameraPos = m_haveTransformation?( (zCameraPos - m_zPositionTransformation ) /
503  m_zScaleTransformation ):zCameraPos;
504 
505  if( aDrawMiddle )
506  DrawMiddle();
507 
508  if( zCameraPos > m_zTop )
509  {
510  DrawTop();
511  }
512  else
513  {
514  if( zCameraPos < m_zBot )
515  {
516  DrawBot();
517  }
518  else
519  {
520  // If camera is in the middle dont draw it
521  }
522  }
523 }
524 
525 
527  const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractA,
528  const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractB,
529  bool aDrawMiddle ) const
530 {
531  if( aDrawMiddle )
532  DrawMiddle();
533 
534  glClearStencil( 0x00 );
535  glClear( GL_STENCIL_BUFFER_BIT );
536 
537  glEnable( GL_CULL_FACE );
538  glCullFace( GL_BACK );
539 
540  glDisable( GL_DEPTH_TEST );
541  glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
542  glDepthMask( GL_FALSE );
543  glEnable( GL_STENCIL_TEST );
544  glStencilFunc( GL_ALWAYS, 1, 0 );
545  glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
546 
547  if( aLayerToSubtractA )
548  aLayerToSubtractA->DrawBot();
549 
550  if( aLayerToSubtractB )
551  aLayerToSubtractB->DrawBot();
552 
553 
554  //if( !m_draw_it_transparent )
555  {
556  glEnable(GL_DEPTH_TEST);
557  glDepthMask(GL_TRUE);
558  }
559 
560  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
561  glStencilFunc( GL_EQUAL, 0, 1 );
562  glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
563  DrawBot();
564 
565  glDisable( GL_DEPTH_TEST );
566  glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
567  glDepthMask( GL_FALSE );
568  glEnable( GL_STENCIL_TEST );
569  glStencilFunc( GL_ALWAYS, 2, 0 );
570  glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
571 
572  if( aLayerToSubtractA )
573  aLayerToSubtractA->DrawTop();
574 
575  if( aLayerToSubtractB )
576  aLayerToSubtractB->DrawTop();
577 
578  //if( !m_draw_it_transparent )
579  {
580  glEnable(GL_DEPTH_TEST);
581  glDepthMask(GL_TRUE);
582  }
583 
584  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
585  glStencilFunc( GL_NOTEQUAL, 2, 0x03 );
586  glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
587  DrawTop();
588 
589 
590  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE );
591 
592  glCullFace( GL_FRONT );
593  glStencilFunc( GL_GEQUAL, 3, 0x03 );
594  glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
595  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
596 
597  if( aDrawMiddle )
598  {
599  if( aLayerToSubtractA )
600  aLayerToSubtractA->DrawMiddle();
601 
602  // It will not render the middle contours of the layer.
603  // It is used with vias and holes (copper vias and to subtract solder
604  // mask holes). But since in the vias, it will draw a cylinder
605  // and in soldermask it doesn't need to draw the contour.
606  // so it is not used the middle part of B
607 // if( aLayerToSubtractB )
608 // aLayerToSubtractB->DrawMiddle();
609  }
610 
611  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
612 
613  glCullFace( GL_BACK );
614  glDisable( GL_STENCIL_TEST );
615 
616 /*
617  if( m_draw_it_transparent )
618  {
619  glEnable(GL_DEPTH_TEST);
620  glDepthMask(GL_TRUE);
621  }*/
622 }
623 
624 
626  float aZscale )
627 {
628  wxASSERT( aZscale > FLT_EPSILON );
629 
630  m_zPositionTransformation = aZposition;
631  m_zScaleTransformation = aZscale;
632  m_haveTransformation = true;
633 }
634 
635 
636 void CLAYERS_OGL_DISP_LISTS::SetItIsTransparent( bool aSetTransparent )
637 {
638  m_draw_it_transparent = aSetTransparent;
639 }
640 
641 
643  const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer,
644  bool aIsNormalUp,
645  GLuint aTextureId ) const
646 {
647  wxASSERT( aTriangleContainer != NULL );
648 
649  wxASSERT( (aTriangleContainer->GetVertexSize() % 3) == 0 );
650 
651  // Top and Bot dont have normals array stored in container
652  wxASSERT( aTriangleContainer->GetNormalsSize() == 0 );
653 
654  if( (aTriangleContainer->GetVertexSize() > 0) &&
655  ((aTriangleContainer->GetVertexSize() % 3) == 0) )
656  {
657  GLuint listIdx = glGenLists( 1 );
658 
659  if( glIsList( listIdx ) )
660  {
661  // Prepare an array of UV text coordinates
662  SFVEC2F *uvArray = new SFVEC2F[aTriangleContainer->GetVertexSize()];
663 
664  for( unsigned int i = 0;
665  i < aTriangleContainer->GetVertexSize();
666  i += 3 )
667  {
668  uvArray[i + 0] = SFVEC2F( 1.0f, 0.0f );
669  uvArray[i + 1] = SFVEC2F( 0.0f, 1.0f );
670  uvArray[i + 2] = SFVEC2F( 0.0f, 0.0f );
671  }
672 
673  glEnableClientState( GL_TEXTURE_COORD_ARRAY );
674  glDisableClientState( GL_COLOR_ARRAY );
675  glDisableClientState( GL_NORMAL_ARRAY );
676  glEnableClientState( GL_VERTEX_ARRAY );
677  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
678  glTexCoordPointer( 2, GL_FLOAT, 0, uvArray );
679 
680  glNewList( listIdx, GL_COMPILE );
681 
682  glDisable( GL_COLOR_MATERIAL );
683 
684  glEnable( GL_TEXTURE_2D );
685  glBindTexture( GL_TEXTURE_2D, aTextureId );
686 
688 
689  glAlphaFunc( GL_GREATER, 0.2f );
690  glEnable( GL_ALPHA_TEST );
691 
692  glNormal3f( 0.0f, 0.0f, aIsNormalUp?1.0f:-1.0f );
693 
694  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
695 
696  glDisable( GL_TEXTURE_2D );
697  glDisable( GL_ALPHA_TEST );
698  glDisable( GL_BLEND );
699 
700  glEndList();
701 
702  glDisableClientState( GL_VERTEX_ARRAY );
703  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
704 
705  delete [] uvArray;
706  return listIdx;
707  }
708  }
709 
710  return 0;
711 }
712 
713 
715  const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer,
716  bool aIsNormalUp ) const
717 {
718  wxASSERT( aTriangleContainer != NULL );
719 
720  wxASSERT( (aTriangleContainer->GetVertexSize() % 3) == 0 );
721 
722  // Top and Bot dont have normals array stored in container
723  wxASSERT( aTriangleContainer->GetNormalsSize() == 0 );
724 
725  if( (aTriangleContainer->GetVertexSize() > 0) &&
726  ( (aTriangleContainer->GetVertexSize() % 3) == 0) )
727  {
728  const GLuint listIdx = glGenLists( 1 );
729 
730  if( glIsList( listIdx ) )
731  {
732  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
733  glDisableClientState( GL_COLOR_ARRAY );
734  glDisableClientState( GL_NORMAL_ARRAY );
735  glEnableClientState( GL_VERTEX_ARRAY );
736  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
737 
738  glNewList( listIdx, GL_COMPILE );
739 
741 
742  glNormal3f( 0.0f, 0.0f, aIsNormalUp?1.0f:-1.0f );
743 
744  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
745 
746  glDisable( GL_BLEND );
747  glEndList();
748 
749  glDisableClientState( GL_VERTEX_ARRAY );
750 
751  return listIdx;
752  }
753  }
754 
755  return 0;
756 }
757 
758 
760  const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer ) const
761 {
762  wxASSERT( aTriangleContainer != NULL );
763 
764  // We expect that it is a multiple of 3 vertex
765  wxASSERT( (aTriangleContainer->GetVertexSize() % 3) == 0 );
766 
767  // We expect that it is a multiple of 6 vertex (because we expect to add quads)
768  wxASSERT( (aTriangleContainer->GetVertexSize() % 6) == 0 );
769 
770  // We expect that there are normals with same size as vertex
771  wxASSERT( aTriangleContainer->GetNormalsSize() == aTriangleContainer->GetVertexSize() );
772 
773 
774  if( ( aTriangleContainer->GetVertexSize() > 0 ) &&
775  ( (aTriangleContainer->GetVertexSize() % 3) == 0 ) &&
776  ( (aTriangleContainer->GetVertexSize() % 6) == 0 ) &&
777  ( aTriangleContainer->GetNormalsSize() == aTriangleContainer->GetVertexSize() ) )
778  {
779  const GLuint listIdx = glGenLists( 1 );
780 
781  if( glIsList( listIdx ) )
782  {
783  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
784  glDisableClientState( GL_COLOR_ARRAY );
785  glEnableClientState( GL_NORMAL_ARRAY );
786  glEnableClientState( GL_VERTEX_ARRAY );
787  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
788  glNormalPointer( GL_FLOAT, 0, aTriangleContainer->GetNormalsPointer() );
789 
790  glNewList( listIdx, GL_COMPILE );
791 
793 
794  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
795 
796  glDisable( GL_BLEND );
797  glEndList();
798 
799  glDisableClientState( GL_VERTEX_ARRAY );
800  glDisableClientState( GL_NORMAL_ARRAY );
801 
802  return listIdx;
803  }
804  }
805 
806  return 0;
807 }
808 
809 
811 {
813  {
814  glPopMatrix();
815  }
816 }
817 
818 
820 {
821  glEnable( GL_BLEND );
822  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
823 }
824 
825 
827 {
829  {
830  glPushMatrix();
831  glTranslatef( 0.0f, 0.0f, m_zPositionTransformation );
832  glScalef( 1.0f, 1.0f, m_zScaleTransformation );
833  }
834 }
The CLAYER_TRIANGLES class stores arrays of triangles to be used to create display lists...
int PointCount() const
Function PointCount()
GLuint generate_middle_triangles(const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer) const
GLuint generate_top_or_bot_seg_ends(const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer, bool aIsNormalUp, GLuint aTextureId) const
int HoleCount(int aOutline) const
Returns the number of holes in a given outline
void DrawTopAndMiddle() const
DrawTopAndMiddle - This function calls the display lists for the top elements and middle contourns...
const float * GetVertexPointer() const
GetVertexPointer - Get the array of vertexes.
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
void DrawMiddle() const
DrawMiddle - This function calls the display lists for the middle elements.
int OutlineCount() const
Returns the number of outlines in the set
CLAYER_TRIANGLE_CONTAINER(unsigned int aNrReservedTriangles, bool aReserveNormals)
CLAYER_TRIANGLE_CONTAINER.
void ApplyScalePosition(float aZposition, float aZscale)
~CLAYER_TRIANGLES()
~CLAYER_TRIANGLES - Free containers
CLAYER_TRIANGLES(unsigned int aNrReservedTriangles)
CLAYER_TRIANGLES - initialize arrays with reserved triangles.
The CLAYER_TRIANGLE_CONTAINER class stores an manage vector of triangles.
glm::vec2 SFVEC2F
Definition: xv3d_types.h:45
Class SHAPE_POLY_SET.
CLAYERS_OGL_DISP_LISTS(const CLAYER_TRIANGLES &aLayerTriangles, GLuint aTextureIndexForSegEnds, float aZBot, float aZTop)
CLAYERS_OGL_DISP_LISTS - Creates the display lists for a layer.
CLAYER_TRIANGLE_CONTAINER * m_layer_top_triangles
~CLAYERS_OGL_DISP_LISTS()
~CLAYERS_OGL_DISP_LISTS - Destroy this class while free the display lists from GPU mem ...
void DrawTop() const
DrawTop - This function calls the display lists for the top elements.
CLAYER_TRIANGLE_CONTAINER * m_layer_middle_contourns_quads
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
SFVEC3F_VECTOR m_vertexs
vertex array
const float * GetNormalsPointer() const
GetNormalsPointer - Get the array of normals.
void AddNormal(const SFVEC3F &aN1, const SFVEC3F &aN2, const SFVEC3F &aN3)
AddNormal.
void AddTriangle(const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3)
AddTriangle.
void AddToMiddleContourns(const SHAPE_LINE_CHAIN &outlinePath, float zBot, float zTop, double aBiuTo3Du, bool aInvertFaceDirection)
unsigned int GetNormalsSize() const
GetNormalsSize.
The CLAYERS_OGL_DISP_LISTS class stores the openGL display lists to related with a layer...
void Reserve_More(unsigned int aNrReservedTriangles, bool aReserveNormals)
Reserve_More - reserve more triangles.
void DrawBot() const
DrawBot - This function calls the display lists for the botton elements.
void DrawAllCameraCulledSubtractLayer(const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractA, const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractB, bool aDrawMiddle=true) const
CLAYER_TRIANGLE_CONTAINER * m_layer_bot_segment_ends
unsigned int GetVertexSize() const
GetVertexSize.
void DrawBotAndMiddle() const
DrawBotAndMiddle - This function calls the display lists for the botton elements and middle contourns...
GLuint generate_top_or_bot_triangles(const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer, bool aIsNormalUp) const
void DrawAllCameraCulled(float zCameraPos, bool aDrawMiddle=true) const
DrawAllCameraCulled - Draw all layers if they are visible by the camera.
CLAYER_TRIANGLE_CONTAINER * m_layer_bot_triangles
Class SHAPE_LINE_CHAIN.
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
void SetItIsTransparent(bool aSetTransparent)
void beginTransformation() const
CLAYER_TRIANGLE_CONTAINER * m_layer_top_segment_ends
const VECTOR2I & CPoint(int aIndex) const
Function CPoint()
void DrawAll(bool aDrawMiddle=true) const
DrawAll - This function calls all the display lists.
SFVEC3F_VECTOR m_normals
normals array
void AddQuad(const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3, const SFVEC3F &aV4)
AddQuad.