diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index 2d5fdfb39..2c0b9f0e3 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -248,6 +248,9 @@ namespace Shader void ShaderVisitor::createProgram(const ShaderRequirements &reqs) { + if (!reqs.mShaderRequired && !mForceShaders) + return; + osg::Node& node = *reqs.mNode; osg::StateSet* writableStateSet = NULL; if (mAllowedToModifyStateSets) @@ -305,6 +308,36 @@ namespace Shader } } + bool ShaderVisitor::adjustGeometry(osg::Geometry& sourceGeometry, const ShaderRequirements& reqs) + { + bool useShader = reqs.mShaderRequired || mForceShaders; + bool generateTangents = reqs.mTexStageRequiringTangents != -1; + bool changed = false; + + if (mAllowedToModifyStateSets && (useShader || generateTangents)) + { + // make sure that all UV sets are there + for (std::map::const_iterator it = reqs.mTextures.begin(); it != reqs.mTextures.end(); ++it) + { + if (sourceGeometry.getTexCoordArray(it->first) == NULL) + { + sourceGeometry.setTexCoordArray(it->first, sourceGeometry.getTexCoordArray(0)); + changed = true; + } + } + + if (generateTangents) + { + osg::ref_ptr generator (new osgUtil::TangentSpaceGenerator); + generator->generate(&sourceGeometry, reqs.mTexStageRequiringTangents); + + sourceGeometry.setTexCoordArray(7, generator->getTangentArray(), osg::Array::BIND_PER_VERTEX); + changed = true; + } + } + return changed; + } + void ShaderVisitor::apply(osg::Geometry& geometry) { bool needPop = (geometry.getStateSet() != NULL); @@ -318,43 +351,9 @@ namespace Shader { const ShaderRequirements& reqs = mRequirements.back(); - bool useShader = reqs.mShaderRequired || mForceShaders; - bool generateTangents = reqs.mTexStageRequiringTangents != -1; - - if (mAllowedToModifyStateSets && (useShader || generateTangents)) - { - osg::ref_ptr sourceGeometry = &geometry; - SceneUtil::RigGeometry* rig = dynamic_cast(&geometry); - if (rig) - sourceGeometry = rig->getSourceGeometry(); - - bool requiresSetGeometry = false; + adjustGeometry(geometry, reqs); - // make sure that all UV sets are there - for (std::map::const_iterator it = reqs.mTextures.begin(); it != reqs.mTextures.end(); ++it) - { - if (sourceGeometry->getTexCoordArray(it->first) == NULL) - { - sourceGeometry->setTexCoordArray(it->first, sourceGeometry->getTexCoordArray(0)); - requiresSetGeometry = true; - } - } - - if (generateTangents) - { - osg::ref_ptr generator (new osgUtil::TangentSpaceGenerator); - generator->generate(sourceGeometry, reqs.mTexStageRequiringTangents); - - sourceGeometry->setTexCoordArray(7, generator->getTangentArray(), osg::Array::BIND_PER_VERTEX); - requiresSetGeometry = true; - } - - if (rig && requiresSetGeometry) - rig->setSourceGeometry(sourceGeometry); - } - - if (useShader) - createProgram(reqs); + createProgram(reqs); } if (needPop) @@ -375,8 +374,14 @@ namespace Shader if (!mRequirements.empty()) { const ShaderRequirements& reqs = mRequirements.back(); - if (reqs.mShaderRequired || mForceShaders) - createProgram(reqs); + createProgram(reqs); + + if (SceneUtil::RigGeometry* rig = dynamic_cast(&drawable)) + { + osg::ref_ptr sourceGeometry = rig->getSourceGeometry(); + if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs)) + rig->setSourceGeometry(sourceGeometry); + } } if (needPop) diff --git a/components/shader/shadervisitor.hpp b/components/shader/shadervisitor.hpp index 83f28e063..cb0538d9d 100644 --- a/components/shader/shadervisitor.hpp +++ b/components/shader/shadervisitor.hpp @@ -99,6 +99,7 @@ namespace Shader std::string mDefaultFsTemplate; void createProgram(const ShaderRequirements& reqs); + bool adjustGeometry(osg::Geometry& sourceGeometry, const ShaderRequirements& reqs); }; }