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

Reply via email to