From Don Liech, Qt/OSG integration example
This commit is contained in:
parent
d0916e63c6
commit
9d792c279b
@ -168,7 +168,10 @@ IF(DYNAMIC_OPENSCENEGRAPH)
|
||||
|
||||
IF (QT_FOUND AND QT_QTOPENGL_LIBRARY)
|
||||
ADD_SUBDIRECTORY(osgviewerQT)
|
||||
ENDIF(QT_FOUND AND QT_QTOPENGL_LIBRARY)
|
||||
IF (QT4_FOUND)
|
||||
ADD_SUBDIRECTORY(osgviewerQtWidget)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF (FLTK_FOUND)
|
||||
ADD_SUBDIRECTORY(osgviewerFLTK)
|
||||
|
42
examples/osgviewerQtWidget/CMakeLists.txt
Normal file
42
examples/osgviewerQtWidget/CMakeLists.txt
Normal file
@ -0,0 +1,42 @@
|
||||
#user interface compilation
|
||||
SET(SOURCES_UI testMainWin.ui testOutboardWin.ui)
|
||||
QT4_WRAP_UI( SOURCES_UI_H ${SOURCES_UI})
|
||||
|
||||
#ressources
|
||||
#SET(QtApp_RCCS ressources/images/icons.qrc)
|
||||
#QT4_ADD_RESOURCES(QtApp_RCC_SRCS ${QtApp_RCCS})
|
||||
|
||||
# for the macro Q_OBJECT..
|
||||
SET(SOURCES_H
|
||||
CompositeViewerQOSG.h
|
||||
testMainWin.h
|
||||
testOutboardWin.h
|
||||
)
|
||||
|
||||
QT4_WRAP_CPP( SOURCES_H_MOC ${SOURCES_H} )
|
||||
|
||||
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} "./")
|
||||
|
||||
SET(TARGET_SRC
|
||||
${SOURCES_H_MOC}
|
||||
${SOURCES_UI_H}
|
||||
QOSGWidget.h
|
||||
testOutboardWin.cpp
|
||||
CompositeViewerQOSG.cpp
|
||||
QOSGWidget.cpp
|
||||
testMainWin.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
IF (QT4_FOUND)
|
||||
SET(TARGET_EXTERNAL_LIBRARIES ${QT_QTCORE_LIBRARY_RELEASE} ${QT_QTGUI_LIBRARY_RELEASE} ${QT_QTOPENGL_LIBRARY_RELEASE} )
|
||||
ADD_DEFINITIONS(-DUSE_QT4)
|
||||
ELSE(QT4_FOUND)
|
||||
SET(TARGET_EXTERNAL_LIBRARIES ${QT_LIBRARIES} )
|
||||
ENDIF(QT4_FOUND)
|
||||
|
||||
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR} )
|
||||
|
||||
#### end var setup ###
|
||||
SETUP_EXAMPLE(osgviewerQtWidget)
|
||||
|
22
examples/osgviewerQtWidget/CompositeViewerQOSG.cpp
Normal file
22
examples/osgviewerQtWidget/CompositeViewerQOSG.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
// CompositeViewerQOSG.cpp
|
||||
|
||||
// #include <QCore/QDebug>
|
||||
#include "CompositeViewerQOSG.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
CompositeViewerQOSG::CompositeViewerQOSG( QWidget * parent, Qt::WindowFlags f)
|
||||
: QWidget( parent, f ), osgViewer::CompositeViewer()
|
||||
{
|
||||
setThreadingModel(osgViewer::CompositeViewer::SingleThreaded);
|
||||
|
||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
|
||||
_timer.start(10); // Don't know why 10, but 1 was no faster.
|
||||
}
|
||||
|
||||
|
||||
void CompositeViewerQOSG::paintEvent( QPaintEvent * /* event */ )
|
||||
{
|
||||
frame();
|
||||
}
|
||||
|
||||
|
28
examples/osgviewerQtWidget/CompositeViewerQOSG.h
Normal file
28
examples/osgviewerQtWidget/CompositeViewerQOSG.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef _COMPOSITE_VIEWER_QOSG_HPP_
|
||||
#define _COMPOSITE_VIEWER_QOSG_HPP_
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QWidget>
|
||||
#include <osgViewer/CompositeViewer>
|
||||
|
||||
class QPaintEvent;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class CompositeViewerQOSG : public QWidget, public osgViewer::CompositeViewer
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
public:
|
||||
|
||||
CompositeViewerQOSG( QWidget * parent = 0, Qt::WindowFlags f = 0 );
|
||||
virtual ~CompositeViewerQOSG() {}
|
||||
|
||||
void paintEvent( QPaintEvent * /* event */ );
|
||||
|
||||
protected:
|
||||
QTimer _timer;
|
||||
|
||||
}; // CompositeViewerQOSG
|
||||
|
||||
#endif // _COMPOSITE_VIEWER_QOSG_HPP_
|
606
examples/osgviewerQtWidget/QOSGWidget.cpp
Normal file
606
examples/osgviewerQtWidget/QOSGWidget.cpp
Normal file
@ -0,0 +1,606 @@
|
||||
/* 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 <QtCore/QDebug>
|
||||
#include <CompositeViewerQOSG.h>
|
||||
#include <QOSGWidget.h>
|
||||
|
||||
#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 <Carbon/Carbon.h>
|
||||
#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;
|
||||
// 10/17/08 LM -- osgViewer/api/X11/GraphicsWindowX11 includes X.h.
|
||||
// X.h defines KeyPress and KeyRelease.
|
||||
// By doing so, using QEvent::KeyPress resolves into QEvent::2,
|
||||
// causing a compile error.
|
||||
#undef KeyPress
|
||||
#undef KeyRelease
|
||||
#endif
|
||||
|
||||
QOSGWidget::QOSGWidget( QWidget * parent, WindowFlags f)
|
||||
: QWidget(parent, f),
|
||||
_gw(0)
|
||||
{
|
||||
#if 0
|
||||
// This was a win on Linux. Same as WA_PaintOnScreen?
|
||||
extern void qt_x11_set_global_double_buffer(bool);
|
||||
qt_x11_set_global_double_buffer(false);
|
||||
#endif
|
||||
createContext(parent);
|
||||
|
||||
// Date: Tue, 16 Jun 2009 10:07:16 +0000
|
||||
// From: "Eric Pouliquen" <epouliquen@silicon-worlds.fr>
|
||||
// Subject: Re: [osg-submissions] New QOSGWidget demo with a 4-way split
|
||||
// window and bonus outboard window.
|
||||
// Suggested replacing the two setAttribute calls with this...
|
||||
// setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
// This solverd a flickering problem on Windows
|
||||
// 8600 GT (185.85) and a Quadro FX1400 (182.65)
|
||||
// but causes a visible black border to be visible in the rendering
|
||||
// windows on Linux. This problem gone when WA_PaintOnScreen
|
||||
// is used in combination.
|
||||
|
||||
// Hmmm...
|
||||
// According to Qt doc, WA_PaintOnScreen is X11 only and disables
|
||||
// double-buffering. I think this just means it disables a
|
||||
// buffer swap under Qt control. We want OSG to have full control.
|
||||
//
|
||||
// Equivalent to qt_x11_set_global_double_buffer(false)?
|
||||
//
|
||||
// Tried turning it off and got severe flashing on Linux.
|
||||
// Looks like without this we get an extraneous clear and
|
||||
// buffer swap form Qt.
|
||||
setAttribute(Qt::WA_PaintOnScreen);
|
||||
// This flags that something other than Qt is responsible for
|
||||
// all rendering in the window under the widget's control.
|
||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||
// This seems superfluous now.
|
||||
// setAttribute(Qt::WA_NoSystemBackground);
|
||||
|
||||
// Here or in ViewQOSG?
|
||||
// Either way is OK; but since this class is also the one implementing
|
||||
// eventFilter(), I thought it might be wiser here.
|
||||
// Qt
|
||||
// If you want to see how TAB and SHIFT-TAB work wrt focus,
|
||||
// uncomment the following line.
|
||||
// NOTE: If focusPolicy was set in the .ui file, that setting will
|
||||
// override this. So don't set focusPolicy in the .ui file!
|
||||
if (parent)
|
||||
{
|
||||
|
||||
// The desire is to allow tabbing among the views of the
|
||||
// composite viewer. On Linux, I could get that to work in many
|
||||
// different ways, including setting StrongFocus on the QOSGWidget and
|
||||
// re-implementing focusInEvent() in ViewQOSG. But the only thing
|
||||
// that worked on Windows was to set StrongFocus on the *parent*, NOT
|
||||
// on this QOSGWidget, AND to have ViewQOSG::keyReleaseEvent() do
|
||||
// something special on the release of a Tab or Shift-Tab key. (The
|
||||
// release is seen by the ViewQOSG that is getting the focus.)
|
||||
|
||||
parent->setFocusPolicy( Qt::StrongFocus );
|
||||
|
||||
// This instance of the QOSGWidget becomes the filter object on its
|
||||
// 'parent'. Ie, the child is now filtering events for the parent
|
||||
// QWidget.
|
||||
parent->installEventFilter( this );
|
||||
|
||||
qDebug() << "parent->width() is " << parent->width();
|
||||
qDebug() << "parent->height() is " << parent->height();
|
||||
qDebug() << "parent->x() is " << parent->x();
|
||||
qDebug() << "parent->y() is " << parent->y();
|
||||
|
||||
qDebug() << "width() is " << width();
|
||||
qDebug() << "height() is " << height();
|
||||
qDebug() << "x() is " << x();
|
||||
qDebug() << "y() is " << y();
|
||||
}
|
||||
else
|
||||
setFocusPolicy( Qt::StrongFocus );
|
||||
}
|
||||
|
||||
void QOSGWidget::createContext(QWidget * parent)
|
||||
{
|
||||
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 = "qosgwidget";
|
||||
traits->screenNum = 0;
|
||||
// original location:
|
||||
// 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());
|
||||
|
||||
// A person named Lukas on the OSG group posted that to support embedding
|
||||
// in another window, the following traits had to be set after the
|
||||
// graphics context was created. And he's right, if embedding, you
|
||||
// definitely have to do this AFTER creating the context.... Since it
|
||||
// also works when creating a top-level window, do it here for all cases
|
||||
|
||||
// We may have just gotten some Bad Window errors from X11 calling
|
||||
// XGetWindowAttributes before the Window has been realized.
|
||||
// We'll also have garbage in the traits which get fixed up next.
|
||||
|
||||
// _overrideTraits is superfluous now.
|
||||
|
||||
if (parent)
|
||||
{
|
||||
traits->x = parent->x();
|
||||
traits->y = parent->y();
|
||||
traits->width = parent->width();
|
||||
traits->height = parent->height();
|
||||
}
|
||||
else
|
||||
{
|
||||
traits->x = x();
|
||||
traits->y = y();
|
||||
traits->width = width();
|
||||
traits->height = height();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// From the Qt Doc:
|
||||
// "eventFilter() can accept or reject the event, and allow or deny further
|
||||
// processing of the event.
|
||||
//
|
||||
// If all event filters allow further processing of an event (by each
|
||||
// returning false), the event is sent to the target object, in this case, the
|
||||
// parent of this QOSGWidget instance.
|
||||
//
|
||||
// If one of them stops processing (by returning true), the target (ie the
|
||||
// parent widget) and any later event filters do not get to see the event at
|
||||
// all. "
|
||||
//
|
||||
// Effectively, this filter takes all the events it's interested in, most
|
||||
// notably keyboard events, and passes them along to OSG and *prevents* them
|
||||
// from reaching their intended target, this widget's parent.
|
||||
//
|
||||
// Since QOSGWidget sets Qt focusPolicy to StrongFocus, eventFilter() isn't
|
||||
// needed for the keyboard events...at least this what I've observed on Linux;
|
||||
// however it is essential to support resizing in embedded Qt windows that
|
||||
// aren't a top-level window.
|
||||
//
|
||||
// Addendum: I think the above statement is true only if the parent has the
|
||||
// NoFocus policy? If the parent also has StrongFocus, then
|
||||
// eventFilter() has to return false for key events or tabbing
|
||||
// breaks.
|
||||
//------------------------------------------------------------------------------
|
||||
// Return false to allow event to go to the intended target, the parent of
|
||||
// this QOSGWidget. The only events we really want to go to the parent are
|
||||
// TAB or shift-TAB presses and releases.
|
||||
bool QOSGWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (obj != parent())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (event->type() == QEvent::KeyPress)
|
||||
{
|
||||
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
|
||||
|
||||
if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab)
|
||||
{
|
||||
qDebug() << "QOSGWidget::eventFilter: TAB Press on "
|
||||
<< qPrintable(objectName());
|
||||
|
||||
// Empirically have found that it's not necessary to call
|
||||
// keyPressEvent on tab press ... my guess is that OSG ignores it.
|
||||
keyPressEvent( ke );
|
||||
|
||||
// Return false so that the parent QWidget will process the tab.
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "QOSGWidget::eventFilter: KeyPress on "
|
||||
<< qPrintable(objectName());
|
||||
keyPressEvent( ke );
|
||||
// event handled, return true because parent does not have to see
|
||||
// this event
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (event->type() == QEvent::KeyRelease)
|
||||
{
|
||||
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
|
||||
|
||||
if (ke->key() == Qt::Key_Tab || ke->key() == Qt::Key_Backtab)
|
||||
{
|
||||
qDebug() << "QOSGWidget::eventFilter: TAB Release on "
|
||||
<< qPrintable(objectName());
|
||||
|
||||
keyReleaseEvent( ke );
|
||||
// Return false so that the parent QWidget will process the tab..
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "QOSGWidget::eventFilter: KeyRelease on "
|
||||
<< qPrintable(objectName());
|
||||
keyReleaseEvent( ke );
|
||||
// event handled, return true because parent does not have to see
|
||||
// this event
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (event->type() == QEvent::Resize)
|
||||
{
|
||||
QResizeEvent *re = static_cast<QResizeEvent *>(event);
|
||||
|
||||
qDebug() << "QOSGWidget::eventFilter: width is "
|
||||
<< re->size().width()
|
||||
<< "; height is " << re->size().height()
|
||||
<< " on " << qPrintable(objectName())
|
||||
;
|
||||
|
||||
// Call setGeometry on 'this', which will trigger
|
||||
// QOSGWidget::resizeEvent
|
||||
setGeometry(0, 0, re->size().width(), re->size().height());
|
||||
|
||||
// event handled, return true because parent does not have to see
|
||||
// this event
|
||||
return true;
|
||||
}
|
||||
else if (event->type() == QEvent::Close)
|
||||
{
|
||||
QCloseEvent *ce = static_cast<QCloseEvent *>(event);
|
||||
closeEvent( ce );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip all of the event queue reimplementations on WIN32.
|
||||
// On second thought, all but the key events.
|
||||
#ifndef WIN32
|
||||
|
||||
void QOSGWidget::destroyEvent(bool /* destroyWindow */, bool /* destroySubWindows */ )
|
||||
{
|
||||
qDebug() << "QOSGWidget::destroyEvent";
|
||||
_gw->getEventQueue()->closeWindow();
|
||||
}
|
||||
|
||||
|
||||
void QOSGWidget::closeEvent( QCloseEvent * /* event */ )
|
||||
{
|
||||
qDebug() << "QOSGWidget::closeEvent";
|
||||
_gw->getEventQueue()->closeWindow();
|
||||
}
|
||||
|
||||
|
||||
void QOSGWidget::resizeEvent( QResizeEvent * event )
|
||||
{
|
||||
const QSize & size = event->size();
|
||||
|
||||
qDebug() << "QOSGWidget::resizeEvent on " << qPrintable(objectName())
|
||||
<< " - width is " << size.width()
|
||||
<< "; height is " << size.height();
|
||||
|
||||
_gw->getEventQueue()->windowResize(0, 0, size.width(), size.height() );
|
||||
_gw->resized(0, 0, size.width(), size.height());
|
||||
|
||||
}
|
||||
|
||||
void QOSGWidget::mousePressEvent( QMouseEvent* event )
|
||||
{
|
||||
qDebug() << "QOSGWidget::mousePressEvent on "
|
||||
<< qPrintable(objectName()) << " at X, Y = "
|
||||
<< event->x() << ", " << event->y();
|
||||
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 )
|
||||
{
|
||||
qDebug() << "QOSGWidget::mouseDoubleClickEvent on "
|
||||
<< qPrintable(objectName());
|
||||
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 )
|
||||
{
|
||||
qDebug() << "QOSGWidget::mouseReleaseEvent on "
|
||||
<< qPrintable(objectName()) << " at X, Y = "
|
||||
<< event->x() << ", " << event->y();
|
||||
|
||||
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 )
|
||||
{
|
||||
qDebug() << "QOSGWidget::mouseMoveEvent";
|
||||
_gw->getEventQueue()->mouseMotion(event->x(), event->y());
|
||||
}
|
||||
|
||||
#endif // ndef WIN32
|
||||
|
||||
void QOSGWidget::keyPressEvent( QKeyEvent* event )
|
||||
{
|
||||
qDebug() << "QOSGWidget::keyPressEvent on " << qPrintable(objectName());
|
||||
_gw->getEventQueue()->keyPress(
|
||||
(osgGA::GUIEventAdapter::KeySymbol) *(event->text().toAscii().data() ) );
|
||||
}
|
||||
|
||||
void QOSGWidget::keyReleaseEvent( QKeyEvent* event )
|
||||
{
|
||||
qDebug() << "QOSGWidget::keyReleaseEvent on " << qPrintable(objectName());
|
||||
if (event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab)
|
||||
{
|
||||
qDebug() << "---- It's a TAB Release" ;
|
||||
}
|
||||
else
|
||||
{
|
||||
int c = *event->text().toAscii().data();
|
||||
_gw->getEventQueue()->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) (c) );
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// ViewQOSG creates the traits...
|
||||
ViewQOSG::ViewQOSG( QWidget *parent )
|
||||
: osgViewer::View(),
|
||||
QOSGWidget( parent ),
|
||||
_daw(parent)
|
||||
{
|
||||
|
||||
// OSG
|
||||
setGeometry( 0, 0, parent->width(), parent->height() );
|
||||
|
||||
getCamera()->setGraphicsContext( getGraphicsWindow() );
|
||||
|
||||
getCamera()->setProjectionMatrixAsPerspective(
|
||||
30.0f,
|
||||
static_cast<double>(parent->width()) /
|
||||
static_cast<double>(parent->height()), 1.0, 1000.0);
|
||||
|
||||
getCamera()->setViewport(
|
||||
new osg::Viewport( 0, 0, parent->width(), parent->height()));
|
||||
|
||||
setupManipulatorAndHandler( *this );
|
||||
|
||||
} // ViewQOSG::ViewQOSG
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// note: since ViewQOSG has focusPolicy of Qt::NoFocus, this won't be called,
|
||||
// but leaving it here anyway.
|
||||
// See keyReleaseEvent()
|
||||
void ViewQOSG::focusInEvent( QFocusEvent * /* event */)
|
||||
{
|
||||
qDebug() << "ViewQOSG::focusInEvent on " << qPrintable(objectName());
|
||||
|
||||
CompositeViewerQOSG *cv =
|
||||
dynamic_cast<CompositeViewerQOSG *>(getViewerBase());
|
||||
if (cv)
|
||||
// Tell the viewer that this view's camera should now have focus
|
||||
cv->setCameraWithFocus( getCamera() );
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
//---------------------------------------------------------------------------
|
||||
void ViewQOSG::resizeEvent( QResizeEvent * event )
|
||||
{
|
||||
const QSize & size = event->size();
|
||||
|
||||
qDebug() << "ViewQOSG::resizeEvent: width is "
|
||||
<< size.width() << "; height is " << size.height();
|
||||
|
||||
QOSGWidget::resizeEvent( event );
|
||||
|
||||
// This call seems to be essential to getting a picture after view's
|
||||
// parent QWidget has been collapsed due to QSplitter activity.
|
||||
getCamera()->setProjectionMatrixAsPerspective(
|
||||
30.0f,
|
||||
static_cast<double>(size.width()) /
|
||||
static_cast<double>(size.height()), 1.0, 1000.0);
|
||||
|
||||
////
|
||||
// This is an attempt to prevent Qt from giving tab focus to a ViewQOSG that
|
||||
// has been collapsed; in our example, this can happen by using the QSplitters
|
||||
// in the QMainWindow.
|
||||
//
|
||||
// However, while testing this, discovered the bigger problem:
|
||||
// On *any* resize, osgViewer::CompositeViewer::eventTraversal() calls
|
||||
// setCameraWithFocus(0) (ie, to the first view).
|
||||
// Meanwhile, Qt's focus widget may or may not be the correpsonding ViewQOSG.
|
||||
// Possibly worse, the ViewQOSG corresponding to the first view in the
|
||||
// composite viewer may not even be visible.
|
||||
// Doesn't seem to matter in this sense: regardless of which VIEWQOSG gets a
|
||||
// keyboard event, the compositeViewer applies the key's corresponding action
|
||||
// to the current camera/view.
|
||||
//
|
||||
// All of which suggests that trying to support TAB focus on the ViewQOSG
|
||||
// widgets just isn't worth it.
|
||||
|
||||
// if (size.width() == 0 || size.height() == 0)
|
||||
// setFocusPolicy( Qt::NoFocus );
|
||||
// else
|
||||
// setFocusPolicy( Qt::StrongFocus );
|
||||
|
||||
////
|
||||
|
||||
} // ViewQOSG::resizeEvent
|
||||
#endif // WIN32
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Reimplementing keyReleaseEvent from QOSGWidget.
|
||||
// When tabbing in Qt, the current widget sees the TAB Press and the widget
|
||||
// that gets the focus sees the TAB Release.
|
||||
// On that TAB Release, we need to tell the CompositeViewer the camera that
|
||||
// should now have the focus.
|
||||
//
|
||||
// SEE COMMENTS IN ViewQOSG::resizeEvent re how resizing screws this all up...
|
||||
|
||||
void ViewQOSG::keyReleaseEvent( QKeyEvent* event )
|
||||
{
|
||||
qDebug() << "ViewQOSG::keyReleaseEvent on " << qPrintable(objectName());
|
||||
|
||||
if (event->key() == Qt::Key_Tab || event->key() == Qt::Key_Backtab)
|
||||
{
|
||||
if (event->key() == Qt::Key_Tab)
|
||||
qDebug() << "... and it's a TAB";
|
||||
else
|
||||
qDebug() << "... and it's a SHIFT-TAB";
|
||||
|
||||
CompositeViewerQOSG *cv =
|
||||
dynamic_cast<CompositeViewerQOSG *>(getViewerBase());
|
||||
if (cv)
|
||||
{
|
||||
// Tell the viewer that this view's camera should now have focus
|
||||
cv->setCameraWithFocus( getCamera() );
|
||||
|
||||
// Note that the Stats come up wherever; having little success in
|
||||
// getting them to come up in a specific osgView.
|
||||
// cv->setEventQueue( _gw->getEventQueue() );
|
||||
}
|
||||
// and otherwise ignore the event
|
||||
}
|
||||
else
|
||||
{
|
||||
QOSGWidget::keyReleaseEvent( event );
|
||||
}
|
||||
|
||||
} // ViewQOSG::keyReleaseEvent
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void ViewQOSG::setData( osg::ref_ptr<osg::Node> loadedModel )
|
||||
{
|
||||
setSceneData(loadedModel.get());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
float ViewQOSG::aspectRatio( int width, int height )
|
||||
{
|
||||
return static_cast<float>(width) / static_cast<float>(height);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void setupManipulatorAndHandler(osgViewer::View & view
|
||||
/*, 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() );
|
||||
|
||||
view.setCameraManipulator( keyswitchManipulator.get() );
|
||||
}
|
||||
|
||||
// add the state manipulator
|
||||
view.addEventHandler( new osgGA::StateSetManipulator(
|
||||
view.getCamera()->getOrCreateStateSet()) );
|
||||
|
||||
// add the thread model handler
|
||||
view.addEventHandler(new osgViewer::ThreadingHandler);
|
||||
|
||||
// add the window size toggle handler
|
||||
view.addEventHandler(new osgViewer::WindowSizeHandler);
|
||||
|
||||
// add the stats handler
|
||||
view.addEventHandler(new osgViewer::StatsHandler);
|
||||
|
||||
// add the help handler
|
||||
view.addEventHandler(new osgViewer::HelpHandler(/*arguments.getApplicationUsage()*/));
|
||||
}
|
||||
|
163
examples/osgviewerQtWidget/QOSGWidget.h
Normal file
163
examples/osgviewerQtWidget/QOSGWidget.h
Normal file
@ -0,0 +1,163 @@
|
||||
/* 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.
|
||||
*/
|
||||
#ifndef _QOSG_WIDGET_HPP_
|
||||
#define _QOSG_WIDGET_HPP_
|
||||
|
||||
|
||||
#include <QtCore/QString>
|
||||
//#include <QtCore/QTimer>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QApplication>
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtGui/QFocusEvent>
|
||||
|
||||
|
||||
using Qt::WindowFlags;
|
||||
|
||||
// Port Note 10/14/08 LM -- I tried putting some of these headers into the
|
||||
// source file, but ran into compile problems. Very order dependent?
|
||||
#include <osgViewer/View>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgViewer/CompositeViewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
#include <osgViewer/GraphicsWindow>
|
||||
|
||||
#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>
|
||||
|
||||
class QOSGWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
|
||||
QOSGWidget( QWidget * parent = 0, WindowFlags f = 0 );
|
||||
|
||||
virtual ~QOSGWidget() {}
|
||||
|
||||
osgViewer::GraphicsWindow* getGraphicsWindow() {
|
||||
return _gw.get();
|
||||
}
|
||||
const osgViewer::GraphicsWindow* getGraphicsWindow() const {
|
||||
return _gw.get();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void init();
|
||||
void createContext( QWidget *qwindow = 0 );
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
// Looking at the doc for Qt::WA_PaintOnScreen this may be appropriate.
|
||||
// Didn't seem to help or hurt.
|
||||
virtual QPaintEngine *paintEngine() { return 0; }
|
||||
|
||||
// Grabbed this from Martin Beckett:
|
||||
// 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
|
||||
|
||||
#ifndef WIN32
|
||||
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 mousePressEvent( QMouseEvent* event );
|
||||
virtual void mouseReleaseEvent( QMouseEvent* event );
|
||||
virtual void mouseMoveEvent( QMouseEvent* event );
|
||||
#endif // ndef WIN32
|
||||
virtual void keyPressEvent( QKeyEvent* event );
|
||||
virtual void keyReleaseEvent( QKeyEvent* event );
|
||||
|
||||
osg::ref_ptr<osgViewer::GraphicsWindow> _gw;
|
||||
bool _overrideTraits;
|
||||
|
||||
}; // QOSGWidget
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// I could get Linux to work in so many different ways.
|
||||
//
|
||||
// But I could get Windows to work in only one way:
|
||||
// 1. If QOSGWidget is constructed with a parent QWidget, the parent's
|
||||
// focusPolicy is set to StrongFocus. The QOSGWidget widget
|
||||
// will have NoFocus, the default for QWidget.
|
||||
//
|
||||
// 2. If ViewQOSG is part of a osgViewer::CompositeViewer,
|
||||
// ViewQOSG::keyReleaseEvent(), on a TAB or Shift-TAB key release,
|
||||
// sets the Viewer's cameraWithFocus to the ViewQOSG's camera.
|
||||
// All other key releases are passed up to QOSGWidget::keyReleaseEvent.
|
||||
//
|
||||
// 3. Since the QOSGWidget's focusPolicy is noFocus, and hence ViewQOSG's
|
||||
// is as well, ViewQOSG::focusInEvent() will never be called.
|
||||
//
|
||||
// This was the only way I could get Windows to allow tabbing to change
|
||||
// which View of the CompositeViewer should have focus.
|
||||
//
|
||||
// Using StrongFocus on the QOSGWidget (and hence ViewQOSG) instead of its
|
||||
// parent caused all sorts of behavioral problems on Windows. For example,
|
||||
// tabbing didn't work as expected. Or it did, but it didn't matter
|
||||
// because the CompositeViewer considered the "current ViewQOSG" to be the
|
||||
// one under the mouse.
|
||||
//
|
||||
// The code we based this on created a class that inherited from
|
||||
// QOSGWidget and osgViewer::Viewer. We instead inherit from
|
||||
// QOSGWidget and osgViewer::View. This allows us to post a different
|
||||
// scene graph in each view that the viewer manages.
|
||||
|
||||
class ViewQOSG : public osgViewer::View, public QOSGWidget
|
||||
{
|
||||
public:
|
||||
ViewQOSG( QWidget *parent /*, osg::GraphicsContext::Traits* traits*/ );
|
||||
|
||||
virtual ~ViewQOSG() {}
|
||||
|
||||
// Reimplement from QWidget
|
||||
#ifndef WIN32
|
||||
virtual void resizeEvent( QResizeEvent * event );
|
||||
#endif // ndef WIN32
|
||||
virtual void keyReleaseEvent( QKeyEvent* event );
|
||||
|
||||
void setData( osg::ref_ptr<osg::Node> loadedModel );
|
||||
|
||||
QWidget * getDrawingAreaWidget() { return _daw; }
|
||||
|
||||
float aspectRatio( int width, int height );
|
||||
|
||||
protected:
|
||||
void focusInEvent( QFocusEvent *event );
|
||||
|
||||
QWidget *_daw; // drawing area widget
|
||||
int _x, _y, _width, _height;
|
||||
|
||||
};
|
||||
|
||||
|
||||
extern void setupManipulatorAndHandler(osgViewer::View & viewer
|
||||
/*, osg::ArgumentParser & arguments*/);
|
||||
#endif // _QOSG_WIDGET_HPP_
|
107
examples/osgviewerQtWidget/README
Normal file
107
examples/osgviewerQtWidget/README
Normal file
@ -0,0 +1,107 @@
|
||||
This now builds with cmake if added to the osg examples tree. A change to
|
||||
examples/CMakeLists.txt is also required.
|
||||
|
||||
It is also possible to build this stand alone with qmake using the .pro file.
|
||||
I think I've made the .pro sufficiently generic to build anywhere. The first
|
||||
couple of lines in the file need to be adjusted for anyone's local environment.
|
||||
|
||||
This builds and runs on Linux and Win32 OK. See status section.
|
||||
|
||||
Mac has some problems. Qt was 4.4.2 and Mac OS X 10.5.2. 1) Had to adjust the
|
||||
.pro file to hide QT_NO_DEBUG_OUTPUT or problems with a Frameworks header. 2)
|
||||
Had to eliminate the outboard window to avoid a crash. 3) Only the lower-left
|
||||
of the 4 views is OK. The other 3 views filled with frame buffer garbage. 4)
|
||||
Maximize twice and we loose the lower-left too.
|
||||
|
||||
My colleague Liz Martin collaborated on the design and did the Qt work.
|
||||
She is known for her copious comments. -- Don Leich, Intelligent Light
|
||||
|
||||
|
||||
Linux/Win32 builds (on Mac substitute make for gmake):
|
||||
|
||||
gmake clean
|
||||
qmake qosgwidget.pro
|
||||
gmake
|
||||
|
||||
|
||||
|
||||
12/05/08 Status
|
||||
---------------
|
||||
o Implemented the skeleton of CompositeViewerQOSG and ViewQOSG (in
|
||||
QOSGWidget.cpp)
|
||||
|
||||
o In testMainWin.ui, osgGraphicsArea is a "promoted" widget: It is promoted to
|
||||
CompositeViewerQOSG
|
||||
|
||||
CompositeViewerQOSG inherits from both QWidget and osgViewer::CompositeViewer
|
||||
|
||||
o ViewQOSG inherits from QOSGWidget (which inherits from QWidget) and
|
||||
osgViewer::View
|
||||
|
||||
o Bagged on allowing tab focus between the ViewQOSG widgets because:
|
||||
|
||||
o on resizing, OSG's CompositeViewer sets the camera (and view) focus to its
|
||||
first osgViewer::View, which can create a disconnect between the Qt widget
|
||||
(ie ViewQOSG) that has the focus and is receiving keyboard events, and the
|
||||
actual ViewQOSG that the composite viewer acts on
|
||||
|
||||
o From empirical observation, it didn't seem to matter which ViewQOSG
|
||||
received the keyboard event; the composite viewer applied the designated
|
||||
action to the view the composite viewer consider current
|
||||
|
||||
o TAB focus would be given to a ViewQOSG even it had been completely
|
||||
collapsed via QSplitter action in the QMainWindow. I was not successful
|
||||
in my attempts to modify this behavior.
|
||||
|
||||
12/15/08 Status
|
||||
---------------
|
||||
|
||||
o In this area, in testMainWin.ui, not only is osgGraphicsArea a promoted
|
||||
widget (to CompositeViewerQOSG), but the 4 subviews are now also promoted
|
||||
widgets, to ViewQOSG.
|
||||
|
||||
o I eliminated QOSGWidget::eventFilter().
|
||||
|
||||
o In QOSGWidget::QOSGWidget(), I no longer take x, y, width, and height from
|
||||
the 'parent', I simply take it from itself.
|
||||
|
||||
Unfortunately, these changes don't help the Windows exe at all. Linux
|
||||
continues to run just fine. But Windows doesn't see that TAB, and doesn't see
|
||||
any *results* of the Key presses (Like 'l' to change lighting.)
|
||||
|
||||
|
||||
5/15/09 Status
|
||||
---------------
|
||||
|
||||
o Applied Martin Beckett's fix for WIN32 event queue handling.
|
||||
|
||||
5/19/09 Status
|
||||
---------------
|
||||
|
||||
o Altered WIN32 event queue handling to not skip key events.
|
||||
|
||||
o Got Mac to build and sort of run. Qt is 4.4.2 and Mac OS X 10.5.2.
|
||||
1) Had to adjust the .pro file to hide QT_NO_DEBUG_OUTPUT or problems with
|
||||
a Frameworks header. 2) Had to eliminate the outboard window to
|
||||
avoid a crash. 3) Only the lower-left of the 4 views is OK.
|
||||
The other 3 views filled with frame buffer garbage. 4) Maximize
|
||||
twice and we loose the lower-left too.
|
||||
|
||||
|
||||
6/18/09 Status
|
||||
---------------
|
||||
|
||||
o Simon Loic provided cmake infrastructure and help me debug some cmake
|
||||
configuration problems. I needed to wipe my out-of-source object tree
|
||||
and start over explicitly defining QT version 4, ala:
|
||||
ccmake ../OpenSceneGraph-2.8.1 -DDESIRED_QT_VERSION=4
|
||||
|
||||
o Reimplemented QWidget::paintEngine to return 0 as recommended by doc.
|
||||
This is purported to stop Qt from rendering anything in our windows.
|
||||
|
||||
o Eric Pouliquen recommended replacing setAttribute Qt::WA_PaintOnScreen
|
||||
and Qt::WA_NoSystemBackground with Qt::WA_OpaquePaintEvent. Seems best
|
||||
if we add Qt::WA_OpaquePaintEvent, get rid of Qt::WA_NoSystemBackground,
|
||||
but keep Qt::WA_PaintOnScreen.
|
||||
|
||||
|
118
examples/osgviewerQtWidget/main.cpp
Normal file
118
examples/osgviewerQtWidget/main.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
// Demo for a 4-way split window with a different scene graph in
|
||||
// each of the 4 views. Also, an optional 5th view in it's own window.
|
||||
// Qt 4.4.3 was used for this example.
|
||||
//
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osg/ArgumentParser>
|
||||
|
||||
#include "testMainWin.h"
|
||||
#include "testOutboardWin.h"
|
||||
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define DO_OUTBOARD_WINDOW 0 // won't go on Mac
|
||||
#else
|
||||
#define DO_OUTBOARD_WINDOW 1
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
int main( int argc, char **argv )
|
||||
|
||||
{
|
||||
QApplication app( argc, argv );
|
||||
|
||||
// load some standard files
|
||||
osg::ref_ptr<osg::Node> Cow = osgDB::readNodeFile("cow.osg");
|
||||
if (!Cow)
|
||||
{
|
||||
qDebug() << "No cow loaded.";
|
||||
return 1;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> Truck = osgDB::readNodeFile("dumptruck.osg");
|
||||
if (!Truck)
|
||||
{
|
||||
qDebug() << "No truck loaded.";
|
||||
return 1;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> Spaceship = osgDB::readNodeFile("spaceship.osg");
|
||||
if (!Spaceship)
|
||||
{
|
||||
qDebug() << "No spaceship loaded.";
|
||||
return 1;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> Cessna = osgDB::readNodeFile("cessna.osg");
|
||||
if (!Cessna)
|
||||
{
|
||||
qDebug() << "No cessna loaded.";
|
||||
return 1;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Node> Fountain = osgDB::readNodeFile("fountain.osg");
|
||||
if (!Fountain)
|
||||
{
|
||||
qDebug() << "No fountain loaded.";
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
app.connect( &app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()) );
|
||||
|
||||
osg::ArgumentParser arguments(&argc, argv);
|
||||
|
||||
QPointer<testMainWin> myMainWindow = new testMainWin;
|
||||
|
||||
#if DO_OUTBOARD_WINDOW
|
||||
QPointer<testOutboardWin> mySecondaryWindow = new testOutboardWin;
|
||||
#endif
|
||||
|
||||
// The .ui file uses the "Promoted" widget, CompositeViewerQOSG
|
||||
osg::ref_ptr<CompositeViewerQOSG> compositeViewer = myMainWindow->ui.osgGraphicsArea;
|
||||
|
||||
osg::ref_ptr<ViewQOSG> view1 = new ViewQOSG( myMainWindow->ui.graphicsView1 );
|
||||
view1->setObjectName("ViewQOSG 1");
|
||||
osg::ref_ptr<ViewQOSG> view2 = new ViewQOSG( myMainWindow->ui.graphicsView2 );
|
||||
view2->setObjectName("ViewQOSG 2");
|
||||
osg::ref_ptr<ViewQOSG> view3 = new ViewQOSG( myMainWindow->ui.graphicsView3 );
|
||||
view3->setObjectName("ViewQOSG 3");
|
||||
osg::ref_ptr<ViewQOSG> view4 = new ViewQOSG( myMainWindow->ui.graphicsView4 );
|
||||
view4->setObjectName("ViewQOSG 4");
|
||||
|
||||
view1->setData( Cow );
|
||||
view2->setData( Truck );
|
||||
view3->setData( Spaceship );
|
||||
view4->setData( Cessna );
|
||||
|
||||
compositeViewer->addView( view1.get() );
|
||||
compositeViewer->addView( view2.get() );
|
||||
compositeViewer->addView( view3.get() );
|
||||
compositeViewer->addView( view4.get() );
|
||||
|
||||
myMainWindow->show();
|
||||
|
||||
#if DO_OUTBOARD_WINDOW
|
||||
QWidget *outboardGfx = mySecondaryWindow->getDrawingAreaWidget();
|
||||
osg::ref_ptr<ViewQOSG> outboardView = static_cast<ViewQOSG*>( outboardGfx );
|
||||
outboardView->setObjectName("ViewQOSG Outboard");
|
||||
outboardView->setData( Fountain );
|
||||
|
||||
// Note that outboardView, in a completely different window, is going to be
|
||||
// managed by the compositeViewer in the QMainWindow.
|
||||
compositeViewer->addView( outboardView.get() );
|
||||
|
||||
mySecondaryWindow->show();
|
||||
#endif
|
||||
|
||||
return app.exec();
|
||||
|
||||
}
|
80
examples/osgviewerQtWidget/qosgwidget.pro
Normal file
80
examples/osgviewerQtWidget/qosgwidget.pro
Normal file
@ -0,0 +1,80 @@
|
||||
# Adjust these for your build environment.
|
||||
win32 {
|
||||
OSGHOME=c:/Program Files/OpenSceneGraph
|
||||
} else {
|
||||
OSGHOME=/usr/osg/OpenSceneGraph-2.8.1
|
||||
#OUT_OF_SOURCE_POSTFIX=
|
||||
# OUT_OF_SOURCE_POSTFIX=.build_debug
|
||||
OUT_OF_SOURCE_POSTFIX=.build_release
|
||||
}
|
||||
|
||||
D=
|
||||
# Uncomment to enable debug library linkinig
|
||||
# CONFIG += debug
|
||||
# D=d
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# This is untested...
|
||||
# Added for Qt-4.5.1 which now requires linking with Frameworks
|
||||
# /usr/local/Trolltech/Qt-4.5.1/lib/QtGui.framework/QtGui
|
||||
#
|
||||
# QMAKE_FLAGS += -F/usr/local/Trolltech/Qt-4.5.1/lib/
|
||||
# LIBS += -framework QtGui -framework QtCore
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
TEMPLATE = app
|
||||
QMAKE_CXXFLAGS_THREAD += -pthread
|
||||
CONFIG += thread
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
win32 {
|
||||
cpu_type = win32_x86
|
||||
} else {
|
||||
|
||||
cpu_type = $$system(uname -m)
|
||||
OBJECTS_DIR = $${cpu_type}
|
||||
TARGET = $${OBJECTS_DIR}/qosgwidget
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
win32 {
|
||||
CONFIG += console
|
||||
DEPENDPATH += .
|
||||
INCLUDEPATH += . $$quote("\"$${OSGHOME}/include\"")
|
||||
|
||||
} else {
|
||||
# Need the extra path to find OpenThreads/Config with out-of-source builds.
|
||||
INCLUDEPATH += $${OSGHOME}$${OUT_OF_SOURCE_POSTFIX}/include $${OSGHOME}/include
|
||||
}
|
||||
|
||||
macx {
|
||||
CONFIG += x86
|
||||
# Uncomment to turn off qDebug() messages:
|
||||
# When uncommented there's a problem with a Frameworks header file??!!
|
||||
# DEFINES += QT_NO_DEBUG_OUTPUT
|
||||
} else {
|
||||
# Comment out to turn on qDebug() messages:
|
||||
DEFINES += QT_NO_DEBUG_OUTPUT
|
||||
}
|
||||
|
||||
|
||||
FORMS = testMainWin.ui testOutboardWin.ui
|
||||
|
||||
HEADERS = testMainWin.h testOutboardWin.h QOSGWidget.h CompositeViewerQOSG.h
|
||||
|
||||
SOURCES += main.cpp testMainWin.cpp testOutboardWin.cpp QOSGWidget.cpp \
|
||||
CompositeViewerQOSG.cpp
|
||||
|
||||
OSG_LIBS= -losgText$${D} -losgGA$${D} -losgFX$${D} \
|
||||
-losgDB$${D} -losgUtil$${D} -losg$${D} \
|
||||
-lOpenThreads$${D} -losgViewer$${D} \
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
win32 {
|
||||
OSG_LIB_DIR=$${OSGHOME}/lib
|
||||
QMAKE_LFLAGS += /LIBPATH:$$quote("\"$${OSG_LIB_DIR}\"")
|
||||
LIBS += $${OSG_LIBS}
|
||||
} else {
|
||||
LIBS += -L$${OSGHOME}$${OUT_OF_SOURCE_POSTFIX}/lib $${OSG_LIBS}
|
||||
}
|
||||
|
11
examples/osgviewerQtWidget/testMainWin.cpp
Normal file
11
examples/osgviewerQtWidget/testMainWin.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "testMainWin.h"
|
||||
|
||||
testMainWin::testMainWin()
|
||||
: QMainWindow()
|
||||
{
|
||||
ui.setupUi( this );
|
||||
connect ( ui.actionExit, SIGNAL(activated(void)), this, SLOT(close()) );
|
||||
|
||||
}
|
||||
|
||||
|
18
examples/osgviewerQtWidget/testMainWin.h
Normal file
18
examples/osgviewerQtWidget/testMainWin.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef TESTMAINWIN_HPP_
|
||||
#define TESTMAINWIN_HPP_
|
||||
|
||||
#include "ui_testMainWin.h"
|
||||
|
||||
class testMainWin : public QMainWindow // QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
testMainWin();
|
||||
|
||||
public: // for now
|
||||
Ui::testMainWin ui;
|
||||
};
|
||||
|
||||
|
||||
#endif // TESTMAINWIN_HPP_
|
108
examples/osgviewerQtWidget/testMainWin.ui
Normal file
108
examples/osgviewerQtWidget/testMainWin.ui
Normal file
@ -0,0 +1,108 @@
|
||||
<ui version="4.0" >
|
||||
<class>testMainWin</class>
|
||||
<widget class="QMainWindow" name="testMainWin" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>621</width>
|
||||
<height>547</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="graphicsArea" >
|
||||
<layout class="QVBoxLayout" name="graphicsAreaVLayout" >
|
||||
<item>
|
||||
<widget class="CompositeViewerQOSG" native="1" name="osgGraphicsArea" >
|
||||
<layout class="QVBoxLayout" name="osgGraphicsAreaVLayout" >
|
||||
<item>
|
||||
<widget class="QSplitter" name="graphicsAreaVSplitter" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QSplitter" name="graphicsAreaHSplitterTop" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QWidget" native="1" name="graphicsView1" />
|
||||
<widget class="QWidget" native="1" name="graphicsView2" />
|
||||
</widget>
|
||||
<widget class="QSplitter" name="graphicsAreaHSplitterBottom" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QWidget" native="1" name="graphicsView3" />
|
||||
<widget class="QWidget" native="1" name="graphicsView4" />
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>621</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuMain" >
|
||||
<property name="title" >
|
||||
<string>Main</string>
|
||||
</property>
|
||||
<addaction name="actionExit" />
|
||||
</widget>
|
||||
<addaction name="menuMain" />
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar" />
|
||||
<widget class="QToolBar" name="sideToolbar" >
|
||||
<property name="windowTitle" >
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<attribute name="toolBarArea" >
|
||||
<enum>LeftToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak" >
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="topToolbar" >
|
||||
<property name="windowTitle" >
|
||||
<string>toolBar_2</string>
|
||||
</property>
|
||||
<attribute name="toolBarArea" >
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak" >
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<action name="actionExit" >
|
||||
<property name="text" >
|
||||
<string>Exit</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>CompositeViewerQOSG</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>CompositeViewerQOSG.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>graphicsView1</tabstop>
|
||||
<tabstop>graphicsView2</tabstop>
|
||||
<tabstop>graphicsView3</tabstop>
|
||||
<tabstop>graphicsView4</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
12
examples/osgviewerQtWidget/testOutboardWin.cpp
Normal file
12
examples/osgviewerQtWidget/testOutboardWin.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "testOutboardWin.h"
|
||||
|
||||
testOutboardWin::testOutboardWin(QWidget *parent)
|
||||
: QDialog( parent )
|
||||
{
|
||||
ui.setupUi( this );
|
||||
}
|
||||
|
||||
QWidget * testOutboardWin::getDrawingAreaWidget(void)
|
||||
{
|
||||
return ui.graphicsView;
|
||||
}
|
20
examples/osgviewerQtWidget/testOutboardWin.h
Normal file
20
examples/osgviewerQtWidget/testOutboardWin.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef TESTPLOTWIN_HPP_
|
||||
#define TESTPLOTWIN_HPP_
|
||||
|
||||
#include "ui_testOutboardWin.h"
|
||||
|
||||
class testOutboardWin : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
testOutboardWin( QWidget *parent = 0 );
|
||||
QWidget *getDrawingAreaWidget();
|
||||
|
||||
private:
|
||||
Ui::testOutboardWindow ui;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // TESTOUTBOARDWIN_HPP_
|
38
examples/osgviewerQtWidget/testOutboardWin.ui
Normal file
38
examples/osgviewerQtWidget/testOutboardWin.ui
Normal file
@ -0,0 +1,38 @@
|
||||
<ui version="4.0" >
|
||||
<class>testOutboardWindow</class>
|
||||
<widget class="QDialog" name="testOutboardWindow" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>278</width>
|
||||
<height>292</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle" >
|
||||
<string>The Outboard Window</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||
<item>
|
||||
<widget class="ViewQOSG" native="1" name="graphicsView" >
|
||||
<property name="minimumSize" >
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ViewQOSG</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>QOSGWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
Reference in New Issue
Block a user