Commit bd2b2f21 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[CHANGE]

- Every viewer is now in a separate thread
- Moved as many OSG specific code as possible out of QtGLWidget into WGraphicsEngine
parent e29be52e
......@@ -76,6 +76,7 @@ WGEViewer::WGEViewer( osg::ref_ptr<WindowData> wdata, int x, int y, int width, i
WGEViewer::~WGEViewer()
{
// cleanup
wait( true );
}
osg::ref_ptr<osgViewer::CompositeViewer> WGEViewer::getViewer()
......@@ -129,3 +130,20 @@ void WGEViewer::resize( int width, int height )
m_View->getCamera()->setViewport( new osg::Viewport( 0, 0, width, height ) );
}
void WGEViewer::close()
{
// wait for thread to finish
wait( true );
// forward close event
WGEGraphicsWindow::close();
}
void WGEViewer::threadMain()
{
while( !m_FinishRequested )
{
paint();
}
}
......@@ -24,6 +24,8 @@
#ifndef WGEVIEWER_H
#define WGEVIEWER_H
#include <boost/shared_ptr.hpp>
#include <osg/Node>
#include <osgGA/TrackballManipulator>
......@@ -36,8 +38,7 @@
#include <osgViewer/CompositeViewer>
#include <osgViewer/View>
#include <boost/shared_ptr.hpp>
#include "../common/WThreadedRunner.h"
#include "WGEGraphicsWindow.h"
......@@ -46,7 +47,8 @@
* It is, besides WGraphicsEngine, the ONLY entry point for each widget for accessing the graphics engine.
* \ingroup ge
*/
class WGEViewer: public WGEGraphicsWindow
class WGEViewer: public WGEGraphicsWindow,
public WThreadedRunner
{
public:
......@@ -80,6 +82,11 @@ public:
*/
virtual void resize( int width, int height );
/**
* Close the viewer, but wait for the rendering thread to finish.
*/
virtual void close();
/**
* Getter for OpenSceneGraph Viewer instance.
*
......@@ -130,6 +137,10 @@ public:
osg::ref_ptr<osg::Node> getNode();
protected:
/**
* Handler for repainting and event handling. Gets executed in separate thread.
*/
virtual void threadMain();
/**
* OpenSceneGraph viewer.
......
......@@ -23,9 +23,15 @@
#include <iostream>
#include <list>
#include <boost/shared_ptr.hpp>
#include <boost/thread/locks.hpp>
#include "exceptions/WGEInitFailed.h"
#include "../kernel/WKernel.h"
#include "WGraphicsEngine.h"
#include "WGEViewer.h"
WGraphicsEngine::WGraphicsEngine():
WThreadedRunner()
......@@ -42,11 +48,6 @@ WGraphicsEngine::~WGraphicsEngine()
std::cout << "Shutting down Graphics Engine" << std::endl;
}
WGraphicsEngine::WGraphicsEngine( const WGraphicsEngine& other )
{
*this = other;
}
osg::ref_ptr<WGEScene> WGraphicsEngine::getScene()
{
return m_RootNode;
......@@ -54,11 +55,28 @@ osg::ref_ptr<WGEScene> WGraphicsEngine::getScene()
void WGraphicsEngine::threadMain()
{
while( !m_FinishRequested )
{
// TODO(ebaum): is this thread actually needed since each viewer runs in separate thread
// while( !m_FinishRequested )
// {
// currently a dummy
// TODO(ebaum): add drawing and event handling here
sleep( 1 );
}
// sleep( 1 );
// }
}
boost::shared_ptr<WGEViewer> WGraphicsEngine::createViewer( osg::ref_ptr<WindowData> wdata, int x, int y, int width, int height )
{
boost::shared_ptr<WGEViewer> viewer = boost::shared_ptr<WGEViewer>( new WGEViewer( wdata, x, y, width, height ) );
viewer->setScene( WKernel::getRunningKernel()->getGraphicsEngine()->getScene() );
// start rendering
viewer->run();
// store it in viewer list
// XXX is this list needed? If yes someone has to care about a deregisterViewer function
// boost::mutex::scoped_lock lock(m_ViewerLock);
// m_Viewer.push_back( viewer );
return viewer;
}
......@@ -27,13 +27,18 @@
#include <list>
#include <boost/shared_ptr.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <osg/Camera>
#include <osgViewer/Viewer>
#include "WGEScene.h"
#include "WGEGraphicsWindow.h"
#include "WGEViewer.h"
#include "../common/WThreadedRunner.h"
/**
* Base class for initializing the graphics engine. This Class also serves as adaptor to access the graphics
* engine.
......@@ -53,12 +58,6 @@ public:
*/
virtual ~WGraphicsEngine();
/**
* Copy constructor
* \param other Reference on object to copy.
*/
WGraphicsEngine( const WGraphicsEngine& other );
/**
* Returns the root node of the OSG.
*
......@@ -66,6 +65,19 @@ public:
*/
osg::ref_ptr<WGEScene> getScene();
/**
* Creates a new viewer. Does basic initialization and sets the default scene.
*
* \param wdata the WindowData instance for the widget to use as render widget
* \param x X coordinate of widget where to create the context.
* \param y Y coordinate of widget where to create the context.
* \param width Width of the widget.
* \param height Height of the Widget.
* \return the new instance, ready to be used.
* \exception WGEInitFailed thrown if initialization of graphics context or graphics window has failed.
*/
boost::shared_ptr<WGEViewer> createViewer( osg::ref_ptr<WindowData> wdata, int x, int y, int width, int height );
protected:
/**
......@@ -78,6 +90,16 @@ protected:
*/
virtual void threadMain();
/**
* All registered viewer.
*/
std::list<boost::shared_ptr<WGEViewer> > m_Viewer;
/**
* Mutex used to lock the list of viewers.
*/
boost::mutex m_ViewerLock;
private:
};
......
......@@ -47,6 +47,7 @@ void WMainWindow::addDockableGLWidget( QMainWindow *MainWindow )
dockWidget->setAllowedAreas( Qt::LeftDockWidgetArea
| Qt::RightDockWidgetArea );
boost::shared_ptr<WQtGLWidget> widget = boost::shared_ptr<WQtGLWidget>( new WQtGLWidget( dockWidget ) );
// TODO(all): add some way to remove QtGLWidgets on destruction to delete QtGLWidget
m_glWidgets.push_back( widget );
dockWidget->setWidget( widget.get() );
MainWindow->addDockWidget( Qt::LeftDockWidgetArea, dockWidget );
......
......@@ -25,10 +25,11 @@
#include <QtGui/QKeyEvent>
#include "../../kernel/WKernel.h"
#include "WQtGLWidget.h"
#include "../../graphicsEngine/WGEViewer.h"
#include "../../kernel/WKernel.h"
WQtGLWidget::WQtGLWidget( QWidget* parent )
: QWidget( parent ),
......@@ -43,21 +44,15 @@ WQtGLWidget::WQtGLWidget( QWidget* parent )
// 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.
wdata = osg::ref_ptr<WindowData>(
osg::ref_ptr<WindowData> wdata = osg::ref_ptr<WindowData>(
new WindowData( HIViewGetWindow( static_cast<HIViewRef>winId() ) )
);
#else // all others
wdata = osg::ref_ptr<WindowData>( new WindowData( winId() ) );
osg::ref_ptr<WindowData> wdata = osg::ref_ptr<WindowData>( new WindowData( winId() ) );
#endif
// create viewer
m_Viewer = boost::shared_ptr<WGEViewer>( new WGEViewer( wdata, x(), y(), width(), height() ) );
m_Viewer->setScene( WKernel::getRunningKernel()->getGraphicsEngine()->getScene() );
// timer
// XXX this will be done by a separate thread in the future. For prototyping it is enough.
m_Timer.start( 10 );
connect( &m_Timer, SIGNAL( timeout() ), this, SLOT( repaint() ) );
m_Viewer = WKernel::getRunningKernel()->getGraphicsEngine()->createViewer( wdata, x(), y(), width(), height() );
// required
setAttribute( Qt::WA_PaintOnScreen );
......@@ -67,7 +62,7 @@ WQtGLWidget::WQtGLWidget( QWidget* parent )
WQtGLWidget::~WQtGLWidget()
{
m_Timer.stop();
// cleanup
}
QSize WQtGLWidget::sizeHint() const
......@@ -116,7 +111,7 @@ WQtGLWidget::CameraManipulators WQtGLWidget::getCameraManipulators()
void WQtGLWidget::paintEvent( QPaintEvent* event )
{
m_Viewer->paint();
// m_Viewer->paint();
}
#ifndef WIN32
......
......@@ -25,15 +25,14 @@
#define WQTGLWIDGET_H
#include <QtCore/QTimer>
#include <QtOpenGL/QGLWidget>
#include <QtGui/QWidget>
#include <boost/shared_ptr.hpp>
#include "../../graphicsEngine/WGECamera.h"
#include "../../graphicsEngine/WGEGraphicsWindow.h"
#include "../../graphicsEngine/WGEViewer.h"
class WGEViewer;
/**
* A widget containing an open gl display area. This initializes OpenGL context and adds a view to the
......@@ -183,17 +182,6 @@ private:
* Holds the recommended size for the widget
*/
QSize m_recommendedSize;
/**
* Window Data for this widget needed by OpenSceneGraph.
*/
osg::ref_ptr<WindowData> wdata;
/**
* Timer used for permanent redraw of all views. This is just a hack and will be improved
* so that redraws are done by separate threads.
*/
QTimer m_Timer;
};
#endif // WQTGLWIDGET_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment