Port QuarterWidget to QGraphicsView

Derive from QGraphicsView instead of QGLWidget to allow to add widgets as overlay over the 3d scene later on.
This commit is contained in:
Stefan Tröger 2014-08-28 17:57:45 +02:00 committed by wmayer
parent cf167ec60a
commit b18ebc9064
7 changed files with 129 additions and 72 deletions

View File

@ -55,7 +55,7 @@ bool GLPainter::begin(View3DInventorViewer* v)
this->width = view[0];
this->height = view[1];
viewer->makeCurrent();
static_cast<QGLWidget*>(viewer->viewport())->makeCurrent();
glMatrixMode(GL_PROJECTION);
glPushMatrix();

View File

@ -155,7 +155,7 @@ DragDropHandlerP::dropEvent(QDropEvent * event)
// set new scenegraph
this->quarterwidget->setSceneGraph(root);
this->quarterwidget->updateGL();
this->quarterwidget->viewport()->update();
}
#undef PRIVATE

View File

@ -54,6 +54,8 @@
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtGui/QAction>
#include <QPaintEvent>
#include <QResizeEvent>
#include <Inventor/SbViewportRegion.h>
#include <Inventor/system/gl.h>
@ -121,28 +123,38 @@ using namespace SIM::Coin3D::Quarter;
/*! constructor */
QuarterWidget::QuarterWidget(const QGLFormat & format, QWidget * parent, const QGLWidget * sharewidget, Qt::WindowFlags f)
: inherited(format, parent, sharewidget, f)
: inherited(parent)
{
this->constructor(sharewidget);
this->constructor(format, sharewidget);
}
/*! constructor */
QuarterWidget::QuarterWidget(QWidget * parent, const QGLWidget * sharewidget, Qt::WindowFlags f)
: inherited(parent, sharewidget, f)
: inherited(parent)
{
this->constructor(sharewidget);
this->constructor(QGLFormat(), sharewidget);
}
/*! constructor */
QuarterWidget::QuarterWidget(QGLContext * context, QWidget * parent, const QGLWidget * sharewidget, Qt::WindowFlags f)
: inherited(context, parent, sharewidget, f)
: inherited(parent)
{
this->constructor(sharewidget);
this->constructor(context->format(), sharewidget);
}
void
QuarterWidget::constructor(const QGLWidget * sharewidget)
QuarterWidget::constructor(const QGLFormat & format, const QGLWidget * sharewidget)
{
QGraphicsScene* scene = new QGraphicsScene;
setScene(scene);
setViewport(new QGLWidget(format, this, sharewidget));
setFrameStyle(QFrame::NoFrame);
setAutoFillBackground(false);
viewport()->setAutoFillBackground(false);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
PRIVATE(this) = new QuarterWidgetP(this, sharewidget);
PRIVATE(this)->sorendermanager = new SoRenderManager;
@ -181,6 +193,8 @@ QuarterWidget::constructor(const QGLWidget * sharewidget)
this->installEventFilter(PRIVATE(this)->eventfilter);
this->installEventFilter(PRIVATE(this)->interactionmode);
initialized = false;
}
/*! destructor */
@ -638,68 +652,105 @@ QuarterWidget::seek(void)
}
}
}
/*!
This function will be called whenever the GLContext changes,
for instance when the widget is reparented.
Overridden from QGLWidget to enable OpenGL depth buffer
and reinitialize the SoRenderManager.
*/
void
QuarterWidget::initializeGL(void)
{
glEnable(GL_DEPTH_TEST);
this->getSoRenderManager()->reinitialize();
}
/*!
Overridden from QGLWidget to resize the Coin scenegraph
*/
void
QuarterWidget::resizeGL(int width, int height)
void QuarterWidget::resizeEvent(QResizeEvent* event)
{
SbViewportRegion vp(width, height);
PRIVATE(this)->sorendermanager->setViewportRegion(vp);
PRIVATE(this)->soeventmanager->setViewportRegion(vp);
SbViewportRegion vp(event->size().width(), event->size().height());
PRIVATE(this)->sorendermanager->setViewportRegion(vp);
PRIVATE(this)->soeventmanager->setViewportRegion(vp);
}
/*!
Overridden from QGLWidget to render the scenegraph
*/
void
QuarterWidget::paintGL(void)
{
assert(this->isValid() && "No valid GL context found!");
// We might have to process the delay queue here since we don't know
// if paintGL() is called from Qt, and we might have some sensors
// waiting to trigger (the redraw sensor has a lower priority than a
// normal field sensor to guarantee that your sensor is processed
// before the next redraw). Disable autorendering while we do this
// to avoid recursive redraws.
void QuarterWidget::paintEvent(QPaintEvent* event)
{
if(!initialized) {
glEnable(GL_DEPTH_TEST);
this->getSoRenderManager()->reinitialize();
initialized = true;
}
getSoRenderManager()->activate();
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
QGLWidget* w = static_cast<QGLWidget*>(this->viewport());
assert(w->isValid() && "No valid GL context found!");
// We might have to process the delay queue here since we don't know
// if paintGL() is called from Qt, and we might have some sensors
// waiting to trigger (the redraw sensor has a lower priority than a
// normal field sensor to guarantee that your sensor is processed
// before the next redraw). Disable autorendering while we do this
// to avoid recursive redraws.
// We set the PRIVATE(this)->processdelayqueue = false in redraw()
// to avoid processing the delay queue when paintGL() is triggered
// by us, and we don't want to process the delay queue in those
// cases
// We set the PRIVATE(this)->processdelayqueue = false in redraw()
// to avoid processing the delay queue when paintGL() is triggered
// by us, and we don't want to process the delay queue in those
// cases
PRIVATE(this)->autoredrawenabled = false;
if (PRIVATE(this)->processdelayqueue && SoDB::getSensorManager()->isDelaySensorPending()) {
// processing the sensors might trigger a redraw in another
// context. Release this context temporarily
this->doneCurrent();
SoDB::getSensorManager()->processDelayQueue(FALSE);
this->makeCurrent();
}
assert(this->isValid() && "No valid GL context found!");
// we need to render immediately here, and not do scheduleRedraw()
// since Qt will swap the GL buffers after calling paintGL().
this->actualRedraw();
PRIVATE(this)->autoredrawenabled = true;
// process the delay queue the next time we enter this function,
// unless we get here after a call to redraw().
PRIVATE(this)->processdelayqueue = true;
PRIVATE(this)->autoredrawenabled = false;
if(PRIVATE(this)->processdelayqueue && SoDB::getSensorManager()->isDelaySensorPending()) {
// processing the sensors might trigger a redraw in another
// context. Release this context temporarily
w->doneCurrent();
SoDB::getSensorManager()->processDelayQueue(FALSE);
w->makeCurrent();
}
assert(w->isValid() && "No valid GL context found!");
glDrawBuffer(w->doubleBuffer() ? GL_BACK : GL_FRONT);
w->makeCurrent();
this->actualRedraw();
//start the standart graphicsview processing for all widgets and graphic items. As
//QGraphicsView initaliizes a QPainter whcih changes the opengl context in an unpredictable
//manner we need to store the context and recreate it after qt is done.
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushAttrib(GL_MULTISAMPLE_BIT_EXT);
inherited::paintEvent(event);
glPopAttrib();
glPopAttrib();
if (w->doubleBuffer()) { w->swapBuffers(); }
PRIVATE(this)->autoredrawenabled = true;
// process the delay queue the next time we enter this function,
// unless we get here after a call to redraw().
PRIVATE(this)->processdelayqueue = true;
}
bool QuarterWidget::viewportEvent(QEvent* event)
{
if( event->type() == QEvent::Paint || event->type() == QEvent::Resize) {
return QGraphicsView::viewportEvent(event);
}
else if(event->type() == QEvent::MouseMove
|| event->type() == QEvent::Wheel
|| event->type() == QEvent::MouseButtonDblClick
|| event->type() == QEvent::MouseButtonRelease
|| event->type() == QEvent::MouseButtonPress) {
QMouseEvent* mouse = static_cast<QMouseEvent*>(event);
QGraphicsItem *item = itemAt(mouse->pos());
if(!item) {
return false;
}
return QGraphicsView::viewportEvent(event);
}
//if we return false the events get processed normally, this means they get passed to the quarter
//event filters for processing in the scene graph. If we return true event processing stops here.
return false;
}
/*!
@ -716,7 +767,7 @@ QuarterWidget::redraw(void)
// we're triggering the next paintGL(). Set a flag to remember this
// to avoid that we process the delay queue in paintGL()
PRIVATE(this)->processdelayqueue = false;
this->updateGL();
this->viewport()->update();
}
/*!

View File

@ -38,6 +38,7 @@
#include <Inventor/actions/SoGLRenderAction.h>
#include <QtGui/QColor>
#include <QGraphicsView>
#include <QtCore/QUrl>
#include <QtOpenGL/QGLWidget>
#include "Gui/Quarter/Basic.h"
@ -56,8 +57,8 @@ namespace SIM { namespace Coin3D { namespace Quarter {
class EventFilter;
const char DEFAULT_NAVIGATIONFILE [] = "coin:///scxml/navigation/examiner.xml";
class QUARTER_DLL_API QuarterWidget : public QGLWidget {
typedef QGLWidget inherited;
class QUARTER_DLL_API QuarterWidget : public QGraphicsView {
typedef QGraphicsView inherited;
Q_OBJECT
Q_PROPERTY(QUrl navigationModeFile READ navigationModeFile WRITE setNavigationModeFile RESET resetNavigationModeFile)
@ -183,15 +184,17 @@ public Q_SLOTS:
void setTransparencyType(TransparencyType type);
protected:
virtual void resizeGL(int width, int height);
virtual void initializeGL(void);
virtual void paintGL(void);
virtual void paintEvent(QPaintEvent*);
virtual void resizeEvent(QResizeEvent*);
virtual bool viewportEvent(QEvent* event);
virtual void actualRedraw(void);
private:
void constructor(const QGLWidget * sharewidget);
void constructor(const QGLFormat& format, const QGLWidget* sharewidget);
friend class QuarterWidgetP;
class QuarterWidgetP * pimpl;
bool initialized;
};
}}} // namespace

View File

@ -93,7 +93,8 @@ QuarterWidgetP::QuarterWidgetP(QuarterWidget * masterptr, const QGLWidget * shar
QuarterWidgetP::~QuarterWidgetP()
{
removeFromCacheContext(this->cachecontext, this->master);
//TODO:fix this function call
//removeFromCacheContext(this->cachecontext, this->master);
if (this->contextmenu) {
delete this->contextmenu;
}

View File

@ -81,6 +81,7 @@
#include "View3DPy.h"
#include "SoFCDB.h"
#include "NavigationStyle.h"
#include "PropertyView.h"
#include <locale>
@ -146,6 +147,7 @@ View3DInventor::View3DInventor(Gui::Document* pcDocument, QWidget* parent, Qt::W
_viewer = new View3DInventorViewer(f,this);
_viewer->setDocument(this->_pcDocument);
#endif
// apply the user settings
OnChange(*hGrp,"EyeDistance");
OnChange(*hGrp,"CornerCoordSystem");

View File

@ -1123,7 +1123,7 @@ void View3DInventorViewer::setRenderFramebuffer(const SbBool enable)
SbVec2s origin = vp.getViewportOriginPixels();
SbVec2s size = vp.getViewportSizePixels();
this->makeCurrent();
static_cast<QGLWidget*>(this->viewport())->makeCurrent();
this->framebuffer = new QGLFramebufferObject(size[0],size[1],QGLFramebufferObject::Depth);
renderToFramebuffer(this->framebuffer);
}
@ -1136,7 +1136,7 @@ SbBool View3DInventorViewer::isRenderFramebuffer() const
void View3DInventorViewer::renderToFramebuffer(QGLFramebufferObject* fbo)
{
this->makeCurrent();
static_cast<QGLWidget*>(this->viewport())->makeCurrent();
fbo->bind();
int width = fbo->size().width();
int height = fbo->size().height();
@ -2589,7 +2589,7 @@ void View3DInventorViewer::setAntiAliasingMode(View3DInventorViewer::AntiAliasin
if(getSoRenderManager()->getGLRenderAction()->isSmoothing() != smoothing)
getSoRenderManager()->getGLRenderAction()->setSmoothing(smoothing);
if(this->format().sampleBuffers() != buffers)
if(static_cast<QGLWidget*>(this->viewport())->format().sampleBuffers() != buffers)
Base::Console().Message("To change multisampling settings please close and open the 3d view again");
}
@ -2599,7 +2599,7 @@ View3DInventorViewer::AntiAliasing View3DInventorViewer::getAntiAliasingMode() c
if(getSoRenderManager()->getGLRenderAction()->isSmoothing())
return Smoothing;
int buffers = this->format().sampleBuffers();
int buffers = static_cast<QGLWidget*>(this->viewport())->format().sampleBuffers();
switch(buffers) {
case 1: