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