Robert-

I have modified AdapterWidget.cpp from the osgviewerQt example. Use with Osg 
2.4, Qt 3.3.3. It is obviously much simplified from what I have but exhibits a 
similar problem.

What I changed: 
1. Created 3 ViewerQts instead of just 1
2. Added a destructor to ViewerQt
3. Added the Qt::WDestructiveClose flag to the AdapterWidget, which triggers 
the ViewerQt destructor to be called when the window is closed

How to use:
1. osgViewerQTd.exe cow.osg
2. Mine pops up cascaded, cow in each window
3. Close a window (middle window works well for me)
4. Check remaining windows, cow will likely have disappeard from one of them
5. If this didn't work, try closing the other windows, or running again and 
closing the windows in a different order.

Thank you so much,
Virginia


Hi Virginia,

There is not much I can do without seeing the problem first hand.  Is it 
possible to recreate it by modifying the existing osgviewerQT example?  If so, 
could do this to effectively create a unit test for this particular usage case.

Another possible route with solving this type of usage case might be to 
explicitly pass in the parent window when creating the graphics context, but 
leave it to the OSG itself to create the windows rather that QT.  I haven't 
personally tried this, but it should be possible, even if it requires a few 
tweaks to the OSG itself to enable it.

Robert.

On Wed, Jul 2, 2008 at 3:22 PM, Virginia Holmstrom <[EMAIL PROTECTED]> wrote:
> Hello
>
> I have been having problems with the destruction of my ViewerQT window and I 
> was wondering if anyone could shed some light on the issue. I am seeing 
> corruption in one view when another view is deleted (screen shot attached). 
> We are using OSG 2.4 and Qt 3.3.3 on WindowsXP and Linux. Problems are 
> reproducible on both platforms.
>
> We are required to permit muliple views into the same scene, each in 
> its own window with its own navigation. The user may open one or more views, 
> close views at anytime, and open new ones. We have a set up similar to the 
> osgViewerQT example shipped with osg, where our ViewerQT inherits from both 
> osgViewer::Viewer and the AdapterWidget. We actually flipped the inheritance 
> order from the example, so that ours looks like this: ViewerQT : public 
> AdapterWidget, public osgViewer::Viewer due to compilation problems with the 
> Qt moc'ing the other way around.
>
> Note we are using QGLWidget, not QOSGWidget, and we use multiple ViewerQts 
> instead of CompositeViewer due to problems discussed in thread 
> http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/2007-December/005676.html.
>  Hence our use of multiple ViewerQts is also similar to Enrique Parodi's 
> implementation he provided in that thread.
>
> We store a ref_ptr to the root node of our scene external to the ViewerQts.
> osg::ref_ptr < osg::Group > _osgScene; This ref_ptr persists as views 
> are opened and closed and is only released when the application closes. Each 
> time a ViewerQT is created we pass it the scene using setSceneData. All 
> ViewerQts get the same root scene node.
>
> We started having a problem when we set the Qt::WDestructiveClose flag in our 
> AdapterWidget, which triggers the following destructors to be called in this 
> order on close:
>
> ViewerQT
> osgViewer::Viewer
> osgViewer::View
> osg::View
> AdapterWidget
>
> We normally perform cleanup of our own classes in ViewerQT::~ViewerQT, 
> however we see the corruption when the ViewerQT destructor is empty as 
> well! The AdapterWidget destructor contains 
> _gw->getEventQueue()->closeWindow();
>
> The easiest way to reproduce the problem is to open multiple windows, then 
> close the first window(view), triggering its destruction. Frequently the last 
> window will be corrupted. I use corruption for lack of a better term. 
> Geometry may disappear, textures may disappear, osgText may become blocks, 
> while other parts of the scene are still visible in their original form. 
> We've also had problems with the background stars flipping to an opaque dome.
>
> In the screen shot provided I closed the first window (hence blank space 
> upper left) and immediatly as I did that portions of the scene disappeard 
> from the last window (bottom right) and the text became blocks.
>
> If I subsequently open a new window the scene usually appears normal.
>
> I am not sure if I have a:
> memory problem?
> problem with the shared scene when ViewerQTs destruct?
> problem in the GraphicsWindowEmbedded?
> QT problem?
> ???
>
> I am very open to suggestions. ;-)
>
> Thank you so much,
> Virginia
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.
> org
>
>
/* OpenSceneGraph example, osganimate.
*
*  Permission is hereby granted, free of charge, to any person obtaining a copy
*  of this software and associated documentation files (the "Software"), to deal
*  in the Software without restriction, including without limitation the rights
*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*  THE SOFTWARE.
*/

