diff --git a/examples/osganimate/GNUmakefile b/examples/osganimate/GNUmakefile index e6573d636..79a25454f 100644 --- a/examples/osganimate/GNUmakefile +++ b/examples/osganimate/GNUmakefile @@ -4,7 +4,7 @@ include $(TOPDIR)/Make/makedefs CXXFILES =\ osganimate.cpp\ -LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) +LIBS += -losgProducer -lProducer -losgSim -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) INSTFILES = \ $(CXXFILES)\ diff --git a/examples/osganimate/osganimate.cpp b/examples/osganimate/osganimate.cpp index dd430dac8..ec3919ecf 100644 --- a/examples/osganimate/osganimate.cpp +++ b/examples/osganimate/osganimate.cpp @@ -13,6 +13,8 @@ #include #include +#include + #include @@ -179,9 +181,19 @@ osg::Node* createModel() osg::Group* root = new osg::Group; - root->addChild(createMovingModel(center,radius*0.8f)); + osg::Node* baseModel = createBase(center-osg::Vec3(0.0f,0.0f,radius*0.5),radius); + osg::Node* movingModel = createMovingModel(center,radius*0.8f); - root->addChild(createBase(center-osg::Vec3(0.0f,0.0f,radius*0.5),radius)); +#if 1 + osgSim::OverlayNode* overlayNode = new osgSim::OverlayNode; + overlayNode->setOverlaySubgraph(movingModel); + overlayNode->addChild(baseModel); + root->addChild(overlayNode); +#else + root->addChild(baseModel); +#endif + + root->addChild(movingModel); return root; } diff --git a/examples/osgspheresegment/osgspheresegment.cpp b/examples/osgspheresegment/osgspheresegment.cpp index 9c63de8fa..94b23787f 100644 --- a/examples/osgspheresegment/osgspheresegment.cpp +++ b/examples/osgspheresegment/osgspheresegment.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -173,9 +174,11 @@ osg::Vec3 computeTerrainIntersection(osg::Node* subgraph,float x,float y) void build_world(osg::Group *root) { - osg::Geode* terrainGeode = new osg::Geode; // create terrain + osg::ref_ptr terrainGeode = 0; { + terrainGeode = new osg::Geode; + osg::StateSet* stateset = new osg::StateSet(); osg::Image* image = osgDB::readImageFile("Images/lz.rgb"); if (image) @@ -205,13 +208,15 @@ void build_world(osg::Group *root) } terrainGeode->addDrawable(new osg::ShapeDrawable(grid)); - root->addChild(terrainGeode); + } + // create sphere segment + osg::ref_ptr ss = 0; { - osgSim::SphereSegment* ss = new osgSim::SphereSegment( - computeTerrainIntersection(terrainGeode,550.0f,780.0f), // center + ss = new osgSim::SphereSegment( + computeTerrainIntersection(terrainGeode.get(),550.0f,780.0f), // center 500.0f, // radius osg::DegreesToRadians(135.0f), osg::DegreesToRadians(245.0f), @@ -221,13 +226,24 @@ void build_world(osg::Group *root) ss->setAllColors(osg::Vec4(1.0f,1.0f,1.0f,0.5f)); ss->setSideColor(osg::Vec4(0.0f,1.0f,1.0f,0.1f)); - root->addChild(ss); + root->addChild(ss.get()); } +#if 1 + osgSim::OverlayNode* overlayNode = new osgSim::OverlayNode; + overlayNode->setOverlaySubgraph(ss.get()); + overlayNode->setOverlayTextureSizeHint(2048); + overlayNode->addChild(terrainGeode.get()); + + root->addChild(overlayNode); +#else + root->addChild(terrainGeode); +#endif + // create particle effects { - osg::Vec3 position = computeTerrainIntersection(terrainGeode,100.0f,100.0f); + osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),100.0f,100.0f); osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 10.0f); osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 10.0f); @@ -240,7 +256,7 @@ void build_world(osg::Group *root) // create particle effects { - osg::Vec3 position = computeTerrainIntersection(terrainGeode,200.0f,100.0f); + osg::Vec3 position = computeTerrainIntersection(terrainGeode.get(),200.0f,100.0f); osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, 1.0f); osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, 1.0f); diff --git a/include/osgSim/OverlayNode b/include/osgSim/OverlayNode index 6d23ca3c4..f476dc340 100644 --- a/include/osgSim/OverlayNode +++ b/include/osgSim/OverlayNode @@ -53,6 +53,11 @@ class OSGSIM_EXPORT OverlayNode : public osg::Group /** Get the texture unit that the texture should be assigned to.*/ unsigned int getOverlayTextureUnit() const { return _textureUnit; } + /** Set the texture size hint. The size hint is used to request a texture of specified size.*/ + void setOverlayTextureSizeHint(unsigned int size); + + /** Get the texture size hint.*/ + unsigned int getOverlayTextureSizeHint() const { return _textureSizeHint; } protected : @@ -77,7 +82,8 @@ class OSGSIM_EXPORT OverlayNode : public osg::Group // texture to render to, and to read from. unsigned int _textureUnit; - osg::ref_ptr _texture; + unsigned int _textureSizeHint; + osg::ref_ptr _texture; }; diff --git a/src/osgSim/OverlayNode.cpp b/src/osgSim/OverlayNode.cpp index 557497133..76dd609fd 100644 --- a/src/osgSim/OverlayNode.cpp +++ b/src/osgSim/OverlayNode.cpp @@ -12,13 +12,16 @@ */ #include +#include + #include #include using namespace osgSim; OverlayNode::OverlayNode(): - _textureUnit(1) + _textureUnit(1), + _textureSizeHint(1024) { init(); } @@ -26,34 +29,38 @@ OverlayNode::OverlayNode(): OverlayNode::OverlayNode(const OverlayNode& copy, const osg::CopyOp& copyop): Group(copy,copyop), _overlaySubgraph(copy._overlaySubgraph), - _textureUnit(copy._textureUnit) + _textureUnit(copy._textureUnit), + _textureSizeHint(copy._textureSizeHint) { init(); } void OverlayNode::init() { - unsigned int tex_width = 1024; - unsigned int tex_height = 1024; + + unsigned int tex_width = _textureSizeHint; + unsigned int tex_height = _textureSizeHint; - 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; + if (!_texture) + { + 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. + if (!_camera) { - // create the camera - _camera = new osg::CameraNode; - - _camera->setClearColor(osg::Vec4(1.0f,0.5f,0.5f,1.0f)); + _camera = new osg::CameraNode; + + _camera->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); // set viewport _camera->setViewport(0,0,tex_width,tex_height); @@ -68,11 +75,11 @@ void OverlayNode::init() _camera->attach(osg::CameraNode::COLOR_BUFFER, _texture.get()); } - _texgenNode = new osg::TexGenNode; + if (!_texgenNode) _texgenNode = new osg::TexGenNode; - _mainSubgraphStateSet = new osg::StateSet; + if (!_mainSubgraphStateSet) _mainSubgraphStateSet = new osg::StateSet; - setOverlayTextureUnit(1); + setOverlayTextureUnit(_textureUnit); } @@ -97,8 +104,7 @@ void OverlayNode::traverse(osg::NodeVisitor& nv) // 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) @@ -108,30 +114,66 @@ void OverlayNode::traverse(osg::NodeVisitor& nv) if (!bs.valid()) { - osg::notify(osg::WARN) << "bb invalid"<<_camera.get()<(*itr); + } + _camera->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)); + + if (csn) + { + osg::Vec3d eyePoint(0.0,0.0,0.0); // center of the planet + double centerDistance = (eyePoint-osg::Vec3d(bs.center())).length(); + + double znear = centerDistance-bs.radius(); + double zfar = centerDistance+bs.radius(); + double zNearRatio = 0.001f; + if (znearsetProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar); + _camera->setViewMatrixAsLookAt(eyePoint, bs.center(), osg::Vec3(0.0f,1.0f,0.0f)); + } + else + { + osg::Vec3d upDirection(0.0,1.0,0.0); + osg::Vec3d viewDirection(0.0,0.0,1.0); + + double viewDistance = 2.0*bs.radius(); + osg::Vec3d center = bs.center(); + osg::Vec3d eyePoint = center+viewDirection*viewDistance; + + double znear = viewDistance-bs.radius(); + double zfar = viewDistance+bs.radius(); + + float top = bs.radius(); + float right = top; + + _camera->setProjectionMatrixAsOrtho(-right,right,-top,top,znear,zfar); + _camera->setViewMatrixAsLookAt(eyePoint,center,upDirection); + + } + // 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); + osg::Matrix::scale(0.5,0.5,0.5); _texgenNode->getTexGen()->setMode(osg::TexGen::EYE_LINEAR); _texgenNode->getTexGen()->setPlanesFromMatrix(MVPT); @@ -139,7 +181,7 @@ void OverlayNode::traverse(osg::NodeVisitor& nv) _camera->accept(*cv); -// _textureObjectValidList[contextID] = 1; + _textureObjectValidList[contextID] = 1; } @@ -186,3 +228,14 @@ void OverlayNode::setOverlayTextureUnit(unsigned int unit) _mainSubgraphStateSet->setTextureMode(_textureUnit, GL_TEXTURE_GEN_R, osg::StateAttribute::ON); _mainSubgraphStateSet->setTextureMode(_textureUnit, GL_TEXTURE_GEN_Q, osg::StateAttribute::ON); } + +void OverlayNode::setOverlayTextureSizeHint(unsigned int size) +{ + if (_textureSizeHint == size) return; + + _textureSizeHint = size; + //_texture->dirtyTextureObject(); + _texture->setTextureSize(_textureSizeHint, _textureSizeHint); + _camera->setViewport(0,0,_textureSizeHint,_textureSizeHint); +} +