KiCad PCB EDA Suite
layer_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 <[email protected]>
5 * Copyright (C) 1992-2021 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
25#include "layer_triangles.h"
26#include "../raytracing/ray.h"
27#include <wx/debug.h> // For the wxASSERT
28#include <mutex>
29
30
31TRIANGLE_LIST::TRIANGLE_LIST( unsigned int aNrReservedTriangles, bool aReserveNormals )
32{
33 wxASSERT( aNrReservedTriangles > 0 );
34
35 m_vertexs.clear();
36 m_normals.clear();
37
38 m_vertexs.reserve( aNrReservedTriangles * 3 );
39
40 if( aReserveNormals )
41 m_normals.reserve( aNrReservedTriangles * 3 );
42}
43
44
45void TRIANGLE_LIST::Reserve_More( unsigned int aNrReservedTriangles, bool aReserveNormals )
46{
47 m_vertexs.reserve( m_vertexs.size() + aNrReservedTriangles * 3 );
48
49 if( aReserveNormals )
50 m_normals.reserve( m_normals.size() + aNrReservedTriangles * 3 );
51}
52
53
54void TRIANGLE_LIST::AddQuad( const SFVEC3F& aV1, const SFVEC3F& aV2, const SFVEC3F& aV3,
55 const SFVEC3F& aV4 )
56{
57 m_vertexs.push_back( aV1 );
58 m_vertexs.push_back( aV2 );
59 m_vertexs.push_back( aV3 );
60
61 m_vertexs.push_back( aV3 );
62 m_vertexs.push_back( aV4 );
63 m_vertexs.push_back( aV1 );
64}
65
66
67void TRIANGLE_LIST::AddTriangle( const SFVEC3F& aV1, const SFVEC3F& aV2, const SFVEC3F& aV3 )
68{
69 m_vertexs.push_back( aV1 );
70 m_vertexs.push_back( aV2 );
71 m_vertexs.push_back( aV3 );
72}
73
74
75void TRIANGLE_LIST::AddNormal( const SFVEC3F& aN1, const SFVEC3F& aN2, const SFVEC3F& aN3 )
76{
77 m_normals.push_back( aN1 );
78 m_normals.push_back( aN2 );
79 m_normals.push_back( aN3 );
80}
81
82void TRIANGLE_LIST::AddNormal( const SFVEC3F& aN1, const SFVEC3F& aN2, const SFVEC3F& aN3,
83 const SFVEC3F& aN4 )
84{
85 m_normals.push_back( aN1 );
86 m_normals.push_back( aN2 );
87 m_normals.push_back( aN3 );
88
89 m_normals.push_back( aN3 );
90 m_normals.push_back( aN4 );
91 m_normals.push_back( aN1 );
92}
93
94
95TRIANGLE_DISPLAY_LIST::TRIANGLE_DISPLAY_LIST( unsigned int aNrReservedTriangles )
96{
97 wxASSERT( aNrReservedTriangles > 0 );
98
99 m_layer_top_segment_ends = new TRIANGLE_LIST( aNrReservedTriangles, false );
100 m_layer_top_triangles = new TRIANGLE_LIST( aNrReservedTriangles, false );
101 m_layer_middle_contourns_quads = new TRIANGLE_LIST( aNrReservedTriangles, true );
102 m_layer_bot_triangles = new TRIANGLE_LIST( aNrReservedTriangles, false );
103 m_layer_bot_segment_ends = new TRIANGLE_LIST( aNrReservedTriangles, false );
104}
105
106
108{
110 m_layer_top_segment_ends = nullptr;
111
113 m_layer_top_triangles = nullptr;
114
117
119 m_layer_bot_triangles = nullptr;
120
122 m_layer_bot_segment_ends = nullptr;
123}
124
125
126void TRIANGLE_DISPLAY_LIST::AddToMiddleContourns( const std::vector< SFVEC2F >& aContournPoints,
127 float zBot, float zTop, bool aInvertFaceDirection,
128 const BVH_CONTAINER_2D* aThroughHoles )
129{
130 if( aContournPoints.size() >= 4 )
131 {
132 // Calculate normals of each segment of the contourn
133 std::vector< SFVEC2F > contournNormals;
134
135 contournNormals.clear();
136 contournNormals.resize( aContournPoints.size() - 1 );
137
138 if( aInvertFaceDirection )
139 {
140 for( unsigned int i = 0; i < ( aContournPoints.size() - 1 ); ++i )
141 {
142 const SFVEC2F& v0 = aContournPoints[i + 0];
143 const SFVEC2F& v1 = aContournPoints[i + 1];
144 const SFVEC2F n = glm::normalize( v1 - v0 );
145
146 contournNormals[i] = SFVEC2F( n.y,-n.x );
147 }
148 }
149 else
150 {
151 for( unsigned int i = 0; i < ( aContournPoints.size() - 1 ); ++i )
152 {
153 const SFVEC2F& v0 = aContournPoints[i + 0];
154 const SFVEC2F& v1 = aContournPoints[i + 1];
155 const SFVEC2F n = glm::normalize( v1 - v0 );
156
157 contournNormals[i] = SFVEC2F( -n.y, n.x );
158 }
159 }
160
161
162 if( aInvertFaceDirection )
163 std::swap( zBot, zTop );
164
165 const unsigned int nContournsToProcess = ( aContournPoints.size() - 1 );
166
167 for( unsigned int i = 0; i < nContournsToProcess; ++i )
168 {
169 SFVEC2F lastNormal;
170
171 if( i > 0 )
172 lastNormal = contournNormals[i - 1];
173 else
174 lastNormal = contournNormals[nContournsToProcess - 1];
175
176 SFVEC2F n0 = contournNormals[i];
177
178 // Only interpolate the normal if the angle is closer
179 if( glm::dot( n0, lastNormal ) > 0.5f )
180 n0 = glm::normalize( n0 + lastNormal );
181
182 SFVEC2F nextNormal;
183
184 if( i < (nContournsToProcess - 1) )
185 nextNormal = contournNormals[i + 1];
186 else
187 nextNormal = contournNormals[0];
188
189 SFVEC2F n1 = contournNormals[i];
190
191 if( glm::dot( n1, nextNormal ) > 0.5f )
192 n1 = glm::normalize( n1 + nextNormal );
193
194 const SFVEC3F n3d0 = SFVEC3F( n0.x, n0.y, 0.0f );
195 const SFVEC3F n3d1 = SFVEC3F( n1.x, n1.y, 0.0f );
196
197 const SFVEC2F& v0 = aContournPoints[i + 0];
198 const SFVEC2F& v1 = aContournPoints[i + 1];
199
200 if( aThroughHoles && aThroughHoles->IntersectAny( RAYSEG2D( v0, v1 ) ) )
201 {
202 continue;
203 }
204 else
205 {
206 std::lock_guard<std::mutex> lock( m_middle_layer_lock );
207 m_layer_middle_contourns_quads->AddQuad( SFVEC3F( v0.x, v0.y, zTop ),
208 SFVEC3F( v1.x, v1.y, zTop ),
209 SFVEC3F( v1.x, v1.y, zBot ),
210 SFVEC3F( v0.x, v0.y, zBot ) );
211
212 m_layer_middle_contourns_quads->AddNormal( n3d0, n3d1, n3d1, n3d0 );
213 }
214 }
215 }
216}
217
218
220 float zTop, double aBiuTo3Du,
221 bool aInvertFaceDirection,
222 const BVH_CONTAINER_2D* aThroughHoles )
223{
224 std::vector< SFVEC2F >contournPoints;
225
226 contournPoints.clear();
227 contournPoints.reserve( outlinePath.PointCount() + 2 );
228
229 const VECTOR2I& firstV = outlinePath.CPoint( 0 );
230
231 SFVEC2F lastV = SFVEC2F( firstV.x * aBiuTo3Du, -firstV.y * aBiuTo3Du );
232
233 contournPoints.push_back( lastV );
234
235 for( unsigned int i = 1; i < (unsigned int)outlinePath.PointCount(); ++i )
236 {
237 const VECTOR2I& v = outlinePath.CPoint( i );
238
239 const SFVEC2F vf = SFVEC2F( v.x * aBiuTo3Du, -v.y * aBiuTo3Du );
240
241 if( vf != lastV ) // Do not add repeated points
242 {
243 lastV = vf;
244 contournPoints.push_back( vf );
245 }
246 }
247
248 // Add first position fo the list to close the path
249 if( lastV != contournPoints[0] )
250 contournPoints.push_back( contournPoints[0] );
251
252 AddToMiddleContourns( contournPoints, zBot, zTop, aInvertFaceDirection, aThroughHoles );
253}
254
255
257 float zTop, double aBiuTo3Du,
258 bool aInvertFaceDirection,
259 const BVH_CONTAINER_2D* aThroughHoles )
260{
261 if( aPolySet.OutlineCount() == 0 )
262 return;
263
264 // Calculate an estimation of points to reserve
265 unsigned int nrContournPointsToReserve = 0;
266
267 for( int i = 0; i < aPolySet.OutlineCount(); ++i )
268 {
269 const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
270
271 nrContournPointsToReserve += pathOutline.PointCount();
272
273 for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
274 {
275 const SHAPE_LINE_CHAIN& hole = aPolySet.CHole( i, h );
276
277 nrContournPointsToReserve += hole.PointCount();
278 }
279 }
280
281 // Request to reserve more space
282 m_layer_middle_contourns_quads->Reserve_More( nrContournPointsToReserve * 2, true );
283
284 for( int i = 0; i < aPolySet.OutlineCount(); i++ )
285 {
286 // Add outline
287 const SHAPE_LINE_CHAIN& pathOutline = aPolySet.COutline( i );
288
289 AddToMiddleContourns( pathOutline, zBot, zTop, aBiuTo3Du, aInvertFaceDirection,
290 aThroughHoles );
291
292 // Add holes for this outline
293 for( int h = 0; h < aPolySet.HoleCount( i ); ++h )
294 {
295 const SHAPE_LINE_CHAIN& hole = aPolySet.CHole( i, h );
296 AddToMiddleContourns( hole, zBot, zTop, aBiuTo3Du, aInvertFaceDirection,
297 aThroughHoles );
298 }
299 }
300}
301
302
304 GLuint aTextureIndexForSegEnds,
305 float aZBot, float aZTop )
306{
307 m_zBot = aZBot;
308 m_zTop = aZTop;
309
315
316 if( aTextureIndexForSegEnds )
317 {
318 wxASSERT( glIsTexture( aTextureIndexForSegEnds ) );
319
320 if( glIsTexture( aTextureIndexForSegEnds ) )
321 {
324 true, aTextureIndexForSegEnds );
325
328 false, aTextureIndexForSegEnds );
329 }
330 }
331
333 true );
334
336 false );
337
338
339 if( aLayerTriangles.m_layer_middle_contourns_quads->GetVertexSize() > 0 )
340 {
343 }
344
345 m_draw_it_transparent = false;
346 m_haveTransformation = false;
349}
350
351
353{
354 if( glIsList( m_layer_top_segment_ends ) )
355 glDeleteLists( m_layer_top_segment_ends, 1 );
356
357 if( glIsList( m_layer_top_triangles ) )
358 glDeleteLists( m_layer_top_triangles, 1 );
359
360 if( glIsList( m_layer_middle_contourns_quads ) )
361 glDeleteLists( m_layer_middle_contourns_quads, 1 );
362
363 if( glIsList( m_layer_bot_triangles ) )
364 glDeleteLists( m_layer_bot_triangles, 1 );
365
366 if( glIsList( m_layer_bot_segment_ends ) )
367 glDeleteLists( m_layer_bot_segment_ends, 1 );
368
374}
375
376
378{
380
381 if( glIsList( m_layer_middle_contourns_quads ) )
382 glCallList( m_layer_middle_contourns_quads );
383
384 if( glIsList( m_layer_top_triangles ) )
385 glCallList( m_layer_top_triangles );
386
387 if( glIsList( m_layer_top_segment_ends ) )
388 glCallList( m_layer_top_segment_ends );
389
391}
392
393
395{
397
398 if( glIsList( m_layer_middle_contourns_quads ) )
399 glCallList( m_layer_middle_contourns_quads );
400
401 if( glIsList( m_layer_bot_triangles ) )
402 glCallList( m_layer_bot_triangles );
403
404 if( glIsList( m_layer_bot_segment_ends ) )
405 glCallList( m_layer_bot_segment_ends );
406
408}
409
410
412{
414
415 if( glIsList( m_layer_top_triangles ) )
416 glCallList( m_layer_top_triangles );
417
418 if( glIsList( m_layer_top_segment_ends ) )
419 glCallList( m_layer_top_segment_ends );
420
422}
423
424
426{
428
429 if( glIsList( m_layer_bot_triangles ) )
430 glCallList( m_layer_bot_triangles );
431
432 if( glIsList( m_layer_bot_segment_ends ) )
433 glCallList( m_layer_bot_segment_ends );
434
436}
437
438
440{
442
443 if( glIsList( m_layer_middle_contourns_quads ) )
444 glCallList( m_layer_middle_contourns_quads );
445
447}
448
449
450void OPENGL_RENDER_LIST::DrawAll( bool aDrawMiddle ) const
451{
453
454 if( aDrawMiddle )
455 if( glIsList( m_layer_middle_contourns_quads ) )
456 glCallList( m_layer_middle_contourns_quads );
457
458 if( glIsList( m_layer_top_triangles ) )
459 glCallList( m_layer_top_triangles );
460
461 if( glIsList( m_layer_bot_triangles ) )
462 glCallList( m_layer_bot_triangles );
463
464 if( glIsList( m_layer_top_segment_ends ) )
465 glCallList( m_layer_top_segment_ends );
466
467 if( glIsList( m_layer_bot_segment_ends ) )
468 glCallList( m_layer_bot_segment_ends );
469
471}
472
473
474void OPENGL_RENDER_LIST::DrawAllCameraCulled( float zCameraPos, bool aDrawMiddle ) const
475{
476 zCameraPos = m_haveTransformation
478 : zCameraPos;
479
480 if( aDrawMiddle )
481 DrawMiddle();
482
483 if( zCameraPos > m_zTop )
484 {
485 DrawTop();
486 }
487 else
488 {
489 if( zCameraPos < m_zBot )
490 {
491 DrawBot();
492 }
493 else
494 {
495 // If camera is in the middle dont draw it.
496 }
497 }
498}
499
500
502 const OPENGL_RENDER_LIST* aLayerToSubtractA,
503 const OPENGL_RENDER_LIST* aLayerToSubtractB,
504 const OPENGL_RENDER_LIST* aLayerToSubtractC,
505 const OPENGL_RENDER_LIST* aLayerToSubtractD ) const
506{
507 glClearStencil( 0x00 );
508 glClear( GL_STENCIL_BUFFER_BIT );
509
510 glEnable( GL_CULL_FACE );
511 glCullFace( GL_BACK );
512
513 glDisable( GL_DEPTH_TEST );
514 glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
515 glDepthMask( GL_FALSE );
516 glEnable( GL_STENCIL_TEST );
517 glStencilFunc( GL_ALWAYS, 1, 0 );
518 glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
519
520 if( aLayerToSubtractA )
521 aLayerToSubtractA->DrawBot();
522
523 if( aLayerToSubtractB )
524 aLayerToSubtractB->DrawBot();
525
526 if( aLayerToSubtractC )
527 aLayerToSubtractC->DrawBot();
528
529 if( aLayerToSubtractD )
530 aLayerToSubtractD->DrawBot();
531
532 glEnable(GL_DEPTH_TEST);
533 glDepthMask(GL_TRUE);
534
535 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
536 glStencilFunc( GL_EQUAL, 0, 1 );
537 glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
538 DrawBot();
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, 2, 0 );
545 glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
546
547 if( aLayerToSubtractA )
548 aLayerToSubtractA->DrawTop();
549
550 if( aLayerToSubtractB )
551 aLayerToSubtractB->DrawTop();
552
553 if( aLayerToSubtractC )
554 aLayerToSubtractC->DrawTop();
555
556 if( aLayerToSubtractD )
557 aLayerToSubtractD->DrawTop();
558
559 glEnable(GL_DEPTH_TEST);
560 glDepthMask(GL_TRUE);
561 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
562 glStencilFunc( GL_NOTEQUAL, 2, 0x03 );
563 glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
564 DrawTop();
565
566 if( aDrawMiddle )
567 DrawMiddle();
568
569 glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE );
570
571 glCullFace( GL_FRONT );
572 glStencilFunc( GL_GEQUAL, 3, 0x03 );
573 glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
574 glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
575
576 if( aDrawMiddle )
577 {
578 if( aLayerToSubtractA )
579 aLayerToSubtractA->DrawMiddle();
580 }
581
582 glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
583
584 glCullFace( GL_BACK );
585 glDisable( GL_STENCIL_TEST );
586}
587
588
589void OPENGL_RENDER_LIST::ApplyScalePosition( float aZposition, float aZscale )
590{
591 wxASSERT( aZscale > FLT_EPSILON );
592
593 m_zPositionTransformation = aZposition;
594 m_zScaleTransformation = aZscale;
596}
597
598
599void OPENGL_RENDER_LIST::SetItIsTransparent( bool aSetTransparent )
600{
601 m_draw_it_transparent = aSetTransparent;
602}
603
604
606 const TRIANGLE_LIST* aTriangleContainer, bool aIsNormalUp, GLuint aTextureId ) const
607{
608 wxASSERT( aTriangleContainer != nullptr );
609
610 wxASSERT( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 );
611
612 // Top and Bot dont have normals array stored in container
613 wxASSERT( aTriangleContainer->GetNormalsSize() == 0 );
614
615 if( ( aTriangleContainer->GetVertexSize() > 0 )
616 && ( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 ) )
617 {
618 GLuint listIdx = glGenLists( 1 );
619
620 if( glIsList( listIdx ) )
621 {
622 // Prepare an array of UV text coordinates
623 SFVEC2F* uvArray = new SFVEC2F[aTriangleContainer->GetVertexSize()];
624
625 for( unsigned int i = 0; i < aTriangleContainer->GetVertexSize(); i += 3 )
626 {
627 uvArray[i + 0] = SFVEC2F( 1.0f, 0.0f );
628 uvArray[i + 1] = SFVEC2F( 0.0f, 1.0f );
629 uvArray[i + 2] = SFVEC2F( 0.0f, 0.0f );
630 }
631
632 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
633 glDisableClientState( GL_COLOR_ARRAY );
634 glDisableClientState( GL_NORMAL_ARRAY );
635 glEnableClientState( GL_VERTEX_ARRAY );
636 glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
637 glTexCoordPointer( 2, GL_FLOAT, 0, uvArray );
638
639 glNewList( listIdx, GL_COMPILE );
640
641 glDisable( GL_COLOR_MATERIAL );
642
643 glEnable( GL_TEXTURE_2D );
644 glBindTexture( GL_TEXTURE_2D, aTextureId );
645
646 glAlphaFunc( GL_GREATER, 0.2f );
647 glEnable( GL_ALPHA_TEST );
648
649 glNormal3f( 0.0f, 0.0f, aIsNormalUp?1.0f:-1.0f );
650
651 glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
652
653 glBindTexture( GL_TEXTURE_2D, 0 );
654 glDisable( GL_TEXTURE_2D );
655 glDisable( GL_ALPHA_TEST );
656 glDisable( GL_BLEND );
657
658 glEndList();
659
660 glDisableClientState( GL_VERTEX_ARRAY );
661 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
662
663 delete [] uvArray;
664 return listIdx;
665 }
666 }
667
668 return 0;
669}
670
671
673 bool aIsNormalUp ) const
674{
675 wxASSERT( aTriangleContainer != nullptr );
676
677 wxASSERT( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 );
678
679 // Top and Bot dont have normals array stored in container
680 wxASSERT( aTriangleContainer->GetNormalsSize() == 0 );
681
682 if( ( aTriangleContainer->GetVertexSize() > 0 )
683 && ( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 ) )
684 {
685 const GLuint listIdx = glGenLists( 1 );
686
687 if( glIsList( listIdx ) )
688 {
689 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
690 glDisableClientState( GL_COLOR_ARRAY );
691 glDisableClientState( GL_NORMAL_ARRAY );
692 glEnableClientState( GL_VERTEX_ARRAY );
693 glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
694
695 glNewList( listIdx, GL_COMPILE );
696
698
699 glNormal3f( 0.0f, 0.0f, aIsNormalUp?1.0f:-1.0f );
700
701 glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
702
703 glDisable( GL_BLEND );
704 glEndList();
705
706 glDisableClientState( GL_VERTEX_ARRAY );
707
708 return listIdx;
709 }
710 }
711
712 return 0;
713}
714
715
717 const TRIANGLE_LIST* aTriangleContainer ) const
718{
719 wxASSERT( aTriangleContainer != nullptr );
720
721 // We expect that it is a multiple of 3 vertex
722 wxASSERT( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 );
723
724 // We expect that it is a multiple of 6 vertex (because we expect to add quads)
725 wxASSERT( (aTriangleContainer->GetVertexSize() % 6 ) == 0 );
726
727 // We expect that there are normals with same size as vertex
728 wxASSERT( aTriangleContainer->GetNormalsSize() == aTriangleContainer->GetVertexSize() );
729
730 if( ( aTriangleContainer->GetVertexSize() > 0 )
731 && ( ( aTriangleContainer->GetVertexSize() % 3 ) == 0 )
732 && ( ( aTriangleContainer->GetVertexSize() % 6 ) == 0 )
733 && ( aTriangleContainer->GetNormalsSize() == aTriangleContainer->GetVertexSize() ) )
734 {
735 const GLuint listIdx = glGenLists( 1 );
736
737 if( glIsList( listIdx ) )
738 {
739 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
740 glDisableClientState( GL_COLOR_ARRAY );
741 glEnableClientState( GL_NORMAL_ARRAY );
742 glEnableClientState( GL_VERTEX_ARRAY );
743 glVertexPointer( 3, GL_FLOAT, 0, aTriangleContainer->GetVertexPointer() );
744 glNormalPointer( GL_FLOAT, 0, aTriangleContainer->GetNormalsPointer() );
745
746 glNewList( listIdx, GL_COMPILE );
747
749
750 glDrawArrays( GL_TRIANGLES, 0, aTriangleContainer->GetVertexSize() );
751
752 glDisable( GL_BLEND );
753 glEndList();
754
755 glDisableClientState( GL_VERTEX_ARRAY );
756 glDisableClientState( GL_NORMAL_ARRAY );
757
758 return listIdx;
759 }
760 }
761
762 return 0;
763}
764
765
767{
769 {
770 glPopMatrix();
771 }
772}
773
774
776{
777 glEnable( GL_BLEND );
778 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
779}
780
781
783{
785 {
786 glPushMatrix();
787 glTranslatef( 0.0f, 0.0f, m_zPositionTransformation );
788 glScalef( 1.0f, 1.0f, m_zScaleTransformation );
789 }
790}
bool IntersectAny(const RAYSEG2D &aSegRay) const override
Intersect and check if a segment ray hits a object or is inside it.
Store the OpenGL display lists to related with a layer.
GLuint generate_middle_triangles(const TRIANGLE_LIST *aTriangleContainer) const
GLuint m_layer_middle_contourns_quads
void beginTransformation() const
void DrawAllCameraCulledSubtractLayer(bool aDrawMiddle, const OPENGL_RENDER_LIST *aLayerToSubtractA=nullptr, const OPENGL_RENDER_LIST *aLayerToSubtractB=nullptr, const OPENGL_RENDER_LIST *aLayerToSubtractC=nullptr, const OPENGL_RENDER_LIST *aLayerToSubtractD=nullptr) const
void DrawMiddle() const
Call the display lists for the middle elements.
GLuint generate_top_or_bot_seg_ends(const TRIANGLE_LIST *aTriangleContainer, bool aIsNormalUp, GLuint aTextureId) const
void DrawTop() const
Call the display lists for the top elements.
void DrawBot() const
Call the display lists for the bottom elements.
void DrawAllCameraCulled(float zCameraPos, bool aDrawMiddle=true) const
Draw all layers if they are visible by the camera if camera position is above the layer.
void ApplyScalePosition(float aZposition, float aZscale)
GLuint generate_top_or_bot_triangles(const TRIANGLE_LIST *aTriangleContainer, bool aIsNormalUp) const
void setBlendfunction() const
void DrawBotAndMiddle() const
Call the display lists for the bottom elements and middle contours.
void SetItIsTransparent(bool aSetTransparent)
void endTransformation() const
~OPENGL_RENDER_LIST()
Destroy this class while free the display lists from GPU memory.
OPENGL_RENDER_LIST(const TRIANGLE_DISPLAY_LIST &aLayerTriangles, GLuint aTextureIndexForSegEnds, float aZBot, float aZTop)
Create the display lists for a layer.
void DrawTopAndMiddle() const
Call the display lists for the top elements and middle contours.
void DrawAll(bool aDrawMiddle=true) const
Call to draw all the display lists.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
int OutlineCount() const
Return the number of vertices in a given outline/hole.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Store arrays of triangles to be used to create display lists.
TRIANGLE_LIST * m_layer_bot_segment_ends
TRIANGLE_LIST * m_layer_top_segment_ends
TRIANGLE_LIST * m_layer_bot_triangles
TRIANGLE_DISPLAY_LIST(unsigned int aNrReservedTriangles)
Initialize arrays with reserved triangles.
TRIANGLE_LIST * m_layer_top_triangles
std::mutex m_middle_layer_lock
void AddToMiddleContourns(const SHAPE_LINE_CHAIN &outlinePath, float zBot, float zTop, double aBiuTo3Du, bool aInvertFaceDirection, const BVH_CONTAINER_2D *aThroughHoles=nullptr)
TRIANGLE_LIST * m_layer_middle_contourns_quads
Container to manage a vector of triangles.
void AddTriangle(const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3)
const float * GetVertexPointer() const
Get the array of vertices.
SFVEC3F_VECTOR m_normals
normals array
unsigned int GetNormalsSize() const
void AddQuad(const SFVEC3F &aV1, const SFVEC3F &aV2, const SFVEC3F &aV3, const SFVEC3F &aV4)
void AddNormal(const SFVEC3F &aN1, const SFVEC3F &aN2, const SFVEC3F &aN3)
unsigned int GetVertexSize() const
SFVEC3F_VECTOR m_vertexs
vertex array
const float * GetNormalsPointer() const
Get the array of normals.
TRIANGLE_LIST(unsigned int aNrReservedTriangles, bool aReserveNormals)
void Reserve_More(unsigned int aNrReservedTriangles, bool aReserveNormals)
Reserve more triangles.
T y
Definition: vector3.h:62
T x
Definition: vector3.h:61
Definition: ray.h:106
VECTOR3I v1(5, 5, 5)
glm::vec2 SFVEC2F
Definition: xv3d_types.h:42
glm::vec3 SFVEC3F
Definition: xv3d_types.h:44