KiCad PCB EDA Suite
opengl_gal.h
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KICAD, a free EDA CAD application.
3  *
4  * Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
5  * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  * Copyright (C) 2013-2017 CERN
7  * @author Maciej Suminski <[email protected]>
8  *
9  * Graphics Abstraction Layer (GAL) for OpenGL
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, you may find one here:
23  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
24  * or you may search the http://www.gnu.org website for the version 2 license,
25  * or you may write to the Free Software Foundation, Inc.,
26  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27  */
28 
29 #ifndef OPENGLGAL_H_
30 #define OPENGLGAL_H_
31 
32 // GAL imports
35 #include <gal/opengl/shader.h>
37 #include <gal/opengl/vertex_item.h>
41 #include <gal/hidpi_gl_canvas.h>
42 
43 #include <unordered_map>
44 #include <boost/smart_ptr/shared_array.hpp>
45 #include <memory>
46 #include <wx/event.h>
47 
48 #ifndef CALLBACK
49 #define CALLBACK
50 #endif
51 
53 #define SEG_PER_CIRCLE_COUNT 64
54 
55 struct bitmap_glyph;
56 
57 namespace KIGFX
58 {
59 class SHADER;
60 class GL_BITMAP_CACHE;
61 
62 
70 class OPENGL_GAL : public GAL, public HIDPI_GL_CANVAS
71 {
72 public:
86  OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
87  wxEvtHandler* aMouseListener = nullptr, wxEvtHandler* aPaintListener = nullptr,
88  const wxString& aName = wxT( "GLCanvas" ) );
89 
90  ~OPENGL_GAL();
91 
98  static wxString CheckFeatures( GAL_DISPLAY_OPTIONS& aOptions );
99 
100  bool IsOpenGlEngine() override { return true; }
101 
103  bool IsInitialized() const override
104  {
105  // is*Initialized flags, but it is enough for OpenGL to show up
106  return IsShownOnScreen() && !GetClientRect().IsEmpty();
107  }
108 
110  bool IsVisible() const override
111  {
112  return IsShownOnScreen() && !GetClientRect().IsEmpty();
113  }
114 
115  // ---------------
116  // Drawing methods
117  // ---------------
118 
120  void DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) override;
121 
123  void DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint,
124  double aWidth ) override;
125 
127  void DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) override;
128 
130  void DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
131  double aStartAngle, double aEndAngle ) override;
132 
134  void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
135  double aStartAngle, double aEndAngle, double aWidth,
136  double aMaxError ) override;
137 
139  void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) override;
140 
142  void DrawPolyline( const std::deque<VECTOR2D>& aPointList ) override;
143  void DrawPolyline( const VECTOR2D aPointList[], int aListSize ) override;
144  void DrawPolyline( const SHAPE_LINE_CHAIN& aLineChain ) override;
145 
147  void DrawPolygon( const std::deque<VECTOR2D>& aPointList ) override;
148  void DrawPolygon( const VECTOR2D aPointList[], int aListSize ) override;
149  void DrawPolygon( const SHAPE_POLY_SET& aPolySet, bool aStrokeTriangulation = false ) override;
150  void DrawPolygon( const SHAPE_LINE_CHAIN& aPolySet ) override;
151 
153  void DrawCurve( const VECTOR2D& startPoint, const VECTOR2D& controlPointA,
154  const VECTOR2D& controlPointB, const VECTOR2D& endPoint,
155  double aFilterValue = 0.0 ) override;
156 
158  void DrawBitmap( const BITMAP_BASE& aBitmap ) override;
159 
161  void BitmapText( const wxString& aText, const VECTOR2D& aPosition,
162  double aRotationAngle ) override;
163 
165  void DrawGrid() override;
166 
167  // --------------
168  // Screen methods
169  // --------------
170 
172  void ResizeScreen( int aWidth, int aHeight ) override;
173 
175  bool Show( bool aShow ) override;
176 
178  void Flush() override;
179 
181  void ClearScreen( ) override;
182 
183  // --------------
184  // Transformation
185  // --------------
186 
188  void Transform( const MATRIX3x3D& aTransformation ) override;
189 
191  void Rotate( double aAngle ) override;
192 
194  void Translate( const VECTOR2D& aTranslation ) override;
195 
197  void Scale( const VECTOR2D& aScale ) override;
198 
200  void Save() override;
201 
203  void Restore() override;
204 
205  // --------------------------------------------
206  // Group methods
207  // ---------------------------------------------
208 
210  int BeginGroup() override;
211 
213  void EndGroup() override;
214 
216  void DrawGroup( int aGroupNumber ) override;
217 
219  void ChangeGroupColor( int aGroupNumber, const COLOR4D& aNewColor ) override;
220 
222  void ChangeGroupDepth( int aGroupNumber, int aDepth ) override;
223 
225  void DeleteGroup( int aGroupNumber ) override;
226 
228  void ClearCache() override;
229 
230  // --------------------------------------------------------
231  // Handling the world <-> screen transformation
232  // --------------------------------------------------------
233 
235  void SetTarget( RENDER_TARGET aTarget ) override;
236 
238  RENDER_TARGET GetTarget() const override;
239 
241  void ClearTarget( RENDER_TARGET aTarget ) override;
242 
244  virtual bool HasTarget( RENDER_TARGET aTarget ) override;
245 
247  void SetNegativeDrawMode( bool aSetting ) override {}
248 
250  void StartDiffLayer() override;
251  //
253  void EndDiffLayer() override;
254 
255  void ComputeWorldScreenMatrix() override;
256 
257  // -------
258  // Cursor
259  // -------
260 
262  bool SetNativeCursorStyle( KICURSOR aCursor ) override;
263 
265  void DrawCursor( const VECTOR2D& aCursorPosition ) override;
266 
273  void PostPaint( wxPaintEvent& aEvent );
274 
275  void SetMouseListener( wxEvtHandler* aMouseListener )
276  {
277  m_mouseListener = aMouseListener;
278  }
279 
280  void SetPaintListener( wxEvtHandler* aPaintListener )
281  {
282  m_paintListener = aPaintListener;
283  }
284 
285  void EnableDepthTest( bool aEnabled = false ) override;
286 
287  bool IsContextLocked() override
288  {
289  return m_isContextLocked;
290  }
291 
292  void LockContext( int aClientCookie ) override;
293 
294  void UnlockContext( int aClientCookie ) override;
295 
297  void BeginDrawing() override;
298 
300  void EndDrawing() override;
301 
303  struct TessParams
304  {
307 
309  std::deque< boost::shared_array<GLdouble> >& intersectPoints;
310  };
311 
312 private:
314  typedef GAL super;
315 
316  static wxGLContext* m_glMainContext;
317  wxGLContext* m_glPrivContext;
318  static int m_instanceCounter;
319  wxEvtHandler* m_mouseListener;
320  wxEvtHandler* m_paintListener;
321 
322  static GLuint g_fontTexture;
323 
324  // Vertex buffer objects related fields
325  typedef std::unordered_map< unsigned int, std::shared_ptr<VERTEX_ITEM> > GROUPS_MAP;
326 
328  unsigned int m_groupCounter;
335 
336  // Framebuffer & compositing
338  unsigned int m_mainBuffer;
339  unsigned int m_overlayBuffer;
340  unsigned int m_tempBuffer;
342 
343  // Shader
345 
347  // Internal flags
349  static bool m_isBitmapFontLoaded;
352  bool m_isGrouping;
360 
361  wxCursor m_currentwxCursor;
362 
363  std::unique_ptr<GL_BITMAP_CACHE> m_bitmapCache;
364 
365  // Polygon tesselation
366  GLUtesselator* m_tesselator;
367  std::deque< boost::shared_array<GLdouble> > m_tessIntersects;
368 
370  void beginUpdate() override;
371 
373  void endUpdate() override;
374 
376  bool updatedGalDisplayOptions( const GAL_DISPLAY_OPTIONS& aOptions ) override;
377 
384  void drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
385 
397  void drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
398 
407  void drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
408 
417  void drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
418 
425  void drawPolyline( const std::function<VECTOR2D (int)>& aPointGetter, int aPointCount );
426 
434  void drawPolygon( GLdouble* aPoints, int aPointCount );
435 
442  void drawTriangulatedPolyset( const SHAPE_POLY_SET& aPoly, bool aStrokeTriangulation );
443 
444 
453  int drawBitmapChar( unsigned long aChar );
454 
465  void drawBitmapOverbar( double aLength, double aHeight );
466 
474  std::pair<VECTOR2D, float> computeBitmapTextSize( const UTF8& aText ) const;
475 
476  // Event handling
482  void onPaint( wxPaintEvent& aEvent );
483 
489  void skipMouseEvent( wxMouseEvent& aEvent );
490 
496  void onSetNativeCursor( wxSetCursorEvent& aEvent );
497 
501  void blitCursor();
502 
508  unsigned int getNewGroupNumber();
509 
513  double calcAngleStep( double aRadius ) const
514  {
515  // Bigger arcs need smaller alpha increment to make them look smooth
516  return std::min( 1e6 / aRadius, 2.0 * M_PI / SEG_PER_CIRCLE_COUNT );
517  }
518 
519  double getWorldPixelSize() const;
520 
522 
528  void init();
529 };
530 } // namespace KIGFX
531 
532 #endif // OPENGLGAL_H_
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:70
void onSetNativeCursor(wxSetCursorEvent &aEvent)
Give the correct cursor image when the native widget asks for it.
void beginUpdate() override
Definition: opengl_gal.cpp:662
void LockContext(int aClientCookie) override
Use GAL_CONTEXT_LOCKER RAII object unless you know what you're doing.
Definition: opengl_gal.cpp:638
unsigned int m_overlayBuffer
Auxiliary rendering target (for menus etc.)
Definition: opengl_gal.h:339
GROUPS_MAP m_groups
Stores information about VBO objects (groups)
Definition: opengl_gal.h:327
void DrawBitmap(const BITMAP_BASE &aBitmap) override
Draw a bitmap image.
wxEvtHandler * m_paintListener
Definition: opengl_gal.h:320
static bool m_isBitmapFontLoaded
Is the bitmap font texture loaded?
Definition: opengl_gal.h:349
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:243
std::deque< boost::shared_array< GLdouble > > & intersectPoints
Intersect points, that have to be freed after tessellation.
Definition: opengl_gal.h:309
void Scale(const VECTOR2D &aScale) override
Scale the context.
void ClearTarget(RENDER_TARGET aTarget) override
Clear the target for rendering.
static int m_instanceCounter
GL GAL instance counter.
Definition: opengl_gal.h:318
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 Translate(const VECTOR2D &aTranslation) override
Translate the context.
void drawPolygon(GLdouble *aPoints, int aPointCount)
Draw a filled polygon.
void EndDiffLayer() override
Ends rendering of a differential layer.
VERTEX_MANAGER * m_overlayManager
Container for storing overlaid VERTEX_ITEMs.
Definition: opengl_gal.h:333
void drawLineQuad(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a quad for the line.
void EndDrawing() override
End the drawing, needs to be called for every new frame.
Definition: opengl_gal.cpp:580
std::deque< boost::shared_array< GLdouble > > m_tessIntersects
Definition: opengl_gal.h:367
OpenGL implementation of the Graphics Abstraction Layer.
Definition: opengl_gal.h:70
VECTOR2D getScreenPixelSize() const
Definition: opengl_gal.cpp:411
void ComputeWorldScreenMatrix() override
Compute the world <-> screen transformation matrix.
void Restore() override
Restore the context.
void ChangeGroupDepth(int aGroupNumber, int aDepth) override
Change the depth (Z-axis position) of the group.
void EnableDepthTest(bool aEnabled=false) override
wxGLCanvas wrapper for HiDPI/Retina support.
int BeginGroup() override
Begin a group.
void DrawPolygon(const std::deque< VECTOR2D > &aPointList) override
Draw a polygon.
void SetPaintListener(wxEvtHandler *aPaintListener)
Definition: opengl_gal.h:280
KICURSOR
Definition: cursors.h:33
unsigned int m_mainBuffer
Main rendering target.
Definition: opengl_gal.h:338
void StartDiffLayer() override
Begins rendering of a differential layer.
Handle multitarget rendering (ie.
VERTEX_MANAGER * m_cachedManager
Container for storing cached VERTEX_ITEMs.
Definition: opengl_gal.h:331
std::unordered_map< unsigned int, std::shared_ptr< VERTEX_ITEM > > GROUPS_MAP
Definition: opengl_gal.h:325
bool IsInitialized() const override
Return the initialization status for the canvas.
Definition: opengl_gal.h:103
OPENGL_GAL(GAL_DISPLAY_OPTIONS &aDisplayOptions, wxWindow *aParent, wxEvtHandler *aMouseListener=nullptr, wxEvtHandler *aPaintListener=nullptr, const wxString &aName=wxT("GLCanvas"))
Definition: opengl_gal.cpp:195
void ResizeScreen(int aWidth, int aHeight) override
Resizes the canvas.
void Transform(const MATRIX3x3D &aTransformation) override
Transform the context.
VERTEX_MANAGER * vboManager
Manager used for storing new vertices.
Definition: opengl_gal.h:306
double getWorldPixelSize() const
Definition: opengl_gal.cpp:404
RENDER_TARGET m_currentTarget
Current rendering target.
Definition: opengl_gal.h:341
RENDER_TARGET GetTarget() const override
Get the currently used target for rendering.
This class handle bitmap images in KiCad.
Definition: bitmap_base.h:51
wxEvtHandler * m_mouseListener
Definition: opengl_gal.h:319
void endUpdate() override
Definition: opengl_gal.cpp:678
bool SetNativeCursorStyle(KICURSOR aCursor) override
Set the cursor in the native panel.
void Save() override
Save the context.
void init()
Basic OpenGL initialization and feature checks.
void DrawArcSegment(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle, double aWidth, double aMaxError) override
Draw an arc segment.
Definition: opengl_gal.cpp:875
VERTEX_MANAGER * m_currentManager
Currently used VERTEX_MANAGER (for storing VERTEX_ITEMs).
Definition: opengl_gal.h:329
static wxGLContext * m_glMainContext
Parent OpenGL context.
Definition: opengl_gal.h:316
void BeginDrawing() override
Start/end drawing functions, draw calls can be only made in between the calls to BeginDrawing()/EndDr...
Definition: opengl_gal.cpp:419
bool Show(bool aShow) override
Shows/hides the GAL canvas.
void SetMouseListener(wxEvtHandler *aMouseListener)
Definition: opengl_gal.h:275
Represent a set of closed polygons.
void SetNegativeDrawMode(bool aSetting) override
Set negative draw mode in the renderer.
Definition: opengl_gal.h:247
void EndGroup() override
End the group.
void DeleteGroup(int aGroupNumber) override
Delete the group from the memory.
double calcAngleStep(double aRadius) const
Compute the angle step when drawing arcs/circles approximated with lines.
Definition: opengl_gal.h:513
SHADER * m_shader
There is only one shader used for different objects.
Definition: opengl_gal.h:344
bool m_isInitialized
Basic initialization flag, has to be done when the window is visible.
Definition: opengl_gal.h:351
bool updatedGalDisplayOptions(const GAL_DISPLAY_OPTIONS &aOptions) override
Handle updating display options.
Definition: opengl_gal.cpp:375
OPENGL_COMPOSITOR * m_compositor
Handles multiple rendering targets.
Definition: opengl_gal.h:337
void DrawGrid() override
void PostPaint(wxPaintEvent &aEvent)
Function PostPaint posts an event to m_paint_listener.
Definition: opengl_gal.cpp:367
void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint) override
Draw a line.
Definition: opengl_gal.cpp:687
GLUtesselator * m_tesselator
Definition: opengl_gal.h:366
GLint ufm_antialiasingOffset
Definition: opengl_gal.h:359
void onPaint(wxPaintEvent &aEvent)
This is the OnPaint event handler.
GLint ufm_screenPixelSize
Definition: opengl_gal.h:357
void DrawGroup(int aGroupNumber) override
Draw the stored group.
void ClearCache() override
Delete all data created during caching of graphic items.
bool IsOpenGlEngine() override
Return true if the GAL engine is a OpenGL based type.
Definition: opengl_gal.h:100
bool IsContextLocked() override
Checks the state of the context lock.
Definition: opengl_gal.h:287
Provide the access to the OpenGL shaders.
Definition: shader.h:76
GAL super
Super class definition.
Definition: opengl_gal.h:314
void Rotate(double aAngle) override
Rotate the context.
void drawStrokedSemiCircle(const VECTOR2D &aCenterPoint, double aRadius, double aAngle)
Draw a stroked semicircle.
bool m_isContextLocked
Used for assertion checking.
Definition: opengl_gal.h:354
void UnlockContext(int aClientCookie) override
Definition: opengl_gal.cpp:648
void blitCursor()
Blit cursor into the current screen.
static GLuint g_fontTexture
Bitmap font texture handle (shared)
Definition: opengl_gal.h:322
void DrawPolyline(const std::deque< VECTOR2D > &aPointList) override
Draw a polyline.
void DrawSegment(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, double aWidth) override
Draw a rounded segment.
Definition: opengl_gal.cpp:695
GLint ufm_worldPixelSize
Definition: opengl_gal.h:356
void DrawArc(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle) override
Draw an arc.
Definition: opengl_gal.cpp:806
void SetTarget(RENDER_TARGET aTarget) override
Set the target for rendering.
wxGLContext * m_glPrivContext
Canvas-specific OpenGL context.
Definition: opengl_gal.h:317
Class to store instances of VERTEX without caching.
bool m_isFramebufferInitialized
Are the framebuffers initialized?
Definition: opengl_gal.h:348
wxCursor m_currentwxCursor
wxCursor showing the current native cursor
Definition: opengl_gal.h:361
void drawSemiCircle(const VECTOR2D &aCenterPoint, double aRadius, double aAngle)
Draw a semicircle.
static wxString CheckFeatures(GAL_DISPLAY_OPTIONS &aOptions)
Checks OpenGL features.
Definition: opengl_gal.cpp:335
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
Class to handle an item held in a container.
virtual bool HasTarget(RENDER_TARGET aTarget) override
Return true if the target exists.
int drawBitmapChar(unsigned long aChar)
Draw a single character using bitmap font.
unsigned int m_tempBuffer
Temporary rendering target (for diffing etc.)
Definition: opengl_gal.h:340
void ClearScreen() override
Clear the screen.
std::unique_ptr< GL_BITMAP_CACHE > m_bitmapCache
Definition: opengl_gal.h:363
unsigned int getNewGroupNumber()
Return a valid key that can be used as a new group number.
void DrawRectangle(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint) override
Draw a rectangle.
Definition: opengl_gal.cpp:986
#define SEG_PER_CIRCLE_COUNT
Definition: opengl_gal.h:53
void Flush() override
Force all remaining objects to be drawn.
void DrawCursor(const VECTOR2D &aCursorPosition) override
Draw the cursor.
void drawPolyline(const std::function< VECTOR2D(int)> &aPointGetter, int aPointCount)
Generic way of drawing a polyline stored in different containers.
Class to control vertex container and GPU with possibility of emulating old-style OpenGL 1....
VERTEX_MANAGER * m_tempManager
Container for storing temp (diff mode) VERTEX_ITEMs.
Definition: opengl_gal.h:334
unsigned int m_groupCounter
Counter used for generating keys for groups.
Definition: opengl_gal.h:328
std::pair< VECTOR2D, float > computeBitmapTextSize(const UTF8 &aText) const
Compute a size of text drawn using bitmap font with current text setting applied.
RENDER_TARGET
RENDER_TARGET: Possible rendering targets.
Definition: definitions.h:46
void BitmapText(const wxString &aText, const VECTOR2D &aPosition, double aRotationAngle) override
Draw a text using a bitmap font.
bool m_isBitmapFontInitialized
Is the shader set to use bitmap fonts?
Definition: opengl_gal.h:350
VERTEX_MANAGER * m_nonCachedManager
Container for storing non-cached VERTEX_ITEMs.
Definition: opengl_gal.h:332
bool IsVisible() const override
Return true if the GAL canvas is visible on the screen.
Definition: opengl_gal.h:110
GLint ufm_pixelSizeMultiplier
Definition: opengl_gal.h:358
void DrawCircle(const VECTOR2D &aCenterPoint, double aRadius) override
Draw a circle using world coordinates.
Definition: opengl_gal.cpp:749
void skipMouseEvent(wxMouseEvent &aEvent)
Skip the mouse event to the parent.
bool m_isGrouping
Was a group started?
Definition: opengl_gal.h:353
void drawFilledSemiCircle(const VECTOR2D &aCenterPoint, double aRadius, double aAngle)
Draw a filled semicircle.
void drawTriangulatedPolyset(const SHAPE_POLY_SET &aPoly, bool aStrokeTriangulation)
Draw a set of polygons with a cached triangulation.
void ChangeGroupColor(int aGroupNumber, const COLOR4D &aNewColor) override
Change the color used to draw the group.
Abstract interface for drawing on a 2D-surface.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103
void drawBitmapOverbar(double aLength, double aHeight)
Draw an overbar over the currently drawn text.