59using namespace std::placeholders;
67#include <glsl_kicad_frag.h>
68#include <glsl_kicad_vert.h>
78 wxGLAttributes attribs;
79 attribs.RGBA().DoubleBuffer().Depth( 8 ).EndList();
128 glDeleteTextures( 1, &bitmap.second.id );
134#ifndef DISABLE_BITMAP_CACHE
140 if( glIsTexture( it->second.id ) )
142 it->second.accessTime = wxGetUTCTimeMillis().GetValue();
143 return it->second.id;
148 glDeleteTextures( 1, &it->second.id );
176 return std::numeric_limits< GLuint >::max();
178 const wxImage& imgData = *imgPtr;
180 bmp.
w = imgData.GetSize().x;
181 bmp.
h = imgData.GetSize().y;
187 glGenTextures( 1, &textureID );
195 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
197 if( imgData.HasAlpha() || imgData.HasMask() )
199 bmp.
size = bmp.
w * bmp.
h * 4;
200 auto buf = std::make_unique<uint8_t[]>( bmp.
size );
202 uint8_t* dstP = buf.get();
203 uint8_t* srcP = imgData.GetData();
205 long long pxCount =
static_cast<long long>( bmp.
w ) * bmp.
h;
207 if( imgData.HasAlpha() )
209 uint8_t* srcAlpha = imgData.GetAlpha();
211 for(
long long px = 0; px < pxCount; px++ )
213 memcpy( dstP, srcP, 3 );
221 else if( imgData.HasMask() )
223 uint8_t maskRed = imgData.GetMaskRed();
224 uint8_t maskGreen = imgData.GetMaskGreen();
225 uint8_t maskBlue = imgData.GetMaskBlue();
227 for(
long long px = 0; px < pxCount; px++ )
229 memcpy( dstP, srcP, 3 );
231 if( srcP[0] == maskRed && srcP[1] == maskGreen && srcP[2] == maskBlue )
232 dstP[3] = wxALPHA_TRANSPARENT;
234 dstP[3] = wxALPHA_OPAQUE;
241 glBindTexture( GL_TEXTURE_2D, textureID );
242 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.
w, bmp.
h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
247 bmp.
size = bmp.
w * bmp.
h * 3;
249 uint8_t* srcP = imgData.GetData();
251 glBindTexture( GL_TEXTURE_2D, textureID );
252 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, bmp.
w, bmp.
h, 0, GL_RGB, GL_UNSIGNED_BYTE, srcP );
255 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
256 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
258 long long currentTime = wxGetUTCTimeMillis().GetValue();
263#ifndef DISABLE_BITMAP_CACHE
271 for(
const auto& [kiid, cachedBmp] :
m_bitmaps )
273 const int cacheTimeoutMillis = 1000L;
275 if( currentTime - cachedBmp.accessTime > cacheTimeoutMillis )
289 toRemove = *toRemoveLru;
295 glDeleteTextures( 1, &cachedBitmap.
id );
313 wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener,
314 const wxString& aName ) :
315 GAL( aDisplayOptions ),
337 throw std::runtime_error(
"Could not create the main OpenGL context" );
346 throw std::runtime_error(
"Could not create a private OpenGL context" );
391#if defined _WIN32 || defined _WIN64
398 SetSize( aParent->GetClientSize() );
409 gluTessProperty(
m_tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
480 static std::optional<wxString> cached;
482 if( cached.has_value() )
485 wxString retVal = wxEmptyString;
487 wxFrame* testFrame =
new wxFrame(
nullptr, wxID_ANY, wxT(
"" ), wxDefaultPosition,
488 wxSize( 1, 1 ), wxFRAME_TOOL_WINDOW | wxNO_BORDER );
510 catch( std::runtime_error& err )
513 retVal = wxString( err.what() );
572#ifdef KICAD_GAL_PROFILE
573 PROF_TIMER totalRealTime(
"OPENGL_GAL::beginDrawing()",
true );
576 wxASSERT_MSG(
m_isContextLocked,
"GAL_DRAWING_CONTEXT RAII object should have locked context. "
577 "Calling GAL::beginDrawing() directly is not allowed." );
579 wxASSERT_MSG(
IsVisible(),
"GAL::beginDrawing() must not be entered when GAL is not visible. "
580 "Other drawing routines will expect everything to be initialized "
581 "which will not be the case." );
587 glMatrixMode( GL_PROJECTION );
603 catch(
const std::runtime_error& )
605 wxLogVerbose(
"Could not create a framebuffer for diff mode blending.\n" );
612 catch(
const std::runtime_error& )
614 wxLogVerbose(
"Could not create a framebuffer for overlays.\n" );
624 glDisable( GL_TEXTURE_2D );
626 glShadeModel( GL_FLAT );
629 glEnable( GL_DEPTH_TEST );
630 glDepthFunc( GL_LESS );
633 glEnable( GL_BLEND );
634 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
636 glMatrixMode( GL_MODELVIEW );
640 GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
650 glLoadMatrixd( matrixData );
669 const GLint FONT_TEXTURE_UNIT = 2;
674 glActiveTexture( GL_TEXTURE0 + FONT_TEXTURE_UNIT );
679 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
680 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
681 checkGlError(
"loading bitmap font", __FILE__, __LINE__ );
683 glActiveTexture( GL_TEXTURE0 );
689 glActiveTexture( GL_TEXTURE0 + FONT_TEXTURE_UNIT );
691 glActiveTexture( GL_TEXTURE0 );
698 checkGlError(
"setting bitmap font sampler as shader parameter", __FILE__, __LINE__ );
708 double pixelSizeMultiplier =
m_compositor->GetAntialiasSupersamplingFactor();
711 renderingOffset.
x *= screenPixelSize.
x;
712 renderingOffset.
y *= screenPixelSize.
y;
719 glActiveTexture( GL_TEXTURE0 );
724#ifdef KICAD_GAL_PROFILE
725 totalRealTime.
Stop();
726 wxLogTrace(
traceGalProfile, wxT(
"OPENGL_GAL::beginDrawing(): %.1f ms" ),
727 totalRealTime.
msecs() );
750 PROF_TIMER cntEndNoncached(
"gl-end-noncached" );
760 cntEndNoncached.
Start();
762 cntEndNoncached.
Stop();
764 cntEndCached.
Start();
768 cntEndOverlay.
Start();
774 cntEndOverlay.
Stop();
776 cntComposite.
Start();
779 glColor4d( 1.0, 1.0, 1.0, 1.0 );
798#ifdef KICAD_GAL_PROFILE
816 glGetIntegerv( GL_VIEWPORT, viewport );
818 const int w = viewport[2];
819 const int h = viewport[3];
821 GLint readBuffer = GL_COLOR_ATTACHMENT0;
822 glGetIntegerv( GL_DRAW_BUFFER, &readBuffer );
828 std::vector<unsigned char> rgba( (
size_t) w * h * 4 );
831 glPixelStorei( GL_PACK_ALIGNMENT, 1 );
832 glReadBuffer( (GLenum) readBuffer );
833 glReadPixels( 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgba.data() );
836 unsigned char* rgb = (
unsigned char*) malloc( (
size_t) w * h * 3 );
837 unsigned char* alpha = (
unsigned char*) malloc( (
size_t) w * h );
839 for(
int i = 0; i < w * h; ++i )
841 rgb[i * 3 + 0] = rgba[i * 4 + 0];
842 rgb[i * 3 + 1] = rgba[i * 4 + 1];
843 rgb[i * 3 + 2] = rgba[i * 4 + 2];
844 alpha[i] = rgba[i * 4 + 3];
847 aDstImage.SetData( rgb, w, h,
false );
848 aDstImage.SetAlpha( alpha,
false );
850 aDstImage = aDstImage.Mirror(
false );
877 wxASSERT_MSG(
m_isContextLocked,
"Context not locked. A GAL_CONTEXT_LOCKER RAII object must "
878 "be stacked rather than making separate lock/unlock calls." );
881 "Context was locked by a different client. "
882 "Should not be possible with RAII objects." );
897 wxASSERT_MSG(
m_isContextLocked,
"GAL_UPDATE_CONTEXT RAII object should have locked context. "
898 "Calling this from anywhere else is not allowed." );
900 wxASSERT_MSG(
IsVisible(),
"GAL::beginUpdate() must not be entered when GAL is not visible. "
901 "Other update routines will expect everything to be initialized "
902 "which will not be the case." );
938 VECTOR2D startEndVector = aEndPoint - aStartPoint;
945 float startX =
static_cast<float>( aStartPoint.
x );
946 float startY =
static_cast<float>( aStartPoint.
y );
947 float endX =
static_cast<float>( aEndPoint.
x );
948 float endY =
static_cast<float>( aEndPoint.
y );
950 if( startX == endX && startY == endY )
952 drawCircle( aStartPoint, aWidth / 2, aReserve );
1087 double startAngle = aStartAngle.
AsRadians();
1088 double endAngle = startAngle + aAngle.
AsRadians();
1105 for( alpha = startAngle; ( alpha + alphaIncrement ) < endAngle; )
1111 alpha += alphaIncrement;
1117 const VECTOR2D endPoint( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1130 VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1132 unsigned int lineCount = 0;
1134 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1137 if( alpha != endAngle )
1142 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1144 VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
1151 if( alpha != endAngle )
1153 VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1164 double aWidth,
double aMaxError )
1175 double startAngle = aStartAngle.
AsRadians();
1176 double endAngle = startAngle + aAngle.
AsRadians();
1184 double alphaIncrement = 2.0 *
M_PI / segCount360;
1189 int seg_count =
KiROUND( ( endAngle - startAngle ) / alphaIncrement );
1191 if( seg_count % 2 != 0 )
1195 if( seg_count == 0 )
1197 VECTOR2D p_start( aCenterPoint.
x + cos( startAngle ) * aRadius,
1198 aCenterPoint.
y + sin( startAngle ) * aRadius );
1200 VECTOR2D p_end( aCenterPoint.
x + cos( endAngle ) * aRadius,
1201 aCenterPoint.
y + sin( endAngle ) * aRadius );
1208 alphaIncrement = ( endAngle - startAngle ) / seg_count;
1218 double width = aWidth / 2.0;
1219 VECTOR2D startPoint( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1220 VECTOR2D endPoint( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1225 VECTOR2D pOuter( cos( startAngle ) * ( aRadius + width ),
1226 sin( startAngle ) * ( aRadius + width ) );
1228 VECTOR2D pInner( cos( startAngle ) * ( aRadius - width ),
1229 sin( startAngle ) * ( aRadius - width ) );
1233 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1235 VECTOR2D pNextOuter( cos( alpha ) * ( aRadius + width ),
1236 sin( alpha ) * ( aRadius + width ) );
1237 VECTOR2D pNextInner( cos( alpha ) * ( aRadius - width ),
1238 sin( alpha ) * ( aRadius - width ) );
1243 pOuter = pNextOuter;
1244 pInner = pNextInner;
1248 if( alpha != endAngle )
1250 VECTOR2D pLastOuter( cos( endAngle ) * ( aRadius + width ),
1251 sin( endAngle ) * ( aRadius + width ) );
1252 VECTOR2D pLastInner( cos( endAngle ) * ( aRadius - width ),
1253 sin( endAngle ) * ( aRadius - width ) );
1265 VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1270 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1276 if( alpha != endAngle )
1283 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1285 VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
1292 if( alpha != endAngle )
1294 VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1306 if( aMajorRadius <= 0 || aMinorRadius <= 0 )
1309 const double alphaIncrement =
calcAngleStep( aMajorRadius );
1310 const double cosPhi = std::cos( aRotation.
AsRadians() );
1311 const double sinPhi = std::sin( aRotation.
AsRadians() );
1313 auto eval = [&](
double theta ) ->
VECTOR2D
1315 const double lx = aMajorRadius * std::cos( theta );
1316 const double ly = aMinorRadius * std::sin( theta );
1317 return VECTOR2D( lx * cosPhi - ly * sinPhi, lx * sinPhi + ly * cosPhi );
1330 for( alpha = 0.0; ( alpha + alphaIncrement ) < 2.0 *
M_PI; )
1333 alpha += alphaIncrement;
1357 unsigned int lineCount = 0;
1360 for( countAlpha = alphaIncrement; countAlpha < 2.0 *
M_PI; countAlpha += alphaIncrement )
1370 for( alpha = alphaIncrement; alpha < 2.0 *
M_PI; alpha += alphaIncrement )
1372 const VECTOR2D p_next = eval( alpha );
1388 if( aMajorRadius <= 0 || aMinorRadius <= 0 )
1391 double startAngle = aStartAngle.
AsRadians();
1392 double endAngle = aEndAngle.
AsRadians();
1395 const double alphaIncrement =
calcAngleStep( aMajorRadius );
1396 const double cosPhi = std::cos( aRotation.
AsRadians() );
1397 const double sinPhi = std::sin( aRotation.
AsRadians() );
1399 auto eval = [&](
double theta ) ->
VECTOR2D
1401 const double lx = aMajorRadius * std::cos( theta );
1402 const double ly = aMinorRadius * std::sin( theta );
1403 return VECTOR2D( lx * cosPhi - ly * sinPhi, lx * sinPhi + ly * cosPhi );
1417 for( alpha = startAngle; ( alpha + alphaIncrement ) < endAngle; )
1420 alpha += alphaIncrement;
1431 const VECTOR2D p2 = eval( endAngle );
1443 unsigned int lineCount = 0;
1446 for( countAlpha = startAngle + alphaIncrement; countAlpha <= endAngle; countAlpha += alphaIncrement )
1449 if( countAlpha != endAngle )
1457 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1459 const VECTOR2D p_next = eval( alpha );
1465 if( alpha != endAngle )
1467 const VECTOR2D p_last = eval( endAngle );
1479 VECTOR2D diagonalPointA( aEndPoint.
x, aStartPoint.
y );
1480 VECTOR2D diagonalPointB( aStartPoint.
x, aEndPoint.
y );
1506 if( aStartPoint == aEndPoint )
1512 std::deque<VECTOR2D> pointList;
1514 pointList.push_back( aStartPoint );
1515 pointList.push_back( diagonalPointA );
1516 pointList.push_back( aEndPoint );
1517 pointList.push_back( diagonalPointB );
1518 pointList.push_back( aStartPoint );
1530 return aPointList[idx];
1532 aPointList.size(), aWidth );
1546 return aLineChain.
CPoint( idx );
1548 numPoints, aWidth );
1557 return aPointList[idx];
1559 aPointList.size() );
1568 return aPointList[idx];
1570 aPointList.size() );
1579 return aPointList[idx];
1595 return aLineChain.
CPoint( idx );
1603 int lineQuadCount = 0;
1605 for(
const std::vector<VECTOR2D>& points : aPointList )
1606 lineQuadCount += points.size() - 1;
1610 for(
const std::vector<VECTOR2D>& points : aPointList )
1617 points.size(),
false );
1624 wxCHECK( aPointList.size() >= 2, );
1625 auto points = std::unique_ptr<GLdouble[]>(
new GLdouble[3 * aPointList.size()] );
1626 GLdouble* ptr = points.get();
1628 for(
const VECTOR2D& p : aPointList )
1641 wxCHECK( aListSize >= 2, );
1642 auto points = std::unique_ptr<GLdouble[]>(
new GLdouble[3 * aListSize] );
1643 GLdouble* target = points.get();
1646 for(
int i = 0; i < aListSize; ++i )
1659 bool aStrokeTriangulation )
1666 int totalTriangleCount = 0;
1681 for(
size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
1684 triPoly->GetTriangle( i, a, b, c );
1696 const auto& poly = aPolySet.
Polygon( j );
1698 for(
const auto& lc : poly )
1707 aStrokeTriangulation =
true;
1711 if( aStrokeTriangulation )
1720 for(
size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
1723 triPoly->GetTriangle( i, a, b, c );
1755 std::unique_ptr<GLdouble[]> points(
new GLdouble[3 * pointCount] );
1756 GLdouble* ptr = points.get();
1758 for(
int i = 0; i < pointCount; ++i )
1772 double aFilterValue )
1774 std::vector<VECTOR2D>
output;
1775 std::vector<VECTOR2D> pointCtrl;
1777 pointCtrl.push_back( aStartPoint );
1778 pointCtrl.push_back( aControlPointA );
1779 pointCtrl.push_back( aControlPointB );
1780 pointCtrl.push_back( aEndPoint );
1794 GLfloat alpha = std::clamp( alphaBlend, 0.0, 1.0 );
1804 glm::vec4 v0 = xform * glm::vec4( -w / 2, -h / 2, 0.0, 0.0 );
1805 glm::vec4
v1 = xform * glm::vec4( w / 2, h / 2, 0.0, 0.0 );
1806 glm::vec4 trans = xform[3];
1810 if( !glIsTexture( texture_id ) )
1813 GLboolean depthMask = GL_TRUE;
1814 glGetBooleanv( GL_DEPTH_WRITEMASK, &depthMask );
1817 glDepthMask( GL_FALSE );
1819 glDepthFunc( GL_ALWAYS );
1821 glAlphaFunc( GL_GREATER, 0.01f );
1822 glEnable( GL_ALPHA_TEST );
1824 glMatrixMode( GL_TEXTURE );
1826 glTranslated( 0.5, 0.5, 0.5 );
1828 glTranslated( -0.5, -0.5, -0.5 );
1830 glMatrixMode( GL_MODELVIEW );
1832 glTranslated( trans.x, trans.y, trans.z );
1834 glEnable( GL_TEXTURE_2D );
1835 glActiveTexture( GL_TEXTURE0 );
1836 glBindTexture( GL_TEXTURE_2D, texture_id );
1838 float texStartX = aBitmap.
IsMirroredX() ? 1.0 : 0.0;
1839 float texEndX = aBitmap.
IsMirroredX() ? 0.0 : 1.0;
1840 float texStartY = aBitmap.
IsMirroredY() ? 1.0 : 0.0;
1841 float texEndY = aBitmap.
IsMirroredY() ? 0.0 : 1.0;
1843 glBegin( GL_QUADS );
1844 glColor4f( 1.0, 1.0, 1.0, alpha );
1845 glTexCoord2f( texStartX, texStartY );
1847 glColor4f( 1.0, 1.0, 1.0, alpha );
1848 glTexCoord2f( texEndX, texStartY);
1850 glColor4f( 1.0, 1.0, 1.0, alpha );
1851 glTexCoord2f( texEndX, texEndY);
1853 glColor4f( 1.0, 1.0, 1.0, alpha );
1854 glTexCoord2f( texStartX, texEndY);
1858 glBindTexture( GL_TEXTURE_2D, 0 );
1860#ifdef DISABLE_BITMAP_CACHE
1861 glDeleteTextures( 1, &texture_id );
1866 glMatrixMode( GL_TEXTURE );
1868 glMatrixMode( GL_MODELVIEW );
1870 glDisable( GL_ALPHA_TEST );
1872 glDepthMask( depthMask );
1874 glDepthFunc( GL_LESS );
1883 || aText.Contains( wxT(
"^{" ) )
1884 || aText.Contains( wxT(
"_{" ) )
1885 || aText.Contains( wxT(
"\n" ) ) )
1896 double overbarHeight = textSize.
y;
1927 wxFAIL_MSG( wxT(
"Indeterminate state legal only in dialogs." ) );
1943 overbarHeight = -textSize.
y / 2.0;
1947 wxFAIL_MSG( wxT(
"Indeterminate state legal only in dialogs." ) );
1951 int overbarLength = 0;
1952 int overbarDepth = -1;
1953 int braceNesting = 0;
1955 auto iterateString =
1956 [&](
const std::function<void(
int aOverbarLength,
int aOverbarHeight )>& overbarFn,
1957 const std::function<int(
unsigned long aChar )>& bitmapCharFn )
1961 wxASSERT_MSG( *chIt !=
'\n' && *chIt !=
'\r',
1962 "No support for multiline bitmap text yet" );
1964 if( *chIt ==
'~' && overbarDepth == -1 )
1968 if( ++lookahead !=
end && *lookahead ==
'{' )
1971 overbarDepth = braceNesting;
1976 else if( *chIt ==
'{' )
1980 else if( *chIt ==
'}' )
1982 if( braceNesting > 0 )
1985 if( braceNesting == overbarDepth )
1987 overbarFn( overbarLength, overbarHeight );
1995 if( overbarDepth != -1 )
1996 overbarLength += bitmapCharFn( *chIt );
1998 bitmapCharFn( *chIt );
2005 int overbarsCount = 0;
2008 [&overbarsCount](
int aOverbarLength,
int aOverbarHeight )
2012 [&charsCount](
unsigned long aChar ) ->
int
2028 [&](
int aOverbarLength,
int aOverbarHeight )
2032 [&](
unsigned long aChar ) ->
int
2040 if( overbarDepth != -1 && overbarLength > 0 )
2055 float minorLineWidth = std::fmax( 1.0f,
2057 float majorLineWidth = minorLineWidth * 2.0f;
2101 glDisable( GL_DEPTH_TEST );
2102 glDisable( GL_TEXTURE_2D );
2106 glEnable( GL_STENCIL_TEST );
2107 glStencilFunc( GL_ALWAYS, 1, 1 );
2108 glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
2109 glColor4d( 0.0, 0.0, 0.0, 0.0 );
2121 for(
int j = gridStartY; j <= gridEndY; j++ )
2127 for(
int i = gridStartX; i <= gridEndX; i++ )
2130 SetLineWidth( ( ( tickX && tickY ) ? majorLineWidth : minorLineWidth ) );
2144 for(
int j = gridStartY; j <= gridEndY; j++ )
2163 glStencilFunc( GL_NOTEQUAL, 0, 1 );
2169 for(
int i = gridStartX; i <= gridEndX; i++ )
2186 glDisable( GL_STENCIL_TEST );
2190 glEnable( GL_DEPTH_TEST );
2191 glEnable( GL_TEXTURE_2D );
2201 m_compositor->Resize( aWidth * scaleFactor, aHeight * scaleFactor );
2204 wxGLCanvas::SetSize( aWidth, aHeight );
2210 bool s = wxGLCanvas::Show( aShow );
2213 wxGLCanvas::Raise();
2231 glClearColor( 0, 0, 0, 1 );
2232 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
2238 GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
2240 matrixData[0] = aTransformation.
m_data[0][0];
2241 matrixData[1] = aTransformation.
m_data[1][0];
2242 matrixData[2] = aTransformation.
m_data[2][0];
2243 matrixData[4] = aTransformation.
m_data[0][1];
2244 matrixData[5] = aTransformation.
m_data[1][1];
2245 matrixData[6] = aTransformation.
m_data[2][1];
2246 matrixData[12] = aTransformation.
m_data[0][2];
2247 matrixData[13] = aTransformation.
m_data[1][2];
2248 matrixData[14] = aTransformation.
m_data[2][2];
2250 glMultMatrixd( matrixData );
2288 std::shared_ptr<VERTEX_ITEM> newItem = std::make_shared<VERTEX_ITEM>( *
m_cachedManager );
2290 m_groups.insert( std::make_pair( groupNumber, newItem ) );
2419 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::StartDiffLayer() called" ) );
2426 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): setting target to TARGET_TEMP" ) );
2433 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): TARGET_TEMP set and cleared, compositor buffer=%u" ),
2438 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): WARNING - no temp buffer!" ) );
2445 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::EndDiffLayer() called" ) );
2446 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): m_tempBuffer=%u, m_mainBuffer=%u" ),
2451 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): using temp buffer path" ) );
2456 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): calling DrawBufferDifference" ) );
2464 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): DrawBufferDifference returned" ) );
2468 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): NO temp buffer, using fallback path" ) );
2471 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
2473 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
2476 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::EndDiffLayer() complete" ) );
2488#if wxCHECK_VERSION( 3, 3, 0 )
2500#if wxCHECK_VERSION( 3, 3, 0 )
2519 const bool aReserve )
2537 * glm::vec4( aStartPoint.
x, aStartPoint.
y, 0.0, 0.0 );
2539 * glm::vec4( aEndPoint.
x, aEndPoint.
y, 0.0, 0.0 );
2623 double outerRadius = aRadius + (
m_lineWidth / 2 );
2669 GLdouble* point = aPoints;
2671 for(
int i = 0; i < aPointCount; ++i )
2689 return VECTOR2D( aPoints[idx * 3], aPoints[idx * 3 + 1] );
2699 wxCHECK( aPointCount > 0, );
2703 if( aPointCount == 1 )
2705 drawLineQuad( aPointGetter( 0 ), aPointGetter( 0 ), aReserve );
2714 for(
int i = 1; i < aPointCount; ++i )
2716 auto start = aPointGetter( i - 1 );
2717 auto end = aPointGetter( i );
2725 int aPointCount,
double aWidth,
bool aReserve )
2727 wxCHECK( aPointCount >= 2, );
2733 for(
int i = 1; i < aPointCount; ++i )
2735 auto start = aPointGetter( i - 1 );
2736 auto end = aPointGetter( i );
2738 float startx = start.x;
2739 float starty = start.y;
2748 if( startx == endx && starty == endy )
2760 vertices += 6 + 6 + 3 + 3;
2766 for(
int i = 1; i < aPointCount; ++i )
2768 auto start = aPointGetter( i - 1 );
2769 auto end = aPointGetter( i );
2788 double spaceWidth = g->
advance * 0.74;
2806 const float XOFF = glyph->
minx;
2809 const float round_adjust = ( glyph->
maxy - glyph->
miny )
2812 const float YOFF = round_adjust + top_adjust;
2861 const float H = glyph->
maxy - glyph->
miny;
2891 float commonOffset = std::numeric_limits<float>::max();
2893 int overbarDepth = -1;
2894 int braceNesting = 0;
2898 if( *chIt ==
'~' && overbarDepth == -1 )
2902 if( ++lookahead !=
end && *lookahead ==
'{' )
2905 overbarDepth = braceNesting;
2910 else if( *chIt ==
'{' )
2914 else if( *chIt ==
'}' )
2916 if( braceNesting > 0 )
2919 if( braceNesting == overbarDepth )
2929 || *chIt ==
'-' || *chIt ==
'_' )
2931 glyph = defaultGlyph;
2938 textSize.
y = std::max<float>( textSize.
y, charHeight );
2940 textSize.
y -= commonOffset;
2942 return std::make_pair( textSize, commonOffset );
2986 const int cursorSize = 80;
2993 GLboolean depthTestEnabled = glIsEnabled( GL_DEPTH_TEST );
2994 glDisable( GL_DEPTH_TEST );
2996 glActiveTexture( GL_TEXTURE0 );
2997 glDisable( GL_TEXTURE_2D );
2998 glEnable( GL_BLEND );
2999 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
3002 glColor4d( color.
r, color.
g, color.
b, color.
a );
3004 glMatrixMode( GL_PROJECTION );
3006 glTranslated( 0, 0, -0.5 );
3008 glBegin( GL_LINES );
3023 double offset1 = cy - cx;
3024 VECTOR2D pos_start( screenTopLeft.
x, screenTopLeft.
x + offset1 );
3025 VECTOR2D pos_end( screenBottomRight.
x, screenBottomRight.
x + offset1 );
3028 glVertex2d( pos_start.
x, pos_start.
y );
3029 glVertex2d( pos_end.
x, pos_end.
y );
3032 double offset2 = cy + cx;
3033 VECTOR2D neg_start( screenTopLeft.
x, offset2 - screenTopLeft.
x );
3034 VECTOR2D neg_end( screenBottomRight.
x, offset2 - screenBottomRight.
x );
3037 glVertex2d( neg_start.
x, neg_start.
y );
3038 glVertex2d( neg_end.
x, neg_end.
y );
3042 glVertex2d( cursorCenter.
x, cursorBegin.
y );
3043 glVertex2d( cursorCenter.
x, cursorEnd.
y );
3045 glVertex2d( cursorBegin.
x, cursorCenter.
y );
3046 glVertex2d( cursorEnd.
x, cursorCenter.
y );
3053 if( depthTestEnabled )
3054 glEnable( GL_DEPTH_TEST );
3060 wxASSERT_MSG(
m_groups.size() < std::numeric_limits<unsigned int>::max(),
3061 wxT(
"There are no free slots to store a group" ) );
3072 wxASSERT_MSG(
m_isContextLocked,
"This should only be called from within a locked context." );
3076 throw std::runtime_error(
"Could not create the tesselator" );
3080 int glVersion = gladLoaderLoadGL();
3082 if( glVersion == 0 )
3083 throw std::runtime_error(
"Failed to load OpenGL via loader" );
3085 const char* vendor = (
const char*) glGetString( GL_VENDOR );
3086 const char* renderer = (
const char*) glGetString( GL_RENDERER );
3087 const char* version = (
const char*) glGetString( GL_VERSION );
3090 throw std::runtime_error(
"No GL context is current (glGetString returned NULL)" );
3095 if( !GLAD_GL_VERSION_2_1 )
3096 throw std::runtime_error(
"OpenGL 2.1 or higher is required!" );
3098#if defined( __LINUX__ )
3100 if( glDebugMessageCallback )
3106 if( !GLAD_GL_ARB_framebuffer_object )
3107 throw std::runtime_error(
"Framebuffer objects are not supported!" );
3110 if( !GLAD_GL_ARB_vertex_buffer_object )
3111 throw std::runtime_error(
"Vertex buffer objects are not supported!" );
3116 BUILTIN_SHADERS::glsl_kicad_vert ) )
3118 throw std::runtime_error(
"Cannot compile vertex shader!" );
3123 BUILTIN_SHADERS::glsl_kicad_frag ) )
3125 throw std::runtime_error(
"Cannot compile fragment shader!" );
3129 throw std::runtime_error(
"Cannot link the shaders!" );
3136 glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxTextureSize );
3142 throw std::runtime_error(
"Requested texture size is not supported" );
3145#if wxCHECK_VERSION( 3, 3, 3 )
3146 wxGLCanvas::SetSwapInterval( -1 );
3183 GLdouble* vertex =
static_cast<GLdouble*
>( aVertexPtr );
3187 assert( vboManager );
3188 vboManager->
Vertex( vertex[0], vertex[1], vertex[2] );
3193 GLdouble** dataOut,
void* aData )
3195 GLdouble* vertex =
new GLdouble[3];
3201 param->
intersectPoints.emplace_back( vertex, std::default_delete<GLdouble[]>() );
3203 memcpy( vertex, coords, 3 *
sizeof( GLdouble ) );
3241 return ( ceil( f / r ) - 0.5 ) * r;
3274 outlineGlyph.Triangulate(
3289 if( aGlyphs.empty() )
3292 bool allGlyphsAreStroke =
true;
3293 bool allGlyphsAreOutline =
true;
3295 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3297 if( !glyph->IsStroke() )
3299 allGlyphsAreStroke =
false;
3304 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3306 if( !glyph->IsOutline() )
3308 allGlyphsAreOutline =
false;
3313 if( allGlyphsAreStroke )
3316 int lineQuadCount = 0;
3318 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3322 for(
const std::vector<VECTOR2D>& points : strokeGlyph )
3323 lineQuadCount += points.size() - 1;
3328 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3332 for(
const std::vector<VECTOR2D>& points : strokeGlyph )
3339 points.size(),
false );
3345 else if( allGlyphsAreOutline )
3348 int triangleCount = 0;
3350 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3354 for(
unsigned int i = 0; i < outlineGlyph.TriangulatedPolyCount(); i++ )
3357 outlineGlyph.TriangulatedPolygon( i );
3368 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3372 for(
unsigned int i = 0; i < outlineGlyph.TriangulatedPolyCount(); i++ )
3375 outlineGlyph.TriangulatedPolygon( i );
3392 for(
size_t i = 0; i < aGlyphs.size(); i++ )
3393 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.
bool IsInitialized() const override
Return the initialization status for the canvas.
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.
bool GetScreenshot(wxImage &aDstImage)
Parameters passed to the GLU tesselator.
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)