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 ) );
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 ) ) );
95 osg::Program::apply( state );
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 );
std::shared_ptr< WGEShaderDefine< ValueType > > SPtr
Shared pointer for this class.
std::shared_ptr< WGEShaderPreprocessor > SPtr
Shared pointer for this class.
This preprocessor removes the version-statement from the code and puts it to the beginning of the cod...
Update callback which handles the shader reloading.
SafeUpdaterCallback(WGEShader *shader)
Constructor.
virtual void operator()(osg::Node *node, osg::NodeVisitor *nv)
Callback method called by the NodeVisitor when visiting a node.
Class encapsulating the OSG Program class for a more convenient way of adding and modifying shader.
bool m_shaderLoaded
True if the shaders have been loaded successfully previously.
osg::ref_ptr< osg::Shader > m_vertexShader
the vertex shader object
virtual void deactivate(osg::ref_ptr< osg::Node > node)
Removes the shader from the specified node.
std::string processShaderRecursive(const std::string filename, bool optional=false, int level=0)
This method searches and processes all includes in the shader source.
WGEShaderDefine< T >::SPtr setDefine(std::string key, T value)
Sets a define which is include into the shader source code.
virtual void reload()
Initiate a reload of the shader during the next update cycle.
void updatePrograms()
Handles all state changes in m_reload and m_deactivated.
osg::ref_ptr< osg::Shader > m_fragmentShader
the fragment shader object
virtual void applyDirect(osg::State &state)
If enabled, activate our program in the GL pipeline, performing any rebuild operations that might be ...
WGEShaderPreprocessor::SPtr m_versionPreprocessor
This preprocessor needs to be run LAST.
void removePreprocessor(WGEShaderPreprocessor::SPtr preproc)
Removes the specified preprocessor.
void reloadShader()
This completely reloads the shader file and processes it.
boost::signals2::connection m_reloadSignalConnection
Connection object to the reload signal from WGraphbicsEngine.
virtual void apply(osg::ref_ptr< osg::Node > node)
Apply this shader to the specified node.
WGEShader(std::string name, boost::filesystem::path search=WPathHelper::getShaderPath())
Default constructor.
bool m_reload
Flag denoting whether a shader should be reloaded.
void clearPreprocessors()
Removes all preprocessors.
bool m_deactivated
Flag denoting whether a shader should be deactivated.
void addPreprocessor(WGEShaderPreprocessor::SPtr preproc)
Adds the specified preprocessor to this shader.
osg::ref_ptr< osg::Shader > m_geometryShader
the geometry shader object
boost::filesystem::path m_shaderPath
String that stores the location of all shader files.
virtual ~WGEShader()
Destructor.
std::string processShader(const std::string filename, bool optional=false)
This method searches and processes all includes in the shader source.
std::string m_name
The name of the shader.
PreprocessorsList m_preprocessors
List of all pre-processing that need to be applied to this shader instance.
static std::shared_ptr< WGraphicsEngine > getGraphicsEngine()
Returns instance of the graphics engine.
void addLogMessage(std::string message, std::string source="", LogLevel level=LL_DEBUG)
Appends a log message to the logging queue.
static WLogger * getLogger()
Returns pointer to the currently running logger instance.
static boost::filesystem::path getShaderPath()
The path to the global shaders.
T::iterator Iterator
A typedef for the correct iterator to traverse this sequence container.
T::const_iterator ConstIterator
A typedef for the correct const iterator useful to traverse this sequence container.
std::shared_ptr< WSharedObjectTicketRead< T > > ReadTicket
Type for read tickets.
ReadTicket getReadTicket() const
Returns a ticket to get read access to the contained data.
std::shared_ptr< WSharedObjectTicketWrite< T > > WriteTicket
Type for write tickets.
WriteTicket getWriteTicket(bool suppressNotify=false) const
Returns a ticket to get write access to the contained data.