QOSGWidget.h 6.25 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/* 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 <osg/Config>

#if defined(_MSC_VER) && defined(OSG_DISABLE_MSVC_WARNINGS)
22 23
// disable warning "'QtConcurrent::BlockSizeManager' : assignment operator could not be generated"
#pragma warning( disable : 4512 )
24 25
#endif

26 27 28 29 30 31 32
#include <QtCore/QString>
#include <QtCore/QTimer>
#include <QtGui/QKeyEvent>
#include <QtGui/QApplication>
#include <QtGui/QtGui>
#include <QtGui/QWidget>
using Qt::WindowFlags;
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

#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>

#ifndef QOSGWIDGET_H
#define QOSGWIDGET_H

class QOSGWidget : public QWidget
{
74
public:
75

76
    QOSGWidget( QWidget * parent = 0, const char * name = 0, WindowFlags f = 0, bool overrideTraits = false);
77

78
    virtual ~QOSGWidget() {}
79

80 81 82 83 84 85
    osgViewer::GraphicsWindow* getGraphicsWindow() {
        return _gw.get();
    }
    const osgViewer::GraphicsWindow* getGraphicsWindow() const {
        return _gw.get();
    }
86

87
protected:
88

89 90
    void init();
    void createContext();
91

92 93 94
    //  The GraphincsWindowWin32 implementation already takes care of message handling.
    //  We don't want to relay these on Windows, it will just cause duplicate messages
    //  with further problems downstream (i.e. not being able to throw the trackball
95
#ifndef WIN32
96 97 98 99 100 101 102 103 104
    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 );
105
#endif
106
    osg::ref_ptr<osgViewer::GraphicsWindow> _gw;
107 108 109 110 111
    bool _overrideTraits;
};

class ViewerQOSG : public osgViewer::Viewer, public QOSGWidget
{
112
public:
113

114
    ViewerQOSG(QWidget * parent = 0, const char * name = 0, WindowFlags f = 0, int fps = 20):
115
        QOSGWidget( parent, name, f ) {
116
        setThreadingModel(osgViewer::Viewer::SingleThreaded);
117

118 119 120
        connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
        _timer.start(1000.0f/fps);
    }
121

122
    void updateCamera() {
123 124 125 126
        getCamera()->setViewport(new osg::Viewport(0,0,width(),height()));
        getCamera()->setProjectionMatrixAsPerspective(30.0f, 1.0f , static_cast<double>(width())/static_cast<double>(height()), 10000.0f);
        getCamera()->setGraphicsContext(getGraphicsWindow());
    }
127

128 129 130 131
    virtual void paintEvent( QPaintEvent * event ) {
        Q_UNUSED(event);
        frame();
    }
132

133
protected:
134

135
    QTimer _timer;
136 137 138 139 140
};


class CompositeViewerQOSG : public osgViewer::CompositeViewer, public QOSGWidget
{
141 142
public:
    CompositeViewerQOSG(QWidget * parent = 0, const char * name = 0, WindowFlags f = 0, int fps = 20)
143
        : QOSGWidget( parent, name, f ) {
144
        setThreadingModel(osgViewer::CompositeViewer::SingleThreaded);
145

146
        connect(&_timer, SIGNAL(timeout()), this, SLOT(repaint()));
147

148 149 150 151 152 153 154
        // The composite viewer needs at least one view to work
        // Create a dummy view with a zero sized viewport and no
        // scene to keep the viewer alive.
        osgViewer::View * pView = new osgViewer::View;
        pView->getCamera()->setGraphicsContext( getGraphicsWindow() );
        pView->getCamera()->setViewport( 0, 0, 0, 0 );
        addView( pView );
155

156 157 158
        // Clear the viewer of removed views
        getGraphicsWindow()->setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
        getGraphicsWindow()->setClearColor( osg::Vec4( 0.08, 0.08, 0.5, 1.0 ) );
159

160 161 162 163
        // 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(1000.0f/fps);
    }
164

165 166 167 168
    virtual void paintEvent( QPaintEvent * event ) {
        Q_UNUSED(event);
        frame();
    }
169

170 171
    void keyPressEvent( QKeyEvent* event ) {
        if ( event->text() == "a" ) {
172
            AddView( _scene.get() );
173
        }
174

175
        if ( event->text() == "r" ) {
176 177 178
            RemoveView();
        }

179 180 181
        QOSGWidget::keyPressEvent( event );
    }

182

183 184 185
    void AddView( osg::Node * scene );
    void RemoveView();
    void Tile();
186

187
    osg::ref_ptr< osg::Node > _scene;
188

189 190
protected:
    QTimer _timer;
191 192 193 194 195 196 197
};

void setupHandlers(osgViewer::View * viewer);


#endif // QOSGWIDGET_H