OpenWalnut  1.3.1
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 "../common/math/linearAlgebra/WLinearAlgebra.h"
46 #include "WGEViewer.h"
47 #include "exceptions/WGEInitFailed.h"
48 #include "exceptions/WGESignalSubscriptionFailed.h"
49 #include "WGraphicsEngineMode.h"
50 
51 #include "WGraphicsEngine.h"
52 
53 // graphics engine instance as singleton
54 boost::shared_ptr< WGraphicsEngine > WGraphicsEngine::m_instance = boost::shared_ptr< WGraphicsEngine >();
55 
58 {
59  WLogger::getLogger()->addLogMessage( "Initializing Graphics Engine", "GE", LL_INFO );
60 
61 #ifdef WGEMODE_MULTITHREADED
62  // initialize OSG render window
63  m_viewer = osg::ref_ptr<osgViewer::CompositeViewer>( new osgViewer::CompositeViewer() );
64  m_viewer->setThreadingModel( osgViewer::ViewerBase::SingleThreaded );
65 #endif
66 
67  // initialize members
68  m_rootNode = new WGEScene();
69 
70  setThreadName( "WGE" );
71 }
72 
74 {
75  // cleanup
76  WLogger::getLogger()->addLogMessage( "Shutting down Graphics Engine", "GE", LL_INFO );
77 }
78 
80 {
81 #ifdef WGEMODE_SINGLETHREADED
82  if( enable )
83  {
84  WLogger::getLogger()->addLogMessage( "WGraphicsEngine::setMultiThreadedViews not implemented for single threaded mode", "GE", LL_INFO );
85  }
86 #else
87  // ThreadingModel: enum with the following possibilities
88  //
89  // SingleThreaded
90  // CullDrawThreadPerContext
91  // ThreadPerContext
92  // DrawThreadPerContext
93  // CullThreadPerCameraDrawThreadPerContext
94  // ThreadPerCamera
95  // AutomaticSelection
96  if( !enable )
97  {
98  m_viewer->setThreadingModel( osgViewer::Viewer::SingleThreaded );
99  }
100  else
101  {
102  m_viewer->setThreadingModel( osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext );
103  }
104 #endif
105 }
106 
108 {
109 #ifdef WGEMODE_MULTITHREADED
110  return ( osgViewer::Viewer::SingleThreaded != m_viewer->getThreadingModel() );
111 #endif
112  // on mac, this always is false currently
113  return false;
114 }
115 
116 boost::shared_ptr< WGraphicsEngine > WGraphicsEngine::getGraphicsEngine()
117 {
118  if( !m_instance )
119  {
120  m_instance = boost::shared_ptr< WGraphicsEngine >( new WGraphicsEngine() );
121  }
122 
123  return m_instance;
124 }
125 
126 osg::ref_ptr<WGEScene> WGraphicsEngine::getScene()
127 {
128  return m_rootNode;
129 }
130 
131 boost::shared_ptr<WGEViewer> WGraphicsEngine::createViewer( std::string name, osg::ref_ptr<osg::Referenced> wdata, int x, int y,
132  int width, int height, WGECamera::ProjectionMode projectionMode,
133  WColor bgColor )
134 {
135  boost::shared_ptr<WGEViewer> viewer = boost::shared_ptr<WGEViewer>(
136  new WGEViewer( name, wdata, x, y, width, height, projectionMode ) );
137  viewer->setBgColor( bgColor );
138  viewer->setScene( getScene() );
139 
140 #ifdef WGEMODE_MULTITHREADED
141  // finally add view
142  m_viewer->addView( viewer->getView() );
143 #endif
144 
145  // store it in viewer list
146  boost::mutex::scoped_lock lock( m_viewersLock );
147  bool insertSucceeded = m_viewers.insert( make_pair( name, viewer ) ).second;
148  assert( insertSucceeded == true ); // if false, viewer with same name already exists
149 
150  return viewer;
151 }
152 
153 void WGraphicsEngine::closeViewer( const std::string name )
154 {
155  boost::mutex::scoped_lock lock( m_viewersLock );
156  if( m_viewers.count( name ) > 0 )
157  {
158  m_viewers[name]->close();
159 
160  m_viewers.erase( name );
161  }
162 }
163 
164 boost::shared_ptr< WGEViewer > WGraphicsEngine::getViewerByName( std::string name )
165 {
166  boost::mutex::scoped_lock lock( m_viewersLock );
167  boost::shared_ptr< WGEViewer > out = m_viewers.count( name ) > 0 ?
168  m_viewers[name] :
169  boost::shared_ptr< WGEViewer >();
170  return out;
171 }
172 
173 boost::shared_ptr< WGEViewer > WGraphicsEngine::getViewer()
174 {
175  boost::mutex::scoped_lock lock( m_viewersLock );
176  return m_viewers[ "Main View" ];
177 }
178 
180 {
181  if( !m_instance )
182  {
183  return false;
184  }
185 
186  return m_instance->m_running;
187 }
188 
190 {
191  if( !m_instance )
192  {
193  WLogger::getLogger()->addLogMessage( "Not Graphics Engine running", "GE", LL_INFO );
194  return false;
195  }
196 
197  WLogger::getLogger()->addLogMessage( "Blocking for graphics engine startup", "GE", LL_INFO );
198  // this ensures that the startup is completed if returning.
199  m_instance->m_startThreadingCondition.wait();
200 
201  WLogger::getLogger()->addLogMessage( "Done blocking for graphics engine startup, maybe running now", "GE", LL_INFO );
202  // did something went wrong? Ensure by checking if really running.
203  return isRunning();
204 }
205 
207 {
208  WLogger::getLogger()->addLogMessage( "Starting Graphics Engine", "GE", LL_INFO );
209 
210 #ifdef WGEMODE_MULTITHREADED
211  // NOTE: this is needed here since the viewer might start without any widgets being initialized properly.
213  m_running = true;
214  m_viewer->startThreading();
215  m_viewer->run();
216  m_viewer->stopThreading();
217  m_running = false;
218 #else
219  //m_startThreadingCondition.wait();
220  m_running = true; // we have to make sure, that we are "running"
221 #endif
222 }
223 
225 {
226  WLogger::getLogger()->addLogMessage( "Stopping Graphics Engine", "GE", LL_INFO );
227 #ifdef WGEMODE_MULTITHREADED
228  m_viewer->setDone( true );
229 #endif
230 }
231 
233 {
235 }
236 
238 {
240 }
241 
242 boost::signals2::connection WGraphicsEngine::subscribeSignal( GE_SIGNAL signal, t_GEGenericSignalHandlerType notifier )
243 {
244  switch( signal )
245  {
246  case GE_RELOADSHADERS:
247  return m_reloadShadersSignal.connect( notifier );
248  case GE_STARTUPCOMPLETE:
249  return m_startThreadingCondition.subscribeSignal( notifier );
250  default:
251  std::ostringstream s;
252  s << "Could not subscribe to unknown signal.";
253  throw WGESignalSubscriptionFailed( s.str() );
254  break;
255  }
256 }