qwt_plot_opengl_canvas.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
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 
42 
50  QOpenGLWidget( plot ),
52 {
53  QSurfaceFormat fmt = format();
54  fmt.setSamples( 4 );
55 
56  init( fmt );
57 }
58 
60  QOpenGLWidget( plot ),
62 {
63  init( format );
64 }
65 
66 void QwtPlotOpenGLCanvas::init( const QSurfaceFormat &format )
67 {
68  d_data = new PrivateData;
69  d_data->numSamples = format.samples();
70 
71  setFormat( format );
72 
73 #if 1
74  setAttribute( Qt::WA_OpaquePaintEvent, true );
75 #endif
76 }
77 
80 {
81  delete d_data;
82 }
83 
91 {
92  if ( d_data->isPolished )
93  QOpenGLWidget::paintEvent( event );
94 }
95 
102 {
103  const bool ok = QOpenGLWidget::event( event );
104 
105  if ( event->type() == QEvent::PolishRequest )
106  {
107  // In opposite to non OpenGL widgets receive pointless
108  // early repaints. As we always have a QEvent::PolishRequest
109  // followed by QEvent::Paint, we can ignore all thos repaints.
110 
111  d_data->isPolished = true;
112  }
113 
114  if ( event->type() == QEvent::PolishRequest ||
115  event->type() == QEvent::StyleChange )
116  {
117  // assuming, that we always have a styled background
118  // when we have a style sheet
119 
120  setAttribute( Qt::WA_StyledBackground,
121  testAttribute( Qt::WA_StyleSheet ) );
122  }
123 
124  return ok;
125 }
126 
128 {
130 }
131 
133 {
134  d_data->fboDirty = true;
135 }
136 
138 {
139  delete d_data->fbo;
140  d_data->fbo = NULL;
141 }
142 
143 QPainterPath QwtPlotOpenGLCanvas::borderPath( const QRect &rect ) const
144 {
145  return borderPath2( rect );
146 }
147 
149 {
150 }
151 
153 {
154  const bool hasFocusIndicator =
155  hasFocus() && focusIndicator() == CanvasFocusIndicator;
156 
157  QPainter painter;
158 
160  QOpenGLFramebufferObject::hasOpenGLFramebufferBlit() )
161  {
162  const qreal pixelRatio = QwtPainter::devicePixelRatio( NULL );
163  const QSize fboSize = size() * pixelRatio;
164 
165  if ( hasFocusIndicator )
166  painter.begin( this );
167 
168  /*
169  QOpenGLWidget has its own internal FBO, that is used to restore
170  its content without having to repaint. This works fine when f.e
171  a rubberband is moving on top, but there are still situations,
172  where we can repaint without an potentially expensive replot:
173 
174  - when having the focus the top level window gets activated/deactivated
175  - ???
176  */
177 
178  if ( d_data->fbo )
179  {
180  if ( d_data->fbo->size() != fboSize )
181  {
182  delete d_data->fbo;
183  d_data->fbo = NULL;
184  }
185  }
186 
187  if ( d_data->fbo == NULL )
188  {
189  QOpenGLFramebufferObjectFormat fboFormat;
190  fboFormat.setSamples( d_data->numSamples );
191  fboFormat.setAttachment( QOpenGLFramebufferObject::CombinedDepthStencil );
192 
193  d_data->fbo = new QOpenGLFramebufferObject( fboSize, fboFormat );
194  d_data->fboDirty = true;
195  }
196 
197  if ( d_data->fboDirty )
198  {
199  d_data->fbo->bind();
200 
201  QOpenGLPaintDevice pd( fboSize );
202 
203  QPainter fboPainter( &pd );
204  fboPainter.scale( pixelRatio, pixelRatio );
205  draw( &fboPainter);
206  fboPainter.end();
207 
208  d_data->fboDirty = false;
209  }
210 
211  QOpenGLFramebufferObject::blitFramebuffer( NULL, d_data->fbo );
212  }
213  else
214  {
215  painter.begin( this );
216  draw( &painter );
217  }
218 
219  if ( hasFocusIndicator )
220  drawFocusIndicator( &painter );
221 }
222 
224 {
225  // nothing to do
226 }
227 
228 #if QWT_MOC_INCLUDE
229 #include "moc_qwt_plot_opengl_canvas.cpp"
230 #endif
Q_INVOKABLE QPainterPath borderPath(const QRect &) const
Paint double buffered reusing the content of the pixmap buffer when possible.
void init(const QSurfaceFormat &)
FMT_INLINE std::basic_string< Char > format(const S &format_str, Args &&...args)
Definition: core.h:2081
bool testPaintAttribute(PaintAttribute) const
virtual void paintGL() QWT_OVERRIDE
FocusIndicator focusIndicator() const
virtual void paintEvent(QPaintEvent *) QWT_OVERRIDE
A 2-D plotting widget.
Definition: qwt_plot.h:75
virtual bool event(QEvent *) QWT_OVERRIDE
virtual ~QwtPlotOpenGLCanvas()
Destructor.
virtual void resizeGL(int width, int height) QWT_OVERRIDE
virtual void clearBackingStore() QWT_OVERRIDE
static qreal devicePixelRatio(const QPaintDevice *)
virtual Q_INVOKABLE void invalidateBackingStore() QWT_OVERRIDE
QPainterPath borderPath2(const QRect &rect) const
QwtPlot * plot()
Return parent plot widget.
virtual void initializeGL() QWT_OVERRIDE
virtual void drawFocusIndicator(QPainter *)
QwtPlotOpenGLCanvas(QwtPlot *=NULL)
Constructor.


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10