#include <osgViewer/Viewer>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgDB/ReadFile>

#if USE_QT4

    #include <QtCore/QString>
    #include <QtCore/QTimer>
    #include <QtGui/QKeyEvent>
    #include <QtGui/QApplication>
    #include <QtOpenGL/QGLWidget>
    #include <QtGui/QMainWindow>
    #include <QtGui/QMdiSubWindow>
    #include <QtGui/QMdiArea>
    
    using Qt::WindowFlags;

#else

    class QWidget;
    #include <qtimer.h>
    #include <qgl.h>
    #include <qapplication.h>

    #define WindowFlags WFlags

#endif

#include <iostream>

class AdapterWidget : public QGLWidget
{
    public:

        AdapterWidget( QWidget * parent = 0, const char * name = 0, const 
QGLWidget * shareWidget = 0, WindowFlags f = 0 );

        virtual ~AdapterWidget() {}

        osgViewer::GraphicsWindow* getGraphicsWindow() { return _gw.get(); }
        const osgViewer::GraphicsWindow* getGraphicsWindow() const { return 
_gw.get(); }

    protected:

        void init();

        virtual void resizeGL( int width, int height );
        virtual void keyPressEvent( QKeyEvent* event );
        virtual void keyReleaseEvent( QKeyEvent* event );
        virtual void mousePressEvent( QMouseEvent* event );
        virtual void mouseReleaseEvent( QMouseEvent* event );
        virtual void mouseMoveEvent( QMouseEvent* event );

        osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;
};

AdapterWidget::AdapterWidget( QWidget * parent, const char * name, const 
QGLWidget * shareWidget, WindowFlags f):
#if USE_QT4
    QGLWidget(parent, shareWidget, f)
#else
    QGLWidget(parent, name, shareWidget, f)
#endif
{
    _gw = new osgViewer::GraphicsWindowEmbedded(0,0,width(),height());
#if USE_QT4
    setFocusPolicy(Qt::ClickFocus);
#else
    setFocusPolicy(QWidget::ClickFocus);
#endif
}

void AdapterWidget::resizeGL( int width, int height )
{
    _gw->getEventQueue()->windowResize(0, 0, width, height );
    _gw->resized(0,0,width,height);
}

void AdapterWidget::keyPressEvent( QKeyEvent* event )
{
#if USE_QT4
    _gw->getEventQueue()->keyPress( (osgGA::GUIEventAdapter::KeySymbol) 
*(event->text().toAscii().data() ) );
#else
    _gw->getEventQueue()->keyPress( (osgGA::GUIEventAdapter::KeySymbol) 
event->ascii() );
#endif
}

void AdapterWidget::keyReleaseEvent( QKeyEvent* event )
{
#if USE_QT4
    _gw->getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) 
*(event->text().toAscii().data() ) );
#else
    _gw->getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) 
event->ascii() );
#endif
}

void AdapterWidget::mousePressEvent( QMouseEvent* event )
{
    int button = 0;
    switch(event->button())
    {
        case(Qt::LeftButton): button = 1; break;
        case(Qt::MidButton): button = 2; break;
        case(Qt::RightButton): button = 3; break;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    _gw->getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
}

void AdapterWidget::mouseReleaseEvent( QMouseEvent* event )
{
    int button = 0;
    switch(event->button())
    {
        case(Qt::LeftButton): button = 1; break;
        case(Qt::MidButton): button = 2; break;
        case(Qt::RightButton): button = 3; break;
        case(Qt::NoButton): button = 0; break;
        default: button = 0; break;
    }
    _gw->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);
}

void AdapterWidget::mouseMoveEvent( QMouseEvent* event )
{
    _gw->getEventQueue()->mouseMotion(event->x(), event->y());
}


class ViewerQT : public osgViewer::Viewer, public AdapterWidget
{
    public:

                ViewerQT(QWidget * parent = 0, const char * name = 0, const 
QGLWidget * shareWidget = 0, WindowFlags f = Qt::WDestructiveClose):
            AdapterWidget( parent, name, shareWidget, f )
        {
            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(getGraphicsWindow());

            setThreadingModel(osgViewer::Viewer::SingleThreaded);

            connect(&_timer, SIGNAL(timeout()), this, SLOT(updateGL()));
            _timer.start(10);
        }
                virtual ~ViewerQT()
                {

                }

