36#include <glm/geometric.hpp>
53 wxLogTrace(
m_logTrace, wxT(
"RENDER_3D_OPENGL::RENDER_3D_OPENGL" ) );
90 wxLogTrace(
m_logTrace, wxT(
"RENDER_3D_OPENGL::~RENDER_3D_OPENGL" ) );
116 int fbWidth, fbHeight;
117 glGetIntegerv( GL_VIEWPORT, viewport );
130 glEnable( GL_LIGHT0 );
132 glDisable( GL_LIGHT0 );
139 glEnable( GL_LIGHT1 );
141 glDisable( GL_LIGHT1 );
148 glEnable( GL_LIGHT2 );
150 glDisable( GL_LIGHT2 );
213 m_materials.m_Copper.m_Shininess = shininessfactor * 128.0f;
222 m_materials.m_NonPlatedCopper.m_Shininess = 0.1f * 128.0f;
251 m_materials.m_Adhesive.m_Shininess = 0.1f * 128.0f;
265 m_materials.m_SilkSTop.m_Shininess = 0.078125f * 128.0f;
278 m_materials.m_SilkSBot.m_Shininess = 0.078125f * 128.0f;
281 m_materials.m_SolderMask.m_Shininess = 0.8f * 128.0f;
291 m_materials.m_EpoxyBoard.m_Shininess = 0.1f * 128.0f;
321 m_materials.m_SolderMask.m_Transparency = 1.0f - layerColor.a;
389 m_materials.m_Plastic.m_Shininess = 0.078125f * 128.0f;
412 m_materials.m_Plastic.m_Shininess = 0.078125f * 128.0f;
430 const GLfloat ambient[] = { 0.084f, 0.084f, 0.084f, 1.0f };
431 const GLfloat diffuse0[] = { 0.3f, 0.3f, 0.3f, 1.0f };
432 const GLfloat specular0[] = { 0.5f, 0.5f, 0.5f, 1.0f };
434 glLightfv( GL_LIGHT0, GL_AMBIENT, ambient );
435 glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse0 );
436 glLightfv( GL_LIGHT0, GL_SPECULAR, specular0 );
438 const GLfloat diffuse12[] = { 0.7f, 0.7f, 0.7f, 1.0f };
439 const GLfloat specular12[] = { 0.7f, 0.7f, 0.7f, 1.0f };
442 GLfloat position[4] = { 0.0f, 0.0f, 1.0f, 0.0f };
446 glm::pi<float>() * 0.25f );
448 position[0] = vectorLight.x;
449 position[1] = vectorLight.y;
450 position[2] = vectorLight.z;
452 glLightfv( GL_LIGHT1, GL_AMBIENT, ambient );
453 glLightfv( GL_LIGHT1, GL_DIFFUSE, diffuse12 );
454 glLightfv( GL_LIGHT1, GL_SPECULAR, specular12 );
455 glLightfv( GL_LIGHT1, GL_POSITION, position );
458 position[2] = -position[2];
460 glLightfv( GL_LIGHT2, GL_AMBIENT, ambient );
461 glLightfv( GL_LIGHT2, GL_DIFFUSE, diffuse12 );
462 glLightfv( GL_LIGHT2, GL_SPECULAR, specular12 );
463 glLightfv( GL_LIGHT2, GL_POSITION, position );
465 const GLfloat lmodel_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
467 glLightModelfv( GL_LIGHT_MODEL_AMBIENT, lmodel_ambient );
469 glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE );
481 glEnable( GL_POLYGON_OFFSET_FILL );
482 glPolygonOffset( -0.1f, -2.0f );
489 glDisable( GL_POLYGON_OFFSET_FILL );
502 std::shared_ptr<OPENGL_RENDER_LIST_DEFERRED> board_disp_list_def =
nullptr;
509 if( board_disp_list_def )
512 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list = board_disp_list_def->MakeOrGet() )
514 ogl_disp_list->ApplyScalePosition( -
m_boardAdapter.GetBoardBodyThickness() / 2.0f,
517 ogl_disp_list->SetItIsTransparent(
true );
518 ogl_disp_list->DrawAll();
525 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_postMachinePlugs->MakeOrGet() )
527 ogl_disp_list->ApplyScalePosition( -
m_boardAdapter.GetBoardBodyThickness() / 2.0f,
530 ogl_disp_list->SetItIsTransparent(
true );
531 ogl_disp_list->DrawAll();
539 return SFVEC4F( aInput.r * aInput.a, aInput.g * aInput.a, aInput.b * aInput.a, aInput.a );
556 if( reloadRequested )
592 glDepthFunc( GL_LESS );
593 glEnable( GL_CULL_FACE );
594 glFrontFace( GL_CCW );
595 glEnable( GL_NORMALIZE );
599 glDisable( GL_MULTISAMPLE );
601 glEnable( GL_MULTISAMPLE );
604 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
605 glClearDepth( 1.0f );
606 glClearStencil( 0x00 );
607 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
615 glEnable( GL_DEPTH_TEST );
618 glMatrixMode( GL_PROJECTION );
619 glLoadMatrixf( glm::value_ptr(
m_camera.GetProjectionMatrix() ) );
620 glMatrixMode( GL_MODELVIEW );
622 glLoadMatrixf( glm::value_ptr(
m_camera.GetViewMatrix() ) );
629 glEnable( GL_LIGHTING );
638 if( cameraPos.z > 0.0f )
639 zpos = glm::max( cameraPos.z, 0.5f ) + cameraPos.z * cameraPos.z;
641 zpos = glm::min( cameraPos.z,-0.5f ) - cameraPos.z * cameraPos.z;
644 const GLfloat headlight_pos[] = { cameraPos.x, cameraPos.y, zpos, 1.0f };
646 glLightfv( GL_LIGHT0, GL_POSITION, headlight_pos );
652 bool showThickness = !skipThickness;
654 std::bitset<LAYER_3D_END> layerFlags =
m_boardAdapter.GetVisibleLayers();
660 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_microviaHoles->MakeOrGet() )
661 ogl_disp_list->DrawAll();
666 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_padHoles->MakeOrGet() )
667 ogl_disp_list->DrawAll();
671 for( MAP_OGL_DISP_LISTS::const_iterator ii =
m_layers.begin(); ii !=
m_layers.end(); ++ii )
685 const double opacity_min = 0.8;
698 std::shared_ptr<OPENGL_RENDER_LIST_DEFERRED> pLayerDispListDef = ii->second;
699 std::shared_ptr<OPENGL_RENDER_LIST> pLayerDispList = pLayerDispListDef->MakeOrGet();
710 std::shared_ptr<OPENGL_RENDER_LIST> outerTH =
nullptr;
711 std::shared_ptr<OPENGL_RENDER_LIST> viaHoles =
nullptr;
713 if( !skipRenderHoles )
720 anti_board->ApplyScalePosition( pLayerDispList );
723 outerTH->ApplyScalePosition( pLayerDispList );
725 pLayerDispList->DrawCulled( showThickness, outerTH, viaHoles, anti_board );
734 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_platedPadsFront->MakeOrGet() )
735 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles, anti_board );
741 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles );
750 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_platedPadsBack->MakeOrGet() )
751 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles, anti_board );
756 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_disp_list =
m_offboardPadsBack->MakeOrGet() )
757 ogl_disp_list->DrawCulled( showThickness, outerTH, viaHoles );
767 std::shared_ptr<OPENGL_RENDER_LIST> throughHolesOuter =
nullptr;
768 std::shared_ptr<OPENGL_RENDER_LIST> anti_board =
nullptr;
769 std::shared_ptr<OPENGL_RENDER_LIST> solder_mask =
nullptr;
771 if( !skipRenderHoles )
780 anti_board =
nullptr;
787 solder_mask =
m_layers[maskLayer] ?
m_layers[maskLayer]->MakeOrGet() :
nullptr;
790 if( throughHolesOuter )
791 throughHolesOuter->ApplyScalePosition( pLayerDispList );
794 anti_board->ApplyScalePosition( pLayerDispList );
797 solder_mask->ApplyScalePosition( pLayerDispList );
800 glEnable( GL_POLYGON_OFFSET_FILL );
801 glPolygonOffset( 0.0f, -4.0f );
803 pLayerDispList->DrawCulled( showThickness, solder_mask, throughHolesOuter, anti_board );
805 glDisable( GL_POLYGON_OFFSET_FILL );
806 glPolygonOffset( 0.0f, 0.0f );
812 glm::mat4 cameraViewMatrix;
814 glGetFloatv( GL_MODELVIEW_MATRIX, glm::value_ptr( cameraViewMatrix ) );
830 std::shared_ptr<OPENGL_RENDER_LIST> renderList = renderListDef->MakeOrGet();
835 bool highlight =
false;
839 if( fp->IsSelected() )
853 renderList->DrawAll();
864 glEnable( GL_POLYGON_OFFSET_FILL );
865 glPolygonOffset( 0.0f, 2.0f );
869 glDisable( GL_POLYGON_OFFSET_FILL );
870 glPolygonOffset( 0.0f, 0.0f );
879 glEnable( GL_POLYGON_OFFSET_FILL );
880 glPolygonOffset( 0.0f, -2.0f );
887 showThickness, skipRenderHoles );
893 showThickness, skipRenderHoles );
901 showThickness, skipRenderHoles );
907 showThickness, skipRenderHoles );
911 glDisable( GL_POLYGON_OFFSET_FILL );
912 glPolygonOffset( 0.0f, 0.0f );
918 glDepthMask( GL_FALSE );
919 glEnable( GL_BLEND );
920 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
923 glEnable( GL_TEXTURE_2D );
924 glActiveTexture( GL_TEXTURE0 );
929 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
930 glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE );
931 glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE );
933 glTexEnvi( GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR );
934 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR );
936 glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS );
937 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR );
939 glTexEnvi( GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR );
940 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA );
941 glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT );
942 glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA );
946 glDisable( GL_BLEND );
949 glEnable( GL_BLEND );
950 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
954 glDisable( GL_BLEND );
956 glDepthMask( GL_TRUE );
961 glDisable( GL_LIGHTING );
966 glEnable( GL_LIGHTING );
983 glEnable( GL_LINE_SMOOTH );
984 glShadeModel( GL_SMOOTH );
987 glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
1008 delete circleImageBlured;
1009 circleImageBlured =
nullptr;
1012 circleImage =
nullptr;
1026 glEnable( GL_COLOR_MATERIAL );
1027 glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
1034 glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specular.r );
1035 glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, 96.0f );
1037 glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, &ambient.r );
1038 glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, &diffuse.r );
1039 glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, &emissive.r );
1045#define DELETE_AND_FREE( ptr ) \
1050#define DELETE_AND_FREE_MAP( map ) \
1052 for( auto& [ layer, ptr ] : map ) \
1059 glDeleteLists(
m_grid, 1 );
1073 for( std::shared_ptr<TRIANGLE_DISPLAY_LIST>& list :
m_triangles )
1105 std::vector<std::shared_ptr<void>> retired;
1108 std::lock_guard<std::recursive_mutex> lock(
m_renderMutex );
1115 bool aShowThickness,
bool aSkipRenderHoles )
1117 wxASSERT( (aLayerID ==
B_Mask) || (aLayerID ==
F_Mask) );
1121 std::shared_ptr<OPENGL_RENDER_LIST> board_list =
m_board->MakeOrGet();
1122 std::shared_ptr<OPENGL_RENDER_LIST> solder_mask =
1124 std::shared_ptr<OPENGL_RENDER_LIST> via_holes =
1128 via_holes->ApplyScalePosition( aZPos,
m_boardAdapter.GetNonCopperLayerThickness() );
1130 board_list->ApplyScalePosition( aZPos,
m_boardAdapter.GetNonCopperLayerThickness() );
1133 board_list->SetItIsTransparent(
true );
1134 board_list->DrawCulled( aShowThickness, solder_mask, via_holes );
1138 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_draw_list =
m_viaFrontCover->MakeOrGet() )
1140 ogl_draw_list->ApplyScalePosition( aZPos, 4 *
m_boardAdapter.GetNonCopperLayerThickness() );
1141 ogl_draw_list->DrawTop();
1146 if( std::shared_ptr<OPENGL_RENDER_LIST> ogl_draw_list =
m_viaBackCover->MakeOrGet() )
1148 ogl_draw_list->ApplyScalePosition( aZPos, 4 *
m_boardAdapter.GetNonCopperLayerThickness() );
1149 ogl_draw_list->DrawBot();
1157 bool aGetBot,
bool aRenderTransparentOnly,
1158 bool aRenderSelectedOnly )
1160 wxASSERT( ( aGetTop ==
true ) || ( aGetBot ==
true ) );
1170 bool highlight =
false;
1174 if( fp->IsSelected() )
1180 if( aRenderSelectedOnly != highlight )
1184 if( !fp->Models().empty() ||
m_boardAdapter.ShowMissingModels() )
1188 const bool isFlipped = fp->IsFlipped();
1190 if( aGetTop == !isFlipped || aGetBot == isFlipped )
1200 bool aRenderTransparentOnly,
bool aIsSelected )
1202 if( !aFootprint->
Models().empty() )
1204 const glm::mat4 fpMatrix =
m_boardAdapter.GetFootprintMatrix( *aFootprint );
1207 bool placeholderAdded =
false;
1212 if( !sM.m_Show || sM.m_Filename.empty() )
1220 if( !placeholderAdded )
1223 aIsSelected, aRenderTransparentOnly ? sM.m_Opacity : 1.0f );
1224 placeholderAdded =
true;
1230 if(
const std::shared_ptr<MODEL_3D_DEFERRED>& modelPtrDef = cache_i->second )
1232 std::shared_ptr<MODEL_3D> modelPtr = modelPtrDef->MakeOrGet();
1237 bool opaque = sM.m_Opacity >= 1.0;
1239 if( ( !aRenderTransparentOnly && modelPtr->HasOpaqueMeshes() && opaque ) ||
1240 ( aRenderTransparentOnly && ( modelPtr->HasTransparentMeshes() || !opaque ) ) )
1242 glm::mat4 modelworldMatrix = fpMatrix;
1244 const SFVEC3F offset =
SFVEC3F( sM.m_Offset.x, sM.m_Offset.y, sM.m_Offset.z );
1245 const SFVEC3F rotation =
SFVEC3F( sM.m_Rotation.x, sM.m_Rotation.y,
1249 std::vector<float> key = { offset.x, offset.y, offset.z,
1250 rotation.x, rotation.y, rotation.z,
1257 modelworldMatrix *= it->second;
1264 modelworldMatrix *= mtx;
1267 aDstRenderList.emplace_back( modelworldMatrix, modelPtr,
1268 aRenderTransparentOnly ? sM.m_Opacity : 1.0f,
1269 aRenderTransparentOnly,
1277 const glm::mat4 fpMatrix =
m_boardAdapter.GetFootprintMatrix( *aFootprint );
1286 const glm::mat4& aFpMatrix,
const FOOTPRINT* aFootprint,
1287 bool aRenderTransparentOnly,
bool aIsSelected,
float aOpacity )
1301 float scaleX = bboxW;
1302 float scaleY = bboxH;
1303 float scaleZ = std::min( bboxW, bboxH ) * 0.5f;
1306 float offsetX = localCenter.
x /
pcbIUScale.IU_PER_MM;
1307 float offsetY = -localCenter.
y /
pcbIUScale.IU_PER_MM;
1308 float offsetZ = scaleZ * 0.5f;
1313 glm::mat4 mtx = aFpMatrix;
1314 mtx = glm::translate( mtx,
SFVEC3F( offsetX, offsetY, offsetZ ) );
1315 mtx = glm::scale( mtx,
SFVEC3F( scaleX, scaleY, scaleZ ) );
1317 bool placeholderOpaque = aOpacity >= 1.0;
1319 if( ( !aRenderTransparentOnly &&
m_placeholderModel->HasOpaqueMeshes() && placeholderOpaque )
1320 || ( aRenderTransparentOnly && (
m_placeholderModel->HasTransparentMeshes() || !placeholderOpaque ) ) )
1322 aDstRenderList.emplace_back( mtx,
m_placeholderModel, aOpacity, aRenderTransparentOnly,
1336 std::list<MODELTORENDER> renderList;
1344 if( !renderList.empty() )
1349 renderModel( aCameraViewMatrix, mtr, selColor,
nullptr );
1358 if( !renderList.empty() )
1363 renderModel( aCameraViewMatrix, mtr, selColor,
nullptr );
1379 const EXTRUDED_3D_BODY* body = fp->GetBody() ? fp->GetBody()->GetExtruded() :
nullptr;
1384 if( !renderListDef )
1387 std::shared_ptr<OPENGL_RENDER_LIST> renderList = renderListDef->MakeOrGet();
1392 bool highlight =
false;
1396 if( fp->IsSelected() )
1408 if( ( c.
a < 1.0 ) != aTransparentPass )
1424 renderList->DrawAll();
1430 if( std::shared_ptr<OPENGL_RENDER_LIST> pegList = pegIt->second->MakeOrGet() )
1443 std::list<MODELTORENDER> renderListModels;
1454 if( renderListModels.empty() )
1457 std::vector<std::pair<const MODELTORENDER *, float>> transparentModelList;
1459 transparentModelList.reserve( renderListModels.size() );
1466 const BBOX_3D& bBox = mtr.m_model->GetBBox();
1468 const SFVEC3F bBoxWorld = mtr.m_modelWorldMat * glm::vec4( bBoxCenter, 1.0f );
1470 const float distanceToCamera = glm::length( cameraPos - bBoxWorld );
1472 transparentModelList.emplace_back( &mtr, distanceToCamera );
1476 std::sort( transparentModelList.begin(), transparentModelList.end(),
1477 [&]( std::pair<const MODELTORENDER *, float>& a,
1478 std::pair<const MODELTORENDER *, float>& b )
1480 if( a.second != b.second )
1481 return a.second > b.second;
1483 return a.first > b.first;
1489 bool isUsingColorInformation = !( transparentModelList.begin()->first->m_isSelected &&
1494 for(
const std::pair<const MODELTORENDER *, float>& mtr : transparentModelList )
1499 if( !isUsingColorInformation && !mtr.first->m_isSelected )
1501 isUsingColorInformation =
true;
1503 glEnableClientState( GL_COLOR_ARRAY );
1504 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
1505 glEnable( GL_COLOR_MATERIAL );
1507 else if( isUsingColorInformation && mtr.first->m_isSelected )
1509 isUsingColorInformation =
false;
1511 glDisableClientState( GL_COLOR_ARRAY );
1512 glDisableClientState( GL_TEXTURE_COORD_ARRAY );
1513 glDisable( GL_COLOR_MATERIAL );
1519 renderModel( aCameraViewMatrix, *mtr.first, selColor, &cameraPos );
1534 const glm::mat4 modelviewMatrix = aCameraViewMatrix * aModelToRender.
m_modelWorldMat;
1536 glLoadMatrixf( glm::value_ptr( modelviewMatrix ) );
1544 const bool wasBlendEnabled = glIsEnabled( GL_BLEND );
1546 if( !wasBlendEnabled )
1548 glEnable( GL_BLEND );
1549 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1552 glDisable( GL_LIGHTING );
1560 glEnable( GL_LIGHTING );
1562 if( !wasBlendEnabled )
1563 glDisable( GL_BLEND );
1571 glDeleteLists(
m_grid, 1 );
1578 m_grid = glGenLists( 1 );
1580 if( !glIsList(
m_grid ) )
1583 glNewList(
m_grid, GL_COMPILE );
1585 glEnable( GL_BLEND );
1586 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1588 const double zpos = 0.0;
1596 const GLfloat transparency = 0.35f;
1598 double griSizeMM = 0.0;
1611 glNormal3f( 0.0, 0.0, 1.0 );
1616 brd_center_pos.
y = -brd_center_pos.
y;
1618 const int xsize = std::max( brd_size.
x,
pcbIUScale.mmToIU( 100 ) ) * 1.2;
1619 const int ysize = std::max( brd_size.
y,
pcbIUScale.mmToIU( 100 ) ) * 1.2;
1622 double xmin = ( brd_center_pos.
x - xsize / 2 ) *
scale;
1623 double xmax = ( brd_center_pos.
x + xsize / 2 ) *
scale;
1624 double ymin = ( brd_center_pos.
y - ysize / 2 ) *
scale;
1625 double ymax = ( brd_center_pos.
y + ysize / 2 ) *
scale;
1633 for(
int ii = 0; ; ii++ )
1636 glColor4f( gridColor.r, gridColor.g, gridColor.b, transparency );
1638 glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b,
1643 if(
delta <= xsize / 2 )
1645 glBegin( GL_LINES );
1646 glVertex3f( (brd_center_pos.
x +
delta) *
scale, -ymin, zpos );
1647 glVertex3f( (brd_center_pos.
x +
delta) *
scale, -ymax, zpos );
1652 glBegin( GL_LINES );
1653 glVertex3f( (brd_center_pos.
x -
delta) *
scale, -ymin, zpos );
1654 glVertex3f( (brd_center_pos.
x -
delta) *
scale, -ymax, zpos );
1659 if(
delta <= ysize / 2 )
1661 glBegin( GL_LINES );
1662 glVertex3f( xmin, -( brd_center_pos.
y +
delta ) *
scale, zpos );
1663 glVertex3f( xmax, -( brd_center_pos.
y +
delta ) *
scale, zpos );
1668 glBegin( GL_LINES );
1669 glVertex3f( xmin, -( brd_center_pos.
y -
delta ) *
scale, zpos );
1670 glVertex3f( xmax, -( brd_center_pos.
y -
delta ) *
scale, zpos );
1675 if( (
delta > ysize / 2 ) && (
delta > xsize / 2 ) )
1680 glNormal3f( 0.0, -1.0, 0.0 );
1683 double posy = -brd_center_pos.
y *
scale;
1685 for(
int ii = 0; ; ii++ )
1688 glColor4f( gridColor.r, gridColor.g, gridColor.b, transparency );
1690 glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b,
1695 glBegin( GL_LINES );
1698 glVertex3f( xmax, posy, zmin );
1699 glVertex3f( xmax, posy, zmax );
1704 glBegin( GL_LINES );
1706 glVertex3f( xmin, posy, zmin );
1707 glVertex3f( xmin, posy, zmax );
1711 if(
delta > xsize / 2.0f )
1716 for(
int ii = 0; ; ii++ )
1719 glColor4f( gridColor.r, gridColor.g, gridColor.b, transparency );
1721 glColor4f( gridColor_marker.r, gridColor_marker.g, gridColor_marker.b, transparency );
1728 glBegin( GL_LINES );
1729 glVertex3f( xmin, posy,
delta );
1730 glVertex3f( xmax, posy,
delta );
1734 if(
delta <= -zmin && ( ii != 0 ) )
1737 glBegin( GL_LINES );
1738 glVertex3f( xmin, posy, -
delta );
1739 glVertex3f( xmax, posy, -
delta );
1747 glDisable( GL_BLEND );
1756 static SFVEC3F positions[24] = {
1757 { -0.5f, -0.5f, 0.5f },
1758 { 0.5f, -0.5f, 0.5f },
1759 { 0.5f, 0.5f, 0.5f },
1760 { -0.5f, 0.5f, 0.5f },
1763 { -0.5f, 0.5f, -0.5f },
1764 { 0.5f, 0.5f, -0.5f },
1765 { 0.5f, -0.5f, -0.5f },
1766 { -0.5f, -0.5f, -0.5f },
1769 { 0.5f, -0.5f, -0.5f },
1770 { 0.5f, 0.5f, -0.5f },
1771 { 0.5f, 0.5f, 0.5f },
1772 { 0.5f, -0.5f, 0.5f },
1775 { -0.5f, -0.5f, 0.5f },
1776 { -0.5f, 0.5f, 0.5f },
1777 { -0.5f, 0.5f, -0.5f },
1778 { -0.5f, -0.5f, -0.5f },
1781 { -0.5f, 0.5f, 0.5f },
1782 { 0.5f, 0.5f, 0.5f },
1783 { 0.5f, 0.5f, -0.5f },
1784 { -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 },
1790 { -0.5f, -0.5f, 0.5f }
1793 static SFVEC3F normals[24] = {
1825 static unsigned int indices[36] = {
1828 8, 9, 10, 8, 10, 11,
1829 12, 13, 14, 12, 14, 15,
1830 16, 17, 18, 16, 18, 19,
1831 20, 21, 22, 20, 22, 23
1843 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