diff --git a/examples/osgsimulation/osgsimulation.cpp b/examples/osgsimulation/osgsimulation.cpp index d1d53e089..09b618dc3 100644 --- a/examples/osgsimulation/osgsimulation.cpp +++ b/examples/osgsimulation/osgsimulation.cpp @@ -33,6 +33,8 @@ #include +#include + #include class GraphicsContext { @@ -289,7 +291,10 @@ int main(int argc, char **argv) return 1; } - osg::ref_ptr root = createEarth(); + // read the scene from the list of file specified commandline args. + osg::ref_ptr root = osgDB::readNodeFiles(arguments); + + if (!root) root = createEarth(); if (!root) return 0; @@ -299,6 +304,22 @@ int main(int argc, char **argv) osg::CoordinateSystemNode* csn = dynamic_cast(root.get()); if (csn) { + + bool insertOverlayNode = true; + osg::ref_ptr overlayNode; + if (insertOverlayNode) + { + overlayNode = new osgSim::OverlayNode; + for(unsigned int i=0; igetNumChildren(); ++i) + { + overlayNode->addChild( csn->getChild(i) ); + } + + csn->removeChild(0, csn->getNumChildren()); + csn->addChild(overlayNode.get()); + } + + osg::Node* cessna = osgDB::readNodeFile("cessna.osg"); if (cessna) { @@ -318,6 +339,12 @@ int main(int argc, char **argv) mt->setUpdateCallback(nc); csn->addChild(mt); + + // if we are using an overaly node, use the cessna subgraph as the overlay subgraph + if (overlayNode.valid()) + { + overlayNode->setOverlaySubgraph(mt); + } osgGA::NodeTrackerManipulator* tm = new osgGA::NodeTrackerManipulator; tm->setTrackerMode(trackerMode); @@ -331,6 +358,7 @@ int main(int argc, char **argv) { std::cout<<"Failed to read cessna.osg"<accept(*nv); } @@ -35,7 +36,7 @@ public: }; OverlayNode::OverlayNode(): - _textureUnit(0) + _textureUnit(1) { init(); } @@ -50,15 +51,46 @@ OverlayNode::OverlayNode(const OverlayNode& copy, const osg::CopyOp& copyop): void OverlayNode::init() { - _camera = new osg::CameraNode; + unsigned int tex_width = 1024; + unsigned int tex_height = 1024; + + osg::Texture2D* texture = new osg::Texture2D; + texture->setTextureSize(tex_width, tex_height); + texture->setInternalFormat(GL_RGBA); + 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 = texture; + + // set up the render to texture camera. + { + + // create the camera + _camera = new osg::CameraNode; + + _camera->setClearColor(osg::Vec4(1.0f,0.5f,0.5f,1.0f)); + + // set viewport + _camera->setViewport(0,0,tex_width,tex_height); + + // set the camera to render before the main camera. + _camera->setRenderOrder(osg::CameraNode::PRE_RENDER); + + // tell the camera to use OpenGL frame buffer object where supported. + _camera->setRenderTargetImplmentation(osg::CameraNode::FRAME_BUFFER_OBJECT); + + // attach the texture and use it as the color buffer. + _camera->attach(osg::CameraNode::COLOR_BUFFER, _texture.get()); + } _texgenNode = new osg::TexGenNode; - _texgenNode->setTextureUnit(_textureUnit); - - _texture = new osg::Texture2D; _mainSubgraphStateSet = new osg::StateSet; - _mainSubgraphStateSet->setTextureAttributeAndModes(_textureUnit, _texture.get(), osg::StateAttribute::ON); + + setOverlayTextureUnit(1); } @@ -77,14 +109,55 @@ void OverlayNode::traverse(osg::NodeVisitor& nv) return; } + unsigned int contextID = cv->getState()!=0 ? cv->getState()->getContextID() : 0; // if we need to redraw then do cull traversal on camera. if (!_textureObjectValidList[contextID]) { + osg::Vec3 _position(0,0,0); + + // now compute the camera's view and projection matrix to point at the shadower (the camera's children) + osg::BoundingSphere bs; + for(unsigned int i=0; i<_camera->getNumChildren(); ++i) + { + bs.expandBy(_camera->getChild(i)->getBound()); + } + + if (!bs.valid()) + { + osg::notify(osg::WARN) << "bb invalid"<<_camera.get()<setReferenceFrame(osg::CameraNode::ABSOLUTE_RF); + _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); + + _texgenNode->getTexGen()->setMode(osg::TexGen::EYE_LINEAR); + _texgenNode->getTexGen()->setPlanesFromMatrix(MVPT); + + _camera->accept(*cv); - _textureObjectValidList[contextID] = 1; +// _textureObjectValidList[contextID] = 1; } @@ -103,7 +176,13 @@ void OverlayNode::traverse(osg::NodeVisitor& nv) void OverlayNode::setOverlaySubgraph(osg::Node* node) { + if (_overlaySubgraph == node) return; + _overlaySubgraph = node; + + _camera->removeChild(0, _camera->getNumChildren()); + _camera->addChild(node); + dirtyOverlayTexture(); } @@ -114,10 +193,14 @@ void OverlayNode::dirtyOverlayTexture() void OverlayNode::setOverlayTextureUnit(unsigned int unit) { - if (_textureUnit==unit) return; - - _texgenNode->setTextureUnit(unit); + _textureUnit = unit; + + _texgenNode->setTextureUnit(_textureUnit); _mainSubgraphStateSet->clear(); _mainSubgraphStateSet->setTextureAttributeAndModes(_textureUnit, _texture.get(), osg::StateAttribute::ON); + _mainSubgraphStateSet->setTextureMode(_textureUnit, GL_TEXTURE_GEN_S, osg::StateAttribute::ON); + _mainSubgraphStateSet->setTextureMode(_textureUnit, GL_TEXTURE_GEN_T, osg::StateAttribute::ON); + _mainSubgraphStateSet->setTextureMode(_textureUnit, GL_TEXTURE_GEN_R, osg::StateAttribute::ON); + _mainSubgraphStateSet->setTextureMode(_textureUnit, GL_TEXTURE_GEN_Q, osg::StateAttribute::ON); }