qwt_plot_opengl_canvas.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Qwt Widget Library
3  * Copyright (C) 1997 Josef Wilgen
4  * Copyright (C) 2002 Uwe Rathmann
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the Qwt License, Version 1.0
8  *****************************************************************************/
9 
10 #include "qwt_plot_opengl_canvas.h"
11 #include "qwt_plot.h"
12 #include "qwt_painter.h"
13 
14 #include <qpainter.h>
15 #include <qpainterpath.h>
16 #include <qcoreevent.h>
17 #include <qopenglframebufferobject.h>
18 #include <qopenglpaintdevice.h>
19 
21 {
22  public:
24  : isPolished( false )
25  , fboDirty( true )
26  , fbo( NULL )
27  {
28  }
29 
31  {
32  delete fbo;
33  }
34 
36 
37  bool isPolished;
38  bool fboDirty;
39  QOpenGLFramebufferObject* fbo;
40 };
41 
49  : QOpenGLWidget( plot )
50  , QwtPlotAbstractGLCanvas( this )
51 {
52  QSurfaceFormat fmt = format();
53  fmt.setSamples( 4 );
54 
55  init( fmt );
56 }
57 
66  const QSurfaceFormat& format, QwtPlot* plot )
67  : QOpenGLWidget( plot )
68  , QwtPlotAbstractGLCanvas( this )
69 {
70  init( format );
71 }
72 
73 void QwtPlotOpenGLCanvas::init( const QSurfaceFormat& format )
74 {
75  m_data = new PrivateData;
76  m_data->numSamples = format.samples();
77 
78  setFormat( format );
79 
80 #if 1
81  setAttribute( Qt::WA_OpaquePaintEvent, true );
82 #endif
83 
84  setLineWidth( 2 );
85  setFrameShadow( QFrame::Sunken );
86  setFrameShape( QFrame::Panel );
87 }
88 
91 {
92  delete m_data;
93 }
94 
102 {
103  if ( m_data->isPolished )
104  QOpenGLWidget::paintEvent( event );
105 }
106 
113 {
114  const bool ok = QOpenGLWidget::event( event );
115 
116  if ( event->type() == QEvent::PolishRequest )
117  {
118  // In opposite to non OpenGL widgets receive pointless
119  // early repaints. As we always have a QEvent::PolishRequest
120  // followed by QEvent::Paint, we can ignore all these repaints.
121 
122  m_data->isPolished = true;
123  }
124 
125  if ( event->type() == QEvent::PolishRequest ||
126  event->type() == QEvent::StyleChange )
127  {
128  // assuming, that we always have a styled background
129  // when we have a style sheet
130 
131  setAttribute( Qt::WA_StyledBackground,
132  testAttribute( Qt::WA_StyleSheet ) );
133  }
134 
135  return ok;
136 }
137 
143 {
145 }
146 
149 {
150  m_data->fboDirty = true;
151 }
152 
154 {
155  delete m_data->fbo;
156  m_data->fbo = NULL;
157 }
158 
168 QPainterPath QwtPlotOpenGLCanvas::borderPath( const QRect& rect ) const
169 {
170  return canvasBorderPath( rect );
171 }
172 
175 {
176 }
177 
180 {
181  const bool hasFocusIndicator =
182  hasFocus() && focusIndicator() == CanvasFocusIndicator;
183 
184  QPainter painter;
185 
187  QOpenGLFramebufferObject::hasOpenGLFramebufferBlit() )
188  {
189  const qreal pixelRatio = QwtPainter::devicePixelRatio( NULL );
190  const QSize fboSize = size() * pixelRatio;
191 
192  if ( hasFocusIndicator )
193  painter.begin( this );
194 
195  /*
196  QOpenGLWidget has its own internal FBO, that is used to restore
197  its content without having to repaint. This works fine when f.e
198  a rubberband is moving on top, but there are still situations,
199  where we can repaint without an potentially expensive replot:
200 
201  - when having the focus the top level window gets activated/deactivated
202  - ???
203  */
204 
205  if ( m_data->fbo )
206  {
207  if ( m_data->fbo->size() != fboSize )
208  {
209  delete m_data->fbo;
210  m_data->fbo = NULL;
211  }
212  }
213 
214  if ( m_data->fbo == NULL )
215  {
216  QOpenGLFramebufferObjectFormat fboFormat;
217  fboFormat.setSamples( m_data->numSamples );
218  fboFormat.setAttachment( QOpenGLFramebufferObject::CombinedDepthStencil );
219 
220  m_data->fbo = new QOpenGLFramebufferObject( fboSize, fboFormat );
221  m_data->fboDirty = true;
222  }
223 
224  if ( m_data->fboDirty )
225  {
226  m_data->fbo->bind();
227 
228  QOpenGLPaintDevice pd( fboSize );
229 
230  QPainter fboPainter( &pd );
231  fboPainter.scale( pixelRatio, pixelRatio );
232  draw( &fboPainter);
233  fboPainter.end();
234 
235  m_data->fboDirty = false;
236  }
237 
238  QOpenGLFramebufferObject::blitFramebuffer( NULL, m_data->fbo );
239  }
240  else
241  {
242  painter.begin( this );
243  draw( &painter );
244  }
245 
246  if ( hasFocusIndicator )
247  drawFocusIndicator( &painter );
248 }
249 
252 {
253  // nothing to do
254 }
255 
256 #if QWT_MOC_INCLUDE
257 #include "moc_qwt_plot_opengl_canvas.cpp"
258 #endif
Paint double buffered reusing the content of the pixmap buffer when possible.
Q_INVOKABLE QPainterPath borderPath(const QRect &) const
void init(const QSurfaceFormat &)
QPainterPath canvasBorderPath(const QRect &rect) const
void draw(QPainter *)
Helper function for the derived plot canvas.
virtual void paintGL() QWT_OVERRIDE
Paint the plot.
virtual void paintEvent(QPaintEvent *) QWT_OVERRIDE
A 2-D plotting widget.
Definition: qwt_plot.h:78
bool testPaintAttribute(PaintAttribute) const
Base class of QwtPlotOpenGLCanvas and QwtPlotGLCanvas.
virtual bool event(QEvent *) QWT_OVERRIDE
Definition: lz4.c:1706
virtual ~QwtPlotOpenGLCanvas()
Destructor.
virtual void resizeGL(int width, int height) QWT_OVERRIDE
No operation - reserved for some potential use in the future.
virtual void clearBackingStore() QWT_OVERRIDE
static qreal devicePixelRatio(const QPaintDevice *)
virtual Q_INVOKABLE void invalidateBackingStore() QWT_OVERRIDE
Invalidate the internal backing store.
FocusIndicator focusIndicator() const
QwtPlot * plot()
Return parent plot widget.
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1485
virtual void initializeGL() QWT_OVERRIDE
No operation - reserved for some potential use in the future.
virtual void drawFocusIndicator(QPainter *)
QwtPlotOpenGLCanvas(QwtPlot *=NULL)
Constructor.
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)
Definition: color.h:583


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Jun 19 2023 03:01:38