OpenWalnut  1.4.0
WGraphicsEngine.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <stdlib.h>
26 
27 #include <iostream>
28 #include <list>
29 #include <string>
30 #include <vector>
31 
32 #include <boost/shared_ptr.hpp>
33 #include <boost/thread/locks.hpp>
34 
35 #include <osg/Vec3>
36 #include <osg/Vec4>
37 #include <osg/ref_ptr>
38 #include <osgViewer/CompositeViewer>
39 #include <osgViewer/View>
40 #include <osgViewer/Viewer>
41 
42 #include "../common/WColor.h"
43 #include "../common/WLogger.h"
44 #include "../common/WPathHelper.h"
45 #include "WGEViewer.h"
46 #include "exceptions/WGEInitFailed.h"
47 #include "exceptions/WGESignalSubscriptionFailed.h"
48 #include "WGraphicsEngineMode.h"
49 #include "postprocessing/WGEPostprocessor.h"
50 
51 #include "WStaticOSGSetup.h"
52 
53 #include "WGraphicsEngine.h"
54 
55 // graphics engine instance as singleton
56 boost::shared_ptr< WGraphicsEngine > WGraphicsEngine::m_instance = boost::shared_ptr< WGraphicsEngine >();
57 
60 {
61  WLogger::getLogger()->addLogMessage( "Initializing Graphics Engine", "GE", LL_INFO );
62 
63 #ifdef WGEMODE_MULTITHREADED
64  // initialize OSG render window
65  m_viewer = osg::ref_ptr<osgViewer::CompositeViewer>( new osgViewer::CompositeViewer() );
66  m_viewer->setThreadingModel( osgViewer::ViewerBase::SingleThreaded );
67 #endif
68 
69  // initialize members
70  m_rootNode = new WGEScene();
71 
72  setThreadName( "WGE" );
73 }
74 
76 {
77  // cleanup
78  WLogger::getLogger()->addLogMessage( "Shutting down Graphics Engine", "GE", LL_INFO );
79 }
80 
82 {
83 #ifdef WGEMODE_SINGLETHREADED
84  if( enable )
85  {
86  WLogger::getLogger()->addLogMessage( "WGraphicsEngine::setMultiThreadedViews not implemented for single threaded mode", "GE", LL_INFO );
87  }
88 #else
89  // ThreadingModel: enum with the following possibilities
90  //
91  // SingleThreaded
92  // CullDrawThreadPerContext
93  // ThreadPerContext
94  // DrawThreadPerContext
95  // CullThreadPerCameraDrawThreadPerContext
96  // ThreadPerCamera
97  // AutomaticSelection
98  if( !enable )
99  {
100  m_viewer->setThreadingModel( osgViewer::Viewer::SingleThreaded );
101  }
102  else
103  {
104  m_viewer->setThreadingModel( osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext );
105  }
106 #endif
107 }
108 
110 {
111 #ifdef WGEMODE_MULTITHREADED
112  return ( osgViewer::Viewer::SingleThreaded != m_viewer->getThreadingModel() );
113 #endif
114  // on mac, this always is false currently
115  return false;
116 }
117 
118 boost::shared_ptr< WGraphicsEngine > WGraphicsEngine::getGraphicsEngine()
119 {
120  if( !m_instance )
121  {
122  m_instance = boost::shared_ptr< WGraphicsEngine >( new WGraphicsEngine() );
123  }
124 
125  return m_instance;
126 }
127 
128 osg::ref_ptr<WGEScene> WGraphicsEngine::getScene()
129 {
130  return m_rootNode;
131 }
132 
133 boost::shared_ptr<WGEViewer> WGraphicsEngine::createViewer( std::string name, osg::ref_ptr<osg::Referenced> wdata, int x, int y,
134  int width, int height, WGECamera::ProjectionMode projectionMode,
135  WColor bgColor )
136 {
137  boost::shared_ptr<WGEViewer> viewer = boost::shared_ptr<WGEViewer>(
138  new WGEViewer( name, wdata, x, y, width, height, projectionMode ) );
139  viewer->setBgColor( bgColor );
140  viewer->setScene( getScene() );
141 
142 #ifdef WGEMODE_MULTITHREADED
143  // finally add view
144  m_viewer->addView( viewer->getView() );
145 #endif
146 
147  // store it in viewer list
148  boost::mutex::scoped_lock lock( m_viewersLock );
149  bool insertSucceeded = m_viewers.insert( make_pair( name, viewer ) ).second;
150  assert( insertSucceeded == true ); // if false, viewer with same name already exists
151 
152  return viewer;
153 }
154 
155 void WGraphicsEngine::closeViewer( const std::string name )
156 {
157  boost::mutex::scoped_lock lock( m_viewersLock );
158  if( m_viewers.count( name ) > 0 )
159  {
160  m_viewers[name]->close();
161 
162  m_viewers.erase( name );
163  }
164 }
165 
166 boost::shared_ptr< WGEViewer > WGraphicsEngine::getViewerByName( std::string name )
167 {
168  boost::mutex::scoped_lock lock( m_viewersLock );
169  boost::shared_ptr< WGEViewer > out = m_viewers.count( name ) > 0 ?
170  m_viewers[name] :
171  boost::shared_ptr< WGEViewer >();
172  return out;
173 }
174 
175 boost::shared_ptr< WGEViewer > WGraphicsEngine::getViewer()
176 {
177  boost::mutex::scoped_lock lock( m_viewersLock );
178  return m_viewers[ "Main View" ];
179 }
180 
182 {
183  if( !m_instance )
184  {
185  return false;
186  }
187 
188  return m_instance->m_running;
189 }
190 
192 {
193  if( !m_instance )
194  {
195  WLogger::getLogger()->addLogMessage( "Not Graphics Engine running", "GE", LL_INFO );
196  return false;
197  }
198 
199  WLogger::getLogger()->addLogMessage( "Blocking for graphics engine startup", "GE", LL_INFO );
200  // this ensures that the startup is completed if returning.
201  m_instance->m_startThreadingCondition.wait();
202 
203  WLogger::getLogger()->addLogMessage( "Done blocking for graphics engine startup, maybe running now", "GE", LL_INFO );
204  // did something went wrong? Ensure by checking if really running.
205  return isRunning();
206 }
207 
209 {
210  WLogger::getLogger()->addLogMessage( "Starting Graphics Engine", "GE", LL_INFO );
211 
212  // initialize all available postprocessors
214 
215 #ifdef WGEMODE_MULTITHREADED
216  // NOTE: this is needed here since the viewer might start without any widgets being initialized properly.
218  m_running = true;
219  m_viewer->startThreading();
220  m_viewer->run();
221  m_viewer->stopThreading();
222  m_running = false;
223 #else
224  //m_startThreadingCondition.wait();
225  m_running = true; // we have to make sure, that we are "running"
226 #endif
227 }
228 
230 {
231  // when stopping the system while the GE is still waiting.
233  WLogger::getLogger()->addLogMessage( "Stopping Graphics Engine", "GE", LL_INFO );
234 #ifdef WGEMODE_MULTITHREADED
235  m_viewer->setDone( true );
236 #endif
237 }
238 
240 {
242 }
243 
245 {
247 }
248 
250 {
252 }
253 
254 boost::signals2::connection WGraphicsEngine::subscribeSignal( GE_SIGNAL signal, t_GEGenericSignalHandlerType notifier )
255 {
256  switch( signal )
257  {
258  case GE_RELOADSHADERS:
259  return m_reloadShadersSignal.connect( notifier );
260  case GE_STARTUPCOMPLETE:
261  return m_startThreadingCondition.subscribeSignal( notifier );
262  default:
263  std::ostringstream s;
264  s << "Could not subscribe to unknown signal.";
265  throw WGESignalSubscriptionFailed( s.str() );
266  break;
267  }
268 }
boost::signals2::connection subscribeSignal(t_ConditionNotifierType notifier) const
Subscribes a specified function to be notified on condition change.
Definition: WCondition.cpp:50
boost::shared_ptr< WGEViewer > createViewer(std::string name, osg::ref_ptr< osg::Referenced > wdata, int x, int y, int width, int height, WGECamera::ProjectionMode projectionMode=WGECamera::ORTHOGRAPHIC, WColor bgColor=WColor(1.0, 1.0, 1.0, 1.0))
Creates a new viewer.
static bool isRunning()
Checks whether the graphics engine is currently running or not.
static boost::shared_ptr< WGraphicsEngine > m_instance
Singleton instance of WGraphicsEngine.
static WLogger * getLogger()
Returns pointer to the currently running logger instance.
Definition: WLogger.cpp:64
WConditionOneShot m_startThreadingCondition
This condition is fired externally if all the GUI startup is done to ensure all OGL stuff is initiali...
void requestShaderReload()
This requests all shaders to reload during the next update cycle.
void addLogMessage(std::string message, std::string source="", LogLevel level=LL_DEBUG)
Appends a log message to the logging queue.
Definition: WLogger.cpp:84
virtual void threadMain()
Handler for repainting and event handling.
ProjectionMode
List of possible camera modes.
Definition: WGECamera.h:43
virtual ~WGraphicsEngine()
Destructor.
osg::ref_ptr< WGEScene > getScene()
Returns the root node of the WGraphicsEngine (this is not the root node of the OSG).
Base class for all classes needing to be executed in a separate thread.
boost::mutex m_viewersLock
Mutex used to lock the map of viewers.
virtual void notifyStop()
Gets called when the thread should be stopped.
static void initPostprocessors()
Needs to be called prior to any "getPostprocessors" call.
Exception thrown if a notifier could not be subscribed to a signal.
bool isMultiThreadedViews() const
Checks whether the viewers work multithreaded.
Class for managing the OpenSceneGraph root node.
Definition: WGEScene.h:35
virtual void notify()
Notifies all waiting threads.
static boost::shared_ptr< WGraphicsEngine > getGraphicsEngine()
Returns instance of the graphics engine.
boost::shared_ptr< WGEViewer > getViewer()
Returns the unnamed view, which is the view for the default scene which can be acquired using getScen...
void closeViewer(const std::string name)
Closes a viewer and deletes it from the list of viewers.
std::map< std::string, boost::shared_ptr< WGEViewer > > m_viewers
All registered viewers.
Class for managing one view to the scene.
Definition: WGEViewer.h:71
WGraphicsEngine()
Constructors are protected because this is a Singleton.
void setThreadName(std::string name)
Set the name of the thread.
void finalizeStartup()
Function notifies the viewer threads (if any) to start.
bool m_running
True if graphics engine is running.
void setMultiThreadedViews(bool enable=true)
Enables multithreaded view.
void waitForFinalize()
Wait until someone called finalizeStartup().
osg::ref_ptr< osgViewer::CompositeViewer > m_viewer
OpenSceneGraph composite viewer.
osg::ref_ptr< WGEScene > m_rootNode
OpenSceneGraph root node.
static bool waitForStartupComplete()
Waits for the GE to come up.
t_GEGenericSignalType m_reloadShadersSignal
Signal getting emitted whenever a reload shader request is waiting.
boost::signals2::connection subscribeSignal(GE_SIGNAL signal, t_GEGenericSignalHandlerType notifier)
Subscribe a specified handler to the specified signal emited by the GE.
virtual void wait() const
Wait for the condition.
boost::shared_ptr< WGEViewer > getViewerByName(std::string name)
Searches for a viewer with a given name and returns it, if found.