34#include <glm/geometric.hpp>
49#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
55 wxLogTrace(
m_logTrace, wxT(
"RENDER_3D_OPENGL::RENDER_3D_OPENGL" ) );
92 wxLogTrace(
m_logTrace, wxT(
"RENDER_3D_OPENGL::~RENDER_3D_OPENGL" ) );
118 int fbWidth, fbHeight;
119 glGetIntegerv( GL_VIEWPORT, viewport );
132 glEnable( GL_LIGHT0 );
134 glDisable( GL_LIGHT0 );
141 glEnable( GL_LIGHT1 );
143 glDisable( GL_LIGHT1 );
150 glEnable( GL_LIGHT2 );
152 glDisable( GL_LIGHT2 );
215 m_materials.m_Copper.m_Shininess = shininessfactor * 128.0f;
224 m_materials.m_NonPlatedCopper.m_Shininess = 0.1f * 128.0f;
252 m_materials.m_SilkSTop.m_Shininess = 0.078125f * 128.0f;
265 m_materials.m_SilkSBot.m_Shininess = 0.078125f * 128.0f;
268 m_materials.m_SolderMask.m_Shininess = 0.8f * 128.0f;
278 m_materials.m_EpoxyBoard.m_Shininess = 0.1f * 128.0f;
308 m_materials.m_SolderMask.m_Transparency = 1.0f - layerColor.a;
372 m_materials.m_Plastic.m_Shininess = 0.078125f * 128.0f;
395 m_materials.m_Plastic.m_Shininess = 0.078125f * 128.0f;
413 const GLfloat ambient[] = { 0.084f, 0.084f, 0.084f, 1.0f };
414 const GLfloat diffuse0[] = { 0.3f, 0.3f, 0.3f, 1.0f };
415 const GLfloat specular0[] = { 0.5f, 0.5f, 0.5f, 1.0f };
417 glLightfv( GL_LIGHT0, GL_AMBIENT, ambient );
418 glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse0 );
419 glLightfv( GL_LIGHT0, GL_SPECULAR, specular0 );
421 const GLfloat diffuse12[] = { 0.7f, 0.7f, 0.7f, 1.0f };
422 const GLfloat specular12[] = { 0.7f, 0.7f, 0.7f, 1.0f };
425 GLfloat position[4] = { 0.0f, 0.0f, 1.0f, 0.0f };
429 glm::pi<float>() * 0.25f );
431 position[0] = vectorLight.x;
432 position[1] = vectorLight.y;
433 position[2] = vectorLight.z;
435 glLightfv( GL_LIGHT1, GL_AMBIENT, ambient );
436 glLightfv( GL_LIGHT1, GL_DIFFUSE, diffuse12 );
437 glLightfv( GL_LIGHT1, GL_SPECULAR, specular12 );
438 glLightfv( GL_LIGHT1, GL_POSITION, position );
441 position[2] = -position[2];
443 glLightfv( GL_LIGHT2, GL_AMBIENT, ambient );
444 glLightfv( GL_LIGHT2, GL_DIFFUSE, diffuse12 );
445 glLightfv( GL_LIGHT2, GL_SPECULAR, specular12 );
446 glLightfv( GL_LIGHT2, GL_POSITION, position );
448 const GLfloat lmodel_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
450 glLightModelfv( GL_LIGHT_MODEL_AMBIENT, lmodel_ambient );
452 glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
464 glEnable( GL_POLYGON_OFFSET_FILL );
465 glPolygonOffset( -0.1f, -2.0f );
472 glDisable( GL_POLYGON_OFFSET_FILL );
485 std::shared_ptr<OPENGL_RENDER_LIST_DEFERRED> board_disp_list_def =
nullptr;
492 if( board_disp_list_def )
495 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list = board_disp_list_def->MakeOrGet() )
497 ogl_disp_list->ApplyScalePosition( -
m_boardAdapter.GetBoardBodyThickness() / 2.0f,
500 ogl_disp_list->SetItIsTransparent(
true );
501 ogl_disp_list->DrawAll();
508 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_postMachinePlugs->MakeOrGet() )
510 ogl_disp_list->ApplyScalePosition( -
m_boardAdapter.GetBoardBodyThickness() / 2.0f,
513 ogl_disp_list->SetItIsTransparent(
true );
514 ogl_disp_list->DrawAll();
522 return SFVEC4F( aInput.r * aInput.a, aInput.g * aInput.a, aInput.b * aInput.a, aInput.a );
539 if( reloadRequested )
575 glDepthFunc( GL_LESS );
576 glEnable( GL_CULL_FACE );
577 glFrontFace( GL_CCW );
578 glEnable( GL_NORMALIZE );
582 glDisable( GL_MULTISAMPLE );
584 glEnable( GL_MULTISAMPLE );
587 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
588 glClearDepth( 1.0f );
589 glClearStencil( 0x00 );
590 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
598 glEnable( GL_DEPTH_TEST );
601 glMatrixMode( GL_PROJECTION );
602 glLoadMatrixf( glm::value_ptr(
m_camera.GetProjectionMatrix() ) );
603 glMatrixMode( GL_MODELVIEW );
605 glLoadMatrixf( glm::value_ptr(
m_camera.GetViewMatrix() ) );
612 glEnable( GL_LIGHTING );
621 if( cameraPos.z > 0.0f )
622 zpos = glm::max( cameraPos.z, 0.5f ) + cameraPos.z * cameraPos.z;
624 zpos = glm::min( cameraPos.z,-0.5f ) - cameraPos.z * cameraPos.z;
627 const GLfloat headlight_pos[] = { cameraPos.x, cameraPos.y, zpos, 1.0f };
629 glLightfv( GL_LIGHT0, GL_POSITION, headlight_pos );
635 bool showThickness = !skipThickness;
637 std::bitset<LAYER_3D_END> layerFlags =
m_boardAdapter.GetVisibleLayers();
643 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_microviaHoles->MakeOrGet() )
644 ogl_disp_list->DrawAll();
649 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_padHoles->MakeOrGet() )
650 ogl_disp_list->DrawAll();
654 for( MAP_OGL_DISP_LISTS::const_iterator ii =
m_layers.begin(); ii !=
m_layers.end(); ++ii )
668 const double opacity_min = 0.8;
681 std::shared_ptr<OPENGL_RENDER_LIST_DEFERRED> pLayerDispListDef = ii->second;
682 std::shared_ptr<OPENGL_RENDER_LIST> pLayerDispList = pLayerDispListDef->MakeOrGet();
693 std::shared_ptr<OPENGL_RENDER_LIST> outerTH =
nullptr;
694 std::shared_ptr<OPENGL_RENDER_LIST> viaHoles =
nullptr;
696 if( !skipRenderHoles )
703 anti_board->ApplyScalePosition( pLayerDispList );
706 outerTH->ApplyScalePosition( pLayerDispList );
708 pLayerDispList->DrawCulled( showThickness, outerTH, viaHoles, anti_board );
717 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_platedPadsFront->MakeOrGet() )
718 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles, anti_board );
724 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles );
733 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_platedPadsBack->MakeOrGet() )
734 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles, anti_board );
739 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_offboardPadsBack->MakeOrGet() )
740 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles );
750 std::shared_ptr<OPENGL_RENDER_LIST> throughHolesOuter =
nullptr;
751 std::shared_ptr<OPENGL_RENDER_LIST> anti_board =
nullptr;
752 std::shared_ptr<OPENGL_RENDER_LIST> solder_mask =
nullptr;
754 if( !skipRenderHoles )
763 anti_board =
nullptr;
770 solder_mask =
m_layers[maskLayer] ?
m_layers[maskLayer]->MakeOrGet() :
nullptr;
773 if( throughHolesOuter )
774 throughHolesOuter->ApplyScalePosition( pLayerDispList );
777 anti_board->ApplyScalePosition( pLayerDispList );
780 solder_mask->ApplyScalePosition( pLayerDispList );
783 glEnable( GL_POLYGON_OFFSET_FILL );
784 glPolygonOffset( 0.0f, -4.0f );
786 pLayerDispList->DrawCulled( showThickness, solder_mask, throughHolesOuter, anti_board );
788 glDisable( GL_POLYGON_OFFSET_FILL );
789 glPolygonOffset( 0.0f, 0.0f );
795 glm::mat4 cameraViewMatrix;
797 glGetFloatv( GL_MODELVIEW_MATRIX, glm::value_ptr( cameraViewMatrix ) );
813 std::shared_ptr<OPENGL_RENDER_LIST> renderList = renderListDef->MakeOrGet();
818 bool highlight =
false;
822 if( fp->IsSelected() )
836 renderList->DrawAll();
847 glEnable( GL_POLYGON_OFFSET_FILL );
848 glPolygonOffset( 0.0f, 2.0f );
852 glDisable( GL_POLYGON_OFFSET_FILL );
853 glPolygonOffset( 0.0f, 0.0f );
862 glEnable( GL_POLYGON_OFFSET_FILL );
863 glPolygonOffset( 0.0f, -2.0f );
870 showThickness, skipRenderHoles );
876 showThickness, skipRenderHoles );
884 showThickness, skipRenderHoles );
890 showThickness, skipRenderHoles );
894 glDisable( GL_POLYGON_OFFSET_FILL );
895 glPolygonOffset( 0.0f, 0.0f );
901 glDepthMask( GL_FALSE );
902 glEnable( GL_BLEND );
903 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
906 glEnable( GL_TEXTURE_2D );
907 glActiveTexture( GL_TEXTURE0 );
912 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
913 glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE );
914 glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE );
916 glTexEnvi( GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR );
917 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );
919 glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS );
920 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR );
922 glTexEnvi( GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR );
923 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );
924 glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT );
925 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA );
929 glDisable( GL_BLEND );
932 glEnable( GL_BLEND );
933 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
937 glDisable( GL_BLEND );
939 glDepthMask( GL_TRUE );
944 glDisable( GL_LIGHTING );
949 glEnable( GL_LIGHTING );
966 glEnable( GL_LINE_SMOOTH );
967 glShadeModel( GL_SMOOTH );
970 glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
991 delete circleImageBlured;
992 circleImageBlured =
nullptr;
995 circleImage =
nullptr;
1009 glEnable( GL_COLOR_MATERIAL );
1010 glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
1017 glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specular.r );
1018 glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, 96.0f );
1020 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, &ambient.r );
1021 glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse.r );
1022 glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, &emissive.r );
1028#define DELETE_AND_FREE( ptr ) \
1033#define DELETE_AND_FREE_MAP( map ) \
1035 for( auto& [ layer, ptr ] : map ) \
1042 glDeleteLists(
m_grid, 1 );
1056 for( std::shared_ptr<TRIANGLE_DISPLAY_LIST>& list :
m_triangles )
1087 std::vector<std::shared_ptr<void>> retired;
1090 std::lock_guard<std::recursive_mutex> lock(
m_renderMutex );
1097 bool aShowThickness,
bool aSkipRenderHoles )
1099 wxASSERT( (aLayerID ==
B_Mask) || (aLayerID ==
F_Mask) );
1103 std::shared_ptr<OPENGL_RENDER_LIST> board_list =
m_board->MakeOrGet();
1104 std::shared_ptr<OPENGL_RENDER_LIST> solder_mask =
1106 std::shared_ptr<OPENGL_RENDER_LIST> via_holes =
1110 via_holes->ApplyScalePosition( aZPos,
m_boardAdapter.GetNonCopperLayerThickness() );
1112 board_list->ApplyScalePosition( aZPos,
m_boardAdapter.GetNonCopperLayerThickness() );
1115 board_list->SetItIsTransparent(
true );
1116 board_list->DrawCulled( aShowThickness, solder_mask, via_holes );
1120 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_draw_list =
m_viaFrontCover->MakeOrGet() )
1122 ogl_draw_list->ApplyScalePosition( aZPos, 4 *
m_boardAdapter.GetNonCopperLayerThickness() );
1123 ogl_draw_list->DrawTop();
1128 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_draw_list =
m_viaBackCover->MakeOrGet() )
1130 ogl_draw_list->ApplyScalePosition( aZPos, 4 *
m_boardAdapter.GetNonCopperLayerThickness() );
1131 ogl_draw_list->DrawBot();
1139 bool aGetBot,
bool aRenderTransparentOnly,
1140 bool aRenderSelectedOnly )
1142 wxASSERT( ( aGetTop ==
true ) || ( aGetBot ==
true ) );
1152 bool highlight =
false;
1156 if( fp->IsSelected() )
1162 if( aRenderSelectedOnly != highlight )
1166 bool hasModels = !fp->Models().empty();
1167 bool showMissing =
m_boardAdapter.m_Cfg->m_Render.show_missing_models;
1169 if( hasModels || showMissing )
1173 const bool isFlipped = fp->IsFlipped();
1175 if( aGetTop == !isFlipped || aGetBot == isFlipped )
1186 bool aRenderTransparentOnly,
bool aIsSelected )
1188 if( !aFootprint->
Models().empty() )
1194 glm::mat4 fpMatrix( 1.0f );
1202 SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1207 fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(),
SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1208 fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(),
SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1213 fpMatrix = glm::scale( fpMatrix,
SFVEC3F( modelunit_to_3d_units_factor ) );
1216 bool placeholderAdded =
false;
1221 if( !sM.m_Show || sM.m_Filename.empty() )
1229 if( !placeholderAdded )
1232 aIsSelected, aRenderTransparentOnly ? sM.m_Opacity : 1.0f );
1233 placeholderAdded =
true;
1239 if(
const std::shared_ptr<MODEL_3D_DEFERRED>& modelPtrDef = cache_i->second )
1241 std::shared_ptr<MODEL_3D> modelPtr = modelPtrDef->MakeOrGet();
1246 bool opaque = sM.m_Opacity >= 1.0;
1248 if( ( !aRenderTransparentOnly && modelPtr->HasOpaqueMeshes() && opaque ) ||
1249 ( aRenderTransparentOnly && ( modelPtr->HasTransparentMeshes() || !opaque ) ) )
1251 glm::mat4 modelworldMatrix = fpMatrix;
1253 const SFVEC3F offset =
SFVEC3F( sM.m_Offset.x, sM.m_Offset.y, sM.m_Offset.z );
1254 const SFVEC3F rotation =
SFVEC3F( sM.m_Rotation.x, sM.m_Rotation.y,
1258 std::vector<float> key = { offset.x, offset.y, offset.z,
1259 rotation.x, rotation.y, rotation.z,
1266 modelworldMatrix *= it->second;
1270 glm::mat4 mtx( 1.0f );
1271 mtx = glm::translate( mtx, offset );
1272 mtx = glm::rotate( mtx, glm::radians( -rotation.z ), { 0.0f, 0.0f, 1.0f } );
1273 mtx = glm::rotate( mtx, glm::radians( -rotation.y ), { 0.0f, 1.0f, 0.0f } );
1274 mtx = glm::rotate( mtx, glm::radians( -rotation.x ), { 1.0f, 0.0f, 0.0f } );
1275 mtx = glm::scale( mtx,
scale );
1278 modelworldMatrix *= mtx;
1281 aDstRenderList.emplace_back( modelworldMatrix, modelPtr,
1282 aRenderTransparentOnly ? sM.m_Opacity : 1.0f,
1283 aRenderTransparentOnly,
1295 glm::mat4 fpMatrix( 1.0f );
1303 SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1308 fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(),
SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1309 fpMatrix = glm::rotate( fpMatrix, glm::pi<float>(),
SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1314 fpMatrix = glm::scale( fpMatrix,
SFVEC3F( modelunit_to_3d_units_factor ) );
1323 const glm::mat4& aFpMatrix,
const FOOTPRINT* aFootprint,
1324 bool aRenderTransparentOnly,
bool aIsSelected,
float aOpacity )
1338 float scaleX = bboxW;
1339 float scaleY = bboxH;
1340 float scaleZ = std::min( bboxW, bboxH ) * 0.5f;
1343 float offsetX = localCenter.
x /
pcbIUScale.IU_PER_MM;
1344 float offsetY = -localCenter.
y /
pcbIUScale.IU_PER_MM;
1345 float offsetZ = scaleZ * 0.5f;
1350 glm::mat4 mtx = aFpMatrix;
1351 mtx = glm::translate( mtx,
SFVEC3F( offsetX, offsetY, offsetZ ) );
1352 mtx = glm::scale( mtx,
SFVEC3F( scaleX, scaleY, scaleZ ) );
1354 bool placeholderOpaque = aOpacity >= 1.0;
1356 if( ( !aRenderTransparentOnly &&
m_placeholderModel->HasOpaqueMeshes() && placeholderOpaque )
1357 || ( aRenderTransparentOnly && (
m_placeholderModel->HasTransparentMeshes() || !placeholderOpaque ) ) )
1359 aDstRenderList.emplace_back( mtx,
m_placeholderModel, aOpacity, aRenderTransparentOnly,
1373 std::list<MODELTORENDER> renderList;
1381 if( !renderList.empty() )
1386 renderModel( aCameraViewMatrix, mtr, selColor,
nullptr );
1395 if( !renderList.empty() )
1400 renderModel( aCameraViewMatrix, mtr, selColor,
nullptr );
1421 if( !renderListDef )
1424 std::shared_ptr<OPENGL_RENDER_LIST> renderList = renderListDef->MakeOrGet();
1429 bool highlight =
false;
1433 if( fp->IsSelected() )
1445 if( ( c.
a < 1.0 ) != aTransparentPass )
1461 renderList->DrawAll();
1472 std::list<MODELTORENDER> renderListModels;
1483 if( renderListModels.empty() )
1486 std::vector<std::pair<const MODELTORENDER *, float>> transparentModelList;
1488 transparentModelList.reserve( renderListModels.size() );
1495 const BBOX_3D& bBox = mtr.m_model->GetBBox();
1497 const SFVEC3F bBoxWorld = mtr.m_modelWorldMat * glm::vec4( bBoxCenter, 1.0f );
1499 const float distanceToCamera = glm::length( cameraPos - bBoxWorld );
1501 transparentModelList.emplace_back( &mtr, distanceToCamera );
1505 std::sort( transparentModelList.begin(), transparentModelList.end(),
1506 [&]( std::pair<const MODELTORENDER *, float>& a,
1507 std::pair<const MODELTORENDER *, float>& b )
1509 if( a.second != b.second )
1510 return a.second > b.second;
1512 return a.first > b.first;
1518 bool isUsingColorInformation = !( transparentModelList.begin()->first->m_isSelected &&
1523 for(
const std::pair<const MODELTORENDER *, float>& mtr : transparentModelList )
1528 if( !isUsingColorInformation && !mtr.first->m_isSelected )
1530 isUsingColorInformation =
true;
1532 glEnableClientState( GL_COLOR_ARRAY );
1533 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
1534 glEnable( GL_COLOR_MATERIAL );
1536 else if( isUsingColorInformation && mtr.first->m_isSelected )
1538 isUsingColorInformation =
false;
1540 glDisableClientState( GL_COLOR_ARRAY );
1541 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
1542 glDisable( GL_COLOR_MATERIAL );
1548 renderModel( aCameraViewMatrix, *mtr.first, selColor, &cameraPos );
1563 const glm::mat4 modelviewMatrix = aCameraViewMatrix * aModelToRender.
m_modelWorldMat;
1565 glLoadMatrixf( glm::value_ptr( modelviewMatrix ) );
1573 const bool wasBlendEnabled = glIsEnabled( GL_BLEND );
1575 if( !wasBlendEnabled )
1577 glEnable( GL_BLEND );
1578 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1581 glDisable( GL_LIGHTING );
1589 glEnable( GL_LIGHTING );
1591 if( !wasBlendEnabled )
1592 glDisable( GL_BLEND );
1600 glDeleteLists(
m_grid, 1 );
1607 m_grid = glGenLists( 1 );
1609 if( !glIsList(
m_grid ) )
1612 glNewList(
m_grid, GL_COMPILE );
1614 glEnable( GL_BLEND );
1615 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1617 const double zpos = 0.0;
1625 const GLfloat transparency = 0.35f;
1627 double griSizeMM = 0.0;
1640 glNormal3f( 0.0, 0.0, 1.0 );
1645 brd_center_pos.
y = -brd_center_pos.
y;
1647 const int xsize = std::max( brd_size.
x,
pcbIUScale.mmToIU( 100 ) ) * 1.2;
1648 const int ysize = std::max( brd_size.
y,
pcbIUScale.mmToIU( 100 ) ) * 1.2;
1651 double xmin = ( brd_center_pos.
x - xsize / 2 ) *
scale;
1652 double xmax = ( brd_center_pos.
x + xsize / 2 ) *
scale;
1653 double ymin = ( brd_center_pos.
y - ysize / 2 ) *
scale;
1654 double ymax = ( brd_center_pos.
y + ysize / 2 ) *
scale;
1662 for(
int ii = 0; ; ii++ )
1665 glColor4f( gridColor.r, gridColor.g, gridColor.b, transparency );
1667 glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b,
1672 if(
delta <= xsize / 2 )
1674 glBegin( GL_LINES );
1675 glVertex3f( (brd_center_pos.
x +
delta) *
scale, -ymin, zpos );
1676 glVertex3f( (brd_center_pos.
x +
delta) *
scale, -ymax, zpos );
1681 glBegin( GL_LINES );
1682 glVertex3f( (brd_center_pos.
x -
delta) *
scale, -ymin, zpos );
1683 glVertex3f( (brd_center_pos.
x -
delta) *
scale, -ymax, zpos );
1688 if(
delta <= ysize / 2 )
1690 glBegin( GL_LINES );
1691 glVertex3f( xmin, -( brd_center_pos.
y +
delta ) *
scale, zpos );
1692 glVertex3f( xmax, -( brd_center_pos.
y +
delta ) *
scale, zpos );
1697 glBegin( GL_LINES );
1698 glVertex3f( xmin, -( brd_center_pos.
y -
delta ) *
scale, zpos );
1699 glVertex3f( xmax, -( brd_center_pos.
y -
delta ) *
scale, zpos );
1704 if( (
delta > ysize / 2 ) && (
delta > xsize / 2 ) )
1709 glNormal3f( 0.0, -1.0, 0.0 );
1712 double posy = -brd_center_pos.
y *
scale;
1714 for(
int ii = 0; ; ii++ )
1717 glColor4f( gridColor.r, gridColor.g, gridColor.b, transparency );
1719 glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b,
1724 glBegin( GL_LINES );
1727 glVertex3f( xmax, posy, zmin );
1728 glVertex3f( xmax, posy, zmax );
1733 glBegin( GL_LINES );
1735 glVertex3f( xmin, posy, zmin );
1736 glVertex3f( xmin, posy, zmax );
1740 if(
delta > xsize / 2.0f )
1745 for(
int ii = 0; ; ii++ )
1748 glColor4f( gridColor.r, gridColor.g, gridColor.b, transparency );
1750 glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b, transparency );
1757 glBegin( GL_LINES );
1758 glVertex3f( xmin, posy,
delta );
1759 glVertex3f( xmax, posy,
delta );
1763 if(
delta <= -zmin && ( ii != 0 ) )
1766 glBegin( GL_LINES );
1767 glVertex3f( xmin, posy, -
delta );
1768 glVertex3f( xmax, posy, -
delta );
1776 glDisable( GL_BLEND );
1785 static SFVEC3F positions[24] = {
1786 { -0.5f, -0.5f, 0.5f },
1787 { 0.5f, -0.5f, 0.5f },
1788 { 0.5f, 0.5f, 0.5f },
1789 { -0.5f, 0.5f, 0.5f },
1792 { -0.5f, 0.5f, -0.5f },
1793 { 0.5f, 0.5f, -0.5f },
1794 { 0.5f, -0.5f, -0.5f },
1795 { -0.5f, -0.5f, -0.5f },
1798 { 0.5f, -0.5f, -0.5f },
1799 { 0.5f, 0.5f, -0.5f },
1800 { 0.5f, 0.5f, 0.5f },
1801 { 0.5f, -0.5f, 0.5f },
1804 { -0.5f, -0.5f, 0.5f },
1805 { -0.5f, 0.5f, 0.5f },
1806 { -0.5f, 0.5f, -0.5f },
1807 { -0.5f, -0.5f, -0.5f },
1810 { -0.5f, 0.5f, 0.5f },
1811 { 0.5f, 0.5f, 0.5f },
1812 { 0.5f, 0.5f, -0.5f },
1813 { -0.5f, 0.5f, -0.5f },
1816 { -0.5f, -0.5f, -0.5f },
1817 { 0.5f, -0.5f, -0.5f },
1818 { 0.5f, -0.5f, 0.5f },
1819 { -0.5f, -0.5f, 0.5f }
1822 static SFVEC3F normals[24] = {
1854 static unsigned int indices[36] = {
1857 8, 9, 10, 8, 10, 11,
1858 12, 13, 14, 12, 14, 15,
1859 16, 17, 18, 16, 18, 19,
1860 20, 21, 22, 20, 22, 23
1872 static SMESH mesh = { 24, positions, normals,
nullptr,
nullptr, 36, indices, 0 };
@ NORMAL
Use all material properties from model file.
Defines math related functions.
float mapf(float x, float in_min, float in_max, float out_min, float out_max)
SFVEC3F SphericalToCartesian(float aInclination, float aAzimuth)
https://en.wikipedia.org/wiki/Spherical_coordinate_system
EXTRUSION_MATERIAL_PROPS GetMaterialProps(EXTRUSION_MATERIAL aMaterial, const SFVEC3F &aDiffuse)
BOX2I CalcPlaceholderLocalBox(const FOOTPRINT *aFootprint)
Calculate a local space bounding box for a placeholder 3D model.
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Helper class to handle information needed to display 3D board.
constexpr size_type GetWidth() const
constexpr const Vec GetCenter() const
constexpr size_type GetHeight() const
A class used to derive camera objects from.
Implement a canvas based on a wxGLCanvas.
static KIGFX::COLOR4D GetDefaultColor(EXTRUSION_MATERIAL aMaterial)
EXTRUSION_MATERIAL m_material
auto RunWithoutCtxLock(Func &&aFunction, Args &&... args)
Run the given function first releasing the GL context lock, then restoring it.
Manage an 8-bit channel image.
void CircleFilled(int aCx, int aCy, int aRadius, unsigned char aValue)
void EfxFilter_SkipCenter(IMAGE *aInImg, IMAGE_FILTER aFilterType, unsigned int aRadius)
Apply a filter to the input image and store it in the image class.
unsigned int GetHeight() const
unsigned int GetWidth() const
A color representation with 4 components: red, green, blue, alpha.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
static const LSET & PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
void DrawBbox() const
Draw main bounding box of the model.
static void EndDrawMulti()
Cleanup render states after drawing multiple models.
void Draw(bool aTransparent, float aOpacity, bool aUseSelectedMaterial, const SFVEC3F &aSelectionColor, const glm::mat4 *aModelWorldMatrix, const SFVEC3F *aCameraWorldPos) const
Render the model into the current context.
static void BeginDrawMulti(bool aUseColorInformation)
Set some basic render states before drawing multiple models.
void DrawBboxes() const
Draw individual bounding boxes of each mesh.
GL_CONTEXT_MANAGER * GetGLContextManager()
std::unique_ptr< BUSY_INDICATOR > CreateBusyIndicator() const
Return a created busy indicator, if a factory has been set, else a null pointer.
RENDER_3D_BASE(BOARD_ADAPTER &aBoardAdapter, CAMERA &aCamera)
bool m_canvasInitialized
Flag if the canvas specific for this render was already initialized.
std::shared_ptr< REPORTER > m_activityReporter
wxSize m_windowSize
The window size that this camera is working.
BOARD_ADAPTER & m_boardAdapter
Settings reference in use for this render.
void renderExtrudedBodies()
SPHERES_GIZMO::GizmoSphereSelection getSelectedGizmoSphere() const
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_offboardPadsBack
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_microviaHoles
std::map< const FOOTPRINT *, std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > > m_extrudedBodyLists
GRID3D_TYPE m_lastGridType
Stores the last grid type.
std::tuple< int, int, int, int > getGizmoViewport() const
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_viaFrontCover
void renderOpaqueModels(const glm::mat4 &aCameraViewMatrix)
void StopBgWorker() override
Request stop and join any in-progress background loading.
void generate3dGrid(GRID3D_TYPE aGridType)
Create a 3D grid to an OpenGL display list.
void setLightFront(bool enabled)
std::shared_ptr< MODEL_3D > m_placeholderModel
bool Redraw(bool aIsMoving) override
Redraw the view.
MAP_OGL_DISP_LISTS m_layers
MAP_OGL_DISP_LISTS m_innerLayerHoles
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_postMachinePlugs
Board material plugs for backdrill/counterbore/countersink.
RENDER_3D_OPENGL(EDA_3D_CANVAS *aCanvas, BOARD_ADAPTER &aAdapter, CAMERA &aCamera)
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_offboardPadsFront
MAP_OGL_DISP_LISTS m_outerLayerHoles
BOARD_ITEM * m_currentRollOverItem
void renderBoardBody(bool aSkipRenderHoles)
std::map< std::vector< float >, glm::mat4 > m_3dModelMatrixMap
std::recursive_mutex m_renderMutex
LIST_TRIANGLES m_triangles
store pointers so can be deleted latter
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_platedPadsFront
void setLayerMaterial(PCB_LAYER_ID aLayerID)
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_platedPadsBack
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_board
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_boardWithHoles
void resetSelectedGizmoSphere()
struct RENDER_3D_OPENGL::@136145154067207014164113243162246125147361200233 m_materials
void createPlaceholderModel()
void renderModel(const glm::mat4 &aCameraViewMatrix, const MODELTORENDER &aModelToRender, const SFVEC3F &aSelColor, const SFVEC3F *aCameraWorldPos)
int GetWaitForEditingTimeOut() override
Give the interface the time (in ms) that it should wait for editing or movements before (this works f...
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_antiBoard
std::map< wxString, std::shared_ptr< MODEL_3D_DEFERRED > > m_3dModelMap
void renderSolderMaskLayer(PCB_LAYER_ID aLayerID, float aZPos, bool aShowThickness, bool aSkipRenderHoles)
void renderTransparentModels(const glm::mat4 &aCameraViewMatrix)
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_outerThroughHoles
void get3dModelsSelected(std::list< MODELTORENDER > &aDstRenderList, bool aGetTop, bool aGetBot, bool aRenderTransparentOnly, bool aRenderSelectedOnly)
void releaseRetiredRenderPtrs()
void setPlatedCopperAndDepthOffset(PCB_LAYER_ID aLayer_id)
void updateGizmoSelection(glm::mat4 aCameraRotationMatrix)
std::map< const FOOTPRINT *, std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > > m_extrudedPadLists
void SetCurWindowSize(const wxSize &aSize) override
Before each render, the canvas will tell the render what is the size of its windows,...
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_padHoles
void renderPlaceholderForFootprint(std::list< MODELTORENDER > &aDstRenderList, const glm::mat4 &aFpMatrix, const FOOTPRINT *aFootprint, bool aRenderTransparentOnly, bool aIsSelected, float aOpacity)
std::vector< std::shared_ptr< void > > m_retiredRenderPtrs
SPHERES_GIZMO * m_spheres_gizmo
GLuint m_grid
oGL list that stores current grid
void get3dModelsFromFootprint(std::list< MODELTORENDER > &aDstRenderList, const FOOTPRINT *aFootprint, bool aRenderTransparentOnly, bool aIsSelected)
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_outerViaThroughHoles
void handleGizmoMouseInput(int mouseX, int mouseY)
void setLightBottom(bool enabled)
void setGizmoViewport(int x, int y, int width, int height)
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_outerThroughHoleRings
std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > m_viaBackCover
void setLightTop(bool enabled)
Renders a set of colored spheres in 3D space that act as a directional orientation gizmo.
GizmoSphereSelection
Enum to indicate which sphere (direction) is selected.
#define DELETE_AND_FREE_MAP(map)
#define DELETE_AND_FREE(ptr)
#define UNITS3D_TO_UNITSPCB
Implements a model viewer canvas.
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
int MapPCBLayerTo3DLayer(PCB_LAYER_ID aLayer)
@ LAYER_3D_SOLDERMASK_TOP
@ LAYER_3D_SOLDERMASK_BOTTOM
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
void OglResetTextureState()
Reset to default state the texture settings.
void OglSetMaterial(const SMATERIAL &aMaterial, float aOpacity, bool aUseSelectedMaterial, SFVEC3F aSelectionColor)
Set OpenGL materials.
GLuint OglLoadTexture(const IMAGE &aImage)
Generate a new OpenGL texture.
void OglDrawBackground(const SFVEC4F &aTopColor, const SFVEC4F &aBotColor)
Define generic OpenGL functions that are common to any OpenGL target.
PGM_BASE & Pgm()
The global program "get" accessor.
static SFVEC4F premultiplyAlpha(const SFVEC4F &aInput)
#define SIZE_OF_CIRCLE_TEXTURE
Manage a bounding box defined by two SFVEC3F min max points.
SFVEC3F GetCenter() const
Return the center point of the bounding box.
bool opengl_thickness_disableOnMove
KIGFX::COLOR4D opengl_selection_color
bool clip_silk_on_via_annuli
bool subtract_mask_from_silk
bool opengl_microvias_disableOnMove
bool highlight_on_rollover
bool DifferentiatePlatedCopper()
return true if platted copper aeras and non platted copper areas must be drawn using a different colo...
bool opengl_holes_disableOnMove
bool opengl_AA_disableOnMove
glm::mat4 m_modelWorldMat
std::shared_ptr< MODEL_3D > m_model
Store the a model based on meshes and materials.
float m_Transparency
1.0 is completely transparent, 0.0 completely opaque
SFVEC3F m_Diffuse
Default diffuse color if m_Color is NULL.
Per-vertex normal/color/texcoors structure.
VECTOR2< int32_t > VECTOR2I