try changing paintEvent with paintGL and resizeEvent with resizeGL Nick
http://www.linkedin.com/in/tnikolov Sent from Devlet, Ankara, Turkey On Thu, Dec 3, 2009 at 4:55 AM, Job Mulder <[email protected]> wrote: > Hi, > > I have created a OSG-Qt Widget (based on the QOSGWidget example) that uses > threaded rendering so the rendering doesn't block Qt's main thread. This > works fine on my own achine, which has an ATI card (and never seems to use > the GPU according to the StasHandler). However, one of my co-developers has > an NVIDIA card and for some reason the > osg::GraphicsContext::createGraphicsContext call we use returns NULL on his > machine. > > I have added the class below. The line that seems to cause the problem is > at the bottom of the cpp file (at the end of this mail) > > Is there anything I missed there? I hope someone has encountered and solved > this problem before... > > Regards, Job Mulder > > > //////////////////////////// h file /////////////////////////// > #ifndef OSGVIEWERWIDGET_H > #define OSGVIEWERWIDGET_H > > class QPaintEvent; > class QResizeEvent; > class QCloseEvent; > class QShowEvent; > class QHideEvent; > > #include <osgViewer/Viewer> > #include <osgViewer/GraphicsWindow> > > #include <QtOpenGL/QGLWidget> > #include <QThread> > #include <QSize> > > class OsgViewerWidget : public osgViewer::Viewer, public QGLWidget > { > private: > class OsgWidgetThread : public QThread > { > public: > OsgWidgetThread(OsgViewerWidget* parent); > protected: > virtual void run(); > OsgViewerWidget* m_osgWidget; > }; > > public: > OsgViewerWidget(QWidget* parent = 0, Qt::WindowFlags f = 0); > virtual ~OsgViewerWidget(); > virtual void updateCamera(); > virtual void paintEvent(QPaintEvent*); > virtual void resizeEvent(QResizeEvent*); > virtual void closeEvent(QCloseEvent*); > virtual void showEvent(QShowEvent*); > // virtual void hideEvent(QHideEvent*); > void threadMain(); > > protected: > virtual void handleStateUpdatesThreaded(void); > virtual void initializeThreaded(void); > bool isThreadInitComplete() const; > > void createContext(); > osgViewer::GraphicsWindow* getGraphicsWindow() const; > > OsgWidgetThread m_thread; > volatile bool m_terminating; > volatile bool m_resize; > volatile bool m_threadStarted; > QSize m_size; > > osg::ref_ptr<osgViewer::GraphicsWindow> m_graphicsWindow; > }; > > #endif // OSGVIEWERWIDGET_H > > > //////////////////////////// cpp file /////////////////////////// > > #include "osgviewerwidget.h" > > #include <osgViewer/ViewerEventHandlers> > #include <osgViewer/api/Win32/GraphicsWindowWin32> > typedef osgViewer::GraphicsWindowWin32::WindowData WindowData; > #include <osgGA/TrackballManipulator> > #include <QResizeEvent> > #include <QCloseEvent> > #include <QShowEvent> > > /*! \class OsgViewerWidget::OsgWidgetThread > \brief A simple thread handler for the OsgViewerWidget. It starts > the thread function of OsgViewerWidget. > */ > > /*! \brief Constructor, does not start anything, just initializes > > The thread is started by OsgViewerWidget. > */ > OsgViewerWidget::OsgWidgetThread::OsgWidgetThread(OsgViewerWidget* parent) > : QThread(parent) > , m_osgWidget(parent) > { > } > > /*! \brief The main function of the OsgWidgetThread. > \details The function is just a wrapper for the OsgViewerWidget main > thread function > */ > void OsgViewerWidget::OsgWidgetThread::run() > { > m_osgWidget->threadMain(); > } > > /*! \class OsgViewerWidget > \brief An OSG viewer contained in a Qt Widget. > > The class handles the actual drawing of the scenegraph in a separate > thread. > Any inheriting classes should make sure to do the same by > overloading the > \a handleStateUpdatesThreaded function and calling the base function > for the > standard state updates such as resizing and closing > */ > > /*! \brief Constructor, initializes the widget and starts the render thread > */ > OsgViewerWidget::OsgViewerWidget(QWidget* parent, Qt::WindowFlags f) > : QGLWidget( parent, 0, f ) > , m_thread(this) > , m_terminating(false) > , m_resize(false) > , m_threadStarted(false) > { > setAttribute(Qt::WA_PaintOnScreen); > setAttribute(Qt::WA_NoSystemBackground); > setAttribute(Qt::WA_OpaquePaintEvent); > setAttribute(Qt::WA_PaintUnclipped); > setAttribute(Qt::WA_TranslucentBackground); > setFocusPolicy(Qt::ClickFocus); > > setAutoFillBackground(false); > > setThreadingModel(osgViewer::Viewer::SingleThreaded); // we > already handle the multi-threading ourselves > } > > /*! \brief Destructor, stops the render thread if it was still running > */ > OsgViewerWidget::~OsgViewerWidget() > { > m_terminating = true; > m_thread.wait(); > } > > /*! \brief Start the render thread when showing the window > */ > void OsgViewerWidget::showEvent(QShowEvent*) > { > m_thread.start(); > } > > /*! \brief Wait for thread initialization to complete > */ > bool OsgViewerWidget::isThreadInitComplete() const > { > return m_threadStarted; > } > > /*! \brief Update the camera, usually to match a new window size > */ > void OsgViewerWidget::updateCamera() > { > getCamera()->setViewport(new osg::Viewport(0,0,width(),height())); > getCamera()->setProjectionMatrixAsPerspective(30.0f, > static_cast<double>(width())/static_cast<double>(height()), 1.0f, 10000.0f); > getCamera()->setGraphicsContext(m_graphicsWindow.get()); > } > > /*! \brief The paint event is deliberately empty so Qt does not corrupt the > display > > All actual painting is done in the render thread > */ > void OsgViewerWidget::paintEvent(QPaintEvent* event) > { > } > > /*! \brief Handle the resize event by scheduling a threaded resize > */ > void OsgViewerWidget::resizeEvent(QResizeEvent* event) > { > m_size = event->size(); > m_resize = true; > } > > /*! \brief Handle the close event by ending the render thread and waiting > for it > */ > void OsgViewerWidget::closeEvent(QCloseEvent* event) > { > m_terminating = true; > m_thread.wait(); > event->accept(); > } > > /*! \brief Update state change messages coming from other threads in the > render thread > > This function handles things like resize events in the render thread > so they're thread-safe > and don't interfere with the actual drawing. > > Subclasses should overload this function and call it if they want to > define their own > thread-safe handling. If the events handled by the base function > need to be handled by > the subclass, make sure to handle them before calling the function > and make sure to > update the relevant boolean. > > Currently only \a m_resize is checked by this function > */ > void OsgViewerWidget::handleStateUpdatesThreaded(void) > { > if (m_resize) > { > osgViewer::GraphicsWindow* gw = m_graphicsWindow.get(); > if (gw) > { > gw->getEventQueue()->windowResize(0, 0, > m_size.width(), m_size.height() ); > gw->resized(0, 0, m_size.width(), m_size.height()); > } > updateCamera(); > m_resize = false; > } > } > > /*! \brief This function performs the user-specific initialization of the > widget > > Typically this means setting up a statshandler and camera > manipulator, which is > what the default implementation does. > */ > void OsgViewerWidget::initializeThreaded(void) > { > setCameraManipulator(new osgGA::TrackballManipulator); > addEventHandler(new osgViewer::StatsHandler); > } > > /*! \brief The main render thread of the widget. > > \todo Maybe bundle these for multiple widgets to reduce > thread-count? > */ > void OsgViewerWidget::threadMain() > { > createContext(); > initializeThreaded(); > > m_threadStarted = true; > > while(!m_terminating) > { > handleStateUpdatesThreaded(); > frame(); > QThread::yieldCurrentThread(); > } > } > > /*! \brief Return the graphics window of the OSG part > */ > osgViewer::GraphicsWindow* OsgViewerWidget::getGraphicsWindow() const > { > return m_graphicsWindow.get(); > } > > /*! \brief Create the display context for the OSG viewer > > This is based on the QOSGWidget example code and may include some > redundant code. > */ > void OsgViewerWidget::createContext() > { > osg::DisplaySettings* ds = osg::DisplaySettings::instance(); > > osg::ref_ptr<osg::GraphicsContext::Traits> traits = new > osg::GraphicsContext::Traits; > > traits->readDISPLAY(); > if (traits->displayNum<0) traits->displayNum = 0; > > traits->windowName = "osgViewerQt"; > traits->screenNum = 0; > traits->x = x(); > traits->y = y(); > traits->width = width(); > traits->height = height(); > traits->alpha = ds->getMinimumNumAlphaBits(); > traits->stencil = ds->getMinimumNumStencilBits(); > traits->windowDecoration = false; > traits->doubleBuffer = true; > traits->sharedContext = 0; > traits->sampleBuffers = ds->getMultiSamples(); > traits->samples = ds->getNumMultiSamples(); > > traits->inheritedWindowData = new WindowData(winId()); > > if (ds->getStereo()) > { > switch(ds->getStereoMode()) > { > case(osg::DisplaySettings::QUAD_BUFFER): > traits->quadBufferStereo = true; break; > case(osg::DisplaySettings::VERTICAL_INTERLACE): > case(osg::DisplaySettings::CHECKERBOARD): > case(osg::DisplaySettings::HORIZONTAL_INTERLACE): > traits->stencil = 8; break; > default: break; > } > } > > osg::ref_ptr<osg::GraphicsContext> gc = > osg::GraphicsContext::createGraphicsContext(traits.get()); > m_graphicsWindow = dynamic_cast<osgViewer::GraphicsWindow*>(gc.get()); > } > > _______________________________________________ > osg-users mailing list > [email protected] > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org >
_______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

