63using namespace std::placeholders;
71#include <glsl_kicad_frag.h>
72#include <glsl_kicad_vert.h>
82 wxGLAttributes attribs;
83 attribs.RGBA().DoubleBuffer().Depth( 8 ).EndList();
132 glDeleteTextures( 1, &bitmap.second.id );
138#ifndef DISABLE_BITMAP_CACHE
144 if( glIsTexture( it->second.id ) )
146 it->second.accessTime = wxGetUTCTimeMillis().GetValue();
147 return it->second.id;
152 glDeleteTextures( 1, &it->second.id );
180 return std::numeric_limits< GLuint >::max();
182 const wxImage& imgData = *imgPtr;
184 bmp.
w = imgData.GetSize().x;
185 bmp.
h = imgData.GetSize().y;
191 glGenTextures( 1, &textureID );
199 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
201 if( imgData.HasAlpha() || imgData.HasMask() )
203 bmp.
size = bmp.
w * bmp.
h * 4;
204 auto buf = std::make_unique<uint8_t[]>( bmp.
size );
206 uint8_t* dstP = buf.get();
207 uint8_t* srcP = imgData.GetData();
209 long long pxCount =
static_cast<long long>( bmp.
w ) * bmp.
h;
211 if( imgData.HasAlpha() )
213 uint8_t* srcAlpha = imgData.GetAlpha();
215 for(
long long px = 0; px < pxCount; px++ )
217 memcpy( dstP, srcP, 3 );
225 else if( imgData.HasMask() )
227 uint8_t maskRed = imgData.GetMaskRed();
228 uint8_t maskGreen = imgData.GetMaskGreen();
229 uint8_t maskBlue = imgData.GetMaskBlue();
231 for(
long long px = 0; px < pxCount; px++ )
233 memcpy( dstP, srcP, 3 );
235 if( srcP[0] == maskRed && srcP[1] == maskGreen && srcP[2] == maskBlue )
236 dstP[3] = wxALPHA_TRANSPARENT;
238 dstP[3] = wxALPHA_OPAQUE;
245 glBindTexture( GL_TEXTURE_2D, textureID );
246 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.
w, bmp.
h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
251 bmp.
size = bmp.
w * bmp.
h * 3;
253 uint8_t* srcP = imgData.GetData();
255 glBindTexture( GL_TEXTURE_2D, textureID );
256 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, bmp.
w, bmp.
h, 0, GL_RGB, GL_UNSIGNED_BYTE, srcP );
259 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
260 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
262 long long currentTime = wxGetUTCTimeMillis().GetValue();
267#ifndef DISABLE_BITMAP_CACHE
275 for(
const auto& [kiid, cachedBmp] :
m_bitmaps )
277 const int cacheTimeoutMillis = 1000L;
279 if( currentTime - cachedBmp.accessTime > cacheTimeoutMillis )
293 toRemove = *toRemoveLru;
299 glDeleteTextures( 1, &cachedBitmap.
id );
317 wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener,
318 const wxString& aName ) :
319 GAL( aDisplayOptions ),
341 throw std::runtime_error(
"Could not create the main OpenGL context" );
350 throw std::runtime_error(
"Could not create a private OpenGL context" );
395#if defined _WIN32 || defined _WIN64
402 SetSize( aParent->GetClientSize() );
413 gluTessProperty(
m_tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
484 static std::optional<wxString> cached;
486 if( cached.has_value() )
489 wxString retVal = wxEmptyString;
491 wxFrame* testFrame =
new wxFrame(
nullptr, wxID_ANY, wxT(
"" ), wxDefaultPosition,
492 wxSize( 1, 1 ), wxFRAME_TOOL_WINDOW | wxNO_BORDER );
514 catch( std::runtime_error& err )
517 retVal = wxString( err.what() );
576#ifdef KICAD_GAL_PROFILE
577 PROF_TIMER totalRealTime(
"OPENGL_GAL::beginDrawing()",
true );
580 wxASSERT_MSG(
m_isContextLocked,
"GAL_DRAWING_CONTEXT RAII object should have locked context. "
581 "Calling GAL::beginDrawing() directly is not allowed." );
583 wxASSERT_MSG(
IsVisible(),
"GAL::beginDrawing() must not be entered when GAL is not visible. "
584 "Other drawing routines will expect everything to be initialized "
585 "which will not be the case." );
591 glMatrixMode( GL_PROJECTION );
607 catch(
const std::runtime_error& )
609 wxLogVerbose(
"Could not create a framebuffer for diff mode blending.\n" );
616 catch(
const std::runtime_error& )
618 wxLogVerbose(
"Could not create a framebuffer for overlays.\n" );
628 glDisable( GL_TEXTURE_2D );
630 glShadeModel( GL_FLAT );
633 glEnable( GL_DEPTH_TEST );
634 glDepthFunc( GL_LESS );
637 glEnable( GL_BLEND );
638 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
640 glMatrixMode( GL_MODELVIEW );
644 GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
654 glLoadMatrixd( matrixData );
673 const GLint FONT_TEXTURE_UNIT = 2;
678 glActiveTexture( GL_TEXTURE0 + FONT_TEXTURE_UNIT );
683 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
684 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
685 checkGlError(
"loading bitmap font", __FILE__, __LINE__ );
687 glActiveTexture( GL_TEXTURE0 );
693 glActiveTexture( GL_TEXTURE0 + FONT_TEXTURE_UNIT );
695 glActiveTexture( GL_TEXTURE0 );
702 checkGlError(
"setting bitmap font sampler as shader parameter", __FILE__, __LINE__ );
712 double pixelSizeMultiplier =
m_compositor->GetAntialiasSupersamplingFactor();
715 renderingOffset.
x *= screenPixelSize.
x;
716 renderingOffset.
y *= screenPixelSize.
y;
723 glActiveTexture( GL_TEXTURE0 );
728#ifdef KICAD_GAL_PROFILE
729 totalRealTime.
Stop();
730 wxLogTrace(
traceGalProfile, wxT(
"OPENGL_GAL::beginDrawing(): %.1f ms" ),
731 totalRealTime.
msecs() );
754 PROF_TIMER cntEndNoncached(
"gl-end-noncached" );
764 cntEndNoncached.
Start();
766 cntEndNoncached.
Stop();
768 cntEndCached.
Start();
772 cntEndOverlay.
Start();
778 cntEndOverlay.
Stop();
780 cntComposite.
Start();
783 glColor4d( 1.0, 1.0, 1.0, 1.0 );
802#ifdef KICAD_GAL_PROFILE
820 glGetIntegerv( GL_VIEWPORT, viewport );
822 const int w = viewport[2];
823 const int h = viewport[3];
825 GLint readBuffer = GL_COLOR_ATTACHMENT0;
826 glGetIntegerv( GL_DRAW_BUFFER, &readBuffer );
832 std::vector<unsigned char> rgba( (
size_t) w * h * 4 );
835 glPixelStorei( GL_PACK_ALIGNMENT, 1 );
836 glReadBuffer( (GLenum) readBuffer );
837 glReadPixels( 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgba.data() );
840 unsigned char* rgb = (
unsigned char*) malloc( (
size_t) w * h * 3 );
841 unsigned char* alpha = (
unsigned char*) malloc( (
size_t) w * h );
843 for(
int i = 0; i < w * h; ++i )
845 rgb[i * 3 + 0] = rgba[i * 4 + 0];
846 rgb[i * 3 + 1] = rgba[i * 4 + 1];
847 rgb[i * 3 + 2] = rgba[i * 4 + 2];
848 alpha[i] = rgba[i * 4 + 3];
851 aDstImage.SetData( rgb, w, h,
false );
852 aDstImage.SetAlpha( alpha,
false );
854 aDstImage = aDstImage.Mirror(
false );
881 wxASSERT_MSG(
m_isContextLocked,
"Context not locked. A GAL_CONTEXT_LOCKER RAII object must "
882 "be stacked rather than making separate lock/unlock calls." );
885 "Context was locked by a different client. "
886 "Should not be possible with RAII objects." );
901 wxASSERT_MSG(
m_isContextLocked,
"GAL_UPDATE_CONTEXT RAII object should have locked context. "
902 "Calling this from anywhere else is not allowed." );
904 wxASSERT_MSG(
IsVisible(),
"GAL::beginUpdate() must not be entered when GAL is not visible. "
905 "Other update routines will expect everything to be initialized "
906 "which will not be the case." );
942 VECTOR2D startEndVector = aEndPoint - aStartPoint;
949 float startX =
static_cast<float>( aStartPoint.
x );
950 float startY =
static_cast<float>( aStartPoint.
y );
951 float endX =
static_cast<float>( aEndPoint.
x );
952 float endY =
static_cast<float>( aEndPoint.
y );
954 if( startX == endX && startY == endY )
956 drawCircle( aStartPoint, aWidth / 2, aReserve );
1091 double startAngle = aStartAngle.
AsRadians();
1092 double endAngle = startAngle + aAngle.
AsRadians();
1109 for( alpha = startAngle; ( alpha + alphaIncrement ) < endAngle; )
1115 alpha += alphaIncrement;
1121 const VECTOR2D endPoint( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1134 VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1136 unsigned int lineCount = 0;
1138 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1141 if( alpha != endAngle )
1146 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1148 VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
1155 if( alpha != endAngle )
1157 VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1168 double aWidth,
double aMaxError )
1179 double startAngle = aStartAngle.
AsRadians();
1180 double endAngle = startAngle + aAngle.
AsRadians();
1188 double alphaIncrement = 2.0 *
M_PI / segCount360;
1193 int seg_count =
KiROUND( ( endAngle - startAngle ) / alphaIncrement );
1195 if( seg_count % 2 != 0 )
1199 if( seg_count == 0 )
1201 VECTOR2D p_start( aCenterPoint.
x + cos( startAngle ) * aRadius,
1202 aCenterPoint.
y + sin( startAngle ) * aRadius );
1204 VECTOR2D p_end( aCenterPoint.
x + cos( endAngle ) * aRadius,
1205 aCenterPoint.
y + sin( endAngle ) * aRadius );
1212 alphaIncrement = ( endAngle - startAngle ) / seg_count;
1222 double width = aWidth / 2.0;
1223 VECTOR2D startPoint( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1224 VECTOR2D endPoint( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1229 VECTOR2D pOuter( cos( startAngle ) * ( aRadius + width ),
1230 sin( startAngle ) * ( aRadius + width ) );
1232 VECTOR2D pInner( cos( startAngle ) * ( aRadius - width ),
1233 sin( startAngle ) * ( aRadius - width ) );
1237 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1239 VECTOR2D pNextOuter( cos( alpha ) * ( aRadius + width ),
1240 sin( alpha ) * ( aRadius + width ) );
1241 VECTOR2D pNextInner( cos( alpha ) * ( aRadius - width ),
1242 sin( alpha ) * ( aRadius - width ) );
1247 pOuter = pNextOuter;
1248 pInner = pNextInner;
1252 if( alpha != endAngle )
1254 VECTOR2D pLastOuter( cos( endAngle ) * ( aRadius + width ),
1255 sin( endAngle ) * ( aRadius + width ) );
1256 VECTOR2D pLastInner( cos( endAngle ) * ( aRadius - width ),
1257 sin( endAngle ) * ( aRadius - width ) );
1269 VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
1274 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1280 if( alpha != endAngle )
1287 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1289 VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
1296 if( alpha != endAngle )
1298 VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
1310 if( aMajorRadius <= 0 || aMinorRadius <= 0 )
1313 const double alphaIncrement =
calcAngleStep( aMajorRadius );
1314 const double cosPhi = std::cos( aRotation.
AsRadians() );
1315 const double sinPhi = std::sin( aRotation.
AsRadians() );
1317 auto eval = [&](
double theta ) ->
VECTOR2D
1319 const double lx = aMajorRadius * std::cos( theta );
1320 const double ly = aMinorRadius * std::sin( theta );
1321 return VECTOR2D( lx * cosPhi - ly * sinPhi, lx * sinPhi + ly * cosPhi );
1334 for( alpha = 0.0; ( alpha + alphaIncrement ) < 2.0 *
M_PI; )
1337 alpha += alphaIncrement;
1361 unsigned int lineCount = 0;
1364 for( countAlpha = alphaIncrement; countAlpha < 2.0 *
M_PI; countAlpha += alphaIncrement )
1374 for( alpha = alphaIncrement; alpha < 2.0 *
M_PI; alpha += alphaIncrement )
1376 const VECTOR2D p_next = eval( alpha );
1392 if( aMajorRadius <= 0 || aMinorRadius <= 0 )
1395 double startAngle = aStartAngle.
AsRadians();
1396 double endAngle = aEndAngle.
AsRadians();
1399 const double alphaIncrement =
calcAngleStep( aMajorRadius );
1400 const double cosPhi = std::cos( aRotation.
AsRadians() );
1401 const double sinPhi = std::sin( aRotation.
AsRadians() );
1403 auto eval = [&](
double theta ) ->
VECTOR2D
1405 const double lx = aMajorRadius * std::cos( theta );
1406 const double ly = aMinorRadius * std::sin( theta );
1407 return VECTOR2D( lx * cosPhi - ly * sinPhi, lx * sinPhi + ly * cosPhi );
1421 for( alpha = startAngle; ( alpha + alphaIncrement ) < endAngle; )
1424 alpha += alphaIncrement;
1435 const VECTOR2D p2 = eval( endAngle );
1447 unsigned int lineCount = 0;
1450 for( countAlpha = startAngle + alphaIncrement; countAlpha <= endAngle; countAlpha += alphaIncrement )
1453 if( countAlpha != endAngle )
1461 for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
1463 const VECTOR2D p_next = eval( alpha );
1469 if( alpha != endAngle )
1471 const VECTOR2D p_last = eval( endAngle );
1483 VECTOR2D diagonalPointA( aEndPoint.
x, aStartPoint.
y );
1484 VECTOR2D diagonalPointB( aStartPoint.
x, aEndPoint.
y );
1510 if( aStartPoint == aEndPoint )
1516 std::deque<VECTOR2D> pointList;
1518 pointList.push_back( aStartPoint );
1519 pointList.push_back( diagonalPointA );
1520 pointList.push_back( aEndPoint );
1521 pointList.push_back( diagonalPointB );
1522 pointList.push_back( aStartPoint );
1534 return aPointList[idx];
1536 aPointList.size(), aWidth );
1550 return aLineChain.
CPoint( idx );
1552 numPoints, aWidth );
1561 return aPointList[idx];
1563 aPointList.size() );
1572 return aPointList[idx];
1574 aPointList.size() );
1583 return aPointList[idx];
1599 return aLineChain.
CPoint( idx );
1607 int lineQuadCount = 0;
1609 for(
const std::vector<VECTOR2D>& points : aPointList )
1610 lineQuadCount += points.size() - 1;
1614 for(
const std::vector<VECTOR2D>& points : aPointList )
1621 points.size(),
false );
1628 wxCHECK( aPointList.size() >= 2, );
1629 auto points = std::unique_ptr<GLdouble[]>(
new GLdouble[3 * aPointList.size()] );
1630 GLdouble* ptr = points.get();
1632 for(
const VECTOR2D& p : aPointList )
1645 wxCHECK( aListSize >= 2, );
1646 auto points = std::unique_ptr<GLdouble[]>(
new GLdouble[3 * aListSize] );
1647 GLdouble* target = points.get();
1650 for(
int i = 0; i < aListSize; ++i )
1663 bool aStrokeTriangulation )
1670 int totalTriangleCount = 0;
1685 for(
size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
1688 triPoly->GetTriangle( i, a, b, c );
1700 const auto& poly = aPolySet.
Polygon( j );
1702 for(
const auto& lc : poly )
1711 aStrokeTriangulation =
true;
1715 if( aStrokeTriangulation )
1724 for(
size_t i = 0; i < triPoly->GetTriangleCount(); i++ )
1727 triPoly->GetTriangle( i, a, b, c );
1759 std::unique_ptr<GLdouble[]> points(
new GLdouble[3 * pointCount] );
1760 GLdouble* ptr = points.get();
1762 for(
int i = 0; i < pointCount; ++i )
1776 double aFilterValue )
1778 std::vector<VECTOR2D>
output;
1779 std::vector<VECTOR2D> pointCtrl;
1781 pointCtrl.push_back( aStartPoint );
1782 pointCtrl.push_back( aControlPointA );
1783 pointCtrl.push_back( aControlPointB );
1784 pointCtrl.push_back( aEndPoint );
1798 GLfloat alpha = std::clamp( alphaBlend, 0.0, 1.0 );
1808 glm::vec4 v0 = xform * glm::vec4( -w / 2, -h / 2, 0.0, 0.0 );
1809 glm::vec4
v1 = xform * glm::vec4( w / 2, h / 2, 0.0, 0.0 );
1810 glm::vec4 trans = xform[3];
1814 if( !glIsTexture( texture_id ) )
1817 GLboolean depthMask = GL_TRUE;
1818 glGetBooleanv( GL_DEPTH_WRITEMASK, &depthMask );
1821 glDepthMask( GL_FALSE );
1823 glDepthFunc( GL_ALWAYS );
1825 glAlphaFunc( GL_GREATER, 0.01f );
1826 glEnable( GL_ALPHA_TEST );
1828 glMatrixMode( GL_TEXTURE );
1830 glTranslated( 0.5, 0.5, 0.5 );
1832 glTranslated( -0.5, -0.5, -0.5 );
1834 glMatrixMode( GL_MODELVIEW );
1836 glTranslated( trans.x, trans.y, trans.z );
1838 glEnable( GL_TEXTURE_2D );
1839 glActiveTexture( GL_TEXTURE0 );
1840 glBindTexture( GL_TEXTURE_2D, texture_id );
1842 float texStartX = aBitmap.
IsMirroredX() ? 1.0 : 0.0;
1843 float texEndX = aBitmap.
IsMirroredX() ? 0.0 : 1.0;
1844 float texStartY = aBitmap.
IsMirroredY() ? 1.0 : 0.0;
1845 float texEndY = aBitmap.
IsMirroredY() ? 0.0 : 1.0;
1847 glBegin( GL_QUADS );
1848 glColor4f( 1.0, 1.0, 1.0, alpha );
1849 glTexCoord2f( texStartX, texStartY );
1851 glColor4f( 1.0, 1.0, 1.0, alpha );
1852 glTexCoord2f( texEndX, texStartY);
1854 glColor4f( 1.0, 1.0, 1.0, alpha );
1855 glTexCoord2f( texEndX, texEndY);
1857 glColor4f( 1.0, 1.0, 1.0, alpha );
1858 glTexCoord2f( texStartX, texEndY);
1862 glBindTexture( GL_TEXTURE_2D, 0 );
1864#ifdef DISABLE_BITMAP_CACHE
1865 glDeleteTextures( 1, &texture_id );
1870 glMatrixMode( GL_TEXTURE );
1872 glMatrixMode( GL_MODELVIEW );
1874 glDisable( GL_ALPHA_TEST );
1876 glDepthMask( depthMask );
1878 glDepthFunc( GL_LESS );
1887 || aText.Contains( wxT(
"^{" ) )
1888 || aText.Contains( wxT(
"_{" ) )
1889 || aText.Contains( wxT(
"\n" ) ) )
1900 double overbarHeight = textSize.
y;
1931 wxFAIL_MSG( wxT(
"Indeterminate state legal only in dialogs." ) );
1947 overbarHeight = -textSize.
y / 2.0;
1951 wxFAIL_MSG( wxT(
"Indeterminate state legal only in dialogs." ) );
1955 int overbarLength = 0;
1956 int overbarDepth = -1;
1957 int braceNesting = 0;
1959 auto iterateString =
1960 [&](
const std::function<void(
int aOverbarLength,
int aOverbarHeight )>& overbarFn,
1961 const std::function<int(
unsigned long aChar )>& bitmapCharFn )
1965 wxASSERT_MSG( *chIt !=
'\n' && *chIt !=
'\r',
1966 "No support for multiline bitmap text yet" );
1968 if( *chIt ==
'~' && overbarDepth == -1 )
1972 if( ++lookahead !=
end && *lookahead ==
'{' )
1975 overbarDepth = braceNesting;
1980 else if( *chIt ==
'{' )
1984 else if( *chIt ==
'}' )
1986 if( braceNesting > 0 )
1989 if( braceNesting == overbarDepth )
1991 overbarFn( overbarLength, overbarHeight );
1999 if( overbarDepth != -1 )
2000 overbarLength += bitmapCharFn( *chIt );
2002 bitmapCharFn( *chIt );
2009 int overbarsCount = 0;
2012 [&overbarsCount](
int aOverbarLength,
int aOverbarHeight )
2016 [&charsCount](
unsigned long aChar ) ->
int
2032 [&](
int aOverbarLength,
int aOverbarHeight )
2036 [&](
unsigned long aChar ) ->
int
2044 if( overbarDepth != -1 && overbarLength > 0 )
2059 float minorLineWidth = std::fmax( 1.0f,
2061 float majorLineWidth = minorLineWidth * 2.0f;
2105 glDisable( GL_DEPTH_TEST );
2106 glDisable( GL_TEXTURE_2D );
2110 glEnable( GL_STENCIL_TEST );
2111 glStencilFunc( GL_ALWAYS, 1, 1 );
2112 glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
2113 glColor4d( 0.0, 0.0, 0.0, 0.0 );
2125 for(
int j = gridStartY; j <= gridEndY; j++ )
2131 for(
int i = gridStartX; i <= gridEndX; i++ )
2134 SetLineWidth( ( ( tickX && tickY ) ? majorLineWidth : minorLineWidth ) );
2148 for(
int j = gridStartY; j <= gridEndY; j++ )
2167 glStencilFunc( GL_NOTEQUAL, 0, 1 );
2173 for(
int i = gridStartX; i <= gridEndX; i++ )
2190 glDisable( GL_STENCIL_TEST );
2194 glEnable( GL_DEPTH_TEST );
2195 glEnable( GL_TEXTURE_2D );
2205 m_compositor->Resize( aWidth * scaleFactor, aHeight * scaleFactor );
2208 wxGLCanvas::SetSize( aWidth, aHeight );
2214 bool s = wxGLCanvas::Show( aShow );
2217 wxGLCanvas::Raise();
2235 glClearColor( 0, 0, 0, 1 );
2236 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
2242 GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
2244 matrixData[0] = aTransformation.
m_data[0][0];
2245 matrixData[1] = aTransformation.
m_data[1][0];
2246 matrixData[2] = aTransformation.
m_data[2][0];
2247 matrixData[4] = aTransformation.
m_data[0][1];
2248 matrixData[5] = aTransformation.
m_data[1][1];
2249 matrixData[6] = aTransformation.
m_data[2][1];
2250 matrixData[12] = aTransformation.
m_data[0][2];
2251 matrixData[13] = aTransformation.
m_data[1][2];
2252 matrixData[14] = aTransformation.
m_data[2][2];
2254 glMultMatrixd( matrixData );
2292 std::shared_ptr<VERTEX_ITEM> newItem = std::make_shared<VERTEX_ITEM>( *
m_cachedManager );
2294 m_groups.insert( std::make_pair( groupNumber, newItem ) );
2423 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::StartDiffLayer() called" ) );
2430 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): setting target to TARGET_TEMP" ) );
2437 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): TARGET_TEMP set and cleared, compositor buffer=%u" ),
2442 wxLogTrace(
traceGalXorMode, wxT(
"StartDiffLayer(): WARNING - no temp buffer!" ) );
2449 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::EndDiffLayer() called" ) );
2450 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): m_tempBuffer=%u, m_mainBuffer=%u" ),
2455 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): using temp buffer path" ) );
2460 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): calling DrawBufferDifference" ) );
2468 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): DrawBufferDifference returned" ) );
2472 wxLogTrace(
traceGalXorMode, wxT(
"EndDiffLayer(): NO temp buffer, using fallback path" ) );
2475 glBlendFunc( GL_SRC_ALPHA, GL_ONE );
2477 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
2480 wxLogTrace(
traceGalXorMode, wxT(
"OPENGL_GAL::EndDiffLayer() complete" ) );
2492#if wxCHECK_VERSION( 3, 3, 0 )
2504#if wxCHECK_VERSION( 3, 3, 0 )
2523 const bool aReserve )
2541 * glm::vec4( aStartPoint.
x, aStartPoint.
y, 0.0, 0.0 );
2543 * glm::vec4( aEndPoint.
x, aEndPoint.
y, 0.0, 0.0 );
2627 double outerRadius = aRadius + (
m_lineWidth / 2 );
2673 GLdouble* point = aPoints;
2675 for(
int i = 0; i < aPointCount; ++i )
2693 return VECTOR2D( aPoints[idx * 3], aPoints[idx * 3 + 1] );
2703 wxCHECK( aPointCount > 0, );
2707 if( aPointCount == 1 )
2709 drawLineQuad( aPointGetter( 0 ), aPointGetter( 0 ), aReserve );
2718 for(
int i = 1; i < aPointCount; ++i )
2720 auto start = aPointGetter( i - 1 );
2721 auto end = aPointGetter( i );
2729 int aPointCount,
double aWidth,
bool aReserve )
2731 wxCHECK( aPointCount >= 2, );
2737 for(
int i = 1; i < aPointCount; ++i )
2739 auto start = aPointGetter( i - 1 );
2740 auto end = aPointGetter( i );
2742 float startx = start.x;
2743 float starty = start.y;
2752 if( startx == endx && starty == endy )
2764 vertices += 6 + 6 + 3 + 3;
2770 for(
int i = 1; i < aPointCount; ++i )
2772 auto start = aPointGetter( i - 1 );
2773 auto end = aPointGetter( i );
2792 double spaceWidth = g->
advance * 0.74;
2810 const float XOFF = glyph->
minx;
2813 const float round_adjust = ( glyph->
maxy - glyph->
miny )
2816 const float YOFF = round_adjust + top_adjust;
2865 const float H = glyph->
maxy - glyph->
miny;
2895 float commonOffset = std::numeric_limits<float>::max();
2897 int overbarDepth = -1;
2898 int braceNesting = 0;
2902 if( *chIt ==
'~' && overbarDepth == -1 )
2906 if( ++lookahead !=
end && *lookahead ==
'{' )
2909 overbarDepth = braceNesting;
2914 else if( *chIt ==
'{' )
2918 else if( *chIt ==
'}' )
2920 if( braceNesting > 0 )
2923 if( braceNesting == overbarDepth )
2933 || *chIt ==
'-' || *chIt ==
'_' )
2935 glyph = defaultGlyph;
2942 textSize.
y = std::max<float>( textSize.
y, charHeight );
2944 textSize.
y -= commonOffset;
2946 return std::make_pair( textSize, commonOffset );
2990 const int cursorSize = 80;
2997 GLboolean depthTestEnabled = glIsEnabled( GL_DEPTH_TEST );
2998 glDisable( GL_DEPTH_TEST );
3000 glActiveTexture( GL_TEXTURE0 );
3001 glDisable( GL_TEXTURE_2D );
3002 glEnable( GL_BLEND );
3003 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
3006 glColor4d( color.
r, color.
g, color.
b, color.
a );
3008 glMatrixMode( GL_PROJECTION );
3010 glTranslated( 0, 0, -0.5 );
3012 glBegin( GL_LINES );
3027 double offset1 = cy - cx;
3028 VECTOR2D pos_start( screenTopLeft.
x, screenTopLeft.
x + offset1 );
3029 VECTOR2D pos_end( screenBottomRight.
x, screenBottomRight.
x + offset1 );
3032 glVertex2d( pos_start.
x, pos_start.
y );
3033 glVertex2d( pos_end.
x, pos_end.
y );
3036 double offset2 = cy + cx;
3037 VECTOR2D neg_start( screenTopLeft.
x, offset2 - screenTopLeft.
x );
3038 VECTOR2D neg_end( screenBottomRight.
x, offset2 - screenBottomRight.
x );
3041 glVertex2d( neg_start.
x, neg_start.
y );
3042 glVertex2d( neg_end.
x, neg_end.
y );
3046 glVertex2d( cursorCenter.
x, cursorBegin.
y );
3047 glVertex2d( cursorCenter.
x, cursorEnd.
y );
3049 glVertex2d( cursorBegin.
x, cursorCenter.
y );
3050 glVertex2d( cursorEnd.
x, cursorCenter.
y );
3057 if( depthTestEnabled )
3058 glEnable( GL_DEPTH_TEST );
3064 wxASSERT_MSG(
m_groups.size() < std::numeric_limits<unsigned int>::max(),
3065 wxT(
"There are no free slots to store a group" ) );
3076 wxASSERT_MSG(
m_isContextLocked,
"This should only be called from within a locked context." );
3080 throw std::runtime_error(
"Could not create the tesselator" );
3084 int glVersion = gladLoaderLoadGL();
3086 if( glVersion == 0 )
3087 throw std::runtime_error(
"Failed to load OpenGL via loader" );
3089 const char* vendor = (
const char*) glGetString( GL_VENDOR );
3090 const char* renderer = (
const char*) glGetString( GL_RENDERER );
3091 const char* version = (
const char*) glGetString( GL_VERSION );
3094 throw std::runtime_error(
"No GL context is current (glGetString returned NULL)" );
3099 if( !GLAD_GL_VERSION_2_1 )
3100 throw std::runtime_error(
"OpenGL 2.1 or higher is required!" );
3102#if defined( __LINUX__ )
3104 if( glDebugMessageCallback )
3110 if( !GLAD_GL_ARB_framebuffer_object )
3111 throw std::runtime_error(
"Framebuffer objects are not supported!" );
3114 if( !GLAD_GL_ARB_vertex_buffer_object )
3115 throw std::runtime_error(
"Vertex buffer objects are not supported!" );
3120 BUILTIN_SHADERS::glsl_kicad_vert ) )
3122 throw std::runtime_error(
"Cannot compile vertex shader!" );
3127 BUILTIN_SHADERS::glsl_kicad_frag ) )
3129 throw std::runtime_error(
"Cannot compile fragment shader!" );
3133 throw std::runtime_error(
"Cannot link the shaders!" );
3140 glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxTextureSize );
3146 throw std::runtime_error(
"Requested texture size is not supported" );
3149#if wxCHECK_VERSION( 3, 3, 3 )
3150 wxGLCanvas::SetSwapInterval( -1 );
3187 GLdouble* vertex =
static_cast<GLdouble*
>( aVertexPtr );
3191 assert( vboManager );
3192 vboManager->
Vertex( vertex[0], vertex[1], vertex[2] );
3197 GLdouble** dataOut,
void* aData )
3199 GLdouble* vertex =
new GLdouble[3];
3205 param->
intersectPoints.emplace_back( vertex, std::default_delete<GLdouble[]>() );
3207 memcpy( vertex, coords, 3 *
sizeof( GLdouble ) );
3245 return ( ceil( f / r ) - 0.5 ) * r;
3278 outlineGlyph.Triangulate(
3293 if( aGlyphs.empty() )
3296 bool allGlyphsAreStroke =
true;
3297 bool allGlyphsAreOutline =
true;
3299 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3301 if( !glyph->IsStroke() )
3303 allGlyphsAreStroke =
false;
3308 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3310 if( !glyph->IsOutline() )
3312 allGlyphsAreOutline =
false;
3317 if( allGlyphsAreStroke )
3320 int lineQuadCount = 0;
3322 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3326 for(
const std::vector<VECTOR2D>& points : strokeGlyph )
3327 lineQuadCount += points.size() - 1;
3332 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3336 for(
const std::vector<VECTOR2D>& points : strokeGlyph )
3343 points.size(),
false );
3349 else if( allGlyphsAreOutline )
3352 int triangleCount = 0;
3354 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3358 for(
unsigned int i = 0; i < outlineGlyph.TriangulatedPolyCount(); i++ )
3361 outlineGlyph.TriangulatedPolygon( i );
3372 for(
const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
3376 for(
unsigned int i = 0; i < outlineGlyph.TriangulatedPolyCount(); i++ )
3379 outlineGlyph.TriangulatedPolygon( i );
3396 for(
size_t i = 0; i < aGlyphs.size(); i++ )
3397 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)