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 {
131  delete m_layer_top_segment_ends;
132  m_layer_top_segment_ends = 0;
133 
134  delete m_layer_top_triangles;
135  m_layer_top_triangles = 0;
136 
137  delete m_layer_middle_contourns_quads;
138  m_layer_middle_contourns_quads = 0;
139 
140  delete m_layer_bot_triangles;
141  m_layer_bot_triangles = 0;
142 
143  delete m_layer_bot_segment_ends;
144  m_layer_bot_segment_ends = 0;
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 
168  const SFVEC2F n = glm::normalize( v1 - v0 );
169 
170  contournNormals[i] = SFVEC2F( n.y,-n.x );
171  }
172  }
173  else
174  {
175  for( unsigned int i = 0; i < ( aContournPoints.size() - 1 ); ++i )
176  {
177  const SFVEC2F &v0 = aContournPoints[i + 0];
178  const SFVEC2F &v1 = aContournPoints[i + 1];
179 
180  const SFVEC2F n = glm::normalize( v1 - v0 );
181 
182  contournNormals[i] = SFVEC2F( -n.y, n.x );
183  }
184  }
185 
186 
187  if( aInvertFaceDirection )
188  std::swap( zBot, zTop );
189 
190  const unsigned int nContournsToProcess = ( aContournPoints.size() - 1 );
191 
192  for( unsigned int i = 0; i < nContournsToProcess; ++i )
193  {
194  SFVEC2F lastNormal;
195 
196  if( i > 0 )
197  lastNormal = contournNormals[i - 1];
198  else
199  lastNormal = contournNormals[nContournsToProcess - 1];
200 
201  SFVEC2F n0 = contournNormals[i];
202 
203  // Only interpolate the normal if the angle is closer
204  if( glm::dot( n0, lastNormal ) > 0.5f )
205  n0 = glm::normalize( n0 + lastNormal );
206 
207  SFVEC2F nextNormal;
208 
209  if( i < (nContournsToProcess - 1) )
210  nextNormal = contournNormals[i + 1];
211  else
212  nextNormal = contournNormals[0];
213 
214  SFVEC2F n1 = contournNormals[i];
215 
216  if( glm::dot( n1, nextNormal ) > 0.5f )
217  n1 = glm::normalize( n1 + nextNormal );
218 
219  const SFVEC3F n3d0 = SFVEC3F( n0.x, n0.y, 0.0f );
220  const SFVEC3F n3d1 = SFVEC3F( n1.x, n1.y, 0.0f );
221 
222  const SFVEC2F &v0 = aContournPoints[i + 0];
223  const SFVEC2F &v1 = aContournPoints[i + 1];
224 
225  {
226  std::lock_guard<std::mutex> lock( m_middle_layer_lock );
227  m_layer_middle_contourns_quads->AddQuad( SFVEC3F( v0.x, v0.y, zTop ),
228  SFVEC3F( v1.x, v1.y, zTop ),
229  SFVEC3F( v1.x, v1.y, zBot ),
230  SFVEC3F( v0.x, v0.y, zBot ) );
231 
232  m_layer_middle_contourns_quads->AddNormal( n3d0, n3d1, n3d1, n3d0 );
233  }
234  }
235  }
236 }
237 
238 
240  float zBot,
241  float zTop,
242  double aBiuTo3Du,
243  bool aInvertFaceDirection )
244 {
245  std::vector< SFVEC2F >contournPoints;
246 
247  contournPoints.clear();
248  contournPoints.reserve( outlinePath.PointCount() + 2 );
249 
250  const VECTOR2I &firstV = outlinePath.CPoint( 0 );
251 
252  SFVEC2F lastV = SFVEC2F( firstV.x * aBiuTo3Du,
253  -firstV.y * aBiuTo3Du );
254 
255  contournPoints.push_back( lastV );
256 
257  for( unsigned int i = 1; i < (unsigned int)outlinePath.PointCount(); ++i )
258  {
259  const VECTOR2I & v = outlinePath.CPoint( i );
260 
261  const SFVEC2F vf = SFVEC2F( v.x * aBiuTo3Du,
262  -v.y * aBiuTo3Du );
263 
264  if( vf != lastV ) // Do not add repeated points
265  {
266  lastV = vf;
267  contournPoints.push_back( vf );
268  }
269  }
270 
271  // Add first position fo the list to close the path
272  if( lastV != contournPoints[0] )
273  contournPoints.push_back( contournPoints[0] );
274 
275  AddToMiddleContourns( contournPoints, zBot, zTop, aInvertFaceDirection );
276 }
277 
278 
280  float zBot,
281  float zTop,
282  double aBiuTo3Du,
283  bool aInvertFaceDirection )
284 {
285  wxASSERT( aPolySet.OutlineCount() > 0 );
286 
287  if( aPolySet.OutlineCount() == 0 )
288  return;
289 
290  // Calculate an estimation of points to reserve
291  unsigned int nrContournPointsToReserve = 0;
292 
293  for( int i = 0; i < aPolySet.OutlineCount(); ++i )
294  {
295  const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
296 
297  nrContournPointsToReserve += pathOutline.PointCount();
298 
299  for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
300  {
301  const SHAPE_LINE_CHAIN &hole = aPolySet.CHole( i, h );
302 
303  nrContournPointsToReserve += hole.PointCount();
304  }
305  }
306 
307  // Request to reserve more space
308  m_layer_middle_contourns_quads->Reserve_More( nrContournPointsToReserve * 2,
309  true );
310 
311  std::atomic<int> nextItem( 0 );
312  std::atomic<size_t> threadsFinished( 0 );
313 
314  size_t parallelThreadCount = std::min<size_t>(
315  std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
316  static_cast<size_t>( aPolySet.OutlineCount() ) );
317  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
318  {
319  std::thread t = std::thread( [&]()
320  {
321  for( int i = nextItem.fetch_add( 1 );
322  i < aPolySet.OutlineCount();
323  i = nextItem.fetch_add( 1 ) )
324  {
325  // Add outline
326  const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
327 
328  AddToMiddleContourns( pathOutline, zBot, zTop, aBiuTo3Du, aInvertFaceDirection );
329 
330  // Add holes for this outline
331  for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
332  {
333  const SHAPE_LINE_CHAIN &hole = aPolySet.CHole( i, h );
334  AddToMiddleContourns( hole, zBot, zTop, aBiuTo3Du, aInvertFaceDirection );
335  }
336  }
337 
338  threadsFinished++;
339  } );
340 
341  t.detach();
342  }
343 
344  while( threadsFinished < parallelThreadCount )
345  std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
346 }
347 
348 
350  GLuint aTextureIndexForSegEnds,
351  float aZBot,
352  float aZTop )
353 {
354  m_zBot = aZBot;
355  m_zTop = aZTop;
356 
357  m_layer_top_segment_ends = 0;
358  m_layer_top_triangles = 0;
359  m_layer_middle_contourns_quads = 0;
360  m_layer_bot_triangles = 0;
361  m_layer_bot_segment_ends = 0;
362 
363  if( aTextureIndexForSegEnds )
364  {
365  wxASSERT( glIsTexture( aTextureIndexForSegEnds ) );
366 
367  if( glIsTexture( aTextureIndexForSegEnds ) )
368  {
369  m_layer_top_segment_ends =
370  generate_top_or_bot_seg_ends( aLayerTriangles.m_layer_top_segment_ends,
371  true,
372  aTextureIndexForSegEnds );
373 
374  m_layer_bot_segment_ends =
375  generate_top_or_bot_seg_ends( aLayerTriangles.m_layer_bot_segment_ends,
376  false,
377  aTextureIndexForSegEnds );
378  }
379  }
380 
381  m_layer_top_triangles = generate_top_or_bot_triangles( aLayerTriangles.m_layer_top_triangles,
382  true );
383 
384  m_layer_bot_triangles = generate_top_or_bot_triangles( aLayerTriangles.m_layer_bot_triangles,
385  false );
386 
387 
388  if( aLayerTriangles.m_layer_middle_contourns_quads->GetVertexSize() > 0 )
389  {
390  m_layer_middle_contourns_quads =
391  generate_middle_triangles( aLayerTriangles.m_layer_middle_contourns_quads );
392  }
393 
394  m_draw_it_transparent = false;
395  m_haveTransformation = false;
396  m_zPositionTransformation = 0.0f;
397  m_zScaleTransformation = 0.0f;
398 }
399 
400 
402 {
403  if( glIsList( m_layer_top_segment_ends ) )
404  glDeleteLists( m_layer_top_segment_ends, 1 );
405 
406  if( glIsList( m_layer_top_triangles ) )
407  glDeleteLists( m_layer_top_triangles, 1 );
408 
409  if( glIsList( m_layer_middle_contourns_quads ) )
410  glDeleteLists( m_layer_middle_contourns_quads, 1 );
411 
412  if( glIsList( m_layer_bot_triangles ) )
413  glDeleteLists( m_layer_bot_triangles, 1 );
414 
415  if( glIsList( m_layer_bot_segment_ends ) )
416  glDeleteLists( m_layer_bot_segment_ends, 1 );
417 
418  m_layer_top_segment_ends = 0;
419  m_layer_top_triangles = 0;
420  m_layer_middle_contourns_quads = 0;
421  m_layer_bot_triangles = 0;
422  m_layer_bot_segment_ends = 0;
423 }
424 
425 
427 {
428  beginTransformation();
429 
430  if( glIsList( m_layer_middle_contourns_quads ) )
431  glCallList( m_layer_middle_contourns_quads );
432 
433  if( glIsList( m_layer_top_triangles ) )
434  glCallList( m_layer_top_triangles );
435 
436  if( glIsList( m_layer_top_segment_ends ) )
437  glCallList( m_layer_top_segment_ends );
438 
439  endTransformation();
440 }
441 
442 
444 {
445  beginTransformation();
446 
447  if( glIsList( m_layer_middle_contourns_quads ) )
448  glCallList( m_layer_middle_contourns_quads );
449 
450  if( glIsList( m_layer_bot_triangles ) )
451  glCallList( m_layer_bot_triangles );
452 
453  if( glIsList( m_layer_bot_segment_ends ) )
454  glCallList( m_layer_bot_segment_ends );
455 
456  endTransformation();
457 }
458 
459 
461 {
462  beginTransformation();
463 
464  if( glIsList( m_layer_top_triangles ) )
465  glCallList( m_layer_top_triangles );
466 
467  if( glIsList( m_layer_top_segment_ends ) )
468  glCallList( m_layer_top_segment_ends );
469 
470  endTransformation();
471 }
472 
473 
475 {
476  beginTransformation();
477 
478  if( glIsList( m_layer_bot_triangles ) )
479  glCallList( m_layer_bot_triangles );
480 
481  if( glIsList( m_layer_bot_segment_ends ) )
482  glCallList( m_layer_bot_segment_ends );
483 
484  endTransformation();
485 }
486 
487 
489 {
490  beginTransformation();
491 
492  if( glIsList( m_layer_middle_contourns_quads ) )
493  glCallList( m_layer_middle_contourns_quads );
494 
495  endTransformation();
496 }
497 
498 
499 void CLAYERS_OGL_DISP_LISTS::DrawAll( bool aDrawMiddle ) const
500 {
501  beginTransformation();
502 
503  if( aDrawMiddle )
504  if( glIsList( m_layer_middle_contourns_quads ) )
505  glCallList( m_layer_middle_contourns_quads );
506 
507  if( glIsList( m_layer_top_triangles ) )
508  glCallList( m_layer_top_triangles );
509 
510  if( glIsList( m_layer_bot_triangles ) )
511  glCallList( m_layer_bot_triangles );
512 
513  if( glIsList( m_layer_top_segment_ends ) )
514  glCallList( m_layer_top_segment_ends );
515 
516  if( glIsList( m_layer_bot_segment_ends ) )
517  glCallList( m_layer_bot_segment_ends );
518 
519  endTransformation();
520 }
521 
522 
523 void CLAYERS_OGL_DISP_LISTS::DrawAllCameraCulled(float zCameraPos, bool aDrawMiddle ) const
524 {
525  zCameraPos = m_haveTransformation?( (zCameraPos - m_zPositionTransformation ) /
526  m_zScaleTransformation ):zCameraPos;
527 
528  if( aDrawMiddle )
529  DrawMiddle();
530 
531  if( zCameraPos > m_zTop )
532  {
533  DrawTop();
534  }
535  else
536  {
537  if( zCameraPos < m_zBot )
538  {
539  DrawBot();
540  }
541  else
542  {
543  // If camera is in the middle dont draw it
544  }
545  }
546 }
547 
548 
550  const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractA,
551  const CLAYERS_OGL_DISP_LISTS *aLayerToSubtractB,
552  bool aDrawMiddle ) const
553 {
554  if( aDrawMiddle )
555  DrawMiddle();
556 
557  glClearStencil( 0x00 );
558  glClear( GL_STENCIL_BUFFER_BIT );
559 
560  glEnable( GL_CULL_FACE );
561  glCullFace( GL_BACK );
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, 1, 0 );
568  glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
569 
570  if( aLayerToSubtractA )
571  aLayerToSubtractA->DrawBot();
572 
573  if( aLayerToSubtractB )
574  aLayerToSubtractB->DrawBot();
575 
576 
577  //if( !m_draw_it_transparent )
578  {
579  glEnable(GL_DEPTH_TEST);
580  glDepthMask(GL_TRUE);
581  }
582 
583  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
584  glStencilFunc( GL_EQUAL, 0, 1 );
585  glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
586  DrawBot();
587 
588  glDisable( GL_DEPTH_TEST );
589  glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
590  glDepthMask( GL_FALSE );
591  glEnable( GL_STENCIL_TEST );
592  glStencilFunc( GL_ALWAYS, 2, 0 );
593  glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
594 
595  if( aLayerToSubtractA )
596  aLayerToSubtractA->DrawTop();
597 
598  if( aLayerToSubtractB )
599  aLayerToSubtractB->DrawTop();
600 
601  //if( !m_draw_it_transparent )
602  {
603  glEnable(GL_DEPTH_TEST);
604  glDepthMask(GL_TRUE);
605  }
606 
607  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
608  glStencilFunc( GL_NOTEQUAL, 2, 0x03 );
609  glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
610  DrawTop();
611 
612 
613  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE );
614 
615  glCullFace( GL_FRONT );
616  glStencilFunc( GL_GEQUAL, 3, 0x03 );
617  glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
618  glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
619 
620  if( aDrawMiddle )
621  {
622  if( aLayerToSubtractA )
623  aLayerToSubtractA->DrawMiddle();
624 
625  // It will not render the middle contours of the layer.
626  // It is used with vias and holes (copper vias and to subtract solder
627  // mask holes). But since in the vias, it will draw a cylinder
628  // and in soldermask it doesn't need to draw the contour.
629  // so it is not used the middle part of B
630 // if( aLayerToSubtractB )
631 // aLayerToSubtractB->DrawMiddle();
632  }
633 
634  glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
635 
636  glCullFace( GL_BACK );
637  glDisable( GL_STENCIL_TEST );
638 
639 /*
640  if( m_draw_it_transparent )
641  {
642  glEnable(GL_DEPTH_TEST);
643  glDepthMask(GL_TRUE);
644  }*/
645 }
646 
647 
649  float aZscale )
650 {
651  wxASSERT( aZscale > FLT_EPSILON );
652 
653  m_zPositionTransformation = aZposition;
654  m_zScaleTransformation = aZscale;
655  m_haveTransformation = true;
656 }
657 
658 
659 void CLAYERS_OGL_DISP_LISTS::SetItIsTransparent( bool aSetTransparent )
660 {
661  m_draw_it_transparent = aSetTransparent;
662 }
663 
664 
666  const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer,
667  bool aIsNormalUp,
668  GLuint aTextureId ) const
669 {
670  wxASSERT( aTriangleContainer != NULL );
671 
672  wxASSERT( (aTriangleContainer->GetVertexSize() % 3) == 0 );
673 
674  // Top and Bot dont have normals array stored in container
675  wxASSERT( aTriangleContainer->GetNormalsSize() == 0 );
676 
677  if( (aTriangleContainer->GetVertexSize() > 0) &&
678  ((aTriangleContainer->GetVertexSize() % 3) == 0) )
679  {
680  GLuint listIdx = glGenLists( 1 );
681 
682  if( glIsList( listIdx ) )
683  {
684  // Prepare an array of UV text coordinates
685  SFVEC2F *uvArray = new SFVEC2F[aTriangleContainer->GetVertexSize()];
686 
687  for( unsigned int i = 0;
688  i < aTriangleContainer->GetVertexSize();
689  i += 3 )
690  {
691  uvArray[i + 0] = SFVEC2F( 1.0f, 0.0f );
692  uvArray[i + 1] = SFVEC2F( 0.0f, 1.0f );
693  uvArray[i + 2] = SFVEC2F( 0.0f, 0.0f );
694  }
695 
696  glEnableClientState( GL_TEXTURE_COORD_ARRAY );
697  glDisableClientState( GL_COLOR_ARRAY );
698  glDisableClientState( GL_NORMAL_ARRAY );
699  glEnableClientState( GL_VERTEX_ARRAY );
700  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
701  glTexCoordPointer( 2, GL_FLOAT, 0, uvArray );
702 
703  glNewList( listIdx, GL_COMPILE );
704 
705  glDisable( GL_COLOR_MATERIAL );
706 
707  glEnable( GL_TEXTURE_2D );
708  glBindTexture( GL_TEXTURE_2D, aTextureId );
709 
710  setBlendfunction();
711 
712  glAlphaFunc( GL_GREATER, 0.2f );
713  glEnable( GL_ALPHA_TEST );
714 
715  glNormal3f( 0.0f, 0.0f, aIsNormalUp?1.0f:-1.0f );
716 
717  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
718 
719  glDisable( GL_TEXTURE_2D );
720  glDisable( GL_ALPHA_TEST );
721  glDisable( GL_BLEND );
722 
723  glEndList();
724 
725  glDisableClientState( GL_VERTEX_ARRAY );
726  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
727 
728  delete [] uvArray;
729  return listIdx;
730  }
731  }
732 
733  return 0;
734 }
735 
736 
738  const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer,
739  bool aIsNormalUp ) const
740 {
741  wxASSERT( aTriangleContainer != NULL );
742 
743  wxASSERT( (aTriangleContainer->GetVertexSize() % 3) == 0 );
744 
745  // Top and Bot dont have normals array stored in container
746  wxASSERT( aTriangleContainer->GetNormalsSize() == 0 );
747 
748  if( (aTriangleContainer->GetVertexSize() > 0) &&
749  ( (aTriangleContainer->GetVertexSize() % 3) == 0) )
750  {
751  const GLuint listIdx = glGenLists( 1 );
752 
753  if( glIsList( listIdx ) )
754  {
755  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
756  glDisableClientState( GL_COLOR_ARRAY );
757  glDisableClientState( GL_NORMAL_ARRAY );
758  glEnableClientState( GL_VERTEX_ARRAY );
759  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
760 
761  glNewList( listIdx, GL_COMPILE );
762 
763  setBlendfunction();
764 
765  glNormal3f( 0.0f, 0.0f, aIsNormalUp?1.0f:-1.0f );
766 
767  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
768 
769  glDisable( GL_BLEND );
770  glEndList();
771 
772  glDisableClientState( GL_VERTEX_ARRAY );
773 
774  return listIdx;
775  }
776  }
777 
778  return 0;
779 }
780 
781 
783  const CLAYER_TRIANGLE_CONTAINER *aTriangleContainer ) const
784 {
785  wxASSERT( aTriangleContainer != NULL );
786 
787  // We expect that it is a multiple of 3 vertex
788  wxASSERT( (aTriangleContainer->GetVertexSize() % 3) == 0 );
789 
790  // We expect that it is a multiple of 6 vertex (because we expect to add quads)
791  wxASSERT( (aTriangleContainer->GetVertexSize() % 6) == 0 );
792 
793  // We expect that there are normals with same size as vertex
794  wxASSERT( aTriangleContainer->GetNormalsSize() == aTriangleContainer->GetVertexSize() );
795 
796 
797  if( ( aTriangleContainer->GetVertexSize() > 0 ) &&
798  ( (aTriangleContainer->GetVertexSize() % 3) == 0 ) &&
799  ( (aTriangleContainer->GetVertexSize() % 6) == 0 ) &&
800  ( aTriangleContainer->GetNormalsSize() == aTriangleContainer->GetVertexSize() ) )
801  {
802  const GLuint listIdx = glGenLists( 1 );
803 
804  if( glIsList( listIdx ) )
805  {
806  glDisableClientState( GL_TEXTURE_COORD_ARRAY );
807  glDisableClientState( GL_COLOR_ARRAY );
808  glEnableClientState( GL_NORMAL_ARRAY );
809  glEnableClientState( GL_VERTEX_ARRAY );
810  glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
811  glNormalPointer( GL_FLOAT, 0, aTriangleContainer->GetNormalsPointer() );
812 
813  glNewList( listIdx, GL_COMPILE );
814 
815  setBlendfunction();
816 
817  glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
818 
819  glDisable( GL_BLEND );
820  glEndList();
821 
822  glDisableClientState( GL_VERTEX_ARRAY );
823  glDisableClientState( GL_NORMAL_ARRAY );
824 
825  return listIdx;
826  }
827  }
828 
829  return 0;
830 }
831 
832 
834 {
835  if( m_haveTransformation )
836  {
837  glPopMatrix();
838  }
839 }
840 
841 
843 {
844  glEnable( GL_BLEND );
845  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
846 }
847 
848 
850 {
851  if( m_haveTransformation )
852  {
853  glPushMatrix();
854  glTranslatef( 0.0f, 0.0f, m_zPositionTransformation );
855  glScalef( 1.0f, 1.0f, m_zScaleTransformation );
856  }
857 }
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)
size_t i
Definition: json11.cpp:597
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.