diff --git a/include/osgShadow/ShadowTexture b/include/osgShadow/ShadowTexture index d6ed50bd5..2588a29fa 100644 --- a/include/osgShadow/ShadowTexture +++ b/include/osgShadow/ShadowTexture @@ -15,6 +15,7 @@ #define OSGSHADOW_SHADOWETEXTURE 1 #include +#include #include @@ -30,10 +31,36 @@ class OSGSHADOW_EXPORT ShadowTexture : public ShadowTechnique META_Object(osgShadow, ShadowTexture); + /** Set the texture unit that the shadow texture will be applied on.*/ + void setTextureUnit(unsigned int unit); + + /** Get the texture unit that the shadow texture will be applied on.*/ + unsigned int getTextureUnit() const { return _textureUnit; } + + + /** initialize the ShadowedScene and local cached data structures.*/ + virtual void init(); + + /** run the update traversal of the ShadowedScene and update any loca chached data structures.*/ + virtual void update(osg::NodeVisitor& nv); + + /** run the cull traversal of the ShadowedScene and set up the rendering for this ShadowTechnique.*/ + virtual void cull(osgUtil::CullVisitor& cv); + + /** Clean scene graph from any shadow technique specific nodes, state and drawables.*/ + virtual void cleanSceneGraph(); + + protected : virtual ~ShadowTexture() {} - + + osg::ref_ptr _camera; + osg::ref_ptr _texgen; + osg::ref_ptr _texture; + osg::ref_ptr _stateset; + osg::ref_ptr _material; + unsigned int _textureUnit; }; } diff --git a/src/osgShadow/ShadowTexture.cpp b/src/osgShadow/ShadowTexture.cpp index 6f3ec6003..9d332b0d7 100644 --- a/src/osgShadow/ShadowTexture.cpp +++ b/src/osgShadow/ShadowTexture.cpp @@ -12,16 +12,147 @@ */ #include +#include #include +#include + using namespace osgShadow; -ShadowTexture::ShadowTexture() +class CameraCullCallback : public osg::NodeCallback { - osg::notify(osg::NOTICE)<<"Warning: osgShadow::ShadowTexture technique not implemented yet."<getTraversalMask(); + + nv->setTraversalMask( traversalMask & + _shadowTexture->getShadowedScene()->getCastsShadowTraversalMask() ); + + _shadowTexture->getShadowedScene()->osg::Group::traverse(*nv); + + nv->setTraversalMask( traversalMask ); + } + + protected: + + ShadowTexture* _shadowTexture; +}; + +ShadowTexture::ShadowTexture(): + _textureUnit(1) +{ + osg::notify(osg::NOTICE)<<"Warning: osgShadow::ShadowTexture technique is in development."<setTextureSize(tex_width, tex_height); + _texture->setInternalFormat(GL_RGB); + _texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); + _texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); + _texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER); + _texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER); + _texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + + _texture->setImage(osgDB::readImageFile("Images/road.png")); + + // set up the render to texture camera. + { + // create the camera + _camera = new osg::Camera; + + _camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); + + _camera->setCullCallback(new CameraCullCallback(this)); + + // set viewport + _camera->setViewport(0,0,tex_width,tex_height); + + // set the camera to render before the main camera. + _camera->setRenderOrder(osg::Camera::PRE_RENDER); + + // tell the camera to use OpenGL frame buffer object where supported. + _camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); + + // attach the texture and use it as the color buffer. + _camera->attach(osg::Camera::COLOR_BUFFER, _texture.get()); + + _material = new osg::Material; + _material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f)); + _material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f)); + _material->setEmission(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f)); + _material->setShininess(osg::Material::FRONT_AND_BACK,0.0f); + + osg::StateSet* stateset = _camera->getOrCreateStateSet(); + stateset->setAttribute(_material.get(),osg::StateAttribute::OVERRIDE); + } + + { + _stateset = new osg::StateSet; + _stateset->setTextureAttributeAndModes(_textureUnit,_texture.get(),osg::StateAttribute::ON); + _stateset->setTextureMode(_textureUnit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON); + _stateset->setTextureMode(_textureUnit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON); + _stateset->setTextureMode(_textureUnit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON); + _stateset->setTextureMode(_textureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON); + } +} + + +void ShadowTexture::update(osg::NodeVisitor&) +{ +} + +void ShadowTexture::cull(osgUtil::CullVisitor& cv) +{ + // record the traversal mask on entry so we can reapply it later. + unsigned int traversalMask = cv.getTraversalMask(); + + // do RTT camera traversal + // _camera->accept(cv); + + // do traversal of shadow casting scene which does not need to be decorated by the shadow texture + { + cv.setTraversalMask( traversalMask & + getShadowedScene()->getCastsShadowTraversalMask() ); + + _shadowedScene->osg::Group::traverse(cv); + } + + // do traversal of shadow recieving scene which does need to be decorated by the shadow texture + { + cv.pushStateSet(_stateset.get()); + + cv.setTraversalMask( traversalMask & + getShadowedScene()->getRecievesShadowTraversalMask() ); + + _shadowedScene->osg::Group::traverse(cv); + + cv.popStateSet(); + + } + + // reapply the original traversal mask + cv.setTraversalMask( traversalMask ); +} + +void ShadowTexture::cleanSceneGraph() { } diff --git a/src/osgShadow/ShadowVolume.cpp b/src/osgShadow/ShadowVolume.cpp index fb216e4ea..d960a2f04 100644 --- a/src/osgShadow/ShadowVolume.cpp +++ b/src/osgShadow/ShadowVolume.cpp @@ -205,7 +205,7 @@ void ShadowVolume::init() if (_drawMode == osgShadow::ShadowVolumeGeometry::STENCIL_TWO_SIDED) { - osg::notify(osg::NOTICE)<<"STENCIL_TWO_SIDED seleteced"<getOrCreateStateSet(); ss_sv1->setRenderBinDetails(shadowVolumeBin, "RenderBin"); @@ -213,7 +213,7 @@ void ShadowVolume::init() } else { - osg::notify(osg::NOTICE)<<"STENCIL_TWO_PASSES seleteced"<getOrCreateStateSet(); ss_sv1->setRenderBinDetails(shadowVolumeBin, "RenderBin"); @@ -407,7 +407,7 @@ void ShadowVolume::cull(osgUtil::CullVisitor& cv) } _ambientLight->setPosition(lightpos); - if (selectLight) + orig_rs->addPositionedAttribute(0,_ambientLight.get()); _diffuseLight->setPosition(lightpos); @@ -417,7 +417,6 @@ void ShadowVolume::cull(osgUtil::CullVisitor& cv) _diffuseLight->setDiffuse(selectLight->getDiffuse()); _diffuseLight->setSpecular(selectLight->getSpecular()); - _diffuseLight->setSpecular(selectLight->getSpecular()); _diffuseLight->setDirection(selectLight->getDirection()); _diffuseLight->setConstantAttenuation(selectLight->getConstantAttenuation()); _diffuseLight->setLinearAttenuation(selectLight->getLinearAttenuation());