Hi, I try from the example osgKeyboardMouse.osg to change the program code indeed I want to move the viewer with the scroll button. I add it in the example where it get the callbacks passed from the KeyboardMouseCallback to EventQueue. If I understand this right than I have only to add a inherited class from GUIHandler.. to the EvenHandler list where I can set the ViewMatrix. What I not understand how can I define in this class that if the mouse scroll that it call the method of the inherited class (where I can set the view Matrix)? Thanks Sascha
-----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Behalf Of Robert Osfield Sent: Tuesday, February 13, 2007 2:11 PM To: osg users Subject: Re: [osg-users] osgShadow::ShadowMap implementation Hu Mihai, To get the position of the light source you do what the osgShadow::ShadowVolume technique does and let the traversal happen for the scene then get the PositionalStateContainer from the RenderStage that the cull traversal has populated, then build the view and projection matrix according to this position. Robert. On 2/13/07, Mihai Radu <[EMAIL PROTECTED]> wrote: > Hello Robert, > > I've been trying to implement osgShadow::ShadowMap, using the old > osgdepthshadow as a starting point. > > I am attaching ShadowMap[.cpp] and testShadow.cpp[ based on osgshadow > example ]. > > I hit a bit of a wall, and here are some of the points I'm not very > clear on: > > 1. there is a Camera[PRE_RENDER] to RTT the depthMap, it's viewFrustum > needs to be updated according to the light, but where is the appropriate > call-back for it in the Update or in the Cull traversals ?? > 2. same for TexGenNode for applying the said depthMap > 3. how do I add the Camera to the rendering ? (if I add it to > ShadowedScene, there is a loop, since the sceneData of the Camera is > ShadowedScene) > 4. where is appropriate to add the TexGenNode (ShadowedScene seems like > the candidate) ? > > Right now I've turned off the depth comparing on the depthMap to see > what is happening, and all I get is a black rectangle. > > I've looked through the code for ShadowVolume, and I see you do some > magic with the renderBins in Cull traversal, but I can't quite figure if > I need to do something similar (I guess because I don't quite get what > is happening there :) > > I would really like to have this going, then I could use the nodeKit > with the application we are working on ( I'll have to back-port it to > osg 1.2, but that's not a big deal if I exclude ShadowVolume technique). > > Regards > Mihai Radu > ------------ > cm-labs.com > > #include <osg/ArgumentParser> > > #include <osg/LightModel> > #include <osg/Depth> > #include <osg/BlendFunc> > #include <osg/Camera> > #include <osg/Stencil> > #include <osg/StencilTwoSided> > #include <osg/CullFace> > #include <osg/Geometry> > #include <osg/Switch> > > #include <osgGA/TrackballManipulator> > #include <osgGA/FlightManipulator> > #include <osgGA/DriveManipulator> > #include <osgGA/KeySwitchMatrixManipulator> > #include <osgGA/AnimationPathManipulator> > #include <osgGA/TerrainManipulator> > #include <osgGA/AnimationPathManipulator> > #include <osgGA/StateSetManipulator> > > #include <osgViewer/Viewer> > #include <osgViewer/StatsHandler> > > #include <osgShadow/OccluderGeometry> > #include <osgShadow/ShadowedScene> > #include <osgShadow/ShadowVolume> > #include <osgShadow/ShadowMap> > > #include <osgDB/ReadFile> > #include <osgDB/WriteFile> > > #include <osg/Geode> > #include <osg/BlendFunc> > > #include <iostream> > > class ComputeBoundingBoxVisitor : public osg::NodeVisitor > { > public: > ComputeBoundingBoxVisitor(): > osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) > { > } > > virtual void reset() > { > _matrixStack.clear(); > _bb.init(); > } > > osg::BoundingBox& getBoundingBox() { return _bb; } > > void getPolytope(osg::Polytope& polytope, float margin=0.1) const > { > float delta = _bb.radius()*margin; > polytope.add( osg::Plane(0.0, 0.0, 1.0, -(_bb.zMin()-delta)) ); > polytope.add( osg::Plane(0.0, 0.0, -1.0, (_bb.zMax()+delta)) ); > > polytope.add( osg::Plane(1.0, 0.0, 0.0, -(_bb.xMin()-delta)) ); > polytope.add( osg::Plane(-1.0, 0.0, 0.0, (_bb.xMax()+delta)) ); > > polytope.add( osg::Plane(0.0, 1.0, 0.0, -(_bb.yMin()-delta)) ); > polytope.add( osg::Plane(0.0, -1.0, 0.0, (_bb.yMax()+delta)) ); > } > > void getBase(osg::Polytope& polytope, float margin=0.1) const > { > float delta = _bb.radius()*margin; > polytope.add( osg::Plane(0.0, 0.0, 1.0, -(_bb.zMin()-delta)) ); > } > > void apply(osg::Node& node) > { > traverse(node); > } > > void apply(osg::Transform& transform) > { > osg::Matrix matrix; > if (!_matrixStack.empty()) matrix = _matrixStack.back(); > > transform.computeLocalToWorldMatrix(matrix,this); > > pushMatrix(matrix); > > traverse(transform); > > popMatrix(); > } > > void apply(osg::Geode& geode) > { > for(unsigned int i=0; i<geode.getNumDrawables(); ++i) > { > apply(geode.getDrawable(i)); > } > } > > void pushMatrix(osg::Matrix& matrix) > { > _matrixStack.push_back(matrix); > } > > void popMatrix() > { > _matrixStack.pop_back(); > } > > void apply(osg::Drawable* drawable) > { > if (_matrixStack.empty()) _bb.expandBy(drawable->getBound()); > else > { > osg::Matrix& matrix = _matrixStack.back(); > const osg::BoundingBox& dbb = drawable->getBound(); > if (dbb.valid()) > { > _bb.expandBy(dbb.corner(0) * matrix); > _bb.expandBy(dbb.corner(1) * matrix); > _bb.expandBy(dbb.corner(2) * matrix); > _bb.expandBy(dbb.corner(3) * matrix); > _bb.expandBy(dbb.corner(4) * matrix); > _bb.expandBy(dbb.corner(5) * matrix); > _bb.expandBy(dbb.corner(6) * matrix); > _bb.expandBy(dbb.corner(7) * matrix); > } > } > } > > protected: > > typedef std::vector<osg::Matrix> MatrixStack; > > MatrixStack _matrixStack; > osg::BoundingBox _bb; > }; > > > > osg::Camera* makeHud(osg::Texture2D* tex) > { > // set hud to render shadow texture, just for interest > #if 1 > osg::Geode* geode = new osg::Geode; > osg::Geometry* geom = > osg::createTexturedQuadGeometry(osg::Vec3(0,0,0),osg::Vec3(100.0,0.0,0.0),osg::Vec3(0.0,100.0,0.0)); > > geom->getOrCreateStateSet()->setTextureAttributeAndModes(0,tex,osg::StateAttribute::ON); > > geom->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF); > geode->addDrawable(geom); > > osg::Camera* camera = new osg::Camera; > > // set the projection matrix > camera->setProjectionMatrix(osg::Matrix::ortho2D(0,100,0,100)); > > // set the view matrix > camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); > camera->setViewMatrix(osg::Matrix::identity()); > > camera->setViewport(50,50,100,100); > > // only clear the depth buffer > camera->setClearMask(GL_DEPTH_BUFFER_BIT); > > // draw subgraph after main camera view. > camera->setRenderOrder(osg::Camera::POST_RENDER); > > camera->addChild(geode); > > > #else > osg::Geode* geode = new osg::Geode(); > { > osg::Geometry* geom = new osg::Geometry; > > osg::Vec3Array* vertices = new osg::Vec3Array; > float depth = -0.1; > vertices->push_back(osg::Vec3(0,512,depth)); > vertices->push_back(osg::Vec3(0,0,depth)); > vertices->push_back(osg::Vec3(512,0,depth)); > vertices->push_back(osg::Vec3(512,512,depth)); > geom->setVertexArray(vertices); > > osg::Vec3Array* normals = new osg::Vec3Array; > normals->push_back(osg::Vec3(0.0f,0.0f,1.0f)); > geom->setNormalArray(normals); > geom->setNormalBinding(osg::Geometry::BIND_OVERALL); > > osg::Vec4Array* colors = new osg::Vec4Array; > colors->push_back(osg::Vec4(1.0f,1.0,0.8f,0.2f)); > geom->setColorArray(colors); > geom->setColorBinding(osg::Geometry::BIND_OVERALL); > > geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS,0,4)); > > osg::StateSet* stateset = geom->getOrCreateStateSet(); > stateset->setMode(GL_BLEND,osg::StateAttribute::ON); > //stateset->setAttribute(new > osg::PolygonOffset(1.0f,1.0f),osg::StateAttribute::ON); > stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); > > geode->addDrawable(geom); > } > > > osg::StateSet* set = geode->getOrCreateStateSet(); > set->setTextureAttributeAndModes(0, tex ,osg::StateAttribute::ON); > > > osg::Camera* camera = new osg::Camera; > > // set the projection matrix > camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1280,0,1024)); > > // set the view matrix > camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); > camera->setViewMatrix(osg::Matrix::identity()); > > // only clear the depth buffer > camera->setClearMask(GL_DEPTH_BUFFER_BIT); > > // draw subgraph after main camera view. > camera->setRenderOrder(osg::Camera::POST_RENDER); > > camera->addChild(geode); > #endif > return camera; > > } > > > int main(int argc, char** argv) > { > // use an ArgumentParser object to manage the program arguments. > osg::ArgumentParser arguments(&argc, argv); > > // set up the usage document, in case we need to print out how to use > this program. > > arguments.getApplicationUsage()->setDescription(arguments.getApplicationName() > + " is the example which demonstrates using of GL_ARB_shadow extension > implemented in osg::Texture class"); > > arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()); > arguments.getApplicationUsage()->addCommandLineOption("-h or --help", > "Display this information"); > > arguments.getApplicationUsage()->addCommandLineOption("--positionalLight", > "Use a positional light."); > > arguments.getApplicationUsage()->addCommandLineOption("--directionalLight", > "Use a direction light."); > > arguments.getApplicationUsage()->addCommandLineOption("--addOccluderToScene", > "Add the occluders geometry."); > arguments.getApplicationUsage()->addCommandLineOption("--noUpdate", > "Disable the updating the of light source."); > arguments.getApplicationUsage()->addCommandLineOption("--base", "Add a > base geometry to test shadows."); > arguments.getApplicationUsage()->addCommandLineOption("--noShadow", > "Disable the shadows."); > arguments.getApplicationUsage()->addCommandLineOption("--two-sided", "Use > two-sided stencil extension for shadow volumes."); > arguments.getApplicationUsage()->addCommandLineOption("--two-pass", "Use > two-pass stencil for shadow volumes."); > > // hint to tell viewer to request stencil buffer when setting up windows > osg::DisplaySettings::instance()->setMinimumNumStencilBits(8); > > // construct the viewer. > osgViewer::Viewer viewer; > > // if user request help write it out to cout. > if (arguments.read("-h") || arguments.read("--help")) > { > arguments.getApplicationUsage()->write(std::cout); > return 1; > } > > // default to single threaded during dev work. > viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); > > while (arguments.read("--SingleThreaded")) > viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); > while (arguments.read("--CullDrawThreadPerContext")) > viewer.setThreadingModel(osgViewer::Viewer::CullDrawThreadPerContext); > while (arguments.read("--DrawThreadPerContext")) > viewer.setThreadingModel(osgViewer::Viewer::DrawThreadPerContext); > while (arguments.read("--CullThreadPerCameraDrawThreadPerContext")) > viewer.setThreadingModel(osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext); > > > bool postionalLight = false; > while (arguments.read("--positionalLight")) postionalLight = true; > while (arguments.read("--directionalLight")) postionalLight = false; > > bool updateLightPosition = true; > while (arguments.read("--noUpdate")) updateLightPosition = false; > > bool createBase = false; > while (arguments.read("--base")) createBase = true; > > > int screenNum = -1; > while (arguments.read("--screen", screenNum)) > viewer.setUpViewOnSingleScreen(screenNum); > > bool ShadowMap = true; > while (arguments.read("--ShadowMap")) ShadowMap = true; > > > // set up the camera manipulators. > { > osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator > = new osgGA::KeySwitchMatrixManipulator; > > keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new > osgGA::TrackballManipulator() ); > keyswitchManipulator->addMatrixManipulator( '2', "Flight", new > osgGA::FlightManipulator() ); > keyswitchManipulator->addMatrixManipulator( '3', "Drive", new > osgGA::DriveManipulator() ); > keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new > osgGA::TerrainManipulator() ); > > std::string pathfile; > char keyForAnimationPath = '5'; > while (arguments.read("-p",pathfile)) > { > osgGA::AnimationPathManipulator* apm = new > osgGA::AnimationPathManipulator(pathfile); > if (apm || !apm->valid()) > { > unsigned int num = > keyswitchManipulator->getNumMatrixManipulators(); > keyswitchManipulator->addMatrixManipulator( > keyForAnimationPath, "Path", apm ); > keyswitchManipulator->selectMatrixManipulator(num); > ++keyForAnimationPath; > } > } > > viewer.setCameraManipulator( keyswitchManipulator.get() ); > } > > > // add the state manipulator > viewer.addEventHandler( new > osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); > > // add stats > viewer.addEventHandler( new osgViewer::StatsHandler() ); > > // any option left unread are converted into errors to write out later. > arguments.reportRemainingOptionsAsUnrecognized(); > > // report any errors if they have occured when parsing the program > aguments. > if (arguments.errors()) > { > arguments.writeErrorMessages(std::cout); > return 1; > } > > > osg::ref_ptr<osg::Node> model = osgDB::readNodeFiles(arguments); > if (!model) > { > return 1; > } > > // get the bounds of the model. > ComputeBoundingBoxVisitor cbbv; > model->accept(cbbv); > osg::BoundingBox bb = cbbv.getBoundingBox(); > > if (createBase) > { > osg::ref_ptr<osg::Group> newGroup = new osg::Group; > newGroup->addChild(model.get()); > > osg::Geode* geode = new osg::Geode; > > osg::Vec3 widthVec(bb.radius(), 0.0f, 0.0f); > osg::Vec3 depthVec(0.0f, bb.radius(), 0.0f); > osg::Vec3 centerBase( (bb.xMin()+bb.xMax())*0.5f, > (bb.yMin()+bb.yMax())*0.5f, bb.zMin()-bb.radius()*0.1f ); > > geode->addDrawable( osg::createTexturedQuadGeometry( > centerBase-widthVec*1.5f-depthVec*1.5f, > widthVec*3.0f, > depthVec*3.0f) ); > newGroup->addChild(geode); > > model = newGroup.get(); > } > > osg::Vec4 lightpos; > > if (postionalLight) > { > lightpos.set(bb.center().x(), bb.center().y(), bb.zMax() + > bb.radius() ,1.0f); > } > else > { > lightpos.set(0.5f,0.25f,0.8f,0.0f); > } > > > osg::ref_ptr<osgShadow::ShadowedScene> shadowedScene = new > osgShadow::ShadowedScene; > osg::ref_ptr<osgShadow::ShadowMap> shadowMap = new osgShadow::ShadowMap; > > shadowedScene->setShadowTechnique(shadowMap.get()); > > shadowedScene->addChild(model.get()); > > osgShadow::ShadowMap* map = dynamic_cast<osgShadow::ShadowMap*>( > shadowedScene->getShadowTechnique()); > > osg::ref_ptr<osg::LightSource> ls = new osg::LightSource; > > ls->getLight()->setPosition(lightpos); > > map->setLight(ls.get()); > > //osg::Camera* cam = map->getCamera(); > //osg::Camera::BufferAttachmentMap bMap = cam->getBufferAttachmentMap(); > //osg::Camera::Attachment attach = > (*bMap.find(osg::Camera::COLOR_BUFFER)).second; > osg::ref_ptr<osg::Camera> _hud; > > osg::Texture2D* tex = map->getTexture(); > tex->setShadowComparison(false); > > if (! tex) > exit(1); > > _hud = makeHud(tex); > > > //shadowedScene->addChild( map->getCamera() ); > > shadowedScene->addChild( map->getTexGen() ); > > //shadowedScene->addChild( _hud.get() ); > > > > shadowedScene->addChild(model.get()); > shadowedScene->addChild(ls.get()); > > viewer.setSceneData(shadowedScene.get()); > > // create the windows and run the threads. > viewer.realize(); > > // osgDB::writeNodeFile(*group,"test.osg"); > > while (!viewer.done()) > { > if (updateLightPosition) > { > float t = viewer.getFrameStamp()->getSimulationTime(); > if (postionalLight) > { > lightpos.set(bb.center().x()+sinf(t)*bb.radius(), > bb.center().y() + cosf(t)*bb.radius(), bb.zMax() + bb.radius() ,1.0f); > } > else > { > lightpos.set(sinf(t),cosf(t),1.0f,0.0f); > } > ls->getLight()->setPosition(lightpos); > } > > viewer.frame(); > } > > return 0; > } > > /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield > * > * This library is open source and may be redistributed and/or modified under > * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or > * (at your option) any later version. The full license is in LICENSE file > * included with this distribution, and on the openscenegraph.org website. > * > * This library is distributed in the hope that it will be useful, > * but WITHOUT ANY WARRANTY; without even the implied warranty of > * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > * OpenSceneGraph Public License for more details. > */ > > #include <osgShadow/ShadowMap> > #include <osgShadow/ShadowedScene> > > #include <osg/Notify> > #include <osg/Texture2D> > #include <osg/TexGenNode> > #include <osg/PolygonOffset> > #include <osg/CullFace> > #include <osg/LightSource> > #include <osgSim/DOFTransform> > #include <osg/MatrixTransform> > > #include <iomanip> > > using namespace osgShadow; > > ShadowMap::ShadowMap() : > _useLightPos(false) > { > osg::notify(osg::NOTICE)<<"Warning: osgShadow::ShadowMap technique in > development."<<std::endl; > > _textureHeight = 1024; > _textureWidth = 1024; > _textureUnit = 1; > > _position = osg::Vec3(5.0, 5.0, 0.0); > } > > ShadowMap::ShadowMap(const ShadowMap& copy, const osg::CopyOp& copyop): > ShadowTechnique(copy,copyop) > { > } > > void ShadowMap::init() > { > if (!_shadowedScene) return; > > // create the depthMap texture > _texture = new osg::Texture2D; > > _texture->setTextureSize(_textureHeight, _textureWidth); > > _texture->setInternalFormat(GL_DEPTH_COMPONENT); > _texture->setShadowComparison(true); > _texture->setShadowCompareFunc (osg::Texture::LEQUAL); > _texture->setShadowTextureMode(osg::Texture::LUMINANCE); > _texture->setShadowAmbient(0.2); > _texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER > ); > _texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER > ); > > _texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); > _texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); > > _texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); > > /////////////////// create S_CameraNode > _camera = new osg::Camera; > > _camera->setName("ShadowMap"); > > _camera->setClearMask(GL_DEPTH_BUFFER_BIT); > _camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); > // this turns off automatic computation of NEAR & FAR planes for the > camera > _camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); > > // set the CullMask to allow for non_occluder nodes > _camera->setCullMask( _shadowedScene->getCastsShadowTraversalMask() ); > > // set viewport > _camera->setViewport(0,0,_textureHeight, _textureWidth); > > osg::StateSet* _local_stateset = _camera->getOrCreateStateSet(); > > _local_stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); > > // PolygonOffset property to set the bias for shadow > > float factor = 1.85f; > float units = 1.80f; > > osg::ref_ptr<osg::PolygonOffset> polygon_offset = new osg::PolygonOffset; > polygon_offset->setFactor(factor); > polygon_offset->setUnits(units); > _local_stateset->setAttribute(polygon_offset.get(), > osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); > _local_stateset->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON > | osg::StateAttribute::OVERRIDE); > > osg::ref_ptr<osg::CullFace> cull_face = new osg::CullFace; > cull_face->setMode(osg::CullFace::FRONT_AND_BACK); > _local_stateset->setAttribute(cull_face.get(), osg::StateAttribute::ON | > osg::StateAttribute::OVERRIDE); > _local_stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF | > osg::StateAttribute::OVERRIDE); > > > // set the shadowCamera to render before the main camera. > _camera->setRenderOrder(osg::Camera::PRE_RENDER); > //shadowCamera->setRenderOrder(osg::CameraNode::NESTED_RENDER); > > // tell the shadowCamera to use OpenGL frame buffer object where > supported. > _camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); > > // attach the texture and use it as the depth buffer. > _camera->attach(osg::Camera::DEPTH_BUFFER, _texture.get()); > > _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); > > _camera->addChild(_shadowedScene); > > // create TexGen node > _texGen = new osg::TexGenNode; > _texGen->setTextureUnit(_textureUnit); > /* > // find the entity the Light is attached-to > VxEntity* ent; > > osg::Node* ln = NULL; > ln = (osg::Node*)VxSceneGraphManager::find(m_Light->name); > if (!ln) > VxFatalError(0,"Ooops couldn't find Light %s\n", m_Light->name.c_str()); > else > { > osg::Light* light = dynamic_cast<osg::LightSource*>(ln)->getLight(); > VxInfo(1,"VxShadowMap:: shadow caster GL lightID > %d\n",light->getLightNum()); > // TODO set the lightID of the shadowCasting light here ??? > ent = getParentEntityfromNode(ln); > } > // found the part > if ( ent ) > { > const osg::Vec3 lightPosOffset(m_Light->attachementInfo.position[0], > m_Light->attachementInfo.position[1], m_Light->attachementInfo.position[2]); > > // set an update callback to keep moving the camera and tex gen in the > right direction. > _Camera->setUpdateCallback( new > UpdateCameraAndTexGenCallback(lightPosOffset, ent, _TexGen.get()) ); > } > */ > > // enable shadowTexture on the 3Dscene > osg::StateSet* stateset = _shadowedScene->getOrCreateStateSet(); > 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); > //stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON| > StateAttribute::OVERRIDE); > > } > > > void ShadowMap::update(osg::NodeVisitor& nv) > { > > _shadowedScene->osg::Group::traverse(nv); > > } > > void ShadowMap::cull(osgUtil::CullVisitor& cv) > { > //osg::notify(osg::NOTICE)<<className()<<"::cull(osgUtl::CullVisitor&) in > development."<<std::endl; > > // now compute the camera's view and projection matrix to point at the > shadower (the camera's children) > > //TODO cull the scene based on the main camera or LightNode MR > osg::BoundingSphere bs; > // Need to unfold the scene to take in account NodeMask(s) > > for(unsigned int i=0; i<_shadowedScene->getNumChildren(); ++i) > { > if ( _shadowedScene->getChild(i)->getNodeMask() & > _shadowedScene->getCastsShadowTraversalMask() ) > { > #ifdef _DEBUG > osg::notify(osg::NOTICE)<<className()<< " _camera bounding box > exp with child " << i << std::endl; > #endif > bs.expandBy(_shadowedScene->getChild(i)->getBound()); > } > } > > if (!bs.valid()) > { > osg::notify(osg::INFO) << "bb invalid"<<_camera.get()<<std::endl; > return; > } > #ifdef _DEBUG > osg::notify(osg::NOTICE)<<className()<< std::setprecision(6) <<" _camera > bounding box r-x,y,z" << std::setw(10) << bs.radius() << std::setw(10) << > (float)bs.center().x() << std::setw(10) << (float)bs.center().y() << > std::setw(10) << (float)bs.center().z() <<std::endl; > > //VxWarning(0, "ShadowMap: CameraNode bounding box r:%.2f x:%.2f y:%.2f > z:%.2f.\n",bs.radius(), bs.center().x(), bs.center().y(),bs.center().z() ); > #endif > > if(_useLightPos) > { > osg::Vec4 _positionU = _light->getLight()->getPosition(); > if( _positionU.w() != 0.0) > _position.set(_positionU.x()/_positionU.w(), > _positionU.y()/_positionU.w(), _positionU.z()/_positionU.w()); > else > _position.set(_positionU.x(), _positionU.y(), _positionU.z()); > > } > float centerDistance = (_position-bs.center()).length(); > > float znear = centerDistance-bs.radius(); > float zfar = centerDistance+bs.radius(); > float zNearRatio = 0.001f; > if (znear<zfar*zNearRatio) znear = zfar*zNearRatio; > > #if 0 > // hack to illustrate the precision problems of excessive gap between > near far range. > znear = 0.00001*zfar; > #endif > float top = (bs.radius()/centerDistance)*znear; > float right = top; > > > _camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar); > > _camera->setViewMatrixAsLookAt(_position,bs.center(),osg::Vec3(0.0f,1.0f,0.0f)); > > // compute the matrix which takes a vertex from local coords into tex > coords > // will use this later to specify osg::TexGen.. > osg::Matrix MVPT = _camera->getViewMatrix() * > _camera->getProjectionMatrix() * > osg::Matrix::translate(1.0,1.0,1.0) * > osg::Matrix::scale(0.5f,0.5f,0.5f); > > _texGen->getTexGen()->setMode(osg::TexGen::EYE_LINEAR); > _texGen->getTexGen()->setPlanesFromMatrix(MVPT); > > //_camera->traverse(cv); > _shadowedScene->osg::Group::traverse(cv); > } > > /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield > * > * This library is open source and may be redistributed and/or modified under > * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or > * (at your option) any later version. The full license is in LICENSE file > * included with this distribution, and on the openscenegraph.org website. > * > * This library is distributed in the hope that it will be useful, > * but WITHOUT ANY WARRANTY; without even the implied warranty of > * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > * OpenSceneGraph Public License for more details. > */ > > #ifndef OSGSHADOW_SHADOWEDTEXTURE > #define OSGSHADOW_SHADOWEDTEXTURE 1 > > #include <osg/Camera> > > #include <osgShadow/ShadowTechnique> > > namespace osgShadow { > class osg::Texture2D; > class osg::TexGenNode; > > /** ShadowedTexture provides an implementation of shadow textures.*/ > class OSGSHADOW_EXPORT ShadowMap : public ShadowTechnique > { > public : > ShadowMap(); > > ShadowMap(const ShadowMap& es, const osg::CopyOp& > copyop=osg::CopyOp::SHALLOW_COPY); > > META_Object(osgShadow, ShadowMap); > > /** 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); > > > inline osg::Camera* getCamera() { > if(_dirty) > init(); > return _camera.get(); }; > inline osg::Texture2D* getTexture() { > if(_dirty) > init(); > return _texture.get(); }; > inline osg::TexGenNode* getTexGen() { > if(_dirty) > init(); > return _texGen.get(); }; > > inline void setLight(osg::LightSource* light) { _light = light; > _useLightPos=true;}; > > > protected : > > virtual ~ShadowMap() {} > private : > > unsigned int _textureHeight; > unsigned int _textureWidth; > unsigned int _textureUnit; > osg::Vec3 _position; > > bool _useLightPos; > osg::LightSource* _light; > > osg::ref_ptr<osg::Camera> _camera; > osg::ref_ptr<osg::Texture2D> _texture; > osg::ref_ptr<osg::TexGenNode> _texGen; > > > }; > > } > > #endif > > _______________________________________________ > osg-users mailing list > [email protected] > http://openscenegraph.net/mailman/listinfo/osg-users > http://www.openscenegraph.org/ > _______________________________________________ osg-users mailing list [email protected] http://openscenegraph.net/mailman/listinfo/osg-users http://www.openscenegraph.org/ _______________________________________________ osg-users mailing list [email protected] http://openscenegraph.net/mailman/listinfo/osg-users http://www.openscenegraph.org/
