Qwt User's Guide 6.3.0

Loading...
Searching...
No Matches
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 : numFBOSamples( -1 )
25 , isPolished( false )
26 , fboDirty( true )
27 , fbo( NULL )
28 {
29 }
30
31 ~PrivateData()
32 {
33 delete fbo;
34 }
35
36 int numFBOSamples;
37
38 bool isPolished;
39 bool fboDirty;
40 QOpenGLFramebufferObject* fbo;
41};
42
49 QwtPlotOpenGLCanvas::QwtPlotOpenGLCanvas( QwtPlot* plot )
50 : QOpenGLWidget( plot )
51 , QwtPlotAbstractGLCanvas( this )
52{
53 init();
54}
55
63 QwtPlotOpenGLCanvas::QwtPlotOpenGLCanvas( int numSamples, QwtPlot* plot )
64 : QOpenGLWidget( plot )
65 , QwtPlotAbstractGLCanvas( this )
66{
67 if ( numSamples < -1 )
68 numSamples = -1;
69
70 QSurfaceFormat fmt = format();
71 if ( numSamples != fmt.samples() )
72 {
73 fmt.setSamples( numSamples );
74 setFormat( fmt );
75 }
76
77 init();
78}
79
80 void QwtPlotOpenGLCanvas::init()
81{
82 m_data = new PrivateData;
83
84#if 1
85 setAttribute( Qt::WA_OpaquePaintEvent, true );
86#endif
87
88 setLineWidth( 2 );
89 setFrameShadow( QFrame::Sunken );
90 setFrameShape( QFrame::Panel );
91}
92
94 QwtPlotOpenGLCanvas::~QwtPlotOpenGLCanvas()
95{
96 delete m_data;
97}
98
105 void QwtPlotOpenGLCanvas::paintEvent( QPaintEvent* event )
106{
107 if ( m_data->isPolished )
108 QOpenGLWidget::paintEvent( event );
109}
110
116 bool QwtPlotOpenGLCanvas::event( QEvent* event )
117{
118 if ( event->type() == QEvent::Resize )
119 {
120 if ( m_data->numFBOSamples < 0 )
121 {
122 /*
123 QOpenGLWidget always uses a FBO and sets the number of samples for
124 the FBO not for the widget itself. So format().samples() does not
125 return the correct value after the first QEvent::Resize.
126 */
127 m_data->numFBOSamples = qMax( format().samples(), 0 );
128 }
129 }
130
131 const bool ok = QOpenGLWidget::event( event );
132
133 if ( event->type() == QEvent::PolishRequest )
134 {
135 // In opposite to non OpenGL widgets receive pointless
136 // early repaints. As we always have a QEvent::PolishRequest
137 // followed by QEvent::Paint, we can ignore all these repaints.
138
139 m_data->isPolished = true;
140 }
141
142 if ( event->type() == QEvent::PolishRequest ||
143 event->type() == QEvent::StyleChange )
144 {
145 // assuming, that we always have a styled background
146 // when we have a style sheet
147
148 setAttribute( Qt::WA_StyledBackground,
149 testAttribute( Qt::WA_StyleSheet ) );
150 }
151
152 return ok;
153}
154
159 void QwtPlotOpenGLCanvas::replot()
160{
161 QwtPlotAbstractGLCanvas::replot();
162}
163
165 void QwtPlotOpenGLCanvas::invalidateBackingStore()
166{
167 m_data->fboDirty = true;
168}
169
170 void QwtPlotOpenGLCanvas::clearBackingStore()
171{
172 delete m_data->fbo;
173 m_data->fbo = NULL;
174}
175
185QPainterPath QwtPlotOpenGLCanvas::borderPath( const QRect& rect ) const
186{
187 return canvasBorderPath( rect );
188}
189
191 void QwtPlotOpenGLCanvas::initializeGL()
192{
193}
194
196 void QwtPlotOpenGLCanvas::paintGL()
197{
198 const bool hasFocusIndicator =
199 hasFocus() && focusIndicator() == CanvasFocusIndicator;
200
201 QPainter painter;
202
203 if ( testPaintAttribute( QwtPlotOpenGLCanvas::BackingStore ) &&
204 QOpenGLFramebufferObject::hasOpenGLFramebufferBlit() )
205 {
206 const qreal pixelRatio = QwtPainter::devicePixelRatio( this );
207 const QSize fboSize = size() * pixelRatio;
208
209 if ( hasFocusIndicator )
210 painter.begin( this );
211
212 /*
213 QOpenGLWidget has its own internal FBO, that is used to restore
214 its content without having to repaint. This works fine when f.e
215 a rubberband is moving on top, but there are still situations,
216 where we can repaint without an potentially expensive replot:
217
218 - when having the focus the top level window gets activated/deactivated
219 - ???
220 */
221
222 if ( m_data->fbo )
223 {
224 if ( m_data->fbo->size() != fboSize )
225 {
226 delete m_data->fbo;
227 m_data->fbo = NULL;
228 }
229 }
230
231 if ( m_data->fbo == NULL )
232 {
233 QOpenGLFramebufferObjectFormat fboFormat;
234 fboFormat.setAttachment( QOpenGLFramebufferObject::CombinedDepthStencil );
235
236 if ( m_data->numFBOSamples > 0 )
237 fboFormat.setSamples( m_data->numFBOSamples );
238
239 m_data->fbo = new QOpenGLFramebufferObject( fboSize, fboFormat );
240 m_data->fboDirty = true;
241 }
242
243 if ( m_data->fboDirty )
244 {
245 m_data->fbo->bind();
246
247 QOpenGLPaintDevice pd( fboSize );
248
249 QPainter fboPainter( &pd );
250 fboPainter.scale( pixelRatio, pixelRatio );
251 draw( &fboPainter);
252 fboPainter.end();
253
254 m_data->fboDirty = false;
255 }
256
257 QOpenGLFramebufferObject::blitFramebuffer( NULL, m_data->fbo );
258 }
259 else
260 {
261 painter.begin( this );
262 draw( &painter );
263 }
264
265 if ( hasFocusIndicator )
266 drawFocusIndicator( &painter );
267}
268
270 void QwtPlotOpenGLCanvas::resizeGL( int, int )
271{
272 // nothing to do
273}
274
275#include "moc_qwt_plot_opengl_canvas.cpp"
QwtPainter::devicePixelRatio
static qreal devicePixelRatio(const QPaintDevice *)
Definition qwt_painter.cpp:1481
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:105
QwtPlotOpenGLCanvas::initializeGL
virtual void initializeGL() override
No operation - reserved for some potential use in the future.
Definition qwt_plot_opengl_canvas.cpp:191
QwtPlotOpenGLCanvas::~QwtPlotOpenGLCanvas
virtual ~QwtPlotOpenGLCanvas()
Destructor.
Definition qwt_plot_opengl_canvas.cpp:94
QwtPlotOpenGLCanvas::borderPath
Q_INVOKABLE QPainterPath borderPath(const QRect &) const
Definition qwt_plot_opengl_canvas.cpp:185
QwtPlotOpenGLCanvas::replot
void replot()
Definition qwt_plot_opengl_canvas.cpp:159
QwtPlotOpenGLCanvas::QwtPlotOpenGLCanvas
QwtPlotOpenGLCanvas(QwtPlot *=NULL)
Constructor.
Definition qwt_plot_opengl_canvas.cpp:49
QwtPlotOpenGLCanvas::paintGL
virtual void paintGL() override
Paint the plot.
Definition qwt_plot_opengl_canvas.cpp:196
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:270
QwtPlotOpenGLCanvas::event
virtual bool event(QEvent *) override
Definition qwt_plot_opengl_canvas.cpp:116
QwtPlotOpenGLCanvas::invalidateBackingStore
virtual Q_INVOKABLE void invalidateBackingStore() override
Invalidate the internal backing store.
Definition qwt_plot_opengl_canvas.cpp:165