source: ntrip/trunk/BNC/qwt/qwt_plot_opengl_canvas.cpp

Last change on this file was 11158, checked in by stuerze, 4 days ago

deprecated functions exchanged libs updated

File size: 6.6 KB
Line 
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
20class 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
43/*!
44 \brief Constructor
45
46 \param plot Parent plot widget
47 \sa QwtPlot::setCanvas()
48 */
49QwtPlotOpenGLCanvas::QwtPlotOpenGLCanvas( QwtPlot* plot )
50 : QOpenGLWidget( plot )
51 , QwtPlotAbstractGLCanvas( this )
52{
53 init();
54}
55
56/*!
57 \brief Constructor
58
59 \param numSamples Number of samples, see QSurfaceFormat::samples()
60 \param plot Parent plot widget
61 \sa QwtPlot::setCanvas()
62 */
63QwtPlotOpenGLCanvas::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
80void 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
93//! Destructor
94QwtPlotOpenGLCanvas::~QwtPlotOpenGLCanvas()
95{
96 delete m_data;
97}
98
99/*!
100 Paint event
101
102 \param event Paint event
103 \sa QwtPlot::drawCanvas()
104 */
105void QwtPlotOpenGLCanvas::paintEvent( QPaintEvent* event )
106{
107 if ( m_data->isPolished )
108 QOpenGLWidget::paintEvent( event );
109}
110
111/*!
112 Qt event handler for QEvent::PolishRequest and QEvent::StyleChange
113 \param event Qt Event
114 \return See QGLWidget::event()
115 */
116bool 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
155/*!
156 Invalidate the paint cache and repaint the canvas
157 \sa invalidatePaintCache()
158 */
159void QwtPlotOpenGLCanvas::replot()
160{
161 QwtPlotAbstractGLCanvas::replot();
162}
163
164//! Invalidate the internal backing store
165void QwtPlotOpenGLCanvas::invalidateBackingStore()
166{
167 m_data->fboDirty = true;
168}
169
170void QwtPlotOpenGLCanvas::clearBackingStore()
171{
172 delete m_data->fbo;
173 m_data->fbo = NULL;
174}
175
176/*!
177 Calculate the painter path for a styled or rounded border
178
179 When the canvas has no styled background or rounded borders
180 the painter path is empty.
181
182 \param rect Bounding rectangle of the canvas
183 \return Painter path, that can be used for clipping
184 */
185QPainterPath QwtPlotOpenGLCanvas::borderPath( const QRect& rect ) const
186{
187 return canvasBorderPath( rect );
188}
189
190//! No operation - reserved for some potential use in the future
191void QwtPlotOpenGLCanvas::initializeGL()
192{
193}
194
195//! Paint the plot
196void 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
269//! No operation - reserved for some potential use in the future
270void QwtPlotOpenGLCanvas::resizeGL( int, int )
271{
272 // nothing to do
273}
274
275#include "moc_qwt_plot_opengl_canvas.cpp"
Note: See TracBrowser for help on using the repository browser.