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  if( aPolySet.OutlineCount() == 0 )
286  return;
287 
288  // Calculate an estimation of points to reserve
289  unsigned int nrContournPointsToReserve = 0;
290 
291  for( int i = 0; i < aPolySet.OutlineCount(); ++i )
292  {
293  const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
294 
295  nrContournPointsToReserve += pathOutline.PointCount();
296 
297  for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
298  {
299  const SHAPE_LINE_CHAIN &hole = aPolySet.CHole( i, h );
300 
301  nrContournPointsToReserve += hole.PointCount();
302  }
303  }
304 
305  // Request to reserve more space
306  m_layer_middle_contourns_quads->Reserve_More( nrContournPointsToReserve * 2,
307  true );
308 
309  for( 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 
334  m_layer_top_segment_ends = 0;
335  m_layer_top_triangles = 0;
336  m_layer_middle_contourns_quads = 0;
337  m_layer_bot_triangles = 0;
338  m_layer_bot_segment_ends = 0;
339 
340  if( aTextureIndexForSegEnds )
341  {
342  wxASSERT( glIsTexture( aTextureIndexForSegEnds ) );
343 
344  if( glIsTexture( aTextureIndexForSegEnds ) )
345  {
346  m_layer_top_segment_ends =
347  generate_top_or_bot_seg_ends( aLayerTriangles.m_layer_top_segment_ends,
348  true,
349  aTextureIndexForSegEnds );
350 
351  m_layer_bot_segment_ends =
352  generate_top_or_bot_seg_ends( aLayerTriangles.m_layer_bot_segment_ends,
353  false,
354  aTextureIndexForSegEnds );
355  }
356  }
357 
358  m_layer_top_triangles = generate_top_or_bot_triangles( aLayerTriangles.m_layer_top_triangles,
359  true );
360 
361  m_layer_bot_triangles = generate_top_or_bot_triangles( aLayerTriangles.m_layer_bot_triangles,
362  false );
363 
364 
365  if( aLayerTriangles.m_layer_middle_contourns_quads->GetVertexSize() > 0 )
366  {
367  m_layer_middle_contourns_quads =
368  generate_middle_triangles( aLayerTriangles.m_layer_middle_contourns_quads );
369  }
370 
371  m_draw_it_transparent = false;
372  m_haveTransformation = false;
373  m_zPositionTransformation = 0.0f;
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 
395  m_layer_top_segment_ends = 0;
396  m_layer_top_triangles = 0;
397  m_layer_middle_contourns_quads = 0;
398  m_layer_bot_triangles = 0;
399  m_layer_bot_segment_ends = 0;
400 }
401 
402 
404 {
405  beginTransformation();
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 
416  endTransformation();
417 }
418 
419 
421 {
422  beginTransformation();
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 
433  endTransformation();
434 }
435 
436 
438 {
439  beginTransformation();
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 
447  endTransformation();
448 }
449 
450 
452 {
453  beginTransformation();
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 
461  endTransformation();
462 }
463 
464 
466 {
467  beginTransformation();
468 
469  if( glIsList( m_layer_middle_contourns_quads ) )
470  glCallList( m_layer_middle_contourns_quads );
471 
472  endTransformation();
473 }
474 
475 
476 void CLAYERS_OGL_DISP_LISTS::DrawAll( bool aDrawMiddle ) const
477 {
478  beginTransformation();
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 
496  endTransformation();
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 
687  setBlendfunction();
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 
740  setBlendfunction();
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 
792  setBlendfunction();
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 {
812  if( m_haveTransformation )
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 {
828  if( m_haveTransformation )
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)
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.