00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <stdlib.h>
00026
00027 #include <iostream>
00028 #include <list>
00029 #include <string>
00030 #include <vector>
00031
00032 #include <boost/shared_ptr.hpp>
00033 #include <boost/thread/locks.hpp>
00034
00035 #include <osg/Vec3>
00036 #include <osg/Vec4>
00037 #include <osg/ref_ptr>
00038 #include <osgViewer/CompositeViewer>
00039 #include <osgViewer/View>
00040 #include <osgViewer/Viewer>
00041
00042 #include "../common/WColor.h"
00043 #include "../common/WLogger.h"
00044 #include "../common/WPathHelper.h"
00045 #include "../common/math/linearAlgebra/WLinearAlgebra.h"
00046 #include "WGEViewer.h"
00047 #include "exceptions/WGEInitFailed.h"
00048 #include "exceptions/WGESignalSubscriptionFailed.h"
00049 #include "WGraphicsEngine.h"
00050
00051
00052 boost::shared_ptr< WGraphicsEngine > WGraphicsEngine::m_instance = boost::shared_ptr< WGraphicsEngine >();
00053
00054 WGraphicsEngine::WGraphicsEngine():
00055 WThreadedRunner()
00056 {
00057 WLogger::getLogger()->addLogMessage( "Initializing Graphics Engine", "GE", LL_INFO );
00058
00059
00060
00061 #ifndef _WIN32
00062 setenv( "OSGFILEPATH", WPathHelper::getFontPath().file_string().c_str(), 1 );
00063 #else
00064 std::string envStr = std::string( "OSGFILEPATH=" ) + WPathHelper::getFontPath().file_string();
00065 putenv( envStr.c_str() );
00066 #endif
00067
00068 #ifndef __APPLE__
00069
00070 m_viewer = osg::ref_ptr<osgViewer::CompositeViewer>( new osgViewer::CompositeViewer() );
00071 #endif
00072
00073
00074 m_rootNode = new WGEScene();
00075 }
00076
00077 WGraphicsEngine::~WGraphicsEngine()
00078 {
00079
00080 WLogger::getLogger()->addLogMessage( "Shutting down Graphics Engine", "GE", LL_INFO );
00081 }
00082
00083 void WGraphicsEngine::setMultiThreadedViews( bool enable )
00084 {
00085 #ifndef __APPLE__
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 if( !enable )
00096 {
00097 m_viewer->setThreadingModel( osgViewer::Viewer::SingleThreaded );
00098 }
00099 else
00100 {
00101 m_viewer->setThreadingModel( osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext );
00102 }
00103 #endif
00104 }
00105
00106 bool WGraphicsEngine::isMultiThreadedViews() const
00107 {
00108 #ifndef __APPLE__
00109 return ( osgViewer::Viewer::SingleThreaded != m_viewer->getThreadingModel() );
00110 #endif
00111
00112 return false;
00113 }
00114
00115 boost::shared_ptr< WGraphicsEngine > WGraphicsEngine::getGraphicsEngine()
00116 {
00117 if( !m_instance )
00118 {
00119 m_instance = boost::shared_ptr< WGraphicsEngine >( new WGraphicsEngine() );
00120 }
00121
00122 return m_instance;
00123 }
00124
00125 osg::ref_ptr<WGEScene> WGraphicsEngine::getScene()
00126 {
00127 return m_rootNode;
00128 }
00129
00130 boost::shared_ptr<WGEViewer> WGraphicsEngine::createViewer( std::string name, osg::ref_ptr<osg::Referenced> wdata, int x, int y,
00131 int width, int height, WGECamera::ProjectionMode projectionMode,
00132 WColor bgColor )
00133 {
00134 boost::shared_ptr<WGEViewer> viewer = boost::shared_ptr<WGEViewer>(
00135 new WGEViewer( name, wdata, x, y, width, height, projectionMode ) );
00136 viewer->setBgColor( bgColor );
00137 viewer->setScene( getScene() );
00138
00139 #ifndef __APPLE__
00140
00141 m_viewer->addView( viewer->getView() );
00142 #endif
00143
00144
00145 boost::mutex::scoped_lock lock( m_viewersLock );
00146 bool insertSucceeded = m_viewers.insert( make_pair( name, viewer ) ).second;
00147 assert( insertSucceeded == true );
00148
00149 return viewer;
00150 }
00151
00152 void WGraphicsEngine::closeViewer( const std::string name )
00153 {
00154 boost::mutex::scoped_lock lock( m_viewersLock );
00155 if( m_viewers.count( name ) > 0 )
00156 {
00157 m_viewers[name]->close();
00158
00159 m_viewers.erase( name );
00160 }
00161 }
00162
00163 boost::shared_ptr< WGEViewer > WGraphicsEngine::getViewerByName( std::string name )
00164 {
00165 boost::mutex::scoped_lock lock( m_viewersLock );
00166 boost::shared_ptr< WGEViewer > out = m_viewers.count( name ) > 0 ?
00167 m_viewers[name] :
00168 boost::shared_ptr< WGEViewer >();
00169 return out;
00170 }
00171
00172 boost::shared_ptr< WGEViewer > WGraphicsEngine::getViewer()
00173 {
00174 boost::mutex::scoped_lock lock( m_viewersLock );
00175 return m_viewers[ "main" ];
00176 }
00177
00178 bool WGraphicsEngine::isRunning()
00179 {
00180 if( !m_instance )
00181 {
00182 return false;
00183 }
00184
00185 return m_instance->m_running;
00186 }
00187
00188 bool WGraphicsEngine::waitForStartupComplete()
00189 {
00190 if( !m_instance )
00191 {
00192 return false;
00193 }
00194
00195
00196 m_instance->m_startThreadingCondition.wait();
00197
00198
00199 return isRunning();
00200 }
00201
00202 void WGraphicsEngine::threadMain()
00203 {
00204 WLogger::getLogger()->addLogMessage( "Starting Graphics Engine", "GE", LL_INFO );
00205
00206 #ifndef __APPLE__
00207
00208 m_startThreadingCondition.wait();
00209 m_running = true;
00210 m_viewer->startThreading();
00211 m_viewer->run();
00212 m_viewer->stopThreading();
00213 m_running = false;
00214 #endif
00215 }
00216
00217 void WGraphicsEngine::notifyStop()
00218 {
00219 WLogger::getLogger()->addLogMessage( "Stopping Graphics Engine", "GE", LL_INFO );
00220 #ifndef __APPLE__
00221 m_viewer->setDone( true );
00222 #endif
00223 }
00224
00225 void WGraphicsEngine::finalizeStartup()
00226 {
00227 m_startThreadingCondition.notify();
00228 }
00229
00230 void WGraphicsEngine::requestShaderReload()
00231 {
00232 m_reloadShadersSignal();
00233 }
00234
00235 boost::signals2::connection WGraphicsEngine::subscribeSignal( GE_SIGNAL signal, t_GEGenericSignalHandlerType notifier )
00236 {
00237 switch ( signal )
00238 {
00239 case GE_RELOADSHADERS:
00240 return m_reloadShadersSignal.connect( notifier );
00241 default:
00242 std::ostringstream s;
00243 s << "Could not subscribe to unknown signal.";
00244 throw WGESignalSubscriptionFailed( s.str() );
00245 break;
00246 }
00247 }