Commit 21c70af1 authored by Dirk Albrecht's avatar Dirk Albrecht
Browse files

[CHANGE]Modified WShader didn't worked to change Shaders in the rendering...

[CHANGE]Modified WShader didn't worked to change Shaders in the rendering method. Added a new geode to FiberDisplay. OsgNode has now two children of type WTubeDrawable. Each stores one Shader.
parent 20aca258
......@@ -83,6 +83,12 @@ void WShader::apply( osg::ref_ptr< osg::Node > node )
node->addUpdateCallback( osg::ref_ptr< SafeUpdaterCallback >( new SafeUpdaterCallback( this ) ) );
}
void WShader::applyDirect( osg::State& state ) // NOLINT <- ensure this matches the official OSG API by using a non-const ref
{
updatePrograms();
osg::Program::apply( state );
}
void WShader::deactivate( osg::ref_ptr< osg::Node > node )
{
// set the shader attribute
......@@ -102,76 +108,85 @@ void WShader::reload()
m_reload = true;
}
WShader::SafeUpdaterCallback::SafeUpdaterCallback( WShader* shader ):
m_shader( shader )
{
}
void WShader::SafeUpdaterCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
void WShader::reloadShader()
{
// is it needed to do something here?
if ( m_shader->m_deactivated )
try
{
// remove the shaders
m_shader->removeShader( m_shader->m_vertexShader );
m_shader->removeShader( m_shader->m_fragmentShader );
m_shader->removeShader( m_shader->m_geometryShader );
}
removeShader( m_vertexShader );
removeShader( m_fragmentShader );
removeShader( m_geometryShader );
// reload the sources and set the shader
// vertex shader
WLogger::getLogger()->addLogMessage( "Reloading vertex shader \"" + m_name + "-vertex.glsl\"", "WShader", LL_DEBUG );
std::string source = processShader( m_name + "-vertex.glsl" );
if ( source != "" )
{
m_vertexShader->setShaderSource( source );
addShader( m_vertexShader );
}
else if ( m_shader->m_reload )
{
try
// fragment shader
WLogger::getLogger()->addLogMessage( "Reloading fragment shader \"" + m_name + "-fragment.glsl\"", "WShader", LL_DEBUG );
source = processShader( m_name + "-fragment.glsl" );
if ( source != "" )
{
// remove the shaders
m_shader->removeShader( m_shader->m_vertexShader );
m_shader->removeShader( m_shader->m_fragmentShader );
m_shader->removeShader( m_shader->m_geometryShader );
// reload the sources and set the shader
// vertex shader
WLogger::getLogger()->addLogMessage( "Reloading vertex shader \"" + m_shader->m_name + "-vertex.glsl\"", "WShader", LL_DEBUG );
std::string source = m_shader->processShader( m_shader->m_name + "-vertex.glsl" );
if ( source != "" )
{
m_shader->m_vertexShader->setShaderSource( source );
m_shader->addShader( m_shader->m_vertexShader );
}
m_fragmentShader->setShaderSource( source );
addShader( m_fragmentShader );
}
// fragment shader
WLogger::getLogger()->addLogMessage( "Reloading fragment shader \"" + m_shader->m_name + "-fragment.glsl\"", "WShader", LL_DEBUG );
source = m_shader->processShader( m_shader->m_name + "-fragment.glsl" );
if ( source != "" )
{
m_shader->m_fragmentShader->setShaderSource( source );
m_shader->addShader( m_shader->m_fragmentShader );
}
// Geometry Shader
WLogger::getLogger()->addLogMessage( "Reloading geometry shader \"" + m_name + "-geometry.glsl\"", "WShader", LL_DEBUG );
source = processShader( m_name + "-geometry.glsl", true );
if ( source != "" )
{
m_geometryShader->setShaderSource( source );
addShader( m_geometryShader );
}
// Geometry Shader
WLogger::getLogger()->addLogMessage( "Reloading geometry shader \"" + m_shader->m_name + "-geometry.glsl\"", "WShader", LL_DEBUG );
source = m_shader->processShader( m_shader->m_name + "-geometry.glsl", true );
if ( source != "" )
{
m_shader->m_geometryShader->setShaderSource( source );
m_shader->addShader( m_shader->m_geometryShader );
}
m_shaderLoaded = true;
}
catch( const std::exception& e )
{
m_shaderLoaded = false;
m_shader->m_shaderLoaded = true;
}
catch( const std::exception& e )
{
m_shader->m_shaderLoaded = false;
WLogger::getLogger()->addLogMessage( "Problem loading shader.", "WShader", LL_ERROR );
WLogger::getLogger()->addLogMessage( "Problem loading shader.", "WShader", LL_ERROR );
// clean up the mess
removeShader( m_vertexShader );
removeShader( m_fragmentShader );
removeShader( m_geometryShader );
}
// clean up the mess
m_shader->removeShader( m_shader->m_vertexShader );
m_shader->removeShader( m_shader->m_fragmentShader );
m_shader->removeShader( m_shader->m_geometryShader );
}
// everything done now.
m_reload = false;
}
// everything done now.
m_shader->m_reload = false;
void WShader::updatePrograms()
{
// is it needed to do something here?
if ( m_deactivated )
{
// remove the shaders
removeShader( m_vertexShader );
removeShader( m_fragmentShader );
removeShader( m_geometryShader );
}
else if ( m_reload )
{
reloadShader();
}
}
WShader::SafeUpdaterCallback::SafeUpdaterCallback( WShader* shader ):
m_shader( shader )
{
}
void WShader::SafeUpdaterCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
{
m_shader->updatePrograms();
// forward the call
traverse( node, nv );
......
......@@ -66,6 +66,14 @@ public:
*/
virtual void apply( osg::ref_ptr< osg::Node > node );
/**
* If enabled, activate our program in the GL pipeline, performing any rebuild operations that might be pending. In addition to the standard
* OSG functionality, it also loads/reloads the shader source from file.
*
* \param state the state to apply the shader program to.
*/
virtual void applyDirect( osg::State& state ); // NOLINT <- ensure this matches the official OSG API by using a non-const ref
/**
* Removes the shader from the specified node.
*
......@@ -113,6 +121,16 @@ protected:
*/
std::string processShader( const std::string filename, bool optional = false, int level = 0 );
/**
* This completely reloads the shader file and processes it. It also resets m_reload to false.
*/
void reloadShader();
/**
* Handles all state changes in m_reload and m_deactivated. It ensure that the shader programs are bound properly or deactivated.
*/
void updatePrograms();
/**
* String that stores the location of all shader files
*/
......
......@@ -50,12 +50,15 @@ WMFiberDisplay::WMFiberDisplay()
m_osgNode( osg::ref_ptr< osg::Group >() )
{
m_shaderTubes = osg::ref_ptr< WShader > ( new WShader( "WMFiberDisplay-FakeTubes" ) );
m_shaderTubesPS = osg::ref_ptr< WShader > ( new WShader( "WMFiberDisplay-FakeTubes-PS" ) );
m_shaderTubesQS = osg::ref_ptr< WShader > ( new WShader( "WMFiberDisplay-FakeTubes-QS" ) );
m_shaderTexturedFibers = osg::ref_ptr< WShader > ( new WShader( "WMFiberDisplay-Textured" ) );
m_textureChanged = true;
}
WMFiberDisplay::~WMFiberDisplay()
{
m_fiberDisplayRunning = false;
}
boost::shared_ptr< WModule > WMFiberDisplay::factory() const
......@@ -203,16 +206,27 @@ void WMFiberDisplay::create()
m_tubeDrawable->setDataset( m_dataset );
m_tubeDrawable->setUseDisplayList( false );
m_tubeDrawable->setDataVariance( osg::Object::DYNAMIC );
m_tubeDrawable->setWShaders(m_shaderTubesPS, m_shaderTubesQS);
m_geodeTubeDrawable = osg::ref_ptr< osg::Geode >( new osg::Geode );
m_geodeTubeDrawable->addDrawable( m_tubeDrawable );
osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode );
geode->addDrawable( m_tubeDrawable );
m_tubeDrawablePointSprite = osg::ref_ptr< WTubeDrawable >( new WTubeDrawable );
m_tubeDrawablePointSprite->setDataset( m_dataset );
m_tubeDrawablePointSprite->setUseDisplayList( false );
m_tubeDrawablePointSprite->setDataVariance( osg::Object::DYNAMIC );
m_tubeDrawablePointSprite->setWShaders(m_shaderTubesPS, m_shaderTubesQS);
m_geodePointSprite = osg::ref_ptr< osg::Geode >( new osg::Geode );
m_geodePointSprite->addDrawable( m_tubeDrawablePointSprite );
osgNodeNew->addChild( geode );
osgNodeNew->addChild( m_geodePointSprite );
osgNodeNew->addChild( m_geodeTubeDrawable );
osgNodeNew->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->addChild( osgNodeNew.get() );
osgNodeNew->setUserData( this );
osgNodeNew->setUserData( osg::ref_ptr< userData >(
new userData( boost::shared_dynamic_cast< WMFiberDisplay >( shared_from_this() ) )
) );
osgNodeNew->addUpdateCallback( new fdNodeCallback );
// remove previous nodes if there are any
......@@ -224,6 +238,8 @@ void WMFiberDisplay::create()
osg::StateSet* rootState = m_osgNode->getOrCreateStateSet();
initUniforms( rootState );
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->addChild( m_osgNode.get() );
}
void WMFiberDisplay::connectors()
......@@ -302,9 +318,14 @@ void WMFiberDisplay::updateRenderModes()
updateTexture();
m_useTextureProp->get( true );
m_tubeDrawable->setUseTubes( true );
m_tubeDrawablePointSprite->setUseTubes(true);
m_tubeDrawable->setRootState(rootState);
m_shaderTubes->apply( m_osgNode );
m_shaderTubesQS->apply( m_geodeTubeDrawable );
m_tubeDrawable->setWShader(m_shaderTubes);
m_tubeDrawable->setActiveRenderingMode(false,true);
m_shaderTubesPS->apply(m_geodePointSprite );
m_tubeDrawablePointSprite->setActiveRenderingMode(true,false);
rootState->addUniform( osg::ref_ptr<osg::Uniform>( new osg::Uniform( "globalColor", 1 ) ) );
m_uniformTubeThickness = osg::ref_ptr<osg::Uniform>( new osg::Uniform( "u_thickness", static_cast<float>( m_tubeThickness->get() ) ) );
rootState->addUniform( m_uniformTubeThickness );
......@@ -490,3 +511,18 @@ void WMFiberDisplay::initCullBox()
m_cullBox = osg::ref_ptr< WROIBox >( new WROIBox( minROIPos, maxROIPos ) );
m_cullBox->setColor( osg::Vec4( 1.0, 0., 1.0, 0.4 ) );
}
void WMFiberDisplay::userData::update()
{
parent->update();
}
void WMFiberDisplay::userData::updateRenderModes()
{
parent->updateRenderModes();
}
void WMFiberDisplay::userData::toggleColoring()
{
parent->toggleColoring();
}
......@@ -45,7 +45,7 @@
*
* \ingroup modules
*/
class OWKERNEL_EXPORT WMFiberDisplay : public WModule, public osg::Referenced
class OWKERNEL_EXPORT WMFiberDisplay : public WModule
{
public:
/**
......@@ -129,6 +129,18 @@ protected:
*/
void notifyTextureChange();
/**
* switches between fiber display and tube representation,
* texturing and box culling
* activates the neccesary shaders
*/
void updateRenderModes();
/**
* Enable disable global or local coloring
*/
void toggleColoring();
private:
/**
* Updates the output with the current selection and generates a WFiberCluster out of it.
......@@ -172,11 +184,18 @@ private:
*/
osg::ref_ptr< osg::Group > m_osgNode;
osg::ref_ptr<osg::Geode> m_geodeTubeDrawable;
osg::ref_ptr<osg::Geode> m_geodePointSprite;
/**
* stores pointer to the fiber drawer
*/
osg::ref_ptr< WTubeDrawable > m_tubeDrawable;
/**
* stores pointer to the fiber drawer
*/
osg::ref_ptr< WTubeDrawable > m_tubeDrawablePointSprite;
/**
* lock to prevent concurrent threads trying to update the osg node
*/
......@@ -186,6 +205,9 @@ private:
* the shader object for rendering tubes
*/
osg::ref_ptr< WShader >m_shaderTubes;
osg::ref_ptr< WShader >m_shaderTubesPS;
osg::ref_ptr< WShader >m_shaderTubesQS;
/**
* the shader object for rendering textured lines
......@@ -246,17 +268,6 @@ private:
osg::ref_ptr< WROIBox > m_cullBox; //!< stores a pointer to the cull box
/**
* switches between fiber display and tube representation,
* texturing and box culling
* activates the neccesary shaders
*/
void updateRenderModes();
/**
* Enable disable global or local coloring
*/
void toggleColoring();
/**
* changes tube parameters
......@@ -284,6 +295,42 @@ private:
*/
void initCullBox();
/**
* Wrapper class for userData to prevent cyclic destructor calls
*/
class userData: public osg::Referenced
{
public:
/**
* userData Constructur with shared pointer to module
* \param _parent pointer to the module
*/
explicit userData( boost::shared_ptr< WMFiberDisplay > _parent )
{
parent = _parent;
}
/**
* update wrapper Function
*/
void update();
/**
* updateRenderModes wrapper Function
*/
void updateRenderModes();
/**
* toggleColoring wrapper Function
*/
void toggleColoring();
private:
/**
* shared pointer to the module
*/
boost::shared_ptr< WMFiberDisplay > parent;
};
/**
* Node callback to handle updates properly
......@@ -299,7 +346,7 @@ private:
*/
virtual void operator()( osg::Node* node, osg::NodeVisitor* nv )
{
osg::ref_ptr< WMFiberDisplay > module = static_cast< WMFiberDisplay* > ( node->getUserData() );
osg::ref_ptr< userData > module = static_cast< userData* > ( node->getUserData() );
if ( module )
{
......
......@@ -55,6 +55,8 @@ WTubeDrawable::WTubeDrawable():
static_cast<int>( 0 ) ) );
m_uniformViewportWidth = osg::ref_ptr<osg::Uniform>( new osg::Uniform( "u_viewportWidth",
static_cast<int>( 0 ) ) );
m_usePointSprite = false;
m_useQuadStrips = false;
}
// I can't say much about the methods below, but OSG seems to expect
......@@ -212,6 +214,12 @@ void WTubeDrawable::setWShader(osg::ref_ptr< WShader > shaderTubes)
m_shaderTubes = shaderTubes;
}
void WTubeDrawable::setWShaders(osg::ref_ptr< WShader >shaderTubesPS, osg::ref_ptr< WShader >shaderTubesQS)
{
m_shaderTubesPS = shaderTubesPS;
m_shaderTubesQS = shaderTubesQS;
}
void WTubeDrawable::setBoundingBox( const osg::BoundingBox & bb )
{
setBound( bb );
......@@ -319,6 +327,9 @@ void WTubeDrawable::create2DTexSpecularLightning(osg::StateSet* m_rootState) con
osg::Image* image = new osg::Image;
int noPixels = 64;
int noExponents = 64;
//vector<float> sn;
// allocate the image data, noPixels x noPixels x 1 with 4 rgba floats - equivalent to a Vec4!
image->allocateImage(noPixels,noPixels,1,GL_RGBA,GL_FLOAT);
......@@ -451,6 +462,17 @@ void WTubeDrawable::setRootState(osg::StateSet* rootState)
m_rootState = rootState;
}
void WTubeDrawable::setOSGNode(osg::ref_ptr< osg::Group > osgNode)
{
this->m_osgNode = osgNode;
}
void WTubeDrawable::setActiveRenderingMode(bool usePointSprite, bool useQuadStrips)
{
m_usePointSprite = usePointSprite;
m_useQuadStrips = useQuadStrips;
}
void WTubeDrawable::drawTubes( osg::RenderInfo& renderInfo ) const
{
boost::shared_ptr< std::vector< size_t > > startIndexes = m_dataset->getLineStartIndexes();
......@@ -467,8 +489,10 @@ void WTubeDrawable::drawTubes( osg::RenderInfo& renderInfo ) const
}
m_uniformViewportHeight->set( static_cast<int>( (*renderInfo.getCurrentCamera()->getViewport()).height() ) );
m_uniformViewportWidth->set( static_cast<int>( (*renderInfo.getCurrentCamera()->getViewport()).width() ) );
/*
m_rootState->addUniform(m_uniformViewportHeight);
m_rootState->addUniform(m_uniformViewportWidth);
m_rootState->addUniform(m_uniformViewportWidth);*/
osg::State& state = *renderInfo.getState();
......@@ -483,16 +507,20 @@ void WTubeDrawable::drawTubes( osg::RenderInfo& renderInfo ) const
glDisable(GL_LIGHTING);
glEnable(GL_BLEND);
//m_shaderTubes->setDefine(USE_QUADSTRIP);
for ( size_t i = 0; i < active->size(); ++i )
//m_shaderTubesQS->applyDirect(state);
//dynamic_cast< osg::Program* >(m_shaderTubesQS.get())->apply(state);
//m_shaderTubes->setDefine(USE_QUADSTRIP);
if(m_useQuadStrips)
{
if ( (*active)[i] )
for ( size_t i = 0; i < active->size(); ++i )
{
state.glDrawArraysInstanced( osg::PrimitiveSet::QUAD_STRIP, m_tubeStartIndexes->at(i), 2 * (*pointsPerLine)[i], 1);
if ( (*active)[i] )
{
state.glDrawArraysInstanced( GL_TRIANGLE_STRIP, m_tubeStartIndexes->at(i), 2 * (*pointsPerLine)[i], 1);
}
}
}
//m_shaderTubesQS->deactivate();
//m_shaderTubes->eraseDefine(USE_QUADSTRIP);
//osg::TexEnv* texEnvPS = new osg::TexEnv( osg::TexEnv::REPLACE);
......@@ -502,7 +530,10 @@ void WTubeDrawable::drawTubes( osg::RenderInfo& renderInfo ) const
//state.setModeValidity(GL_ALPHA_TEST, osg::StateAttribute::ON);
//state.setModeValidity(GL_POINT_SPRITE, osg::StateAttribute::ON);
m_shaderTubes->setDefine("USE_POINTSPRITE");
//m_shaderTubes->setDefine("USE_POINTSPRITE");
//m_shaderTubesPS->apply(state);
//m_shaderTubesPS->applyDirect(state);
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
glEnable(GL_ALPHA_TEST);
......@@ -513,15 +544,17 @@ void WTubeDrawable::drawTubes( osg::RenderInfo& renderInfo ) const
//state.setModeValidity(alphaFunc, osg::StateAttribute::ON);
//state.setModeValidity(texEnvPS, osg::StateAttribute::ON);
for ( size_t i = 0; i < active->size(); ++i )
if(m_usePointSprite)
{
if ( (*active)[i] )
for ( size_t i = 0; i < active->size(); ++i )
{
state.glDrawArraysInstanced( GL_POINTS, m_tubeStartIndexes->at(i + active->size()), (*pointsPerLine)[i], 1);
if ( (*active)[i] )
{
state.glDrawArraysInstanced( GL_POINTS, m_tubeStartIndexes->at(i + active->size()), (*pointsPerLine)[i], 1);
}
}
}
// m_shaderTubesPS->deactivate(this);
//state.setModeValidity(GL_VERTEX_PROGRAM_POINT_SIZE, osg::StateAttribute::OFF);
//state.setModeValidity(GL_ALPHA_TEST, osg::StateAttribute::OFF);
//state.setModeValidity(GL_POINT_SPRITE, osg::StateAttribute::OFF);
......@@ -532,7 +565,7 @@ void WTubeDrawable::drawTubes( osg::RenderInfo& renderInfo ) const
state.disableVertexPointer();
state.disableColorPointer();
m_shaderTubes->eraseDefine("USE_POINTSPRITE");
//m_shaderTubes->eraseDefine("USE_POINTSPRITE");
/*
boost::shared_ptr< std::vector< size_t > > startIndexes = m_dataset->getLineStartIndexes();
......
......@@ -152,7 +152,9 @@ public:
void setRootState(osg::StateSet* m_rootState);
void setWShader(osg::ref_ptr< WShader > m_shaderTubes);
void setWShaders(osg::ref_ptr< WShader > shaderTubesPS, osg::ref_ptr< WShader > shaderTubesQS);
void setOSGNode(osg::ref_ptr< osg::Group > osgNode);
void setActiveRenderingMode(bool usePointSprite, bool useQuadStrips);
protected:
private:
/**
......@@ -179,7 +181,11 @@ private:
osg::VectorGLuint* m_tubeStartIndexes;
osg::ref_ptr< WShader > m_shaderTubes;
osg::ref_ptr< WShader > m_shaderTubesPS;
osg::ref_ptr< WShader > m_shaderTubesQS;
bool m_usePointSprite;
bool m_useQuadStrips;
/*
boost::shared_ptr< std::vector< float > > m_tubeVerts;
boost::shared_ptr< std::vector< float > > m_tubeTangents;
......@@ -188,6 +194,8 @@ private:
boost::shared_ptr< std::vector< float > > m_tubeColors;
*/
osg::ref_ptr< osg::Group > m_osgNode;
boost::shared_ptr< const WDataSetFibers > m_dataset; //!< stores pointer to dataset
boost::shared_mutex m_recalcLock; //!< lock
......
varying vec3 tangentR3; // Tangent vector in world space
varying float s_param; // s parameter of texture [-1..1]
varying float tangent_dot_view;
uniform bool globalColor;
uniform sampler1D texture;
uniform sampler2D texturePS;
varying float usePointSprite;
varying vec2 imageTangent;
varying vec4 tubeColor;
varying vec3 view;
varying vec3 lightDir;
varying float NdotL;
varying vec3 normal;
varying vec3 halfVector;
varying float endPoint;
uniform gl_DepthRangeParameters gl_DepthRange;
varying float z;
varying float zNear;
varying float zFar;
void main()
{
vec3 L, V, T, N, halfV;
vec3 specular = 0.0;
float NdotL,NdotHV;
float alpha, beta, lt;
T = normalize(tangentR3);
V = normalize(view);
L = normalize(lightDir);
N = normalize(normal);
NdotL = max(dot(N,L),0.0);
vec4 color;