35#include <glm/geometric.hpp>
52 wxLogTrace(
m_logTrace, wxT(
"RENDER_3D_OPENGL::RENDER_3D_OPENGL" ) );
89 wxLogTrace(
m_logTrace, wxT(
"RENDER_3D_OPENGL::~RENDER_3D_OPENGL" ) );
115 int fbWidth, fbHeight;
116 glGetIntegerv( GL_VIEWPORT, viewport );
129 glEnable( GL_LIGHT0 );
131 glDisable( GL_LIGHT0 );
138 glEnable( GL_LIGHT1 );
140 glDisable( GL_LIGHT1 );
147 glEnable( GL_LIGHT2 );
149 glDisable( GL_LIGHT2 );
212 m_materials.m_Copper.m_Shininess = shininessfactor * 128.0f;
221 m_materials.m_NonPlatedCopper.m_Shininess = 0.1f * 128.0f;
249 m_materials.m_SilkSTop.m_Shininess = 0.078125f * 128.0f;
262 m_materials.m_SilkSBot.m_Shininess = 0.078125f * 128.0f;
265 m_materials.m_SolderMask.m_Shininess = 0.8f * 128.0f;
275 m_materials.m_EpoxyBoard.m_Shininess = 0.1f * 128.0f;
305 m_materials.m_SolderMask.m_Transparency = 1.0f - layerColor.a;
369 m_materials.m_Plastic.m_Shininess = 0.078125f * 128.0f;
392 m_materials.m_Plastic.m_Shininess = 0.078125f * 128.0f;
410 const GLfloat ambient[] = { 0.084f, 0.084f, 0.084f, 1.0f };
411 const GLfloat diffuse0[] = { 0.3f, 0.3f, 0.3f, 1.0f };
412 const GLfloat specular0[] = { 0.5f, 0.5f, 0.5f, 1.0f };
414 glLightfv( GL_LIGHT0, GL_AMBIENT, ambient );
415 glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse0 );
416 glLightfv( GL_LIGHT0, GL_SPECULAR, specular0 );
418 const GLfloat diffuse12[] = { 0.7f, 0.7f, 0.7f, 1.0f };
419 const GLfloat specular12[] = { 0.7f, 0.7f, 0.7f, 1.0f };
422 GLfloat position[4] = { 0.0f, 0.0f, 1.0f, 0.0f };
426 glm::pi<float>() * 0.25f );
428 position[0] = vectorLight.x;
429 position[1] = vectorLight.y;
430 position[2] = vectorLight.z;
432 glLightfv( GL_LIGHT1, GL_AMBIENT, ambient );
433 glLightfv( GL_LIGHT1, GL_DIFFUSE, diffuse12 );
434 glLightfv( GL_LIGHT1, GL_SPECULAR, specular12 );
435 glLightfv( GL_LIGHT1, GL_POSITION, position );
438 position[2] = -position[2];
440 glLightfv( GL_LIGHT2, GL_AMBIENT, ambient );
441 glLightfv( GL_LIGHT2, GL_DIFFUSE, diffuse12 );
442 glLightfv( GL_LIGHT2, GL_SPECULAR, specular12 );
443 glLightfv( GL_LIGHT2, GL_POSITION, position );
445 const GLfloat lmodel_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
447 glLightModelfv( GL_LIGHT_MODEL_AMBIENT, lmodel_ambient );
449 glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
461 glEnable( GL_POLYGON_OFFSET_FILL );
462 glPolygonOffset( -0.1f, -2.0f );
469 glDisable( GL_POLYGON_OFFSET_FILL );
482 std::shared_ptr<OPENGL_RENDER_LIST_DEFERRED> board_disp_list_def =
nullptr;
489 if( board_disp_list_def )
492 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list = board_disp_list_def->MakeOrGet() )
494 ogl_disp_list->ApplyScalePosition( -
m_boardAdapter.GetBoardBodyThickness() / 2.0f,
497 ogl_disp_list->SetItIsTransparent(
true );
498 ogl_disp_list->DrawAll();
505 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_postMachinePlugs->MakeOrGet() )
507 ogl_disp_list->ApplyScalePosition( -
m_boardAdapter.GetBoardBodyThickness() / 2.0f,
510 ogl_disp_list->SetItIsTransparent(
true );
511 ogl_disp_list->DrawAll();
519 return SFVEC4F( aInput.r * aInput.a, aInput.g * aInput.a, aInput.b * aInput.a, aInput.a );
536 if( reloadRequested )
572 glDepthFunc( GL_LESS );
573 glEnable( GL_CULL_FACE );
574 glFrontFace( GL_CCW );
575 glEnable( GL_NORMALIZE );
579 glDisable( GL_MULTISAMPLE );
581 glEnable( GL_MULTISAMPLE );
584 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
585 glClearDepth( 1.0f );
586 glClearStencil( 0x00 );
587 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
595 glEnable( GL_DEPTH_TEST );
598 glMatrixMode( GL_PROJECTION );
599 glLoadMatrixf( glm::value_ptr(
m_camera.GetProjectionMatrix() ) );
600 glMatrixMode( GL_MODELVIEW );
602 glLoadMatrixf( glm::value_ptr(
m_camera.GetViewMatrix() ) );
609 glEnable( GL_LIGHTING );
618 if( cameraPos.z > 0.0f )
619 zpos = glm::max( cameraPos.z, 0.5f ) + cameraPos.z * cameraPos.z;
621 zpos = glm::min( cameraPos.z,-0.5f ) - cameraPos.z * cameraPos.z;
624 const GLfloat headlight_pos[] = { cameraPos.x, cameraPos.y, zpos, 1.0f };
626 glLightfv( GL_LIGHT0, GL_POSITION, headlight_pos );
632 bool showThickness = !skipThickness;
634 std::bitset<LAYER_3D_END> layerFlags =
m_boardAdapter.GetVisibleLayers();
640 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_microviaHoles->MakeOrGet() )
641 ogl_disp_list->DrawAll();
646 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_padHoles->MakeOrGet() )
647 ogl_disp_list->DrawAll();
651 for( MAP_OGL_DISP_LISTS::const_iterator ii =
m_layers.begin(); ii !=
m_layers.end(); ++ii )
665 const double opacity_min = 0.8;
678 std::shared_ptr<OPENGL_RENDER_LIST_DEFERRED> pLayerDispListDef = ii->second;
679 std::shared_ptr<OPENGL_RENDER_LIST> pLayerDispList = pLayerDispListDef->MakeOrGet();
690 std::shared_ptr<OPENGL_RENDER_LIST> outerTH =
nullptr;
691 std::shared_ptr<OPENGL_RENDER_LIST> viaHoles =
nullptr;
693 if( !skipRenderHoles )
700 anti_board->ApplyScalePosition( pLayerDispList );
703 outerTH->ApplyScalePosition( pLayerDispList );
705 pLayerDispList->DrawCulled( showThickness, outerTH, viaHoles, anti_board );
714 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_platedPadsFront->MakeOrGet() )
715 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles, anti_board );
721 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles );
730 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_platedPadsBack->MakeOrGet() )
731 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles, anti_board );
736 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_offboardPadsBack->MakeOrGet() )
737 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles );
747 std::shared_ptr<OPENGL_RENDER_LIST> throughHolesOuter =
nullptr;
748 std::shared_ptr<OPENGL_RENDER_LIST> anti_board =
nullptr;
749 std::shared_ptr<OPENGL_RENDER_LIST> solder_mask =
nullptr;
751 if( !skipRenderHoles )
760 anti_board =
nullptr;
767 solder_mask =
m_layers[maskLayer] ?
m_layers[maskLayer]->MakeOrGet() :
nullptr;
770 if( throughHolesOuter )
771 throughHolesOuter->ApplyScalePosition( pLayerDispList );
774 anti_board->ApplyScalePosition( pLayerDispList );
777 solder_mask->ApplyScalePosition( pLayerDispList );
780 glEnable( GL_POLYGON_OFFSET_FILL );
781 glPolygonOffset( 0.0f, -4.0f );
783 pLayerDispList->DrawCulled( showThickness, solder_mask, throughHolesOuter, anti_board );
785 glDisable( GL_POLYGON_OFFSET_FILL );
786 glPolygonOffset( 0.0f, 0.0f );
792 glm::mat4 cameraViewMatrix;
794 glGetFloatv( GL_MODELVIEW_MATRIX, glm::value_ptr( cameraViewMatrix ) );
810 std::shared_ptr<OPENGL_RENDER_LIST> renderList = renderListDef->MakeOrGet();
815 bool highlight =
false;
819 if( fp->IsSelected() )
833 renderList->DrawAll();
844 glEnable( GL_POLYGON_OFFSET_FILL );
845 glPolygonOffset( 0.0f, 2.0f );
849 glDisable( GL_POLYGON_OFFSET_FILL );
850 glPolygonOffset( 0.0f, 0.0f );
859 glEnable( GL_POLYGON_OFFSET_FILL );
860 glPolygonOffset( 0.0f, -2.0f );
867 showThickness, skipRenderHoles );
873 showThickness, skipRenderHoles );
881 showThickness, skipRenderHoles );
887 showThickness, skipRenderHoles );
891 glDisable( GL_POLYGON_OFFSET_FILL );
892 glPolygonOffset( 0.0f, 0.0f );
898 glDepthMask( GL_FALSE );
899 glEnable( GL_BLEND );
900 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
903 glEnable( GL_TEXTURE_2D );
904 glActiveTexture( GL_TEXTURE0 );
909 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
910 glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE );
911 glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE );
913 glTexEnvi( GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR );
914 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );
916 glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS );
917 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR );
919 glTexEnvi( GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR );
920 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );
921 glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT );
922 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA );
926 glDisable( GL_BLEND );
929 glEnable( GL_BLEND );
930 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
934 glDisable( GL_BLEND );
936 glDepthMask( GL_TRUE );
941 glDisable( GL_LIGHTING );
946 glEnable( GL_LIGHTING );
963 glEnable( GL_LINE_SMOOTH );
964 glShadeModel( GL_SMOOTH );
967 glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
988 delete circleImageBlured;
989 circleImageBlured =
nullptr;
992 circleImage =
nullptr;
1006 glEnable( GL_COLOR_MATERIAL );
1007 glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
1014 glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specular.r );
1015 glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, 96.0f );
1017 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, &ambient.r );
1018 glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse.r );
1019 glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, &emissive.r );
1025#define DELETE_AND_FREE( ptr ) \
1030#define DELETE_AND_FREE_MAP( map ) \
1032 for( auto& [ layer, ptr ] : map ) \
1039 glDeleteLists(
m_grid, 1 );
1053 for( std::shared_ptr<TRIANGLE_DISPLAY_LIST>& list :
m_triangles )
1085 std::vector<std::shared_ptr<void>> retired;
1088 std::lock_guard<std::recursive_mutex> lock(
m_renderMutex );
1095 bool aShowThickness,
bool aSkipRenderHoles )
1097 wxASSERT( (aLayerID ==
B_Mask) || (aLayerID ==
F_Mask) );
1101 std::shared_ptr<OPENGL_RENDER_LIST> board_list =
m_board->MakeOrGet();
1102 std::shared_ptr<OPENGL_RENDER_LIST> solder_mask =
1104 std::shared_ptr<OPENGL_RENDER_LIST> via_holes =
1108 via_holes->ApplyScalePosition( aZPos,
m_boardAdapter.GetNonCopperLayerThickness() );
1110 board_list->ApplyScalePosition( aZPos,
m_boardAdapter.GetNonCopperLayerThickness() );
1113 board_list->SetItIsTransparent(
true );
1114 board_list->DrawCulled( aShowThickness, solder_mask, via_holes );
1118 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_draw_list =
m_viaFrontCover->MakeOrGet() )
1120 ogl_draw_list->ApplyScalePosition( aZPos, 4 *
m_boardAdapter.GetNonCopperLayerThickness() );
1121 ogl_draw_list->DrawTop();
1126 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_draw_list =
m_viaBackCover->MakeOrGet() )
1128 ogl_draw_list->ApplyScalePosition( aZPos, 4 *
m_boardAdapter.GetNonCopperLayerThickness() );
1129 ogl_draw_list->DrawBot();
1137 bool aGetBot,
bool aRenderTransparentOnly,
1138 bool aRenderSelectedOnly )
1140 wxASSERT( ( aGetTop ==
true ) || ( aGetBot ==
true ) );
1150 bool highlight =
false;
1154 if( fp->IsSelected() )
1160 if( aRenderSelectedOnly != highlight )
1164 bool hasModels = !fp->Models().empty();
1165 bool showMissing =
m_boardAdapter.m_Cfg->m_Render.show_missing_models;
1167 if( hasModels || showMissing )
1171 const bool isFlipped = fp->IsFlipped();
1173 if( aGetTop == !isFlipped || aGetBot == isFlipped )
1184 bool aRenderTransparentOnly,
bool aIsSelected )
1186 if( !aFootprint->
Models().empty() )
1188 const glm::mat4 fpMatrix =
m_boardAdapter.GetFootprintMatrix( *aFootprint );
1191 bool placeholderAdded =
false;
1196 if( !sM.m_Show || sM.m_Filename.empty() )
1204 if( !placeholderAdded )
1207 aIsSelected, aRenderTransparentOnly ? sM.m_Opacity : 1.0f );
1208 placeholderAdded =
true;
1214 if(
const std::shared_ptr<MODEL_3D_DEFERRED>& modelPtrDef = cache_i->second )
1216 std::shared_ptr<MODEL_3D> modelPtr = modelPtrDef->MakeOrGet();
1221 bool opaque = sM.m_Opacity >= 1.0;
1223 if( ( !aRenderTransparentOnly && modelPtr->HasOpaqueMeshes() && opaque ) ||
1224 ( aRenderTransparentOnly && ( modelPtr->HasTransparentMeshes() || !opaque ) ) )
1226 glm::mat4 modelworldMatrix = fpMatrix;
1228 const SFVEC3F offset =
SFVEC3F( sM.m_Offset.x, sM.m_Offset.y, sM.m_Offset.z );
1229 const SFVEC3F rotation =
SFVEC3F( sM.m_Rotation.x, sM.m_Rotation.y,
1233 std::vector<float> key = { offset.x, offset.y, offset.z,
1234 rotation.x, rotation.y, rotation.z,
1241 modelworldMatrix *= it->second;
1248 modelworldMatrix *= mtx;
1251 aDstRenderList.emplace_back( modelworldMatrix, modelPtr,
1252 aRenderTransparentOnly ? sM.m_Opacity : 1.0f,
1253 aRenderTransparentOnly,
1261 const glm::mat4 fpMatrix =
m_boardAdapter.GetFootprintMatrix( *aFootprint );
1270 const glm::mat4& aFpMatrix,
const FOOTPRINT* aFootprint,
1271 bool aRenderTransparentOnly,
bool aIsSelected,
float aOpacity )
1285 float scaleX = bboxW;
1286 float scaleY = bboxH;
1287 float scaleZ = std::min( bboxW, bboxH ) * 0.5f;
1290 float offsetX = localCenter.
x /
pcbIUScale.IU_PER_MM;
1291 float offsetY = -localCenter.
y /
pcbIUScale.IU_PER_MM;
1292 float offsetZ = scaleZ * 0.5f;
1297 glm::mat4 mtx = aFpMatrix;
1298 mtx = glm::translate( mtx,
SFVEC3F( offsetX, offsetY, offsetZ ) );
1299 mtx = glm::scale( mtx,
SFVEC3F( scaleX, scaleY, scaleZ ) );
1301 bool placeholderOpaque = aOpacity >= 1.0;
1303 if( ( !aRenderTransparentOnly &&
m_placeholderModel->HasOpaqueMeshes() && placeholderOpaque )
1304 || ( aRenderTransparentOnly && (
m_placeholderModel->HasTransparentMeshes() || !placeholderOpaque ) ) )
1306 aDstRenderList.emplace_back( mtx,
m_placeholderModel, aOpacity, aRenderTransparentOnly,
1320 std::list<MODELTORENDER> renderList;
1328 if( !renderList.empty() )
1333 renderModel( aCameraViewMatrix, mtr, selColor,
nullptr );
1342 if( !renderList.empty() )
1347 renderModel( aCameraViewMatrix, mtr, selColor,
nullptr );
1368 if( !renderListDef )
1371 std::shared_ptr<OPENGL_RENDER_LIST> renderList = renderListDef->MakeOrGet();
1376 bool highlight =
false;
1380 if( fp->IsSelected() )
1392 if( ( c.
a < 1.0 ) != aTransparentPass )
1408 renderList->DrawAll();
1414 if( std::shared_ptr<OPENGL_RENDER_LIST> pegList = pegIt->second->MakeOrGet() )
1427 std::list<MODELTORENDER> renderListModels;
1438 if( renderListModels.empty() )
1441 std::vector<std::pair<const MODELTORENDER *, float>> transparentModelList;
1443 transparentModelList.reserve( renderListModels.size() );
1450 const BBOX_3D& bBox = mtr.m_model->GetBBox();
1452 const SFVEC3F bBoxWorld = mtr.m_modelWorldMat * glm::vec4( bBoxCenter, 1.0f );
1454 const float distanceToCamera = glm::length( cameraPos - bBoxWorld );
1456 transparentModelList.emplace_back( &mtr, distanceToCamera );
1460 std::sort( transparentModelList.begin(), transparentModelList.end(),
1461 [&]( std::pair<const MODELTORENDER *, float>& a,
1462 std::pair<const MODELTORENDER *, float>& b )
1464 if( a.second != b.second )
1465 return a.second > b.second;
1467 return a.first > b.first;
1473 bool isUsingColorInformation = !( transparentModelList.begin()->first->m_isSelected &&
1478 for(
const std::pair<const MODELTORENDER *, float>& mtr : transparentModelList )
1483 if( !isUsingColorInformation && !mtr.first->m_isSelected )
1485 isUsingColorInformation =
true;
1487 glEnableClientState( GL_COLOR_ARRAY );
1488 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
1489 glEnable( GL_COLOR_MATERIAL );
1491 else if( isUsingColorInformation && mtr.first->m_isSelected )
1493 isUsingColorInformation =
false;
1495 glDisableClientState( GL_COLOR_ARRAY );
1496 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
1497 glDisable( GL_COLOR_MATERIAL );
1503 renderModel( aCameraViewMatrix, *mtr.first, selColor, &cameraPos );
1518 const glm::mat4 modelviewMatrix = aCameraViewMatrix * aModelToRender.
m_modelWorldMat;
1520 glLoadMatrixf( glm::value_ptr( modelviewMatrix ) );
1528 const bool wasBlendEnabled = glIsEnabled( GL_BLEND );
1530 if( !wasBlendEnabled )
1532 glEnable( GL_BLEND );
1533 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1536 glDisable( GL_LIGHTING );
1544 glEnable( GL_LIGHTING );
1546 if( !wasBlendEnabled )
1547 glDisable( GL_BLEND );
1555 glDeleteLists(
m_grid, 1 );
1562 m_grid = glGenLists( 1 );
1564 if( !glIsList(
m_grid ) )
1567 glNewList(
m_grid, GL_COMPILE );
1569 glEnable( GL_BLEND );
1570 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1572 const double zpos = 0.0;
1580 const GLfloat transparency = 0.35f;
1582 double griSizeMM = 0.0;
1595 glNormal3f( 0.0, 0.0, 1.0 );
1600 brd_center_pos.
y = -brd_center_pos.
y;
1602 const int xsize = std::max( brd_size.
x,
pcbIUScale.mmToIU( 100 ) ) * 1.2;
1603 const int ysize = std::max( brd_size.
y,
pcbIUScale.mmToIU( 100 ) ) * 1.2;
1606 double xmin = ( brd_center_pos.
x - xsize / 2 ) *
scale;
1607 double xmax = ( brd_center_pos.
x + xsize / 2 ) *
scale;
1608 double ymin = ( brd_center_pos.
y - ysize / 2 ) *
scale;
1609 double ymax = ( brd_center_pos.
y + ysize / 2 ) *
scale;
1617 for(
int ii = 0; ; ii++ )
1620 glColor4f( gridColor.r, gridColor.g, gridColor.b, transparency );
1622 glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b,
1627 if(
delta <= xsize / 2 )
1629 glBegin( GL_LINES );
1630 glVertex3f( (brd_center_pos.
x +
delta) *
scale, -ymin, zpos );
1631 glVertex3f( (brd_center_pos.
x +
delta) *
scale, -ymax, zpos );
1636 glBegin( GL_LINES );
1637 glVertex3f( (brd_center_pos.
x -
delta) *
scale, -ymin, zpos );
1638 glVertex3f( (brd_center_pos.
x -
delta) *
scale, -ymax, zpos );
1643 if(
delta <= ysize / 2 )
1645 glBegin( GL_LINES );
1646 glVertex3f( xmin, -( brd_center_pos.
y +
delta ) *
scale, zpos );
1647 glVertex3f( xmax, -( brd_center_pos.
y +
delta ) *
scale, zpos );
1652 glBegin( GL_LINES );
1653 glVertex3f( xmin, -( brd_center_pos.
y -
delta ) *
scale, zpos );
1654 glVertex3f( xmax, -( brd_center_pos.
y -
delta ) *
scale, zpos );
1659 if( (
delta > ysize / 2 ) && (
delta > xsize / 2 ) )
1664 glNormal3f( 0.0, -1.0, 0.0 );
1667 double posy = -brd_center_pos.
y *
scale;
1669 for(
int ii = 0; ; ii++ )
1672 glColor4f( gridColor.r, gridColor.g, gridColor.b, transparency );
1674 glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b,
1679 glBegin( GL_LINES );
1682 glVertex3f( xmax, posy, zmin );
1683 glVertex3f( xmax, posy, zmax );
1688 glBegin( GL_LINES );
1690 glVertex3f( xmin, posy, zmin );
1691 glVertex3f( xmin, posy, zmax );
1695 if(
delta > xsize / 2.0f )
1700 for(
int ii = 0; ; ii++ )
1703 glColor4f( gridColor.r, gridColor.g, gridColor.b, transparency );
1705 glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b, transparency );
1712 glBegin( GL_LINES );
1713 glVertex3f( xmin, posy,
delta );
1714 glVertex3f( xmax, posy,
delta );
1718 if(
delta <= -zmin && ( ii != 0 ) )
1721 glBegin( GL_LINES );
1722 glVertex3f( xmin, posy, -
delta );
1723 glVertex3f( xmax, posy, -
delta );
1731 glDisable( GL_BLEND );
1740 static SFVEC3F positions[24] = {
1741 { -0.5f, -0.5f, 0.5f },
1742 { 0.5f, -0.5f, 0.5f },
1743 { 0.5f, 0.5f, 0.5f },
1744 { -0.5f, 0.5f, 0.5f },
1747 { -0.5f, 0.5f, -0.5f },
1748 { 0.5f, 0.5f, -0.5f },
1749 { 0.5f, -0.5f, -0.5f },
1750 { -0.5f, -0.5f, -0.5f },
1753 { 0.5f, -0.5f, -0.5f },
1754 { 0.5f, 0.5f, -0.5f },
1755 { 0.5f, 0.5f, 0.5f },
1756 { 0.5f, -0.5f, 0.5f },
1759 { -0.5f, -0.5f, 0.5f },
1760 { -0.5f, 0.5f, 0.5f },
1761 { -0.5f, 0.5f, -0.5f },
1762 { -0.5f, -0.5f, -0.5f },
1765 { -0.5f, 0.5f, 0.5f },
1766 { 0.5f, 0.5f, 0.5f },
1767 { 0.5f, 0.5f, -0.5f },
1768 { -0.5f, 0.5f, -0.5f },
1771 { -0.5f, -0.5f, -0.5f },
1772 { 0.5f, -0.5f, -0.5f },
1773 { 0.5f, -0.5f, 0.5f },
1774 { -0.5f, -0.5f, 0.5f }
1777 static SFVEC3F normals[24] = {
1809 static unsigned int indices[36] = {
1812 8, 9, 10, 8, 10, 11,
1813 12, 13, 14, 12, 14, 15,
1814 16, 17, 18, 16, 18, 19,
1815 20, 21, 22, 20, 22, 23
1827 static SMESH mesh = { 24, positions, normals,
nullptr,
nullptr, 36, indices, 0 };
@ NORMAL
Use all material properties from model file.
glm::mat4 CalcModelMatrix(const SFVEC3F &aOffset, const SFVEC3F &aRotation, const SFVEC3F &aScale)
Build the model-to-footprint transform used by rendering and picking.
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
std::map< const FOOTPRINT *, std::shared_ptr< OPENGL_RENDER_LIST_DEFERRED > > m_extrudedPegLists
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)
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