31 #include <boost/algorithm/string.hpp>
32 #include <boost/filesystem.hpp>
33 #include <boost/function.hpp>
34 #include <boost/regex.hpp>
35 #include <boost/signals2/signal.hpp>
36 #include <boost/tokenizer.hpp>
39 #include <osg/StateSet>
41 #include "../../common/WLogger.h"
42 #include "../../common/WPathHelper.h"
43 #include "../../common/WPredicateHelper.h"
44 #include "../WGraphicsEngine.h"
45 #include "WGEShader.h"
46 #include "WGEShaderPreprocessor.h"
47 #include "WGEShaderVersionPreprocessor.h"
51 m_shaderPath( search ),
54 m_shaderLoaded( false ),
55 m_deactivated( false )
58 m_vertexShader = osg::ref_ptr< osg::Shader >(
new osg::Shader( osg::Shader::VERTEX ) );
59 m_fragmentShader = osg::ref_ptr< osg::Shader >(
new osg::Shader( osg::Shader::FRAGMENT ) );
60 m_geometryShader = osg::ref_ptr< osg::Shader >(
new osg::Shader( osg::Shader::GEOMETRY ) );
64 addShader( m_fragmentShader );
65 addShader( m_geometryShader );
83 osg::StateSet* rootState = node->getOrCreateStateSet();
84 rootState->setAttributeAndModes(
this, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED );
89 node->addUpdateCallback( osg::ref_ptr< SafeUpdaterCallback >(
new SafeUpdaterCallback(
this ) ) );
107 osg::StateSet* rootState = node->getOrCreateStateSet();
108 rootState->setAttributeAndModes(
this, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED );
114 node->addUpdateCallback( osg::ref_ptr< SafeUpdaterCallback >(
new SafeUpdaterCallback(
this ) ) );
161 catch(
const std::exception& e )
200 m_shader->updatePrograms();
203 traverse( node, nv );
208 std::stringstream output;
222 "WGEShader (" + filename +
")", LL_ERROR
230 static const boost::regex includeRegexp(
"^[ ]*#[ ]*include[ ]+[\"<](.*)[\">].*" );
239 std::string fn = filename;
240 std::string fnLocal = (
m_shaderPath / filename ).
string();
241 std::string fnLocalShaders = (
m_shaderPath /
"shaders" / filename ).
string();
244 if( boost::filesystem::exists(
m_shaderPath / filename ) )
248 else if( boost::filesystem::exists(
m_shaderPath /
"shaders" / filename ) )
270 std::ifstream input( fn.c_str() );
271 if( !input.is_open() )
282 "WGEShader (" + filename +
")", LL_ERROR
288 "WGEShader (" + filename +
")", LL_ERROR
297 boost::smatch matches;
298 std::size_t lineNo = 0;
300 output <<
"#line 1 ";
302 while( std::getline( input, line ) )
305 if( boost::regex_search( line, matches, includeRegexp ) )
308 output <<
"#line 1" << std::endl;
311 output <<
"#line " << lineNo << std::endl;
351 code = ( *pp ).first->process( filename, code );
362 if( !w->get().count( preproc ) )
365 boost::signals2::connection con = preproc->getChangeCondition()->subscribeSignal( boost::bind( &
WGEShader::reload,
this ) );
366 w->get().insert( std::make_pair( preproc, con ) );
375 if( w->get().count( preproc ) )
377 w->get().operator[]( preproc ).disconnect();
378 w->get().erase( preproc );
391 ( *pp ).second.disconnect();
400 return this->setDefine< bool >( key, true );