        virtual void paintGL()
        {
            frame();
        }
    
    protected:

        QTimer _timer;
};

class CompositeViewerQT : public osgViewer::CompositeViewer, public 
AdapterWidget
{
    public:

        CompositeViewerQT(QWidget * parent = 0, const char * name = 0, const 
QGLWidget * shareWidget = 0, WindowFlags f = 0):
            AdapterWidget( parent, name, shareWidget, f )
        {
            setThreadingModel(osgViewer::CompositeViewer::SingleThreaded);

            connect(&_timer, SIGNAL(timeout()), this, SLOT(updateGL()));
            _timer.start(10);
        }

        virtual void paintGL()
        {
            frame();
        }
    
    protected:

        QTimer _timer;
};

int mainAdapterWidget(QApplication& a, osg::ArgumentParser& arguments)
{
    // load the scene.
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
    if (!loadedModel)
    {
        std::cout << arguments[0] <<": No data loaded." << std::endl;
        return 1;
    }
    
    std::cout<<"Using AdapterWidget - QGLWidget subclassed to integrate with 
osgViewer using its embedded graphics window support."<<std::endl;
    
    if (arguments.read("--CompositeViewer"))
    {
        CompositeViewerQT* viewerWindow = new CompositeViewerQT;

        unsigned int width = viewerWindow->width();
        unsigned int height = viewerWindow->height();
        
        {
            osgViewer::View* view1 = new osgViewer::View;
            
view1->getCamera()->setGraphicsContext(viewerWindow->getGraphicsWindow());
            view1->getCamera()->setProjectionMatrixAsPerspective(30.0f, 
static_cast<double>(width)/static_cast<double>(height/2), 1.0, 1000.0);
            view1->getCamera()->setViewport(new 
osg::Viewport(0,0,width,height/2));
            view1->setCameraManipulator(new osgGA::TrackballManipulator);
            view1->setSceneData(loadedModel.get());
            
            viewerWindow->addView(view1);
        }
        
        {
            osgViewer::View* view2 = new osgViewer::View;
            
view2->getCamera()->setGraphicsContext(viewerWindow->getGraphicsWindow());
            view2->getCamera()->setProjectionMatrixAsPerspective(30.0f, 
static_cast<double>(width)/static_cast<double>(height/2), 1.0, 1000.0);
            view2->getCamera()->setViewport(new 
osg::Viewport(0,height/2,width,height/2));
            view2->setCameraManipulator(new osgGA::TrackballManipulator);
            view2->setSceneData(loadedModel.get());
            
            viewerWindow->addView(view2);
        }

        viewerWindow->show();
#if USE_QT4
    }
    else if (arguments.read("--mdi")) {
          std::cout<<"Using ViewetQT MDI version"<<std::endl;
         /*
         Following problems are found here:
         - miminize causes loaded model to disappear (some problem with Camera 
matrix? - clampProjectionMatrix is invalid)
         */
         ViewerQT* viewerWindow = new ViewerQT;
         viewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);
         viewerWindow->setSceneData(loadedModel.get());
 
         QMainWindow* mw = new QMainWindow();
         QMdiArea* mdiArea = new QMdiArea(mw);
         mw->setCentralWidget(mdiArea);

         QMdiSubWindow *subWindow = mdiArea->addSubWindow(viewerWindow);
         subWindow->showMaximized();
         subWindow->setWindowTitle("New Window");
         mw->show();
#endif // USE_QT4
    } 
        else 
        {
        ViewerQT* viewerWindow = new ViewerQT;

        viewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);
        viewerWindow->setSceneData(loadedModel.get());

        viewerWindow->show();

                ViewerQT* viewerWindow2 = new ViewerQT;

        viewerWindow2->setCameraManipulator(new osgGA::TrackballManipulator);
        viewerWindow2->setSceneData(loadedModel.get());

        viewerWindow2->show();

                ViewerQT* viewerWindow3 = new ViewerQT;

        viewerWindow3->setCameraManipulator(new osgGA::TrackballManipulator);
        viewerWindow3->setSceneData(loadedModel.get());

        viewerWindow3->show();
    }    
    
    
    a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) );
   
    return a.exec();
}

/*EOF*/
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to