Thanks Don, I've merged and checked in your changes, with a few little indentation fixes to improve readability. Cheers, Robert.
On Mon, Jan 5, 2009 at 11:20 PM, Don Leich <[email protected]> wrote: > Hi Robert, > > My previous submission was likely ignored since I had not yet subscribed to > to the [email protected] mailing list. So, here goes > again - this version addressing some problems in addition what was updated > in the SVN version. > > Here are a couple of fixes for the file examples/osgviewerQT/QOSGWidget.cpp > to > address some OS X issues. Most of these fixes were previously submitted by > Julian Scheid. However, this patch however should not break the example for > non-OS X builds and has been tested on 64-bit Linux as well as Mac OS X > 10.5. > > o The value returned by QWidget::winId() is not usable as input for > WindowData under OS X the way it is for both Windows and Unix. Julian's fix > for this uses the Carbon API. Since the fix for X11 in unknown, it is now > assumed that OSG has been built with OSG_WINDOWING_SYSTEM='Carbon' for this > example to work at all when running under OS X. > > o The CompositeViewer version would hang on exit with the original timer > start > argument. Changing the argument value to match the non-composite version > seemed to cure the hanging. > > o Julian's patch altered the setGeometry position to 30/30 in order to see > any > window decorations. I did not have this problem, but left his changes > intact. > > o The non-composite viewer needed it's camera initialization defered until > after the ViewerQOSG's Qt base class had been initialized. Otherwise, the > view > did not cover the entire window. > > > There are still issues with resizing and focus handling that need to be > addressed. I have good resize focus and behavior working in some of my > development code that I'll try to migrate to the osgviewerQT code as soon > as I get a chance. The --MTCompositeViewer feature still has severe > problems. > > > --Don > > =0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0= > > Donald Leich Mailto:[email protected] > Senior Software Developer Voice: 201-460-4700 ext: 215 > Intelligent Light FAX: 201-460-0221 > 301 Route 17 North, 7th Floor > Rutherford, NJ 07070-2575 > > Visit our web site at http://www.ilight.com > =0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0=0= > >> >> ------------------------------------------------------------------------ >> >> Hi Julian, >> >> >> >> For further submissions could you please send whole files rather than >> >> patches. I've looked through the patch by hand and it's not in a >> >> state that suitable for merging - breaking all build on all platforms >> >> except yours isn't acceptable so another solution will need to be >> >> found. >> >> >> >> As a general note, I'm confused by the mixing of X11 and Carbon. Is >> >> Qt built against X11 or Carbon? If Qt is built against X11 then >> >> you'll need to select the X11 build for OSG as well. My guess is that >> >> the Qt example might need to have some CMake code in it to direct the >> >> example to compile different paths. >> >> >> >> Robert. >> >> > > > /* 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. > */ > > #if USE_QT4 > > #include <QtCore/QString> > #include <QtCore/QTimer> > #include <QtGui/QKeyEvent> > #include <QtGui/QApplication> > // #include <QtOpenGL/QGLWidget> > #include <QtGui/QtGui> > #include <QtGui/QWidget> > using Qt::WindowFlags; > > #else > > class QWidget; > #include <qtimer.h> > #include <qgl.h> > #include <qapplication.h> > > #define WindowFlags WFlags > > #endif > > > #include <osgViewer/Viewer> > #include <osgViewer/CompositeViewer> > #include <osgViewer/ViewerEventHandlers> > #include <osgViewer/GraphicsWindow> > > #include <osgViewer/ViewerEventHandlers> > > #if defined(WIN32) && !defined(__CYGWIN__) > #include <osgViewer/api/Win32/GraphicsWindowWin32> > typedef HWND WindowHandle; > typedef osgViewer::GraphicsWindowWin32::WindowData WindowData; > #elif defined(__APPLE__) // Assume using Carbon on Mac. > #include <osgViewer/api/Carbon/GraphicsWindowCarbon> > typedef WindowRef WindowHandle; > typedef osgViewer::GraphicsWindowCarbon::WindowData WindowData; > #else // all other unix > #include <osgViewer/api/X11/GraphicsWindowX11> > typedef Window WindowHandle; > typedef osgViewer::GraphicsWindowX11::WindowData WindowData; > #endif > > > #include <osgGA/TrackballManipulator> > #include <osgGA/FlightManipulator> > #include <osgGA/DriveManipulator> > #include <osgGA/KeySwitchMatrixManipulator> > #include <osgGA/StateSetManipulator> > #include <osgGA/AnimationPathManipulator> > #include <osgGA/TerrainManipulator> > > #include <osgDB/ReadFile> > > #include <iostream> > #include <sstream> > > class QOSGWidget : public QWidget > { > public: > > QOSGWidget( QWidget * parent = 0, const char * name = 0, WindowFlags > f = 0, bool overrideTraits = false); > > virtual ~QOSGWidget() {} > > osgViewer::GraphicsWindow* getGraphicsWindow() { return _gw.get(); } > const osgViewer::GraphicsWindow* getGraphicsWindow() const { return > _gw.get(); } > > protected: > > void init(); > void createContext(); > > virtual void mouseDoubleClickEvent ( QMouseEvent * event ); > virtual void closeEvent( QCloseEvent * event ); > virtual void destroyEvent( bool destroyWindow = true, bool > destroySubWindows = true); > virtual void resizeEvent( QResizeEvent * event ); > 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::GraphicsWindow> _gw; > bool _overrideTraits; > }; > > QOSGWidget::QOSGWidget( QWidget * parent, const char * name, WindowFlags f, > bool overrideTraits): > #if USE_QT4 > QWidget(parent, f), _overrideTraits (overrideTraits) > #else > QWidget(parent, name, f), _overrideTraits (overrideTraits) > #endif > { > createContext(); > > > #if USE_QT4 > setAttribute(Qt::WA_PaintOnScreen); > setAttribute(Qt::WA_NoSystemBackground); > setFocusPolicy(Qt::ClickFocus); > #else > setBackgroundMode(Qt::NoBackground); > #endif > } > > void QOSGWidget::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(); > > #if defined(__APPLE__) > // Extract a WindowPtr from the HIViewRef that QWidget::winId() returns. > // Without this change, the peer tries to call GetWindowPort on the > HIViewRef > // which returns 0 and we only render white. > traits->inheritedWindowData = new > WindowData(HIViewGetWindow((HIViewRef)winId())); > > #else // all others > traits->inheritedWindowData = new WindowData(winId()); > #endif > > > 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()); > _gw = dynamic_cast<osgViewer::GraphicsWindow*>(gc.get()); > > // get around dearanged traits on X11 (MTCompositeViewer only) > if (_overrideTraits) > { > traits->x = x(); > traits->y = y(); > traits->width = width(); > traits->height = height(); > } > > } > void QOSGWidget::destroyEvent(bool destroyWindow, bool destroySubWindows) > { > _gw->getEventQueue()->closeWindow(); > } > > > void QOSGWidget::closeEvent( QCloseEvent * event ) > { > #ifndef USE_QT4 > event->accept(); > #endif > > _gw->getEventQueue()->closeWindow(); > } > > > void QOSGWidget::resizeEvent( QResizeEvent * event ) > { > const QSize & size = event->size(); > _gw->getEventQueue()->windowResize(0, 0, size.width(), size.height() ); > _gw->resized(0, 0, size.width(), size.height()); > } > > void QOSGWidget::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 QOSGWidget::keyReleaseEvent( QKeyEvent* event ) > { > #if USE_QT4 > int c = *event->text().toAscii().data(); > #else > int c = event->ascii(); > #endif > > _gw->getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) (c) > ); > } > > void QOSGWidget::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 QOSGWidget::mouseDoubleClickEvent ( 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()->mouseDoubleButtonPress(event->x(), event->y(), > button); > } > void QOSGWidget::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 QOSGWidget::mouseMoveEvent( QMouseEvent* event ) > { > _gw->getEventQueue()->mouseMotion(event->x(), event->y()); > } > > > > > > > > > class ViewerQOSG : public osgViewer::Viewer, public QOSGWidget > { > public: > > ViewerQOSG(QWidget * parent = 0, const char * name = 0, WindowFlags f > = 0): > QOSGWidget( parent, name, f ) > { > setThreadingModel(osgViewer::Viewer::SingleThreaded); > > connect(&_timer, SIGNAL(timeout()), this, SLOT(update())); > _timer.start(10); > } > void 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(getGraphicsWindow()); > } > > virtual void paintEvent( QPaintEvent * event ) { frame(); } > > protected: > > QTimer _timer; > }; > > > > class CompositeViewerQOSG : public osgViewer::CompositeViewer, public > QOSGWidget > { > public: > > CompositeViewerQOSG(QWidget * parent = 0, const char * name = 0, > WindowFlags f = 0): > QOSGWidget( parent, name, f ) > { > setThreadingModel(osgViewer::CompositeViewer::SingleThreaded); > > connect(&_timer, SIGNAL(timeout()), this, SLOT(repaint())); > // The app would hang on exit when using start(1). Behaves > better with 10 > // like the non-composite viewer. Was this just a typo? > _timer.start(10); > } > > virtual void paintEvent( QPaintEvent * event ) { frame(); } > > protected: > > QTimer _timer; > }; > > > > #if USE_QT4 > // we use this wrapper for CompositeViewer ONLY because of the timer > // NOTE: this is a workaround because we're not using QT's moc precompiler > here. > // > class QViewerTimer : public QWidget > { > > public: > > QViewerTimer (QWidget * parent = 0, WindowFlags f = 0): > QWidget (parent, f) > { > _viewer = new osgViewer::CompositeViewer (); > > _viewer->setThreadingModel(osgViewer::CompositeViewer::DrawThreadPerContext); > connect(&_timer, SIGNAL(timeout()), this, SLOT(repaint())); > _timer.start(10); > } > > ~QViewerTimer () > { > _timer.stop (); > } > > virtual void paintEvent (QPaintEvent * event) { _viewer->frame(); } > > osg::ref_ptr <osgViewer::CompositeViewer> _viewer; > QTimer _timer; > > }; > #endif > > void setupManipulatorAndHandler(osgViewer::View & viewer, > osg::ArgumentParser & arguments) > { > // set up the camera manipulators. > { > osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator > = new osgGA::KeySwitchMatrixManipulator; > > keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new > osgGA::TrackballManipulator() ); > keyswitchManipulator->addMatrixManipulator( '2', "Flight", new > osgGA::FlightManipulator() ); > keyswitchManipulator->addMatrixManipulator( '3', "Drive", new > osgGA::DriveManipulator() ); > keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new > osgGA::TerrainManipulator() ); > > viewer.setCameraManipulator( keyswitchManipulator.get() ); > } > > // add the state manipulator > viewer.addEventHandler( new > osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); > > // add the thread model handler > viewer.addEventHandler(new osgViewer::ThreadingHandler); > > // add the window size toggle handler > viewer.addEventHandler(new osgViewer::WindowSizeHandler); > > // add the stats handler > viewer.addEventHandler(new osgViewer::StatsHandler); > > // add the help handler > viewer.addEventHandler(new > osgViewer::HelpHandler(arguments.getApplicationUsage())); > } > > int mainQOSGWidget(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 QOSGWidget - QWidget + osgViewer creating the graphics > context."<<std::endl; > > if (arguments.read("--CompositeViewer")) > { > osg::ref_ptr<CompositeViewerQOSG> viewerWindow(new > CompositeViewerQOSG); > viewerWindow->setGeometry(0,0,640,480); > // Open the ViewerQOSG window at 30/30 instead of 0/0. In some > instances, > // the window may otherwise lack any window decoration. > // viewerWindow->setGeometry(30,30,640,480); > > 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->setSceneData(loadedModel.get()); > > setupManipulatorAndHandler(*view1, arguments); > > 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->setSceneData(loadedModel.get()); > > setupManipulatorAndHandler(*view2, arguments); > > viewerWindow->addView(view2); > } > > viewerWindow->show(); > > a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) ); > > return a.exec(); > } > #if USE_QT4 > else if (arguments.read("--MTCompositeViewer")) > { > > std::cout <<" + using standard CompositeViewer with seperate contexts > (Multithreaded mode / EXPERIMENTAL !)" <<std::endl; > > int nbCowsX = 3; > int nbCowsY = 2; > int size = 300; > unsigned int width = nbCowsX * size; > unsigned int height = nbCowsY * size; > > QGridLayout *uiLayout = new QGridLayout (); > QWidget *wy = new QWidget (); > > // the timer holds an instance of osgViewer::CompositeViewer > // NOTE: this is a workaround since we're not using QT's moc > precompiler here.. > QViewerTimer *ctimer = new QViewerTimer (); > > for (int x=0;x<nbCowsX; x++) > for (int y=0;y<nbCowsY; y++) > { > > // embed the QOSGWidget into QGroupBox to demonstrate that we > // really use QT's Widgets > // > std::stringstream widgetname; widgetname << "View (" << x << > "," << y << ")"; > QGroupBox *w= new QGroupBox (QString (widgetname.str ().c_str > ()), wy); > QGridLayout *tmpl = new QGridLayout (); > QOSGWidget *gw = new QOSGWidget (w, 0, 0, true); > tmpl->addWidget (gw); > w->setLayout(tmpl); > uiLayout->addWidget (w, y, x); > > // setup views as usual > osgViewer::View* view = new osgViewer::View; > view->getCamera()->setGraphicsContext(gw->getGraphicsWindow > ()); > view->getCamera()->setProjectionMatrixAsPerspective > (30.0f, > static_cast<double>(width*2)/static_cast<double>(height), 1.0, 1000.0); > view->getCamera()->setViewport(new > osg::Viewport(0,0,size,size)); > view->addEventHandler(new osgViewer::StatsHandler); > view->setCameraManipulator(new osgGA::TrackballManipulator); > view->setSceneData(loadedModel.get ()); > ctimer->_viewer->addView(view); > > } > > //uiLayout->addWidget (ctimer); > wy->setLayout (uiLayout); > wy->resize (width, height); > wy->show (); > > // we need the timer to be visible for repaints > // NOTE: this is a workaround since we're not using QT's moc > precompiler here.. > ctimer->resize (1,1); > ctimer->show (); > > a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) ); > > return a.exec(); > } > #endif > else > { > osg::ref_ptr<ViewerQOSG> viewerWindow(new ViewerQOSG); > > // Open the ViewerQOSG window at 30/30 instead of 0/0. In some > instances, > // the window may otherwise lack any window decoration. > viewerWindow->setGeometry(0,0,640,480); > // viewerWindow->setGeometry(30,30,640,480); > > // Setup the camera only after ViewerQOSG's Qt base class has been > // initialized. Without this change the view doesn't cover the whole > // window. > viewerWindow->updateCamera(); > viewerWindow->setCameraManipulator(new osgGA::TrackballManipulator); > viewerWindow->setSceneData(loadedModel.get()); > > viewerWindow->show(); > > setupManipulatorAndHandler(*viewerWindow.get(), arguments); > > a.connect( &a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()) ); > > return a.exec(); > } > } > > _______________________________________________ > osg-submissions mailing list > [email protected] > http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org > > _______________________________________________ osg-submissions mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
