2013-06-10 22:34:25 +08:00
# include <QTimer>
# include <QApplication>
# include <QGridLayout>
2011-04-19 19:40:22 +08:00
# include <osgViewer/CompositeViewer>
# include <osgViewer/ViewerEventHandlers>
From Kristofer Tingdahl, "I and my team have gone over the code again, and we feel that we are comfortable in our current proposal for change. It goes deeper than it did before, and I explain why:
There was code in the osgViewer/Viewer.cpp and osgViewer/CompositeViewer.cpp that transformed the Y-coordinates of an event. The code in the composite viewer did however miss the touch-data of the event. I thought that it should really be the GUIEventAdapter that should know about this, and hence I added the
GUIEventAdapter::setMouseYOrientationAndUpdateCoords which is re-computing the coordinates. First I simply added a boolean to the setMouseYOrientation function:
setMouseYOrientation( MouseYOrientation, bool updatecooreds=false );
but then the serializer complained.
This function is called from both the Viewer and the CompositeViewer. We have not tested from the viewer, but I cannot see it would not work from visual inspection.
The other change is in MultiTouchTrackballManipulator::handleMultiTouchDrag. I have removed the normalisation. The reason for that is that it normalised into screen coordinates from 0,0 to 1,1. The problem with that is that if you have a pinch event and you keep the distance say 300 pixels between your fingers, these 300 pixels represent 0.20 of the screen in the horizontal domain, but 0.3 of the screen in the vertical domain. A rotation of the pinch-fingers will hence result in a zoom in, as the normalised distance is changing between them.
A consequence of this is that I have changed the pan-code to use the same algorithm as the middle-mouse-pan.
The rest of it is very similar from previous revision, and there has been some fine-tuning here and there.
"
2014-04-25 01:14:54 +08:00
# include <osgGA/MultiTouchTrackballManipulator>
2011-04-19 19:40:22 +08:00
# include <osgDB/ReadFile>
# include <osgQt/GraphicsWindowQt>
# include <iostream>
class ViewerWidget : public QWidget , public osgViewer : : CompositeViewer
{
public :
2015-02-26 03:19:37 +08:00
ViewerWidget ( QWidget * parent = 0 , Qt : : WindowFlags f = 0 , osgViewer : : ViewerBase : : ThreadingModel threadingModel = osgViewer : : CompositeViewer : : SingleThreaded ) : QWidget ( parent , f )
2011-04-19 19:40:22 +08:00
{
2011-05-16 17:15:02 +08:00
setThreadingModel ( threadingModel ) ;
2013-07-19 17:43:54 +08:00
2013-06-10 22:34:25 +08:00
// disable the default setting of viewer.done() by pressing Escape.
setKeyEventSetsDone ( 0 ) ;
2011-04-19 19:40:22 +08:00
2015-10-22 21:42:19 +08:00
QWidget * widget1 = addViewWidget ( createGraphicsWindow ( 0 , 0 , 100 , 100 ) , osgDB : : readRefNodeFile ( " cow.osgt " ) ) ;
QWidget * widget2 = addViewWidget ( createGraphicsWindow ( 0 , 0 , 100 , 100 ) , osgDB : : readRefNodeFile ( " glider.osgt " ) ) ;
QWidget * widget3 = addViewWidget ( createGraphicsWindow ( 0 , 0 , 100 , 100 ) , osgDB : : readRefNodeFile ( " axes.osgt " ) ) ;
QWidget * widget4 = addViewWidget ( createGraphicsWindow ( 0 , 0 , 100 , 100 ) , osgDB : : readRefNodeFile ( " fountain.osgt " ) ) ;
QWidget * popupWidget = addViewWidget ( createGraphicsWindow ( 900 , 100 , 320 , 240 , " Popup window " , true ) , osgDB : : readRefNodeFile ( " dumptruck.osgt " ) ) ;
2011-04-19 19:40:22 +08:00
popupWidget - > show ( ) ;
QGridLayout * grid = new QGridLayout ;
grid - > addWidget ( widget1 , 0 , 0 ) ;
grid - > addWidget ( widget2 , 0 , 1 ) ;
grid - > addWidget ( widget3 , 1 , 0 ) ;
grid - > addWidget ( widget4 , 1 , 1 ) ;
setLayout ( grid ) ;
connect ( & _timer , SIGNAL ( timeout ( ) ) , this , SLOT ( update ( ) ) ) ;
_timer . start ( 10 ) ;
}
2013-07-19 17:43:54 +08:00
2015-10-22 21:42:19 +08:00
QWidget * addViewWidget ( osgQt : : GraphicsWindowQt * gw , osg : : ref_ptr < osg : : Node > scene )
2011-04-19 19:40:22 +08:00
{
osgViewer : : View * view = new osgViewer : : View ;
addView ( view ) ;
2013-07-19 17:43:54 +08:00
osg : : Camera * camera = view - > getCamera ( ) ;
camera - > setGraphicsContext ( gw ) ;
const osg : : GraphicsContext : : Traits * traits = gw - > getTraits ( ) ;
camera - > setClearColor ( osg : : Vec4 ( 0.2 , 0.2 , 0.6 , 1.0 ) ) ;
camera - > setViewport ( new osg : : Viewport ( 0 , 0 , traits - > width , traits - > height ) ) ;
camera - > setProjectionMatrixAsPerspective ( 30.0f , static_cast < double > ( traits - > width ) / static_cast < double > ( traits - > height ) , 1.0f , 10000.0f ) ;
2011-04-19 19:40:22 +08:00
view - > setSceneData ( scene ) ;
view - > addEventHandler ( new osgViewer : : StatsHandler ) ;
From Kristofer Tingdahl, "I and my team have gone over the code again, and we feel that we are comfortable in our current proposal for change. It goes deeper than it did before, and I explain why:
There was code in the osgViewer/Viewer.cpp and osgViewer/CompositeViewer.cpp that transformed the Y-coordinates of an event. The code in the composite viewer did however miss the touch-data of the event. I thought that it should really be the GUIEventAdapter that should know about this, and hence I added the
GUIEventAdapter::setMouseYOrientationAndUpdateCoords which is re-computing the coordinates. First I simply added a boolean to the setMouseYOrientation function:
setMouseYOrientation( MouseYOrientation, bool updatecooreds=false );
but then the serializer complained.
This function is called from both the Viewer and the CompositeViewer. We have not tested from the viewer, but I cannot see it would not work from visual inspection.
The other change is in MultiTouchTrackballManipulator::handleMultiTouchDrag. I have removed the normalisation. The reason for that is that it normalised into screen coordinates from 0,0 to 1,1. The problem with that is that if you have a pinch event and you keep the distance say 300 pixels between your fingers, these 300 pixels represent 0.20 of the screen in the horizontal domain, but 0.3 of the screen in the vertical domain. A rotation of the pinch-fingers will hence result in a zoom in, as the normalised distance is changing between them.
A consequence of this is that I have changed the pan-code to use the same algorithm as the middle-mouse-pan.
The rest of it is very similar from previous revision, and there has been some fine-tuning here and there.
"
2014-04-25 01:14:54 +08:00
view - > setCameraManipulator ( new osgGA : : MultiTouchTrackballManipulator ) ;
gw - > setTouchEventsEnabled ( true ) ;
2013-07-19 17:43:54 +08:00
return gw - > getGLWidget ( ) ;
2011-04-19 19:40:22 +08:00
}
2013-07-19 17:43:54 +08:00
osgQt : : GraphicsWindowQt * createGraphicsWindow ( int x , int y , int w , int h , const std : : string & name = " " , bool windowDecoration = false )
2011-04-19 19:40:22 +08:00
{
osg : : DisplaySettings * ds = osg : : DisplaySettings : : instance ( ) . get ( ) ;
osg : : ref_ptr < osg : : GraphicsContext : : Traits > traits = new osg : : GraphicsContext : : Traits ;
traits - > windowName = name ;
traits - > windowDecoration = windowDecoration ;
traits - > x = x ;
traits - > y = y ;
traits - > width = w ;
traits - > height = h ;
traits - > doubleBuffer = true ;
traits - > alpha = ds - > getMinimumNumAlphaBits ( ) ;
traits - > stencil = ds - > getMinimumNumStencilBits ( ) ;
traits - > sampleBuffers = ds - > getMultiSamples ( ) ;
traits - > samples = ds - > getNumMultiSamples ( ) ;
2013-07-19 17:43:54 +08:00
return new osgQt : : GraphicsWindowQt ( traits . get ( ) ) ;
2011-04-19 19:40:22 +08:00
}
2013-07-19 17:43:54 +08:00
2011-04-19 19:40:22 +08:00
virtual void paintEvent ( QPaintEvent * event )
{ frame ( ) ; }
protected :
2013-07-19 17:43:54 +08:00
2011-04-19 19:40:22 +08:00
QTimer _timer ;
} ;
int main ( int argc , char * * argv )
{
2011-05-16 17:15:02 +08:00
osg : : ArgumentParser arguments ( & argc , argv ) ;
2014-01-23 18:09:53 +08:00
# if QT_VERSION >= 0x050000
// 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
osgViewer : : ViewerBase : : ThreadingModel threadingModel = osgViewer : : ViewerBase : : SingleThreaded ;
# else
2011-05-16 17:15:02 +08:00
osgViewer : : ViewerBase : : ThreadingModel threadingModel = osgViewer : : ViewerBase : : CullDrawThreadPerContext ;
2014-01-23 18:09:53 +08:00
# endif
2011-05-16 17:15:02 +08:00
while ( arguments . read ( " --SingleThreaded " ) ) threadingModel = osgViewer : : ViewerBase : : SingleThreaded ;
while ( arguments . read ( " --CullDrawThreadPerContext " ) ) threadingModel = osgViewer : : ViewerBase : : CullDrawThreadPerContext ;
while ( arguments . read ( " --DrawThreadPerContext " ) ) threadingModel = osgViewer : : ViewerBase : : DrawThreadPerContext ;
while ( arguments . read ( " --CullThreadPerCameraDrawThreadPerContext " ) ) threadingModel = osgViewer : : ViewerBase : : CullThreadPerCameraDrawThreadPerContext ;
2013-07-19 17:43:54 +08:00
2015-03-20 19:48:21 +08:00
# if QT_VERSION >= 0x040800
// Required for multithreaded QGLWidget on Linux/X11, see http://blog.qt.io/blog/2011/06/03/threaded-opengl-in-4-8/
if ( threadingModel ! = osgViewer : : ViewerBase : : SingleThreaded )
QApplication : : setAttribute ( Qt : : AA_X11InitThreads ) ;
# endif
2015-10-22 21:42:19 +08:00
2011-04-19 19:40:22 +08:00
QApplication app ( argc , argv ) ;
2015-02-26 03:19:37 +08:00
ViewerWidget * viewWidget = new ViewerWidget ( 0 , Qt : : Widget , threadingModel ) ;
2011-04-19 19:40:22 +08:00
viewWidget - > setGeometry ( 100 , 100 , 800 , 600 ) ;
viewWidget - > show ( ) ;
return app . exec ( ) ;
}