Qwt User's Guide: qwt_plot_opengl_canvas.cpp Source File

Qwt User's Guide 6.2.0

qwt_plot_opengl_canvas.cpp
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
20 class QwtPlotOpenGLCanvas::PrivateData
21 {
22 public:
23 PrivateData()
24 : isPolished( false )
25 , fboDirty( true )
26 , fbo( NULL )
27 {
28 }
29
30 ~PrivateData()
31 {
32 delete fbo;
33 }
34
35 int numSamples;
36
37 bool isPolished;
38 bool fboDirty;
39 QOpenGLFramebufferObject* fbo;
40 };
41
48 QwtPlotOpenGLCanvas::QwtPlotOpenGLCanvas( QwtPlot* plot )
49 : QOpenGLWidget( plot )
50 , QwtPlotAbstractGLCanvas( this )
51 {
52 QSurfaceFormat fmt = format();
53 fmt.setSamples( 4 );
54
55 init( fmt );
56 }
57
65 QwtPlotOpenGLCanvas::QwtPlotOpenGLCanvas(
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
90 QwtPlotOpenGLCanvas::~QwtPlotOpenGLCanvas()
91 {
92 delete m_data;
93 }
94
101 void QwtPlotOpenGLCanvas::paintEvent( QPaintEvent* event )
102 {
103 if ( m_data->isPolished )
104 QOpenGLWidget::paintEvent( event );
105 }
106
112 bool QwtPlotOpenGLCanvas::event( QEvent* event )
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
142 void QwtPlotOpenGLCanvas::replot()
143 {
144 QwtPlotAbstractGLCanvas::replot();
145 }
146
148 void QwtPlotOpenGLCanvas::invalidateBackingStore()
149 {
150 m_data->fboDirty = true;
151 }
152
153 void QwtPlotOpenGLCanvas::clearBackingStore()
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
174 void QwtPlotOpenGLCanvas::initializeGL()
175 {
176 }
177
179 void QwtPlotOpenGLCanvas::paintGL()
180 {
181 const bool hasFocusIndicator =
182 hasFocus() && focusIndicator() == CanvasFocusIndicator;
183
184 QPainter painter;
185
186 if ( testPaintAttribute( QwtPlotOpenGLCanvas::BackingStore ) &&
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
251 void QwtPlotOpenGLCanvas::resizeGL( int, int )
252 {
253 // nothing to do
254 }
255
256 #if QWT_MOC_INCLUDE
257 #include "moc_qwt_plot_opengl_canvas.cpp"
258 #endif
QwtPainter::devicePixelRatio
static qreal devicePixelRatio(const QPaintDevice *)
Definition: qwt_painter.cpp:1491
QwtPlotAbstractCanvas::focusIndicator
FocusIndicator focusIndicator() const
Definition: qwt_plot_abstract_canvas.cpp:578
QwtPlotAbstractCanvas::canvasBorderPath
QPainterPath canvasBorderPath(const QRect &rect) const
Definition: qwt_plot_abstract_canvas.cpp:619
QwtPlotAbstractCanvas::drawFocusIndicator
virtual void drawFocusIndicator(QPainter *)
Definition: qwt_plot_abstract_canvas.cpp:587
QwtPlotAbstractCanvas::CanvasFocusIndicator
@ CanvasFocusIndicator
Definition: qwt_plot_abstract_canvas.h:39
QwtPlotAbstractGLCanvas
Base class of QwtPlotOpenGLCanvas and QwtPlotGLCanvas.
Definition: qwt_plot_abstract_canvas.h:88
QwtPlotAbstractGLCanvas::testPaintAttribute
bool testPaintAttribute(PaintAttribute) const
Definition: qwt_plot_abstract_canvas.cpp:952
QwtPlotAbstractGLCanvas::setLineWidth
void setLineWidth(int)
Definition: qwt_plot_abstract_canvas.cpp:1033
QwtPlotAbstractGLCanvas::BackingStore
@ BackingStore
Paint double buffered reusing the content of the pixmap buffer when possible.
Definition: qwt_plot_abstract_canvas.h:110
QwtPlotAbstractGLCanvas::setFrameShape
void setFrameShape(QFrame::Shape)
Definition: qwt_plot_abstract_canvas.cpp:1011
QwtPlotAbstractGLCanvas::replot
void replot()
Definition: qwt_plot_abstract_canvas.cpp:1093
QwtPlotAbstractGLCanvas::setFrameShadow
void setFrameShadow(QFrame::Shadow)
Definition: qwt_plot_abstract_canvas.cpp:991
QwtPlotAbstractGLCanvas::draw
void draw(QPainter *)
Helper function for the derived plot canvas.
Definition: qwt_plot_abstract_canvas.cpp:1112
QwtPlot
A 2-D plotting widget.
Definition: qwt_plot.h:79
QwtPlotOpenGLCanvas::paintEvent
virtual void paintEvent(QPaintEvent *) override
Definition: qwt_plot_opengl_canvas.cpp:101
QwtPlotOpenGLCanvas::initializeGL
virtual void initializeGL() override
No operation - reserved for some potential use in the future.
Definition: qwt_plot_opengl_canvas.cpp:174
QwtPlotOpenGLCanvas::~QwtPlotOpenGLCanvas
virtual ~QwtPlotOpenGLCanvas()
Destructor.
Definition: qwt_plot_opengl_canvas.cpp:90
QwtPlotOpenGLCanvas::borderPath
Q_INVOKABLE QPainterPath borderPath(const QRect &) const
Definition: qwt_plot_opengl_canvas.cpp:168
QwtPlotOpenGLCanvas::replot
void replot()
Definition: qwt_plot_opengl_canvas.cpp:142
QwtPlotOpenGLCanvas::QwtPlotOpenGLCanvas
QwtPlotOpenGLCanvas(QwtPlot *=NULL)
Constructor.
Definition: qwt_plot_opengl_canvas.cpp:48
QwtPlotOpenGLCanvas::paintGL
virtual void paintGL() override
Paint the plot.
Definition: qwt_plot_opengl_canvas.cpp:179
QwtPlotOpenGLCanvas::resizeGL
virtual void resizeGL(int width, int height) override
No operation - reserved for some potential use in the future.
Definition: qwt_plot_opengl_canvas.cpp:251
QwtPlotOpenGLCanvas::event
virtual bool event(QEvent *) override
Definition: qwt_plot_opengl_canvas.cpp:112
QwtPlotOpenGLCanvas::invalidateBackingStore
virtual Q_INVOKABLE void invalidateBackingStore() override
Invalidate the internal backing store.
Definition: qwt_plot_opengl_canvas.cpp:148