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 wxImage imgData = *imgPtr;
181 GLint maxTextureSize;
182 glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxTextureSize );
184 int imgWidth = imgData.GetWidth();
185 int imgHeight = imgData.GetHeight();
187 if( imgWidth > maxTextureSize || imgHeight > maxTextureSize )
191 double scaleX =
static_cast<double>( maxTextureSize ) / imgWidth;
192 double scaleY =
static_cast<double>( maxTextureSize ) / imgHeight;
193 double scale = std::min( scaleX, scaleY );
195 int newWidth = std::clamp(
KiROUND( imgWidth *
scale ), 1, maxTextureSize );
196 int newHeight = std::clamp(
KiROUND( imgHeight *
scale ), 1, maxTextureSize );
198 imgData = imgData.Scale( newWidth, newHeight, wxIMAGE_QUALITY_HIGH );
200 if( !imgData.IsOk() )
201 return std::numeric_limits< GLuint >::max();
204 bmp.
w = imgData.GetSize().x;
205 bmp.
h = imgData.GetSize().y;
211 glGenTextures( 1, &textureID );
219 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
221 if( imgData.HasAlpha() || imgData.HasMask() )
223 bmp.
size =
static_cast<size_t>( bmp.
w ) * bmp.
h * 4;
224 auto buf = std::make_unique<uint8_t[]>( bmp.
size );
226 uint8_t* dstP = buf.get();
227 uint8_t* srcP = imgData.GetData();
229 long long pxCount =
static_cast<long long>( bmp.
w ) * bmp.
h;
231 if( imgData.HasAlpha() )
233 uint8_t* srcAlpha = imgData.GetAlpha();
235 for(
long long px = 0; px < pxCount; px++ )
237 memcpy( dstP, srcP, 3 );
245 else if( imgData.HasMask() )
247 uint8_t maskRed = imgData.GetMaskRed();
248 uint8_t maskGreen = imgData.GetMaskGreen();
249 uint8_t maskBlue = imgData.GetMaskBlue();
251 for(
long long px = 0; px < pxCount; px++ )
253 memcpy( dstP, srcP, 3 );
255 if( srcP[0] == maskRed && srcP[1] == maskGreen && srcP[2] == maskBlue )
256 dstP[3] = wxALPHA_TRANSPARENT;
258 dstP[3] = wxALPHA_OPAQUE;
265 glBindTexture( GL_TEXTURE_2D, textureID );
266 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.
w, bmp.
h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
271 bmp.
size =
static_cast<size_t>( bmp.
w ) * bmp.
h * 3;
273 uint8_t* srcP = imgData.GetData();
275 glBindTexture( GL_TEXTURE_2D, textureID );
276 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, bmp.
w, bmp.
h, 0, GL_RGB, GL_UNSIGNED_BYTE, srcP );
279 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
280 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
282 long long currentTime = wxGetUTCTimeMillis().GetValue();
287#ifndef DISABLE_BITMAP_CACHE
297 for(
const auto& [kiid, cachedBmp] :
m_bitmaps )
299 const int cacheTimeoutMillis = 1000L;
301 if( currentTime - cachedBmp.accessTime > cacheTimeoutMillis )
315 toRemove = *toRemoveLru;
321 glDeleteTextures( 1, &cachedBitmap.
id );
339 wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener,
340 const wxString& aName ) :
341 GAL( aDisplayOptions ),
363 throw std::runtime_error(
"Could not create the main OpenGL context" );
372 throw std::runtime_error(
"Could not create a private OpenGL context" );
417#if defined _WIN32 || defined _WIN64
424 SetSize( aParent->GetClientSize() );
435 gluTessProperty(
m_tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
506 static std::optional<wxString> cached;
508 if( cached.has_value() )
511 wxString retVal = wxEmptyString;
513 wxFrame* testFrame =
new wxFrame(
nullptr, wxID_ANY, wxT(
"" ), wxDefaultPosition,
514 wxSize( 1, 1 ), wxFRAME_TOOL_WINDOW | wxNO_BORDER );
536 catch( std::runtime_error& err )
539 retVal = wxString( err.what() );
598#ifdef KICAD_GAL_PROFILE
599 PROF_TIMER totalRealTime(
"OPENGL_GAL::beginDrawing()",
true );
602 wxASSERT_MSG(
m_isContextLocked,
"GAL_DRAWING_CONTEXT RAII object should have locked context. "
603 "Calling GAL::beginDrawing() directly is not allowed." );
605 wxASSERT_MSG(
IsVisible(),
"GAL::beginDrawing() must not be entered when GAL is not visible. "
606 "Other drawing routines will expect everything to be initialized "
607 "which will not be the case." );
613 glMatrixMode( GL_PROJECTION );
629 catch(
const std::runtime_error& )
631 wxLogVerbose(
"Could not create a framebuffer for diff mode blending.\n" );
638 catch(
const std::runtime_error& )
640 wxLogVerbose(
"Could not create a framebuffer for overlays.\n" );
650 glDisable( GL_TEXTURE_2D );
652 glShadeModel( GL_FLAT );
655 glEnable( GL_DEPTH_TEST );
656 glDepthFunc( GL_LESS );
659 glEnable( GL_BLEND );
660 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
662 glMatrixMode( GL_MODELVIEW );
666 GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
676 glLoadMatrixd( matrixData );
695 const GLint FONT_TEXTURE_UNIT = 2;
700 glActiveTexture( GL_TEXTURE0 + FONT_TEXTURE_UNIT );
705 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
706 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
707 checkGlError(
"loading bitmap font", __FILE__, __LINE__ );
709 glActiveTexture( GL_TEXTURE0 );
715 glActiveTexture( GL_TEXTURE0 + FONT_TEXTURE_UNIT );
717 glActiveTexture( GL_TEXTURE0 );
724 checkGlError(
"setting bitmap font sampler as shader parameter", __FILE__, __LINE__ );
734 double pixelSizeMultiplier =
m_compositor->GetAntialiasSupersamplingFactor();
737 renderingOffset.
x *= screenPixelSize.
x;
738 renderingOffset.
y *= screenPixelSize.
y;
745 glActiveTexture( GL_TEXTURE0 );
750#ifdef KICAD_GAL_PROFILE
751 totalRealTime.
Stop();
752 wxLogTrace(
traceGalProfile, wxT(
"OPENGL_GAL::beginDrawing(): %.1f ms" ),
753 totalRealTime.
msecs() );
776 PROF_TIMER cntEndNoncached(
"gl-end-noncached" );
786 cntEndNoncached.
Start();
788 cntEndNoncached.
Stop();
790 cntEndCached.
Start();
794 cntEndOverlay.
Start();
800 cntEndOverlay.
Stop();
802 cntComposite.
Start();
805 glColor4d( 1.0, 1.0, 1.0, 1.0 );
824#ifdef KICAD_GAL_PROFILE
842 glGetIntegerv( GL_VIEWPORT, viewport );
844 const int w = viewport[2];
845 const int h = viewport[3];
847 GLint readBuffer = GL_COLOR_ATTACHMENT0;
848 glGetIntegerv( GL_DRAW_BUFFER, &readBuffer );
854 std::vector<unsigned char> rgba( (
size_t) w * h * 4 );
857 glPixelStorei( GL_PACK_ALIGNMENT, 1 );
858 glReadBuffer( (GLenum) readBuffer );
859 glReadPixels( 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgba.data() );
862 unsigned char* rgb = (
unsigned char*) malloc( (
size_t) w * h * 3 );
863 unsigned char* alpha = (
unsigned char*) malloc( (
size_t) w * h );
865 for(
int i = 0; i < w * h; ++i )
867 rgb[i * 3 + 0] = rgba[i * 4 + 0];
868 rgb[i * 3 + 1] = rgba[i * 4 + 1];
869 rgb[i * 3 + 2] = rgba[i * 4 + 2];
870 alpha[i] = rgba[i * 4 + 3];
873 aDstImage.SetData( rgb, w, h,
false );
874 aDstImage.SetAlpha( alpha,
false );
876 aDstImage = aDstImage.Mirror(
false );
903 wxASSERT_MSG(
m_isContextLocked,
"Context not locked. A GAL_CONTEXT_LOCKER RAII object must "
904 "be stacked rather than making separate lock/unlock calls." );
907 "Context was locked by a different client. "
908 "Should not be possible with RAII objects." );
923 wxASSERT_MSG(
m_isContextLocked,
"GAL_UPDATE_CONTEXT RAII object should have locked context. "
924 "Calling this from anywhere else is not allowed." );
926 wxASSERT_MSG(
IsVisible(),
"GAL::beginUpdate() must not be entered when GAL is not visible. "
927 "Other update routines will expect everything to be initialized "
928 "which will not be the case." );
964 VECTOR2D startEndVector = aEndPoint - aStartPoint;
971 float startX =
static_cast<float>( aStartPoint.
x );
972 float startY =
static_cast<float>( aStartPoint.
y );
973 float endX =
static_cast<float>( aEndPoint.
x );
974 float endY =
static_cast<float>( aEndPoint.
y );
976 if( startX == endX && startY == endY )
978 drawCircle( aStartPoint, aWidth / 2, aReserve );
1113 double startAngle = aStartAngle.
AsRadians();
1114 double endAngle = startAngle + aAngle.
AsRadians();
1131 for( alpha = startAngle; ( alpha + alphaIncrement ) < endAngle; )
1137 alpha += alphaIncrement;
1143 const VECTOR2D endPoint( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1156 VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1158 unsigned int lineCount = 0;
1160 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1163 if( alpha != endAngle )
1168 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1170 VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
1177 if( alpha != endAngle )
1179 VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1190 double aWidth,
double aMaxError )
1201 double startAngle = aStartAngle.
AsRadians();
1202 double endAngle = startAngle + aAngle.
AsRadians();
1210 double alphaIncrement = 2.0 *
M_PI / segCount360;
1215 int seg_count =
KiROUND( ( endAngle - startAngle ) / alphaIncrement );
1217 if( seg_count % 2 != 0 )
1221 if( seg_count == 0 )
1223 VECTOR2D p_start( aCenterPoint.
x + cos( startAngle ) * aRadius,
1224 aCenterPoint.
y + sin( startAngle ) * aRadius );
1226 VECTOR2D p_end( aCenterPoint.
x + cos( endAngle ) * aRadius,
1227 aCenterPoint.
y + sin( endAngle ) * aRadius );
1234 alphaIncrement = ( endAngle - startAngle ) / seg_count;
1244 double width = aWidth / 2.0;
1245 VECTOR2D startPoint( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1246 VECTOR2D endPoint( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1251 VECTOR2D pOuter( cos( startAngle ) * ( aRadius + width ),
1252 sin( startAngle ) * ( aRadius + width ) );
1254 VECTOR2D pInner( cos( startAngle ) * ( aRadius - width ),
1255 sin( startAngle ) * ( aRadius - width ) );
1259 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1261 VECTOR2D pNextOuter( cos( alpha ) * ( aRadius + width ),
1262 sin( alpha ) * ( aRadius + width ) );
1263 VECTOR2D pNextInner( cos( alpha ) * ( aRadius - width ),
1264 sin( alpha ) * ( aRadius - width ) );
1269 pOuter = pNextOuter;
1270 pInner = pNextInner;
1274 if( alpha != endAngle )
1276 VECTOR2D pLastOuter( cos( endAngle ) * ( aRadius + width ),
1277 sin( endAngle ) * ( aRadius + width ) );
1278 VECTOR2D pLastInner( cos( endAngle ) * ( aRadius - width ),
1279 sin( endAngle ) * ( aRadius - width ) );
1291 VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1296 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1302 if( alpha != endAngle )
1309 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1311 VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
1318 if( alpha != endAngle )
1320 VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1332 if( aMajorRadius <= 0 || aMinorRadius <= 0 )
1335 const double alphaIncrement =
calcAngleStep( aMajorRadius );
1336 const double cosPhi = std::cos( aRotation.
AsRadians() );
1337 const double sinPhi = std::sin( aRotation.
AsRadians() );
1339 auto eval = [&](
double theta ) ->
VECTOR2D
1341 const double lx = aMajorRadius * std::cos( theta );
1342 const double ly = aMinorRadius * std::sin( theta );
1343 return VECTOR2D( lx * cosPhi - ly * sinPhi, lx * sinPhi + ly * cosPhi );
1356 for( alpha = 0.0; ( alpha + alphaIncrement ) < 2.0 *
M_PI; )
1359 alpha += alphaIncrement;
1383 unsigned int lineCount = 0;
1386 for( countAlpha = alphaIncrement; countAlpha < 2.0 *
M_PI; countAlpha += alphaIncrement )
1396 for( alpha = alphaIncrement; alpha < 2.0 *
M_PI; alpha += alphaIncrement )
1398 const VECTOR2D p_next = eval( alpha );
1414 if( aMajorRadius <= 0 || aMinorRadius <= 0 )
1417 double startAngle = aStartAngle.
AsRadians();
1418 double endAngle = aEndAngle.
AsRadians();
1421 const double alphaIncrement =
calcAngleStep( aMajorRadius );
1422 const double cosPhi = std::cos( aRotation.
AsRadians() );
1423 const double sinPhi = std::sin( aRotation.
AsRadians() );
1425 auto eval = [&](
double theta ) ->
VECTOR2D
1427 const double lx = aMajorRadius * std::cos( theta );
1428 const double ly = aMinorRadius * std::sin( theta );
1429 return VECTOR2D( lx * cosPhi - ly * sinPhi, lx * sinPhi + ly * cosPhi );
1443 for( alpha = startAngle; ( alpha + alphaIncrement ) < endAngle; )
1446 alpha += alphaIncrement;
1457 const VECTOR2D p2 = eval( endAngle );
1469 unsigned int lineCount = 0;
1472 for( countAlpha = startAngle + alphaIncrement; countAlpha <= endAngle; countAlpha += alphaIncrement )
1475 if( countAlpha != endAngle )
1483 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1485 const VECTOR2D p_next = eval( alpha );
1491 if( alpha != endAngle )
1493 const VECTOR2D p_last = eval( endAngle );
1505 VECTOR2D diagonalPointA( aEndPoint.
x, aStartPoint.
y );
1506 VECTOR2D diagonalPointB( aStartPoint.
x, aEndPoint.
y );
1532 if( aStartPoint == aEndPoint )
1538 std::deque<VECTOR2D> pointList;
1540 pointList.push_back( aStartPoint );
1541 pointList.push_back( diagonalPointA );
1542 pointList.push_back( aEndPoint );
1543 pointList.push_back( diagonalPointB );
1544 pointList.push_back( aStartPoint );
1556 return aPointList[idx];
1558 aPointList.size(), aWidth );
1572 return aLineChain.
CPoint( idx );
1574 numPoints, aWidth );
1583 return aPointList[idx];
1585 aPointList.size() );
1594 return aPointList[idx];
1596 aPointList.size() );
1605 return aPointList[idx];
1621 return aLineChain.
CPoint( idx );
1629 int lineQuadCount = 0;
1631 for(
const std::vector<VECTOR2D>& points : aPointList )
1632 lineQuadCount += points.size() - 1;
1636 for(
const std::vector<VECTOR2D>& points : aPointList )
1643 points.size(),
false );
1650 wxCHECK( aPointList.size() >= 2, );
1651 auto points = std::unique_ptr<GLdouble[]>(
new GLdouble[3 * aPointList.size()] );
1652 GLdouble* ptr = points.get();
1654 for(
const VECTOR2D& p : aPointList )
1667 wxCHECK( aListSize >= 2, );
1668 auto points = std::unique_ptr<GLdouble[]>(
new GLdouble[3 * aListSize] );
1669 GLdouble* target = points.get();
1672 for(
int i = 0; i < aListSize; ++i )
1685 bool aStrokeTriangulation )
1692 int totalTriangleCount = 0;
1707 for(
size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
1710 triPoly->GetTriangle( i, a, b, c );
1722 const auto& poly = aPolySet.
Polygon( j );
1724 for(
const auto& lc : poly )
1733 aStrokeTriangulation =
true;
1737 if( aStrokeTriangulation )
1746 for(
size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
1749 triPoly->GetTriangle( i, a, b, c );
1781 std::unique_ptr<GLdouble[]> points(
new GLdouble[3 * pointCount] );
1782 GLdouble* ptr = points.get();
1784 for(
int i = 0; i < pointCount; ++i )
1798 double aFilterValue )
1800 std::vector<VECTOR2D>
output;
1801 std::vector<VECTOR2D> pointCtrl;
1803 pointCtrl.push_back( aStartPoint );
1804 pointCtrl.push_back( aControlPointA );
1805 pointCtrl.push_back( aControlPointB );
1806 pointCtrl.push_back( aEndPoint );
1820 GLfloat alpha = std::clamp( alphaBlend, 0.0, 1.0 );
1830 glm::vec4 v0 = xform * glm::vec4( -w / 2, -h / 2, 0.0, 0.0 );
1831 glm::vec4
v1 = xform * glm::vec4( w / 2, h / 2, 0.0, 0.0 );
1832 glm::vec4 trans = xform[3];
1836 if( !glIsTexture( texture_id ) )
1839 GLboolean depthMask = GL_TRUE;
1840 glGetBooleanv( GL_DEPTH_WRITEMASK, &depthMask );
1843 glDepthMask( GL_FALSE );
1845 glDepthFunc( GL_ALWAYS );
1847 glAlphaFunc( GL_GREATER, 0.01f );
1848 glEnable( GL_ALPHA_TEST );
1850 glMatrixMode( GL_TEXTURE );
1852 glTranslated( 0.5, 0.5, 0.5 );
1854 glTranslated( -0.5, -0.5, -0.5 );
1856 glMatrixMode( GL_MODELVIEW );
1858 glTranslated( trans.x, trans.y, trans.z );
1860 glEnable( GL_TEXTURE_2D );
1861 glActiveTexture( GL_TEXTURE0 );
1862 glBindTexture( GL_TEXTURE_2D, texture_id );
1864 float texStartX = aBitmap.
IsMirroredX() ? 1.0 : 0.0;
1865 float texEndX = aBitmap.
IsMirroredX() ? 0.0 : 1.0;
1866 float texStartY = aBitmap.
IsMirroredY() ? 1.0 : 0.0;
1867 float texEndY = aBitmap.
IsMirroredY() ? 0.0 : 1.0;
1869 glBegin( GL_QUADS );
1870 glColor4f( 1.0, 1.0, 1.0, alpha );
1871 glTexCoord2f( texStartX, texStartY );
1873 glColor4f( 1.0, 1.0, 1.0, alpha );
1874 glTexCoord2f( texEndX, texStartY);
1876 glColor4f( 1.0, 1.0, 1.0, alpha );
1877 glTexCoord2f( texEndX, texEndY);
1879 glColor4f( 1.0, 1.0, 1.0, alpha );
1880 glTexCoord2f( texStartX, texEndY);
1884 glBindTexture( GL_TEXTURE_2D, 0 );
1886#ifdef DISABLE_BITMAP_CACHE
1887 glDeleteTextures( 1, &texture_id );
1892 glMatrixMode( GL_TEXTURE );
1894 glMatrixMode( GL_MODELVIEW );
1896 glDisable( GL_ALPHA_TEST );
1898 glDepthMask( depthMask );
1900 glDepthFunc( GL_LESS );
1909 || aText.Contains( wxT(
"^{" ) )
1910 || aText.Contains( wxT(
"_{" ) )
1911 || aText.Contains( wxT(
"\n" ) ) )
1922 double overbarHeight = textSize.
y;
1953 wxFAIL_MSG( wxT(
"Indeterminate state legal only in dialogs." ) );
1969 overbarHeight = -textSize.
y / 2.0;
1973 wxFAIL_MSG( wxT(
"Indeterminate state legal only in dialogs." ) );
1977 int overbarLength = 0;
1978 int overbarDepth = -1;
1979 int braceNesting = 0;
1981 auto iterateString =
1982 [&](
const std::function<void(
int aOverbarLength,
int aOverbarHeight )>& overbarFn,
1983 const std::function<int(
unsigned long aChar )>& bitmapCharFn )
1987 wxASSERT_MSG( *chIt !=
'\n' && *chIt !=
'\r',
1988 "No support for multiline bitmap text yet" );
1990 if( *chIt ==
'~' && overbarDepth == -1 )
1994 if( ++lookahead !=
end && *lookahead ==
'{' )
1997 overbarDepth = braceNesting;
2002 else if( *chIt ==
'{' )
2006 else if( *chIt ==
'}' )
2008 if( braceNesting > 0 )
2011 if( braceNesting == overbarDepth )
2013 overbarFn( overbarLength, overbarHeight );
2021 if( overbarDepth != -1 )
2022 overbarLength += bitmapCharFn( *chIt );
2024 bitmapCharFn( *chIt );
2031 int overbarsCount = 0;
2034 [&overbarsCount](
int aOverbarLength,
int aOverbarHeight )
2038 [&charsCount](
unsigned long aChar ) ->
int
2054 [&](
int aOverbarLength,
int aOverbarHeight )
2058 [&](
unsigned long aChar ) ->
int
2066 if( overbarDepth != -1 && overbarLength > 0 )
2081 float minorLineWidth = std::fmax( 1.0f,
2083 float majorLineWidth = minorLineWidth * 2.0f;
2127 glDisable( GL_DEPTH_TEST );
2128 glDisable( GL_TEXTURE_2D );
2132 glEnable( GL_STENCIL_TEST );
2133 glStencilFunc( GL_ALWAYS, 1, 1 );
2134 glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
2135 glColor4d( 0.0, 0.0, 0.0, 0.0 );
2147 for(
int j = gridStartY; j <= gridEndY; j++ )
2153 for(
int i = gridStartX; i <= gridEndX; i++ )
2156 SetLineWidth( ( ( tickX && tickY ) ? majorLineWidth : minorLineWidth ) );
2170 for(
int j = gridStartY; j <= gridEndY; j++ )
2189 glStencilFunc( GL_NOTEQUAL, 0, 1 );
2195 for(
int i = gridStartX; i <= gridEndX; i++ )
2212 glDisable( GL_STENCIL_TEST );
2216 glEnable( GL_DEPTH_TEST );
2217 glEnable( GL_TEXTURE_2D );
2227 m_compositor->Resize( aWidth * scaleFactor, aHeight * scaleFactor );
2230 wxGLCanvas::SetSize( aWidth, aHeight );
2236 bool s = wxGLCanvas::Show( aShow );
2239 wxGLCanvas::Raise();
2257 glClearColor( 0, 0, 0, 1 );
2258 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
2264 GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
2266 matrixData[0] = aTransformation.
m_data[0][0];
2267 matrixData[1] = aTransformation.
m_data[1][0];
2268 matrixData[2] = aTransformation.
m_data[2][0];
2269 matrixData[4] = aTransformation.
m_data[0][1];
2270 matrixData[5] = aTransformation.
m_data[1][1];
2271 matrixData[6] = aTransformation.
m_data[2][1];
2272 matrixData[12] = aTransformation.
m_data[0][2];
2273 matrixData[13] = aTransformation.
m_data[1][2];
2274 matrixData[14] = aTransformation.
m_data[2][2];
2276 glMultMatrixd( matrixData );
2314 std::shared_ptr<VERTEX_ITEM> newItem = std::make_shared<VERTEX_ITEM>( *
m_cachedManager );
2316 m_groups.insert( std::make_pair( groupNumber, newItem ) );
2445 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::StartDiffLayer() called" ) );
2452 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): setting target to TARGET_TEMP" ) );
2459 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): TARGET_TEMP set and cleared, compositor buffer=%u" ),
2464 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): WARNING - no temp buffer!" ) );
2471 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::EndDiffLayer() called" ) );
2472 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): m_tempBuffer=%u, m_mainBuffer=%u" ),
2477 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): using temp buffer path" ) );
2482 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): calling DrawBufferDifference" ) );
2490 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): DrawBufferDifference returned" ) );
2494 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): NO temp buffer, using fallback path" ) );
2497 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
2499 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
2502 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::EndDiffLayer() complete" ) );
2514#if wxCHECK_VERSION( 3, 3, 0 )
2526#if wxCHECK_VERSION( 3, 3, 0 )
2545 const bool aReserve )
2563 * glm::vec4( aStartPoint.
x, aStartPoint.
y, 0.0, 0.0 );
2565 * glm::vec4( aEndPoint.
x, aEndPoint.
y, 0.0, 0.0 );
2649 double outerRadius = aRadius + (
m_lineWidth / 2 );
2695 GLdouble* point = aPoints;
2697 for(
int i = 0; i < aPointCount; ++i )
2715 return VECTOR2D( aPoints[idx * 3], aPoints[idx * 3 + 1] );
2725 wxCHECK( aPointCount > 0, );
2729 if( aPointCount == 1 )
2731 drawLineQuad( aPointGetter( 0 ), aPointGetter( 0 ), aReserve );
2740 for(
int i = 1; i < aPointCount; ++i )
2742 auto start = aPointGetter( i - 1 );
2743 auto end = aPointGetter( i );
2751 int aPointCount,
double aWidth,
bool aReserve )
2753 wxCHECK( aPointCount >= 2, );
2759 for(
int i = 1; i < aPointCount; ++i )
2761 auto start = aPointGetter( i - 1 );
2762 auto end = aPointGetter( i );
2764 float startx = start.x;
2765 float starty = start.y;
2774 if( startx == endx && starty == endy )
2786 vertices += 6 + 6 + 3 + 3;
2792 for(
int i = 1; i < aPointCount; ++i )
2794 auto start = aPointGetter( i - 1 );
2795 auto end = aPointGetter( i );
2814 double spaceWidth = g->
advance * 0.74;
2832 const float XOFF = glyph->
minx;
2835 const float round_adjust = ( glyph->
maxy - glyph->
miny )
2838 const float YOFF = round_adjust + top_adjust;
2887 const float H = glyph->
maxy - glyph->
miny;
2917 float commonOffset = std::numeric_limits<float>::max();
2919 int overbarDepth = -1;
2920 int braceNesting = 0;
2924 if( *chIt ==
'~' && overbarDepth == -1 )
2928 if( ++lookahead !=
end && *lookahead ==
'{' )
2931 overbarDepth = braceNesting;
2936 else if( *chIt ==
'{' )
2940 else if( *chIt ==
'}' )
2942 if( braceNesting > 0 )
2945 if( braceNesting == overbarDepth )
2955 || *chIt ==
'-' || *chIt ==
'_' )
2957 glyph = defaultGlyph;
2964 textSize.
y = std::max<float>( textSize.
y, charHeight );
2966 textSize.
y -= commonOffset;
2968 return std::make_pair( textSize, commonOffset );
3012 const int cursorSize = 80;
3019 GLboolean depthTestEnabled = glIsEnabled( GL_DEPTH_TEST );
3020 glDisable( GL_DEPTH_TEST );
3022 glActiveTexture( GL_TEXTURE0 );
3023 glDisable( GL_TEXTURE_2D );
3024 glEnable( GL_BLEND );
3025 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
3028 glColor4d( color.
r, color.
g, color.
b, color.
a );
3030 glMatrixMode( GL_PROJECTION );
3032 glTranslated( 0, 0, -0.5 );
3034 glBegin( GL_LINES );
3049 double offset1 = cy - cx;
3050 VECTOR2D pos_start( screenTopLeft.
x, screenTopLeft.
x + offset1 );
3051 VECTOR2D pos_end( screenBottomRight.
x, screenBottomRight.
x + offset1 );
3054 glVertex2d( pos_start.
x, pos_start.
y );
3055 glVertex2d( pos_end.
x, pos_end.
y );
3058 double offset2 = cy + cx;
3059 VECTOR2D neg_start( screenTopLeft.
x, offset2 - screenTopLeft.
x );
3060 VECTOR2D neg_end( screenBottomRight.
x, offset2 - screenBottomRight.
x );
3063 glVertex2d( neg_start.
x, neg_start.
y );
3064 glVertex2d( neg_end.
x, neg_end.
y );
3068 glVertex2d( cursorCenter.
x, cursorBegin.
y );
3069 glVertex2d( cursorCenter.
x, cursorEnd.
y );
3071 glVertex2d( cursorBegin.
x, cursorCenter.
y );
3072 glVertex2d( cursorEnd.
x, cursorCenter.
y );
3079 if( depthTestEnabled )
3080 glEnable( GL_DEPTH_TEST );
3086 wxASSERT_MSG(
m_groups.size() < std::numeric_limits<unsigned int>::max(),
3087 wxT(
"There are no free slots to store a group" ) );
3098 wxASSERT_MSG(
m_isContextLocked,
"This should only be called from within a locked context." );
3102 throw std::runtime_error(
"Could not create the tesselator" );
3106 int glVersion = gladLoaderLoadGL();
3108 if( glVersion == 0 )
3109 throw std::runtime_error(
"Failed to load OpenGL via loader" );
3111 const char* vendor = (
const char*) glGetString( GL_VENDOR );
3112 const char* renderer = (
const char*) glGetString( GL_RENDERER );
3113 const char* version = (
const char*) glGetString( GL_VERSION );
3116 throw std::runtime_error(
"No GL context is current (glGetString returned NULL)" );
3121 if( !GLAD_GL_VERSION_2_1 )
3122 throw std::runtime_error(
"OpenGL 2.1 or higher is required!" );
3124#if defined( __LINUX__ )
3126 if( glDebugMessageCallback )
3132 if( !GLAD_GL_ARB_framebuffer_object )
3133 throw std::runtime_error(
"Framebuffer objects are not supported!" );
3136 if( !GLAD_GL_ARB_vertex_buffer_object )
3137 throw std::runtime_error(
"Vertex buffer objects are not supported!" );
3142 BUILTIN_SHADERS::glsl_kicad_vert ) )
3144 throw std::runtime_error(
"Cannot compile vertex shader!" );
3149 BUILTIN_SHADERS::glsl_kicad_frag ) )
3151 throw std::runtime_error(
"Cannot compile fragment shader!" );
3155 throw std::runtime_error(
"Cannot link the shaders!" );
3162 glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxTextureSize );
3168 throw std::runtime_error(
"Requested texture size is not supported" );
3171#if wxCHECK_VERSION( 3, 3, 3 )
3172 wxGLCanvas::SetSwapInterval( -1 );
3209 GLdouble* vertex =
static_cast<GLdouble*
>( aVertexPtr );
3213 assert( vboManager );
3214 vboManager->
Vertex( vertex[0], vertex[1], vertex[2] );
3219 GLdouble** dataOut,
void* aData )
3221 GLdouble* vertex =
new GLdouble[3];
3227 param->
intersectPoints.emplace_back( vertex, std::default_delete<GLdouble[]>() );
3229 memcpy( vertex, coords, 3 *
sizeof( GLdouble ) );
3267 return ( ceil( f / r ) - 0.5 ) * r;
3300 outlineGlyph.Triangulate(
3315 if( aGlyphs.empty() )
3318 bool allGlyphsAreStroke =
true;
3319 bool allGlyphsAreOutline =
true;
3321 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3323 if( !glyph->IsStroke() )
3325 allGlyphsAreStroke =
false;
3330 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3332 if( !glyph->IsOutline() )
3334 allGlyphsAreOutline =
false;
3339 if( allGlyphsAreStroke )
3342 int lineQuadCount = 0;
3344 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3348 for(
const std::vector<VECTOR2D>& points : strokeGlyph )
3349 lineQuadCount += points.size() - 1;
3354 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3358 for(
const std::vector<VECTOR2D>& points : strokeGlyph )
3365 points.size(),
false );
3371 else if( allGlyphsAreOutline )
3374 int triangleCount = 0;
3376 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3380 for(
unsigned int i = 0; i < outlineGlyph.TriangulatedPolyCount(); i++ )
3383 outlineGlyph.TriangulatedPolygon( i );
3394 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3398 for(
unsigned int i = 0; i < outlineGlyph.TriangulatedPolyCount(); i++ )
3401 outlineGlyph.TriangulatedPolygon( i );
3418 for(
size_t i = 0; i < aGlyphs.size(); i++ )
3419 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)