OpenWalnut
1.2.5
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 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 // graphics engine instance as singleton 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 // NOTE: the osgViewer::StatsHandler uses a hard coded font filename. :-(. Fortunately OSG allows us to modify the search path using 00060 // environment variables: 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 // initialize OSG render window 00070 m_viewer = osg::ref_ptr<osgViewer::CompositeViewer>( new osgViewer::CompositeViewer() ); 00071 #endif 00072 00073 // initialize members 00074 m_rootNode = new WGEScene(); 00075 } 00076 00077 WGraphicsEngine::~WGraphicsEngine() 00078 { 00079 // cleanup 00080 WLogger::getLogger()->addLogMessage( "Shutting down Graphics Engine", "GE", LL_INFO ); 00081 } 00082 00083 void WGraphicsEngine::setMultiThreadedViews( bool enable ) 00084 { 00085 #ifndef __APPLE__ 00086 // ThreadingModel: enum with the following possibilities 00087 // 00088 // SingleThreaded 00089 // CullDrawThreadPerContext 00090 // ThreadPerContext 00091 // DrawThreadPerContext 00092 // CullThreadPerCameraDrawThreadPerContext 00093 // ThreadPerCamera 00094 // AutomaticSelection 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 // on mac, this always is false currently 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 // finally add view 00141 m_viewer->addView( viewer->getView() ); 00142 #endif 00143 00144 // store it in viewer list 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 // this ensures that the startup is completed if returning. 00196 m_instance->m_startThreadingCondition.wait(); 00197 00198 // did something went wrong? Ensure by checking if really running. 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 // NOTE: this is needed here since the viewer might start without any widgets being initialized properly. 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 }