diff --git a/examples/osgfxbrowser/osgfxbrowser.cpp b/examples/osgfxbrowser/osgfxbrowser.cpp index 07e243afa..f02038816 100644 --- a/examples/osgfxbrowser/osgfxbrowser.cpp +++ b/examples/osgfxbrowser/osgfxbrowser.cpp @@ -341,6 +341,8 @@ int main(int argc, char *argv[]) osg::ref_ptr light = new osg::Light; light->setLightNum(0); light->setDiffuse(osg::Vec4(1, 1, 1, 1)); + light->setSpecular(osg::Vec4(1, 1, 0.8f, 1)); + light->setAmbient(osg::Vec4(0.2f, 0.2f, 0.2f, 0.2f)); light->setPosition(osg::Vec4(1, -1, 1, 0)); osg::ref_ptr root = new osg::LightSource; diff --git a/src/osgFX/AnisotropicLighting.cpp b/src/osgFX/AnisotropicLighting.cpp index fc58f2621..a9b92ce07 100644 --- a/src/osgFX/AnisotropicLighting.cpp +++ b/src/osgFX/AnisotropicLighting.cpp @@ -14,26 +14,35 @@ using namespace osgFX; namespace { + // a state attribute class that grabs the initial inverse view matrix + // and sends it to a VertexProgram. + // NOTE: due to lack of support for per-context parameters in VertexProgram, + // this class will send the matrix to the vp only while the first context + // is being rendered. All subsequent contexts will use the first context's + // matrix. class ViewMatrixExtractor: public osg::StateAttribute { public: ViewMatrixExtractor() : osg::StateAttribute(), vp_(0), - param_(0) + param_(0), + first_context_(-1) { } ViewMatrixExtractor(const ViewMatrixExtractor ©, const osg::CopyOp ©op) : osg::StateAttribute(copy, copyop), vp_(static_cast(copyop(copy.vp_.get()))), - param_(copy.param_) + param_(copy.param_), + first_context_(-1) { } ViewMatrixExtractor(osg::VertexProgram *vp, int param) : osg::StateAttribute(), vp_(vp), - param_(param) + param_(param), + first_context_(-1) { } @@ -50,17 +59,23 @@ namespace void apply(osg::State &state) const { - if (vp_.valid()) { - osg::Matrix M = state.getInitialInverseViewMatrix(); - for (int i=0; i<4; ++i) { - vp_->setProgramLocalParameter(param_+i, osg::Vec4(M(0, i), M(1, i), M(2, i), M(3, i))); - } - } + if (first_context_ == -1) { + first_context_ = state.getContextID(); + } + if (state.getContextID() == first_context_) { + if (vp_.valid()) { + osg::Matrix M = state.getInitialInverseViewMatrix(); + for (int i=0; i<4; ++i) { + vp_->setProgramLocalParameter(param_+i, osg::Vec4(M(0, i), M(1, i), M(2, i), M(3, i))); + } + } + } } private: mutable osg::ref_ptr vp_; int param_; + mutable int first_context_; }; }