1 #include <QTimer>
2 #include <QApplication>
3 #include <QGridLayout>
4 
5 #include <osgViewer/CompositeViewer>
6 #include <osgViewer/ViewerEventHandlers>
7 
8 #include <osgGA/MultiTouchTrackballManipulator>
9 
10 #include <osgDB/ReadFile>
11 
12 #include <osgQt/GraphicsWindowQt>
13 
14 #include <iostream>
15 
16 class ViewerWidget : public QWidget, public osgViewer::CompositeViewer
17 {
18 public:
ViewerWidget(QWidget * parent=0,Qt::WindowFlags f=0,osgViewer::ViewerBase::ThreadingModel threadingModel=osgViewer::CompositeViewer::SingleThreaded)19     ViewerWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, osgViewer::ViewerBase::ThreadingModel threadingModel=osgViewer::CompositeViewer::SingleThreaded) : QWidget(parent, f)
20     {
21         setThreadingModel(threadingModel);
22 
23         // disable the default setting of viewer.done() by pressing Escape.
24         setKeyEventSetsDone(0);
25 
26         QWidget* widget1 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("cow.osgt") );
27         QWidget* widget2 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("glider.osgt") );
28         QWidget* widget3 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("axes.osgt") );
29         QWidget* widget4 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("fountain.osgt") );
30         QWidget* popupWidget = addViewWidget( createGraphicsWindow(900,100,320,240,"Popup window",true), osgDB::readRefNodeFile("dumptruck.osgt") );
31         popupWidget->show();
32 
33         QGridLayout* grid = new QGridLayout;
34         grid->addWidget( widget1, 0, 0 );
35         grid->addWidget( widget2, 0, 1 );
36         grid->addWidget( widget3, 1, 0 );
37         grid->addWidget( widget4, 1, 1 );
38         setLayout( grid );
39 
40         connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );
41         _timer.start( 10 );
42     }
43 
addViewWidget(osgQt::GraphicsWindowQt * gw,osg::ref_ptr<osg::Node> scene)44     QWidget* addViewWidget( osgQt::GraphicsWindowQt* gw, osg::ref_ptr<osg::Node> scene )
45     {
46         osgViewer::View* view = new osgViewer::View;
47         addView( view );
48 
49         osg::Camera* camera = view->getCamera();
50         camera->setGraphicsContext( gw );
51 
52         const osg::GraphicsContext::Traits* traits = gw->getTraits();
53 
54         camera->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 1.0) );
55         camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );
56         camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 1.0f, 10000.0f );
57 
58         view->setSceneData( scene );
59         view->addEventHandler( new osgViewer::StatsHandler );
60         view->setCameraManipulator( new osgGA::MultiTouchTrackballManipulator );
61         gw->setTouchEventsEnabled( true );
62         return gw->getGLWidget();
63     }
64 
createGraphicsWindow(int x,int y,int w,int h,const std::string & name="",bool windowDecoration=false)65     osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name="", bool windowDecoration=false )
66     {
67         osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
68         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
69         traits->windowName = name;
70         traits->windowDecoration = windowDecoration;
71         traits->x = x;
72         traits->y = y;
73         traits->width = w;
74         traits->height = h;
75         traits->doubleBuffer = true;
76         traits->alpha = ds->getMinimumNumAlphaBits();
77         traits->stencil = ds->getMinimumNumStencilBits();
78         traits->sampleBuffers = ds->getMultiSamples();
79         traits->samples = ds->getNumMultiSamples();
80 
81         return new osgQt::GraphicsWindowQt(traits.get());
82     }
83 
paintEvent(QPaintEvent * event)84     virtual void paintEvent( QPaintEvent* event )
85     { frame(); }
86 
87 protected:
88 
89     QTimer _timer;
90 };
91 
main(int argc,char ** argv)92 int main( int argc, char** argv )
93 {
94     osg::ArgumentParser arguments(&argc, argv);
95 
96 #if QT_VERSION >= 0x050000
97     // Qt5 is currently crashing and reporting "Cannot make QOpenGLContext current in a different thread" when the viewer is run multi-threaded, this is regression from Qt4
98     osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::SingleThreaded;
99 #else
100     osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::CullDrawThreadPerContext;
101 #endif
102 
103     while (arguments.read("--SingleThreaded")) threadingModel = osgViewer::ViewerBase::SingleThreaded;
104     while (arguments.read("--CullDrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::CullDrawThreadPerContext;
105     while (arguments.read("--DrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::DrawThreadPerContext;
106     while (arguments.read("--CullThreadPerCameraDrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::CullThreadPerCameraDrawThreadPerContext;
107 
108 #if QT_VERSION >= 0x040800
109     // Required for multithreaded QGLWidget on Linux/X11, see http://blog.qt.io/blog/2011/06/03/threaded-opengl-in-4-8/
110     if (threadingModel != osgViewer::ViewerBase::SingleThreaded)
111         QApplication::setAttribute(Qt::AA_X11InitThreads);
112 #endif
113 
114     QApplication app(argc, argv);
115     ViewerWidget* viewWidget = new ViewerWidget(0, Qt::Widget, threadingModel);
116     viewWidget->setGeometry( 100, 100, 800, 600 );
117     viewWidget->show();
118     return app.exec();
119 }
120