qwt_plot_opengl_canvas.cpp
Go to the documentation of this file.
00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 #include "qwt_plot_opengl_canvas.h"
00011 #include "qwt_plot.h"
00012 #include <qevent.h>
00013 #include <qopenglframebufferobject.h>
00014 #include <qopenglpaintdevice.h>
00015 
00016 class QwtPlotOpenGLCanvas::PrivateData
00017 {
00018 public:
00019     PrivateData():
00020         isPolished( false ),
00021         fboDirty( true ),
00022         fbo( NULL )
00023     {
00024     }
00025 
00026     ~PrivateData()
00027     {
00028         delete fbo;
00029     }
00030 
00031     int numSamples;
00032 
00033     bool isPolished;
00034     bool fboDirty;
00035     QOpenGLFramebufferObject* fbo;
00036 };
00037 
00038 
00045 QwtPlotOpenGLCanvas::QwtPlotOpenGLCanvas( QwtPlot *plot ):
00046     QOpenGLWidget( plot ),
00047     QwtPlotAbstractGLCanvas( this )
00048 {
00049     QSurfaceFormat fmt = format();
00050     fmt.setSamples( 4 );
00051 
00052     init( fmt );
00053 }
00054 
00055 QwtPlotOpenGLCanvas::QwtPlotOpenGLCanvas( const QSurfaceFormat &format, QwtPlot *plot ):
00056     QOpenGLWidget( plot ),
00057     QwtPlotAbstractGLCanvas( this )
00058 {
00059     init( format );
00060 }
00061 
00062 void QwtPlotOpenGLCanvas::init( const QSurfaceFormat &format )
00063 {
00064     d_data = new PrivateData;
00065     d_data->numSamples = format.samples();
00066 
00067     setFormat( format );
00068 
00069 #if 1
00070     setAttribute( Qt::WA_OpaquePaintEvent, true );
00071 #endif
00072 }
00073 
00075 QwtPlotOpenGLCanvas::~QwtPlotOpenGLCanvas()
00076 {
00077     delete d_data;
00078 }
00079 
00086 void QwtPlotOpenGLCanvas::paintEvent( QPaintEvent *event )
00087 {
00088     if ( d_data->isPolished )
00089         QOpenGLWidget::paintEvent( event );
00090 }
00091 
00097 bool QwtPlotOpenGLCanvas::event( QEvent *event )
00098 {
00099     const bool ok = QOpenGLWidget::event( event );
00100 
00101     if ( event->type() == QEvent::PolishRequest )
00102     {
00103         // In opposite to non OpenGL widgets receive pointless
00104         // early repaints. As we always have a QEvent::PolishRequest
00105         // followed by QEvent::Paint, we can ignore all thos repaints.
00106 
00107         d_data->isPolished = true;
00108     }
00109 
00110     if ( event->type() == QEvent::PolishRequest ||
00111         event->type() == QEvent::StyleChange )
00112     {
00113         // assuming, that we always have a styled background
00114         // when we have a style sheet
00115 
00116         setAttribute( Qt::WA_StyledBackground,
00117             testAttribute( Qt::WA_StyleSheet ) );
00118     }
00119 
00120     return ok;
00121 }
00122 
00123 void QwtPlotOpenGLCanvas::replot()
00124 {
00125     QwtPlotAbstractGLCanvas::replot();
00126 }
00127 
00128 void QwtPlotOpenGLCanvas::invalidateBackingStore()
00129 {
00130     d_data->fboDirty = true;
00131 }
00132 
00133 void QwtPlotOpenGLCanvas::clearBackingStore()
00134 {
00135     delete d_data->fbo;
00136     d_data->fbo = NULL;
00137 }
00138 
00139 QPainterPath QwtPlotOpenGLCanvas::borderPath( const QRect &rect ) const
00140 {
00141     return borderPath2( rect );
00142 }
00143 
00144 void QwtPlotOpenGLCanvas::initializeGL()
00145 {
00146 }
00147 
00148 void QwtPlotOpenGLCanvas::paintGL()
00149 {
00150     const bool hasFocusIndicator = 
00151         hasFocus() && focusIndicator() == CanvasFocusIndicator;
00152 
00153     QPainter painter;
00154 
00155     if ( testPaintAttribute( QwtPlotOpenGLCanvas::BackingStore ) &&
00156         QOpenGLFramebufferObject::hasOpenGLFramebufferBlit() )
00157     {
00158         if ( hasFocusIndicator )
00159             painter.begin( this );
00160 
00161         /*
00162            QOpenGLWidget has its own internal FBO, that is used to restore
00163            its content without having to repaint. This works fine when f.e
00164            a rubberband is moving on top, but there are still situations,
00165            where we can repaint without an potentially expensive replot: 
00166 
00167                - when having the focus the top level window gets activated/deactivated
00168                - ???
00169          */
00170 
00171         if ( d_data->fbo && d_data->fbo->size() != size() )
00172         {
00173             delete d_data->fbo;
00174             d_data->fbo = NULL;
00175         }
00176 
00177         if ( d_data->fbo == NULL )
00178         {
00179             QOpenGLFramebufferObjectFormat fboFormat;
00180             fboFormat.setSamples( d_data->numSamples );
00181             fboFormat.setAttachment( QOpenGLFramebufferObject::CombinedDepthStencil );
00182 
00183             d_data->fbo = new QOpenGLFramebufferObject( size(), fboFormat );
00184             d_data->fboDirty = true;
00185         }
00186 
00187         if ( d_data->fboDirty )
00188         {
00189             d_data->fbo->bind();
00190 
00191             QOpenGLPaintDevice pd( size() );
00192 
00193             QPainter fboPainter( &pd );
00194             draw( &fboPainter);
00195             fboPainter.end();
00196         
00197             d_data->fboDirty = false;
00198         }
00199 
00200         QOpenGLFramebufferObject::blitFramebuffer( NULL, d_data->fbo );
00201     }
00202     else
00203     {
00204         painter.begin( this );
00205         draw( &painter );
00206     }
00207 
00208     if ( hasFocusIndicator )
00209         drawFocusIndicator( &painter );
00210 }
00211 
00212 void QwtPlotOpenGLCanvas::resizeGL( int, int )
00213 {
00214     // nothing to do
00215 }


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56