61using namespace std::placeholders;
69#include <glsl_kicad_frag.h>
70#include <glsl_kicad_vert.h>
80 wxGLAttributes attribs;
81 attribs.RGBA().DoubleBuffer().Depth( 8 ).EndList();
130 glDeleteTextures( 1, &bitmap.second.id );
136#ifndef DISABLE_BITMAP_CACHE
142 if( glIsTexture( it->second.id ) )
144 it->second.accessTime = wxGetUTCTimeMillis().GetValue();
145 return it->second.id;
150 glDeleteTextures( 1, &it->second.id );
178 return std::numeric_limits< GLuint >::max();
180 const wxImage& imgData = *imgPtr;
182 bmp.
w = imgData.GetSize().x;
183 bmp.
h = imgData.GetSize().y;
189 glGenTextures( 1, &textureID );
197 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
199 if( imgData.HasAlpha() || imgData.HasMask() )
201 bmp.
size = bmp.
w * bmp.
h * 4;
202 auto buf = std::make_unique<uint8_t[]>( bmp.
size );
204 uint8_t* dstP = buf.get();
205 uint8_t* srcP = imgData.GetData();
207 long long pxCount =
static_cast<long long>( bmp.
w ) * bmp.
h;
209 if( imgData.HasAlpha() )
211 uint8_t* srcAlpha = imgData.GetAlpha();
213 for(
long long px = 0; px < pxCount; px++ )
215 memcpy( dstP, srcP, 3 );
223 else if( imgData.HasMask() )
225 uint8_t maskRed = imgData.GetMaskRed();
226 uint8_t maskGreen = imgData.GetMaskGreen();
227 uint8_t maskBlue = imgData.GetMaskBlue();
229 for(
long long px = 0; px < pxCount; px++ )
231 memcpy( dstP, srcP, 3 );
233 if( srcP[0] == maskRed && srcP[1] == maskGreen && srcP[2] == maskBlue )
234 dstP[3] = wxALPHA_TRANSPARENT;
236 dstP[3] = wxALPHA_OPAQUE;
243 glBindTexture( GL_TEXTURE_2D, textureID );
244 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.
w, bmp.
h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
249 bmp.
size = bmp.
w * bmp.
h * 3;
251 uint8_t* srcP = imgData.GetData();
253 glBindTexture( GL_TEXTURE_2D, textureID );
254 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, bmp.
w, bmp.
h, 0, GL_RGB, GL_UNSIGNED_BYTE, srcP );
257 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
258 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
260 long long currentTime = wxGetUTCTimeMillis().GetValue();
265#ifndef DISABLE_BITMAP_CACHE
273 for(
const auto& [kiid, cachedBmp] :
m_bitmaps )
275 const int cacheTimeoutMillis = 1000L;
277 if( currentTime - cachedBmp.accessTime > cacheTimeoutMillis )
291 toRemove = *toRemoveLru;
297 glDeleteTextures( 1, &cachedBitmap.
id );
315 wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener,
316 const wxString& aName ) :
317 GAL( aDisplayOptions ),
339 throw std::runtime_error(
"Could not create the main OpenGL context" );
348 throw std::runtime_error(
"Could not create a private OpenGL context" );
393#if defined _WIN32 || defined _WIN64
400 SetSize( aParent->GetClientSize() );
411 gluTessProperty(
m_tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
482 static std::optional<wxString> cached;
484 if( cached.has_value() )
487 wxString retVal = wxEmptyString;
489 wxFrame* testFrame =
new wxFrame(
nullptr, wxID_ANY, wxT(
"" ), wxDefaultPosition,
490 wxSize( 1, 1 ), wxFRAME_TOOL_WINDOW | wxNO_BORDER );
512 catch( std::runtime_error& err )
515 retVal = wxString( err.what() );
574#ifdef KICAD_GAL_PROFILE
575 PROF_TIMER totalRealTime(
"OPENGL_GAL::beginDrawing()",
true );
578 wxASSERT_MSG(
m_isContextLocked,
"GAL_DRAWING_CONTEXT RAII object should have locked context. "
579 "Calling GAL::beginDrawing() directly is not allowed." );
581 wxASSERT_MSG(
IsVisible(),
"GAL::beginDrawing() must not be entered when GAL is not visible. "
582 "Other drawing routines will expect everything to be initialized "
583 "which will not be the case." );
589 glMatrixMode( GL_PROJECTION );
605 catch(
const std::runtime_error& )
607 wxLogVerbose(
"Could not create a framebuffer for diff mode blending.\n" );
614 catch(
const std::runtime_error& )
616 wxLogVerbose(
"Could not create a framebuffer for overlays.\n" );
626 glDisable( GL_TEXTURE_2D );
628 glShadeModel( GL_FLAT );
631 glEnable( GL_DEPTH_TEST );
632 glDepthFunc( GL_LESS );
635 glEnable( GL_BLEND );
636 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
638 glMatrixMode( GL_MODELVIEW );
642 GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
652 glLoadMatrixd( matrixData );
671 const GLint FONT_TEXTURE_UNIT = 2;
676 glActiveTexture( GL_TEXTURE0 + FONT_TEXTURE_UNIT );
681 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
682 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
683 checkGlError(
"loading bitmap font", __FILE__, __LINE__ );
685 glActiveTexture( GL_TEXTURE0 );
691 glActiveTexture( GL_TEXTURE0 + FONT_TEXTURE_UNIT );
693 glActiveTexture( GL_TEXTURE0 );
700 checkGlError(
"setting bitmap font sampler as shader parameter", __FILE__, __LINE__ );
710 double pixelSizeMultiplier =
m_compositor->GetAntialiasSupersamplingFactor();
713 renderingOffset.
x *= screenPixelSize.
x;
714 renderingOffset.
y *= screenPixelSize.
y;
721 glActiveTexture( GL_TEXTURE0 );
726#ifdef KICAD_GAL_PROFILE
727 totalRealTime.
Stop();
728 wxLogTrace(
traceGalProfile, wxT(
"OPENGL_GAL::beginDrawing(): %.1f ms" ),
729 totalRealTime.
msecs() );
752 PROF_TIMER cntEndNoncached(
"gl-end-noncached" );
762 cntEndNoncached.
Start();
764 cntEndNoncached.
Stop();
766 cntEndCached.
Start();
770 cntEndOverlay.
Start();
776 cntEndOverlay.
Stop();
778 cntComposite.
Start();
781 glColor4d( 1.0, 1.0, 1.0, 1.0 );
800#ifdef KICAD_GAL_PROFILE
825 wxASSERT_MSG(
m_isContextLocked,
"Context not locked. A GAL_CONTEXT_LOCKER RAII object must "
826 "be stacked rather than making separate lock/unlock calls." );
829 "Context was locked by a different client. "
830 "Should not be possible with RAII objects." );
845 wxASSERT_MSG(
m_isContextLocked,
"GAL_UPDATE_CONTEXT RAII object should have locked context. "
846 "Calling this from anywhere else is not allowed." );
848 wxASSERT_MSG(
IsVisible(),
"GAL::beginUpdate() must not be entered when GAL is not visible. "
849 "Other update routines will expect everything to be initialized "
850 "which will not be the case." );
886 VECTOR2D startEndVector = aEndPoint - aStartPoint;
893 float startX =
static_cast<float>( aStartPoint.
x );
894 float startY =
static_cast<float>( aStartPoint.
y );
895 float endX =
static_cast<float>( aEndPoint.
x );
896 float endY =
static_cast<float>( aEndPoint.
y );
898 if( startX == endX && startY == endY )
900 drawCircle( aStartPoint, aWidth / 2, aReserve );
1035 double startAngle = aStartAngle.
AsRadians();
1036 double endAngle = startAngle + aAngle.
AsRadians();
1053 for( alpha = startAngle; ( alpha + alphaIncrement ) < endAngle; )
1059 alpha += alphaIncrement;
1065 const VECTOR2D endPoint( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1078 VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1080 unsigned int lineCount = 0;
1082 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1085 if( alpha != endAngle )
1090 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1092 VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
1099 if( alpha != endAngle )
1101 VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1112 double aWidth,
double aMaxError )
1123 double startAngle = aStartAngle.
AsRadians();
1124 double endAngle = startAngle + aAngle.
AsRadians();
1132 double alphaIncrement = 2.0 *
M_PI / segCount360;
1137 int seg_count =
KiROUND( ( endAngle - startAngle ) / alphaIncrement );
1139 if( seg_count % 2 != 0 )
1143 if( seg_count == 0 )
1145 VECTOR2D p_start( aCenterPoint.
x + cos( startAngle ) * aRadius,
1146 aCenterPoint.
y + sin( startAngle ) * aRadius );
1148 VECTOR2D p_end( aCenterPoint.
x + cos( endAngle ) * aRadius,
1149 aCenterPoint.
y + sin( endAngle ) * aRadius );
1156 alphaIncrement = ( endAngle - startAngle ) / seg_count;
1166 double width = aWidth / 2.0;
1167 VECTOR2D startPoint( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1168 VECTOR2D endPoint( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1173 VECTOR2D pOuter( cos( startAngle ) * ( aRadius + width ),
1174 sin( startAngle ) * ( aRadius + width ) );
1176 VECTOR2D pInner( cos( startAngle ) * ( aRadius - width ),
1177 sin( startAngle ) * ( aRadius - width ) );
1181 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1183 VECTOR2D pNextOuter( cos( alpha ) * ( aRadius + width ),
1184 sin( alpha ) * ( aRadius + width ) );
1185 VECTOR2D pNextInner( cos( alpha ) * ( aRadius - width ),
1186 sin( alpha ) * ( aRadius - width ) );
1191 pOuter = pNextOuter;
1192 pInner = pNextInner;
1196 if( alpha != endAngle )
1198 VECTOR2D pLastOuter( cos( endAngle ) * ( aRadius + width ),
1199 sin( endAngle ) * ( aRadius + width ) );
1200 VECTOR2D pLastInner( cos( endAngle ) * ( aRadius - width ),
1201 sin( endAngle ) * ( aRadius - width ) );
1213 VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1218 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1224 if( alpha != endAngle )
1231 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1233 VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
1240 if( alpha != endAngle )
1242 VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1254 if( aMajorRadius <= 0 || aMinorRadius <= 0 )
1257 const double alphaIncrement =
calcAngleStep( aMajorRadius );
1258 const double cosPhi = std::cos( aRotation.
AsRadians() );
1259 const double sinPhi = std::sin( aRotation.
AsRadians() );
1261 auto eval = [&](
double theta ) ->
VECTOR2D
1263 const double lx = aMajorRadius * std::cos( theta );
1264 const double ly = aMinorRadius * std::sin( theta );
1265 return VECTOR2D( lx * cosPhi - ly * sinPhi, lx * sinPhi + ly * cosPhi );
1278 for( alpha = 0.0; ( alpha + alphaIncrement ) < 2.0 *
M_PI; )
1281 alpha += alphaIncrement;
1305 unsigned int lineCount = 0;
1308 for( countAlpha = alphaIncrement; countAlpha < 2.0 *
M_PI; countAlpha += alphaIncrement )
1318 for( alpha = alphaIncrement; alpha < 2.0 *
M_PI; alpha += alphaIncrement )
1320 const VECTOR2D p_next = eval( alpha );
1336 if( aMajorRadius <= 0 || aMinorRadius <= 0 )
1339 double startAngle = aStartAngle.
AsRadians();
1340 double endAngle = aEndAngle.
AsRadians();
1343 const double alphaIncrement =
calcAngleStep( aMajorRadius );
1344 const double cosPhi = std::cos( aRotation.
AsRadians() );
1345 const double sinPhi = std::sin( aRotation.
AsRadians() );
1347 auto eval = [&](
double theta ) ->
VECTOR2D
1349 const double lx = aMajorRadius * std::cos( theta );
1350 const double ly = aMinorRadius * std::sin( theta );
1351 return VECTOR2D( lx * cosPhi - ly * sinPhi, lx * sinPhi + ly * cosPhi );
1365 for( alpha = startAngle; ( alpha + alphaIncrement ) < endAngle; )
1368 alpha += alphaIncrement;
1379 const VECTOR2D p2 = eval( endAngle );
1391 unsigned int lineCount = 0;
1394 for( countAlpha = startAngle + alphaIncrement; countAlpha <= endAngle; countAlpha += alphaIncrement )
1397 if( countAlpha != endAngle )
1405 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1407 const VECTOR2D p_next = eval( alpha );
1413 if( alpha != endAngle )
1415 const VECTOR2D p_last = eval( endAngle );
1427 VECTOR2D diagonalPointA( aEndPoint.
x, aStartPoint.
y );
1428 VECTOR2D diagonalPointB( aStartPoint.
x, aEndPoint.
y );
1454 if( aStartPoint == aEndPoint )
1460 std::deque<VECTOR2D> pointList;
1462 pointList.push_back( aStartPoint );
1463 pointList.push_back( diagonalPointA );
1464 pointList.push_back( aEndPoint );
1465 pointList.push_back( diagonalPointB );
1466 pointList.push_back( aStartPoint );
1478 return aPointList[idx];
1480 aPointList.size(), aWidth );
1494 return aLineChain.
CPoint( idx );
1496 numPoints, aWidth );
1505 return aPointList[idx];
1507 aPointList.size() );
1516 return aPointList[idx];
1518 aPointList.size() );
1527 return aPointList[idx];
1543 return aLineChain.
CPoint( idx );
1551 int lineQuadCount = 0;
1553 for(
const std::vector<VECTOR2D>& points : aPointList )
1554 lineQuadCount += points.size() - 1;
1558 for(
const std::vector<VECTOR2D>& points : aPointList )
1565 points.size(),
false );
1572 wxCHECK( aPointList.size() >= 2, );
1573 auto points = std::unique_ptr<GLdouble[]>(
new GLdouble[3 * aPointList.size()] );
1574 GLdouble* ptr = points.get();
1576 for(
const VECTOR2D& p : aPointList )
1589 wxCHECK( aListSize >= 2, );
1590 auto points = std::unique_ptr<GLdouble[]>(
new GLdouble[3 * aListSize] );
1591 GLdouble* target = points.get();
1594 for(
int i = 0; i < aListSize; ++i )
1607 bool aStrokeTriangulation )
1614 int totalTriangleCount = 0;
1629 for(
size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
1632 triPoly->GetTriangle( i, a, b, c );
1644 const auto& poly = aPolySet.
Polygon( j );
1646 for(
const auto& lc : poly )
1655 aStrokeTriangulation =
true;
1659 if( aStrokeTriangulation )
1668 for(
size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
1671 triPoly->GetTriangle( i, a, b, c );
1703 std::unique_ptr<GLdouble[]> points(
new GLdouble[3 * pointCount] );
1704 GLdouble* ptr = points.get();
1706 for(
int i = 0; i < pointCount; ++i )
1720 double aFilterValue )
1722 std::vector<VECTOR2D>
output;
1723 std::vector<VECTOR2D> pointCtrl;
1725 pointCtrl.push_back( aStartPoint );
1726 pointCtrl.push_back( aControlPointA );
1727 pointCtrl.push_back( aControlPointB );
1728 pointCtrl.push_back( aEndPoint );
1742 GLfloat alpha = std::clamp( alphaBlend, 0.0, 1.0 );
1752 glm::vec4 v0 = xform * glm::vec4( -w / 2, -h / 2, 0.0, 0.0 );
1753 glm::vec4
v1 = xform * glm::vec4( w / 2, h / 2, 0.0, 0.0 );
1754 glm::vec4 trans = xform[3];
1758 if( !glIsTexture( texture_id ) )
1761 GLboolean depthMask = GL_TRUE;
1762 glGetBooleanv( GL_DEPTH_WRITEMASK, &depthMask );
1765 glDepthMask( GL_FALSE );
1767 glDepthFunc( GL_ALWAYS );
1769 glAlphaFunc( GL_GREATER, 0.01f );
1770 glEnable( GL_ALPHA_TEST );
1772 glMatrixMode( GL_TEXTURE );
1774 glTranslated( 0.5, 0.5, 0.5 );
1776 glTranslated( -0.5, -0.5, -0.5 );
1778 glMatrixMode( GL_MODELVIEW );
1780 glTranslated( trans.x, trans.y, trans.z );
1782 glEnable( GL_TEXTURE_2D );
1783 glActiveTexture( GL_TEXTURE0 );
1784 glBindTexture( GL_TEXTURE_2D, texture_id );
1786 float texStartX = aBitmap.
IsMirroredX() ? 1.0 : 0.0;
1787 float texEndX = aBitmap.
IsMirroredX() ? 0.0 : 1.0;
1788 float texStartY = aBitmap.
IsMirroredY() ? 1.0 : 0.0;
1789 float texEndY = aBitmap.
IsMirroredY() ? 0.0 : 1.0;
1791 glBegin( GL_QUADS );
1792 glColor4f( 1.0, 1.0, 1.0, alpha );
1793 glTexCoord2f( texStartX, texStartY );
1795 glColor4f( 1.0, 1.0, 1.0, alpha );
1796 glTexCoord2f( texEndX, texStartY);
1798 glColor4f( 1.0, 1.0, 1.0, alpha );
1799 glTexCoord2f( texEndX, texEndY);
1801 glColor4f( 1.0, 1.0, 1.0, alpha );
1802 glTexCoord2f( texStartX, texEndY);
1806 glBindTexture( GL_TEXTURE_2D, 0 );
1808#ifdef DISABLE_BITMAP_CACHE
1809 glDeleteTextures( 1, &texture_id );
1814 glMatrixMode( GL_TEXTURE );
1816 glMatrixMode( GL_MODELVIEW );
1818 glDisable( GL_ALPHA_TEST );
1820 glDepthMask( depthMask );
1822 glDepthFunc( GL_LESS );
1831 || aText.Contains( wxT(
"^{" ) )
1832 || aText.Contains( wxT(
"_{" ) )
1833 || aText.Contains( wxT(
"\n" ) ) )
1844 double overbarHeight = textSize.
y;
1875 wxFAIL_MSG( wxT(
"Indeterminate state legal only in dialogs." ) );
1891 overbarHeight = -textSize.
y / 2.0;
1895 wxFAIL_MSG( wxT(
"Indeterminate state legal only in dialogs." ) );
1899 int overbarLength = 0;
1900 int overbarDepth = -1;
1901 int braceNesting = 0;
1903 auto iterateString =
1904 [&](
const std::function<void(
int aOverbarLength,
int aOverbarHeight )>& overbarFn,
1905 const std::function<int(
unsigned long aChar )>& bitmapCharFn )
1909 wxASSERT_MSG( *chIt !=
'\n' && *chIt !=
'\r',
1910 "No support for multiline bitmap text yet" );
1912 if( *chIt ==
'~' && overbarDepth == -1 )
1916 if( ++lookahead !=
end && *lookahead ==
'{' )
1919 overbarDepth = braceNesting;
1924 else if( *chIt ==
'{' )
1928 else if( *chIt ==
'}' )
1930 if( braceNesting > 0 )
1933 if( braceNesting == overbarDepth )
1935 overbarFn( overbarLength, overbarHeight );
1943 if( overbarDepth != -1 )
1944 overbarLength += bitmapCharFn( *chIt );
1946 bitmapCharFn( *chIt );
1953 int overbarsCount = 0;
1956 [&overbarsCount](
int aOverbarLength,
int aOverbarHeight )
1960 [&charsCount](
unsigned long aChar ) ->
int
1976 [&](
int aOverbarLength,
int aOverbarHeight )
1980 [&](
unsigned long aChar ) ->
int
1988 if( overbarDepth != -1 && overbarLength > 0 )
2003 float minorLineWidth = std::fmax( 1.0f,
2005 float majorLineWidth = minorLineWidth * 2.0f;
2049 glDisable( GL_DEPTH_TEST );
2050 glDisable( GL_TEXTURE_2D );
2054 glEnable( GL_STENCIL_TEST );
2055 glStencilFunc( GL_ALWAYS, 1, 1 );
2056 glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
2057 glColor4d( 0.0, 0.0, 0.0, 0.0 );
2069 for(
int j = gridStartY; j <= gridEndY; j++ )
2075 for(
int i = gridStartX; i <= gridEndX; i++ )
2078 SetLineWidth( ( ( tickX && tickY ) ? majorLineWidth : minorLineWidth ) );
2092 for(
int j = gridStartY; j <= gridEndY; j++ )
2111 glStencilFunc( GL_NOTEQUAL, 0, 1 );
2117 for(
int i = gridStartX; i <= gridEndX; i++ )
2134 glDisable( GL_STENCIL_TEST );
2138 glEnable( GL_DEPTH_TEST );
2139 glEnable( GL_TEXTURE_2D );
2149 m_compositor->Resize( aWidth * scaleFactor, aHeight * scaleFactor );
2152 wxGLCanvas::SetSize( aWidth, aHeight );
2158 bool s = wxGLCanvas::Show( aShow );
2161 wxGLCanvas::Raise();
2179 glClearColor( 0, 0, 0, 1 );
2180 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
2186 GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
2188 matrixData[0] = aTransformation.
m_data[0][0];
2189 matrixData[1] = aTransformation.
m_data[1][0];
2190 matrixData[2] = aTransformation.
m_data[2][0];
2191 matrixData[4] = aTransformation.
m_data[0][1];
2192 matrixData[5] = aTransformation.
m_data[1][1];
2193 matrixData[6] = aTransformation.
m_data[2][1];
2194 matrixData[12] = aTransformation.
m_data[0][2];
2195 matrixData[13] = aTransformation.
m_data[1][2];
2196 matrixData[14] = aTransformation.
m_data[2][2];
2198 glMultMatrixd( matrixData );
2236 std::shared_ptr<VERTEX_ITEM> newItem = std::make_shared<VERTEX_ITEM>( *
m_cachedManager );
2238 m_groups.insert( std::make_pair( groupNumber, newItem ) );
2367 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::StartDiffLayer() called" ) );
2374 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): setting target to TARGET_TEMP" ) );
2381 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): TARGET_TEMP set and cleared, compositor buffer=%u" ),
2386 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): WARNING - no temp buffer!" ) );
2393 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::EndDiffLayer() called" ) );
2394 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): m_tempBuffer=%u, m_mainBuffer=%u" ),
2399 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): using temp buffer path" ) );
2404 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): calling DrawBufferDifference" ) );
2412 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): DrawBufferDifference returned" ) );
2416 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): NO temp buffer, using fallback path" ) );
2419 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
2421 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
2424 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::EndDiffLayer() complete" ) );
2436#if wxCHECK_VERSION( 3, 3, 0 )
2448#if wxCHECK_VERSION( 3, 3, 0 )
2467 const bool aReserve )
2485 * glm::vec4( aStartPoint.
x, aStartPoint.
y, 0.0, 0.0 );
2487 * glm::vec4( aEndPoint.
x, aEndPoint.
y, 0.0, 0.0 );
2571 double outerRadius = aRadius + (
m_lineWidth / 2 );
2617 GLdouble* point = aPoints;
2619 for(
int i = 0; i < aPointCount; ++i )
2637 return VECTOR2D( aPoints[idx * 3], aPoints[idx * 3 + 1] );
2647 wxCHECK( aPointCount > 0, );
2651 if( aPointCount == 1 )
2653 drawLineQuad( aPointGetter( 0 ), aPointGetter( 0 ), aReserve );
2662 for(
int i = 1; i < aPointCount; ++i )
2664 auto start = aPointGetter( i - 1 );
2665 auto end = aPointGetter( i );
2673 int aPointCount,
double aWidth,
bool aReserve )
2675 wxCHECK( aPointCount >= 2, );
2681 for(
int i = 1; i < aPointCount; ++i )
2683 auto start = aPointGetter( i - 1 );
2684 auto end = aPointGetter( i );
2686 float startx = start.x;
2687 float starty = start.y;
2696 if( startx == endx && starty == endy )
2708 vertices += 6 + 6 + 3 + 3;
2714 for(
int i = 1; i < aPointCount; ++i )
2716 auto start = aPointGetter( i - 1 );
2717 auto end = aPointGetter( i );
2736 double spaceWidth = g->
advance * 0.74;
2754 const float XOFF = glyph->
minx;
2757 const float round_adjust = ( glyph->
maxy - glyph->
miny )
2760 const float YOFF = round_adjust + top_adjust;
2809 const float H = glyph->
maxy - glyph->
miny;
2839 float commonOffset = std::numeric_limits<float>::max();
2841 int overbarDepth = -1;
2842 int braceNesting = 0;
2846 if( *chIt ==
'~' && overbarDepth == -1 )
2850 if( ++lookahead !=
end && *lookahead ==
'{' )
2853 overbarDepth = braceNesting;
2858 else if( *chIt ==
'{' )
2862 else if( *chIt ==
'}' )
2864 if( braceNesting > 0 )
2867 if( braceNesting == overbarDepth )
2877 || *chIt ==
'-' || *chIt ==
'_' )
2879 glyph = defaultGlyph;
2886 textSize.
y = std::max<float>( textSize.
y, charHeight );
2888 textSize.
y -= commonOffset;
2890 return std::make_pair( textSize, commonOffset );
2934 const int cursorSize = 80;
2941 GLboolean depthTestEnabled = glIsEnabled( GL_DEPTH_TEST );
2942 glDisable( GL_DEPTH_TEST );
2944 glActiveTexture( GL_TEXTURE0 );
2945 glDisable( GL_TEXTURE_2D );
2946 glEnable( GL_BLEND );
2947 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
2950 glColor4d( color.
r, color.
g, color.
b, color.
a );
2952 glMatrixMode( GL_PROJECTION );
2954 glTranslated( 0, 0, -0.5 );
2956 glBegin( GL_LINES );
2971 double offset1 = cy - cx;
2972 VECTOR2D pos_start( screenTopLeft.
x, screenTopLeft.
x + offset1 );
2973 VECTOR2D pos_end( screenBottomRight.
x, screenBottomRight.
x + offset1 );
2976 glVertex2d( pos_start.
x, pos_start.
y );
2977 glVertex2d( pos_end.
x, pos_end.
y );
2980 double offset2 = cy + cx;
2981 VECTOR2D neg_start( screenTopLeft.
x, offset2 - screenTopLeft.
x );
2982 VECTOR2D neg_end( screenBottomRight.
x, offset2 - screenBottomRight.
x );
2985 glVertex2d( neg_start.
x, neg_start.
y );
2986 glVertex2d( neg_end.
x, neg_end.
y );
2990 glVertex2d( cursorCenter.
x, cursorBegin.
y );
2991 glVertex2d( cursorCenter.
x, cursorEnd.
y );
2993 glVertex2d( cursorBegin.
x, cursorCenter.
y );
2994 glVertex2d( cursorEnd.
x, cursorCenter.
y );
3001 if( depthTestEnabled )
3002 glEnable( GL_DEPTH_TEST );
3008 wxASSERT_MSG(
m_groups.size() < std::numeric_limits<unsigned int>::max(),
3009 wxT(
"There are no free slots to store a group" ) );
3020 wxASSERT_MSG(
m_isContextLocked,
"This should only be called from within a locked context." );
3024 throw std::runtime_error(
"Could not create the tesselator" );
3028 int glVersion = gladLoaderLoadGL();
3030 if( glVersion == 0 )
3031 throw std::runtime_error(
"Failed to load OpenGL via loader" );
3033 const char* vendor = (
const char*) glGetString( GL_VENDOR );
3034 const char* renderer = (
const char*) glGetString( GL_RENDERER );
3035 const char* version = (
const char*) glGetString( GL_VERSION );
3038 throw std::runtime_error(
"No GL context is current (glGetString returned NULL)" );
3043 if( !GLAD_GL_VERSION_2_1 )
3044 throw std::runtime_error(
"OpenGL 2.1 or higher is required!" );
3046#if defined( __LINUX__ )
3048 if( glDebugMessageCallback )
3054 if( !GLAD_GL_ARB_framebuffer_object )
3055 throw std::runtime_error(
"Framebuffer objects are not supported!" );
3058 if( !GLAD_GL_ARB_vertex_buffer_object )
3059 throw std::runtime_error(
"Vertex buffer objects are not supported!" );
3064 BUILTIN_SHADERS::glsl_kicad_vert ) )
3066 throw std::runtime_error(
"Cannot compile vertex shader!" );
3071 BUILTIN_SHADERS::glsl_kicad_frag ) )
3073 throw std::runtime_error(
"Cannot compile fragment shader!" );
3077 throw std::runtime_error(
"Cannot link the shaders!" );
3084 glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxTextureSize );
3090 throw std::runtime_error(
"Requested texture size is not supported" );
3093#if wxCHECK_VERSION( 3, 3, 3 )
3094 wxGLCanvas::SetSwapInterval( -1 );
3131 GLdouble* vertex =
static_cast<GLdouble*
>( aVertexPtr );
3135 assert( vboManager );
3136 vboManager->
Vertex( vertex[0], vertex[1], vertex[2] );
3141 GLdouble** dataOut,
void* aData )
3143 GLdouble* vertex =
new GLdouble[3];
3149 param->
intersectPoints.emplace_back( vertex, std::default_delete<GLdouble[]>() );
3151 memcpy( vertex, coords, 3 *
sizeof( GLdouble ) );
3189 return ( ceil( f / r ) - 0.5 ) * r;
3222 outlineGlyph.Triangulate(
3237 if( aGlyphs.empty() )
3240 bool allGlyphsAreStroke =
true;
3241 bool allGlyphsAreOutline =
true;
3243 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3245 if( !glyph->IsStroke() )
3247 allGlyphsAreStroke =
false;
3252 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3254 if( !glyph->IsOutline() )
3256 allGlyphsAreOutline =
false;
3261 if( allGlyphsAreStroke )
3264 int lineQuadCount = 0;
3266 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3270 for(
const std::vector<VECTOR2D>& points : strokeGlyph )
3271 lineQuadCount += points.size() - 1;
3276 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3280 for(
const std::vector<VECTOR2D>& points : strokeGlyph )
3287 points.size(),
false );
3293 else if( allGlyphsAreOutline )
3296 int triangleCount = 0;
3298 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3302 for(
unsigned int i = 0; i < outlineGlyph.TriangulatedPolyCount(); i++ )
3305 outlineGlyph.TriangulatedPolygon( i );
3316 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3320 for(
unsigned int i = 0; i < outlineGlyph.TriangulatedPolyCount(); i++ )
3323 outlineGlyph.TriangulatedPolygon( i );
3340 for(
size_t i = 0; i < aGlyphs.size(); i++ )
3341 DrawGlyph( *aGlyphs[i], i, aGlyphs.size() );
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
void SetOpenGLInfo(const char *aVendor, const char *aRenderer, const char *aVersion)
A setter for OpenGL info when it's initialized.
void SetOpenGLBackendInfo(wxString aBackend)
A setter for OpenGL backend info after the canvas is created.
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
Bezier curves to polygon converter.
void GetPoly(std::vector< VECTOR2I > &aOutput, int aMaxError=10)
Convert a Bezier curve to a polygon.
This class handle bitmap images in KiCad.
const wxImage * GetOriginalImageData() const
VECTOR2I GetSizePixels() const
EDA_ANGLE Rotation() const
static const WX_CURSOR_TYPE GetCursor(KICURSOR aCursorType, bool aHiDPI=false)
Get a cursor bundle (wx 3.3+) or appropriate cursor (older versions)
void UnlockCtx(wxGLContext *aContext)
Allow other canvases to bind an OpenGL context.
void DestroyCtx(wxGLContext *aContext)
Destroy a managed OpenGL context.
void LockCtx(wxGLContext *aContext, wxGLCanvas *aCanvas)
Set a context as current and prevents other canvases from switching it.
wxGLContext * CreateCtx(wxGLCanvas *aCanvas, const wxGLContext *aOther=nullptr)
Create a managed OpenGL context.
static int SetSwapInterval(wxGLCanvas *aCanvas, int aVal)
Attempt to set the OpenGL swap interval.
static wxString DetectGLBackend(wxGLCanvas *aCanvas)
HIDPI_GL_CANVAS(const KIGFX::VC_SETTINGS &aSettings, wxWindow *aParent, const wxGLAttributes &aGLAttribs, wxWindowID aId=wxID_ANY, const wxPoint &aPos=wxDefaultPosition, const wxSize &aSize=wxDefaultSize, long aStyle=0, const wxString &aName=wxGLCanvasName, const wxPalette &aPalette=wxNullPalette)
virtual wxSize GetNativePixelSize() const
double GetScaleFactor() const
Get the current scale factor.
virtual bool IsStroke() const
virtual bool IsOutline() const
A color representation with 4 components: red, green, blue, alpha.
static const COLOR4D BLACK
bool IsTextMirrored() const
void SetGridColor(const COLOR4D &aGridColor)
Set the grid color.
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
bool IsCursorEnabled() const
Return information about cursor visibility.
friend class GAL_CONTEXT_LOCKER
MATRIX3x3D m_worldScreenMatrix
World transformation.
VECTOR2D GetVisibleGridSize() const
Return the visible grid size in x and y directions.
double m_layerDepth
The actual layer depth.
MATRIX3x3D m_screenWorldMatrix
Screen transformation.
friend class GAL_SCOPED_ATTRS
bool m_axesEnabled
Should the axes be drawn.
float m_gridLineWidth
Line width of the grid.
VECTOR2I m_screenSize
Screen size in screen (wx logical) coordinates.
GR_TEXT_H_ALIGN_T GetHorizontalJustify() const
void normalize(T &a, T &b)
Ensure that the first element is smaller than the second.
VECTOR2D m_depthRange
Range of the depth.
virtual void SetFillColor(const COLOR4D &aColor)
Set the fill color.
virtual bool SetNativeCursorStyle(KICURSOR aCursor, bool aHiDPI)
Set the cursor in the native panel.
GRID_STYLE m_gridStyle
Grid display style.
COLOR4D m_axesColor
Color of the axes.
const MATRIX3x3D & GetScreenWorldMatrix() const
Get the screen <-> world transformation matrix.
float m_lineWidth
The line width.
void computeWorldScale()
Compute the scaling factor for the world->screen matrix.
virtual void SetLineWidth(float aLineWidth)
Set the line width.
VECTOR2D m_gridSize
The grid size.
COLOR4D getCursorColor() const
Get the actual cursor color to draw.
COLOR4D m_fillColor
The fill color.
double m_worldUnitLength
The unit length of the world coordinates [inch].
virtual bool updatedGalDisplayOptions(const GAL_DISPLAY_OPTIONS &aOptions)
Handle updating display options.
void SetAxesColor(const COLOR4D &aAxesColor)
Set the axes color.
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
VECTOR2D m_cursorPosition
Current cursor position (world coordinates)
const VECTOR2I & GetGlyphSize() const
int m_gridTick
Every tick line gets the double width.
double m_worldScale
The scale factor world->screen.
VECTOR2D m_gridOrigin
The grid origin.
virtual void SetMinLineWidth(float aLineWidth)
Set the minimum line width in pixels.
KICURSOR m_currentNativeCursor
Current cursor.
bool m_globalFlipY
Flag for Y axis flipping.
float GetMinLineWidth() const
Get the minimum line width in pixels.
bool m_isFillEnabled
Is filling of graphic objects enabled ?
virtual void ComputeWorldScreenMatrix()
Compute the world <-> screen transformation matrix.
COLOR4D m_gridColor
Color of the grid.
COLOR4D m_strokeColor
The color of the outlines.
bool m_isStrokeEnabled
Are the outlines stroked ?
GAL_DISPLAY_OPTIONS & m_options
bool m_gridVisibility
Should the grid be shown.
virtual void BitmapText(const wxString &aText, const VECTOR2I &aPosition, const EDA_ANGLE &aAngle)
Draw a text using a bitmap font.
float GetLineWidth() const
Get the line width.
bool m_globalFlipX
Flag for X axis flipping.
GR_TEXT_V_ALIGN_T GetVerticalJustify() const
KIGFX::CROSS_HAIR_MODE m_crossHairMode
Crosshair drawing mode.
VECTOR2D m_lookAtPoint
Point to be looked at in world space.
GAL(GAL_DISPLAY_OPTIONS &aOptions)
GLuint cacheBitmap(const BITMAP_BASE *aBitmap)
const size_t m_cacheMaxElements
GLuint RequestBitmap(const BITMAP_BASE *aBitmap)
std::list< GLuint > m_freedTextureIds
const size_t m_cacheMaxSize
std::map< const KIID, CACHED_BITMAP > m_bitmaps
std::list< KIID > m_cacheLru
static const unsigned int DIRECT_RENDERING
OpenGL implementation of the Graphics Abstraction Layer.
void Transform(const MATRIX3x3D &aTransformation) override
Transform the context.
void drawPolygon(GLdouble *aPoints, int aPointCount)
Draw a filled polygon.
void ChangeGroupDepth(int aGroupNumber, int aDepth) override
Change the depth (Z-axis position) of the group.
void skipMouseEvent(wxMouseEvent &aEvent)
Skip the mouse event to the parent.
void drawSegment(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, double aWidth, bool aReserve=true)
Internal method for segment drawing.
unsigned int m_groupCounter
Counter used for generating keys for groups.
void EndDiffLayer() override
Ends rendering of a differential layer.
VERTEX_MANAGER * m_overlayManager
Container for storing overlaid VERTEX_ITEMs.
void Scale(const VECTOR2D &aScale) override
Scale the context.
bool m_isInitialized
Basic initialization flag, has to be done when the window is visible.
VERTEX_MANAGER * m_currentManager
Currently used VERTEX_MANAGER (for storing VERTEX_ITEMs).
void drawCircle(const VECTOR2D &aCenterPoint, double aRadius, bool aReserve=true)
Internal method for circle drawing.
std::deque< std::shared_ptr< GLdouble > > m_tessIntersects
void DrawEllipseArc(const VECTOR2D &aCenterPoint, double aMajorRadius, double aMinorRadius, const EDA_ANGLE &aRotation, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aEndAngle) override
Draw an elliptical arc in world coordinates.
void DrawCircle(const VECTOR2D &aCenterPoint, double aRadius) override
Draw a circle using world coordinates.
void LockContext(int aClientCookie) override
Use GAL_CONTEXT_LOCKER RAII object unless you know what you're doing.
WX_CURSOR_TYPE m_currentwxCursor
wx cursor showing the current native cursor.
unsigned int m_mainBuffer
Main rendering target.
std::unique_ptr< GL_BITMAP_CACHE > m_bitmapCache
std::pair< VECTOR2D, float > computeBitmapTextSize(const UTF8 &aText) const
Compute a size of text drawn using bitmap font with current text setting applied.
void SetTarget(RENDER_TARGET aTarget) override
Set the target for rendering.
void blitCursor()
Blit cursor into the current screen.
static wxString CheckFeatures(GAL_DISPLAY_OPTIONS &aOptions)
Checks OpenGL features.
void ClearTarget(RENDER_TARGET aTarget) override
Clear the target for rendering.
void drawBitmapOverbar(double aLength, double aHeight, bool aReserve=true)
Draw an overbar over the currently drawn text.
void EndGroup() override
End the group.
bool m_isBitmapFontInitialized
Is the shader set to use bitmap fonts?
void drawSegmentChain(const std::function< VECTOR2D(int)> &aPointGetter, int aPointCount, double aWidth, bool aReserve=true)
Generic way of drawing a chain of segments stored in different containers.
void DrawArcSegment(const VECTOR2D &aCenterPoint, double aRadius, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aAngle, double aWidth, double aMaxError) override
Draw an arc segment.
void BitmapText(const wxString &aText, const VECTOR2I &aPosition, const EDA_ANGLE &aAngle) override
Draw a text using a bitmap font.
bool updatedGalDisplayOptions(const GAL_DISPLAY_OPTIONS &aOptions) override
Handle updating display options.
unsigned int m_overlayBuffer
Auxiliary rendering target (for menus etc.)
void PostPaint(wxPaintEvent &aEvent)
Post an event to #m_paint_listener.
OPENGL_COMPOSITOR * m_compositor
Handles multiple rendering targets.
VERTEX_MANAGER * m_cachedManager
Container for storing cached VERTEX_ITEMs.
void Translate(const VECTOR2D &aTranslation) override
Translate the context.
void DrawPolyline(const std::deque< VECTOR2D > &aPointList) override
Draw a polyline.
bool SetNativeCursorStyle(KICURSOR aCursor, bool aHiDPI) override
Set the cursor in the native panel.
void DrawCurve(const VECTOR2D &startPoint, const VECTOR2D &controlPointA, const VECTOR2D &controlPointB, const VECTOR2D &endPoint, double aFilterValue=0.0) override
Draw a cubic bezier spline.
void drawFilledSemiCircle(const VECTOR2D &aCenterPoint, double aRadius, double aAngle)
Draw a filled semicircle.
void onPaint(wxPaintEvent &aEvent)
This is the OnPaint event handler.
void DrawGroup(int aGroupNumber) override
Draw the stored group.
GLint ufm_minLinePixelWidth
void Restore() override
Restore the context.
void DrawSegmentChain(const std::vector< VECTOR2D > &aPointList, double aWidth) override
Draw a chain of rounded segments.
void drawStrokedSemiCircle(const VECTOR2D &aCenterPoint, double aRadius, double aAngle, bool aReserve=true)
Draw a stroked semicircle.
unsigned int getNewGroupNumber()
Return a valid key that can be used as a new group number.
void Flush() override
Force all remaining objects to be drawn.
GLint ufm_antialiasingOffset
void DeleteGroup(int aGroupNumber) override
Delete the group from the memory.
bool IsVisible() const override
Return true if the GAL canvas is visible on the screen.
wxEvtHandler * m_mouseListener
int m_swapInterval
Used to store swap interval information.
void ClearCache() override
Delete all data created during caching of graphic items.
double getWorldPixelSize() const
void DrawSegment(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, double aWidth) override
Draw a rounded segment.
GROUPS_MAP m_groups
Stores information about VBO objects (groups)
void endUpdate() override
void ClearScreen() override
Clear the screen.
void ResizeScreen(int aWidth, int aHeight) override
Resizes the canvas.
GLint ufm_fontTextureWidth
void DrawPolygon(const std::deque< VECTOR2D > &aPointList) override
Draw a polygon.
void drawTriangulatedPolyset(const SHAPE_POLY_SET &aPoly, bool aStrokeTriangulation)
Draw a set of polygons with a cached triangulation.
void DrawCursor(const VECTOR2D &aCursorPosition) override
Draw the cursor.
void DrawRectangle(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint) override
Draw a rectangle.
VERTEX_MANAGER * m_nonCachedManager
Container for storing non-cached VERTEX_ITEMs.
int drawBitmapChar(unsigned long aChar, bool aReserve=true)
Draw a single character using bitmap font.
GLUtesselator * m_tesselator
wxEvtHandler * m_paintListener
void StartDiffLayer() override
Begins rendering of a differential layer.
bool m_isContextLocked
Used for assertion checking.
void Save() override
Save the context.
void DrawHoleWall(const VECTOR2D &aCenterPoint, double aHoleRadius, double aWallWidth) override
Draw a hole wall ring.
bool m_isFramebufferInitialized
Are the framebuffers initialized?
void ComputeWorldScreenMatrix() override
Compute the world <-> screen transformation matrix.
bool Show(bool aShow) override
Shows/hides the GAL canvas.
void SetMinLineWidth(float aLineWidth) override
Set the minimum line width in pixels.
static GLuint g_fontTexture
Bitmap font texture handle (shared)
virtual bool HasTarget(RENDER_TARGET aTarget) override
Return true if the target exists.
void reserveLineQuads(const int aLineCount)
Reserve specified number of line quads.
void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint) override
Draw a line.
OPENGL_GAL(const KIGFX::VC_SETTINGS &aVcSettings, GAL_DISPLAY_OPTIONS &aDisplayOptions, wxWindow *aParent, wxEvtHandler *aMouseListener=nullptr, wxEvtHandler *aPaintListener=nullptr, const wxString &aName=wxT("GLCanvas"))
void beginUpdate() override
void DrawEllipse(const VECTOR2D &aCenterPoint, double aMajorRadius, double aMinorRadius, const EDA_ANGLE &aRotation) override
Draw a closed ellipse.
double calcAngleStep(double aRadius) const
Compute the angle step when drawing arcs/circles approximated with lines.
virtual void DrawGlyph(const KIFONT::GLYPH &aGlyph, int aNth, int aTotal) override
Draw a polygon representing a font glyph.
bool m_isGrouping
Was a group started?
void BeginDrawing() override
Start/end drawing functions, draw calls can be only made in between the calls to BeginDrawing()/EndDr...
GLint ufm_screenPixelSize
void Rotate(double aAngle) override
Rotate the context.
int BeginGroup() override
Begin a group.
GLint ufm_pixelSizeMultiplier
VECTOR2D getScreenPixelSize() const
void DrawBitmap(const BITMAP_BASE &aBitmap, double alphaBlend=1.0) override
Draw a bitmap image.
void drawPolyline(const std::function< VECTOR2D(int)> &aPointGetter, int aPointCount, bool aReserve=true)
Generic way of drawing a polyline stored in different containers.
RENDER_TARGET GetTarget() const override
Get the currently used target for rendering.
void skipGestureEvent(wxGestureEvent &aEvent)
Skip the gesture event to the parent.
void UnlockContext(int aClientCookie) override
void drawSemiCircle(const VECTOR2D &aCenterPoint, double aRadius, double aAngle)
Draw a semicircle.
void drawLineQuad(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, bool aReserve=true)
Draw a quad for the line.
VERTEX_MANAGER * m_tempManager
Container for storing temp (diff mode) VERTEX_ITEMs.
virtual void DrawGlyphs(const std::vector< std::unique_ptr< KIFONT::GLYPH > > &aGlyphs) override
Draw polygons representing font glyphs.
void onSetNativeCursor(wxSetCursorEvent &aEvent)
Give the correct cursor image when the native widget asks for it.
void EnableDepthTest(bool aEnabled=false) override
void EndDrawing() override
End the drawing, needs to be called for every new frame.
SHADER * m_shader
There is only one shader used for different objects.
void DrawArc(const VECTOR2D &aCenterPoint, double aRadius, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aAngle) override
Draw an arc.
void DrawPolylines(const std::vector< std::vector< VECTOR2D > > &aPointLists) override
Draw multiple polylines.
RENDER_TARGET m_currentTarget
Current rendering target.
wxGLContext * m_glPrivContext
Canvas-specific OpenGL context.
void ChangeGroupColor(int aGroupNumber, const COLOR4D &aNewColor) override
Change the color used to draw the group.
static bool m_isBitmapFontLoaded
Is the bitmap font texture loaded?
static wxGLContext * m_glMainContext
Parent OpenGL context.
void setupShaderParameters()
Set up the shader parameters for OpenGL rendering.
unsigned int m_tempBuffer
Temporary rendering target (for diffing etc.)
void init()
Basic OpenGL initialization and feature checks.
static int m_instanceCounter
GL GAL instance counter.
Provide the access to the OpenGL shaders.
Class to control vertex container and GPU with possibility of emulating old-style OpenGL 1....
bool Vertex(const VERTEX &aVertex)
Add a vertex with the given coordinates to the currently set item.
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
GL_CONTEXT_MANAGER * GetGLContextManager()
A small class to help profiling.
void Stop()
Save the time when this function was called, and set the counter stane to stop.
void Start()
Start or restart the counter.
double msecs(bool aSinceLast=false)
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
bool IsClosed() const override
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.
int SegmentCount() const
Return the number of segments in this line chain.
size_t GetTriangleCount() const
void GetTriangle(int index, VECTOR2I &a, VECTOR2I &b, VECTOR2I &c) const
Represent a set of closed polygons.
bool IsTriangulationUpToDate() const
POLYGON & Polygon(int aIndex)
Return the aIndex-th subpolygon in the set.
const TRIANGULATED_POLYGON * TriangulatedPolygon(int aIndex) const
unsigned int TriangulatedPolyCount() const
Return the number of triangulated polygons.
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
uni_iter is a non-mutating iterator that walks through unicode code points in the UTF8 encoded string...
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
uni_iter uend() const
Return a uni_iter initialized to the end of "this" UTF8 byte sequence.
uni_iter ubegin() const
Returns a uni_iter initialized to the start of "this" UTF8 byte sequence.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
static constexpr EDA_ANGLE FULL_CIRCLE
a few functions useful in geometry calculations.
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
const wxChar *const traceGalProfile
Flag to enable debug output of GAL performance profiling.
This file contains miscellaneous commonly used macros and functions.
MATRIX3x3< double > MATRIX3x3D
FONT_IMAGE_TYPE font_image
const FONT_GLYPH_TYPE * LookupGlyph(unsigned int aCodepoint)
FONT_INFO_TYPE font_information
The Cairo implementation of the graphics abstraction layer.
@ SMALL_CROSS
Use small cross instead of dots for the grid.
@ DOTS
Use dots for the grid.
@ SHADER_TYPE_VERTEX
Vertex shader.
@ SHADER_TYPE_FRAGMENT
Fragment shader.
RENDER_TARGET
RENDER_TARGET: Possible rendering targets.
@ TARGET_NONCACHED
Auxiliary rendering target (noncached)
@ TARGET_TEMP
Temporary target for drawing in separate layer.
@ TARGET_CACHED
Main rendering target (cached)
@ TARGET_OVERLAY
Items that may change while the view stays the same (noncached)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
static const wxChar *const traceGalXorMode
static void InitTesselatorCallbacks(GLUtesselator *aTesselator)
void CALLBACK CombineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut, void *aData)
void CALLBACK VertexCallback(GLvoid *aVertexPtr, void *aData)
void CALLBACK EdgeCallback(GLboolean aEdgeFlag)
static wxGLAttributes getGLAttribs()
void CALLBACK ErrorCallback(GLenum aErrorCode)
double round_to_half_pixel(double f, double r)
#define SEG_PER_CIRCLE_COUNT
#define CALLBACK
The default number of points for circle approximation.
PGM_BASE & Pgm()
The global program "get" accessor.
std::vector< FAB_LAYER_COLOR > dummy
VERTEX_MANAGER * vboManager
Manager used for storing new vertices.
std::deque< std::shared_ptr< GLdouble > > & intersectPoints
Intersect points, that have to be freed after tessellation.
Structure to keep VIEW_CONTROLS settings for easy store/restore operations.
@ GR_TEXT_H_ALIGN_INDETERMINATE
@ GR_TEXT_V_ALIGN_INDETERMINATE
wxLogTrace helper definitions.
void enableGlDebug(bool aEnable)
Enable or disable OpenGL driver messages output.
int checkGlError(const std::string &aInfo, const char *aFile, int aLine, bool aThrow)
Check if a recent OpenGL operation has failed.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D
VECTOR2I ToVECTOR2I(const wxSize &aSize)