OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 "WGraphicsEngine.h"
50 
51 // graphics engine instance as singleton
52 boost::shared_ptr< WGraphicsEngine > WGraphicsEngine::m_instance = boost::shared_ptr< WGraphicsEngine >();
53 
56 {
57  WLogger::getLogger()->addLogMessage( "Initializing Graphics Engine", "GE", LL_INFO );
58 
59  // NOTE: the osgViewer::StatsHandler uses a hard coded font filename. :-(. Fortunately OSG allows us to modify the search path using
60  // environment variables:
61 #ifndef _WIN32
62  setenv( "OSGFILEPATH", WPathHelper::getFontPath().file_string().c_str(), 1 );
63 #else
64  std::string envStr = std::string( "OSGFILEPATH=" ) + WPathHelper::getFontPath().file_string();
65  putenv( envStr.c_str() );
66 #endif
67 
68 #ifndef __APPLE__
69  // initialize OSG render window
70  m_viewer = osg::ref_ptr<osgViewer::CompositeViewer>( new osgViewer::CompositeViewer() );
71 #endif
72 
73  // initialize members
74  m_rootNode = new WGEScene();
75 }
76 
78 {
79  // cleanup
80  WLogger::getLogger()->addLogMessage( "Shutting down Graphics Engine", "GE", LL_INFO );
81 }
82 
84 {
85 #ifndef __APPLE__
86  // ThreadingModel: enum with the following possibilities
87  //
88  // SingleThreaded
89  // CullDrawThreadPerContext
90  // ThreadPerContext
91  // DrawThreadPerContext
92  // CullThreadPerCameraDrawThreadPerContext
93  // ThreadPerCamera
94  // AutomaticSelection
95  if( !enable )
96  {
97  m_viewer->setThreadingModel( osgViewer::Viewer::SingleThreaded );
98  }
99  else
100  {
101  m_viewer->setThreadingModel( osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext );
102  }
103 #endif
104 }
105 
107 {
108 #ifndef __APPLE__
109  return ( osgViewer::Viewer::SingleThreaded != m_viewer->getThreadingModel() );
110 #endif
111  // on mac, this always is false currently
112  return false;
113 }
114 
115 boost::shared_ptr< WGraphicsEngine > WGraphicsEngine::getGraphicsEngine()
116 {
117  if( !m_instance )
118  {
119  m_instance = boost::shared_ptr< WGraphicsEngine >( new WGraphicsEngine() );
120  }
121 
122  return m_instance;
123 }
124 
125 osg::ref_ptr<WGEScene> WGraphicsEngine::getScene()
126 {
127  return m_rootNode;
128 }
129 
130 boost::shared_ptr<WGEViewer> WGraphicsEngine::createViewer( std::string name, osg::ref_ptr<osg::Referenced> wdata, int x, int y,
131  int width, int height, WGECamera::ProjectionMode projectionMode,
132  WColor bgColor )
133 {
134  boost::shared_ptr<WGEViewer> viewer = boost::shared_ptr<WGEViewer>(
135  new WGEViewer( name, wdata, x, y, width, height, projectionMode ) );
136  viewer->setBgColor( bgColor );
137  viewer->setScene( getScene() );
138 
139 #ifndef __APPLE__
140  // finally add view
141  m_viewer->addView( viewer->getView() );
142 #endif
143 
144  // store it in viewer list
145  boost::mutex::scoped_lock lock( m_viewersLock );
146  bool insertSucceeded = m_viewers.insert( make_pair( name, viewer ) ).second;
147  assert( insertSucceeded == true );
148 
149  return viewer;
150 }
151 
152 void WGraphicsEngine::closeViewer( const std::string name )
153 {
154  boost::mutex::scoped_lock lock( m_viewersLock );
155  if( m_viewers.count( name ) > 0 )
156  {
157  m_viewers[name]->close();
158 
159  m_viewers.erase( name );
160  }
161 }
162 
163 boost::shared_ptr< WGEViewer > WGraphicsEngine::getViewerByName( std::string name )
164 {
165  boost::mutex::scoped_lock lock( m_viewersLock );
166  boost::shared_ptr< WGEViewer > out = m_viewers.count( name ) > 0 ?
167  m_viewers[name] :
168  boost::shared_ptr< WGEViewer >();
169  return out;
170 }
171 
172 boost::shared_ptr< WGEViewer > WGraphicsEngine::getViewer()
173 {
174  boost::mutex::scoped_lock lock( m_viewersLock );
175  return m_viewers[ "main" ];
176 }
177 
179 {
180  if( !m_instance )
181  {
182  return false;
183  }
184 
185  return m_instance->m_running;
186 }
187 
189 {
190  if( !m_instance )
191  {
192  return false;
193  }
194 
195  // this ensures that the startup is completed if returning.
196  m_instance->m_startThreadingCondition.wait();
197 
198  // did something went wrong? Ensure by checking if really running.
199  return isRunning();
200 }
201 
203 {
204  WLogger::getLogger()->addLogMessage( "Starting Graphics Engine", "GE", LL_INFO );
205 
206 #ifndef __APPLE__
207  // NOTE: this is needed here since the viewer might start without any widgets being initialized properly.
209  m_running = true;
210  m_viewer->startThreading();
211  m_viewer->run();
212  m_viewer->stopThreading();
213  m_running = false;
214 #endif
215 }
216 
218 {
219  WLogger::getLogger()->addLogMessage( "Stopping Graphics Engine", "GE", LL_INFO );
220 #ifndef __APPLE__
221  m_viewer->setDone( true );
222 #endif
223 }
224 
226 {
228 }
229 
231 {
233 }
234 
235 boost::signals2::connection WGraphicsEngine::subscribeSignal( GE_SIGNAL signal, t_GEGenericSignalHandlerType notifier )
236 {
237  switch ( signal )
238  {
239  case GE_RELOADSHADERS:
240  return m_reloadShadersSignal.connect( notifier );
241  default:
242  std::ostringstream s;
243  s << "Could not subscribe to unknown signal.";
244  throw WGESignalSubscriptionFailed( s.str() );
245  break;
246  }
247 }