diff --git a/include/osgSim/OverlayNode b/include/osgSim/OverlayNode index 2e3c0d6ac..76ae9625a 100644 --- a/include/osgSim/OverlayNode +++ b/include/osgSim/OverlayNode @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -72,10 +73,10 @@ class OSGSIM_EXPORT OverlayNode : public osg::Group /** Set the clear color to use when rendering the overlay subgraph.*/ - void setOverlayClearColor(const osg::Vec4& color); + void setOverlayClearColor(const osg::Vec4& color) { _overlayClearColor = _overlayClearColor; } /** Get the clear color to use when rendering the overlay subgraph.*/ - osg::Vec4 getOverlayClearColor() const; + const osg::Vec4& getOverlayClearColor() const { return _overlayClearColor; } /** Set the TexEnv mode used to combine the overlay texture with the base color/texture of the OverlayNode's decorate subgraph.*/ void setTexEnvMode(GLenum mode); @@ -95,12 +96,6 @@ class OSGSIM_EXPORT OverlayNode : public osg::Group /** Get the texture size hint.*/ unsigned int getOverlayTextureSizeHint() const { return _textureSizeHint; } - - /** Get the camera used to implement the render to texture of the overlay subgraph.*/ - osg::Camera* getCamera() { return _camera.get(); } - - /** Get the const camera used to implement the render to texture of the overlay subgraph.*/ - const osg::Camera* getCamera() const { return _camera.get(); } /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ virtual void setThreadSafeRefUnref(bool threadSafe); @@ -135,35 +130,34 @@ class OSGSIM_EXPORT OverlayNode : public osg::Group OverlayTechnique _overlayTechnique; - osg::ref_ptr _camera; - // overlay subgraph is render to a texture osg::ref_ptr _overlaySubgraph; - // texgen node to generate the tex coordinates for us - osg::ref_ptr _texgenNode; - - // state set to decoate the main subgraph. - osg::ref_ptr _mainSubgraphStateSet; - // texture to render to, and to read from. GLenum _texEnvMode; unsigned int _textureUnit; unsigned int _textureSizeHint; - osg::ref_ptr _texture; + osg::Vec4 _overlayClearColor; bool _continuousUpdate; bool _updateCamera; - osg::Polytope _textureFrustum; private: struct OverlayData { - osg::ref_ptr _camera; - osg::ref_ptr _overlayStateSet; - osg::ref_ptr _mainSubgraphStateSet; - osg::ref_ptr _texgen; + + void setThreadSafeRefUnref(bool threadSafe); + void resizeGLObjectBuffers(unsigned int maxSize); + void releaseGLObjects(osg::State* state= 0) const; + + osg::ref_ptr _camera; + osg::ref_ptr _overlayStateSet; + osg::ref_ptr _mainSubgraphStateSet; + osg::ref_ptr _texgenNode; + osg::ref_ptr _texture; + osg::Polytope _textureFrustum; + osg::ref_ptr _geode; }; typedef std::map OverlayDataMap; diff --git a/src/osgSim/OverlayNode.cpp b/src/osgSim/OverlayNode.cpp index 89837a3ce..c9341a19a 100644 --- a/src/osgSim/OverlayNode.cpp +++ b/src/osgSim/OverlayNode.cpp @@ -28,6 +28,7 @@ OverlayNode::OverlayNode(OverlayTechnique technique): _texEnvMode(GL_DECAL), _textureUnit(1), _textureSizeHint(1024), + _overlayClearColor(0.0f,0.0f,0.0f,0.0f), _continuousUpdate(false), _updateCamera(false) { @@ -42,43 +43,77 @@ OverlayNode::OverlayNode(const OverlayNode& copy, const osg::CopyOp& copyop): _texEnvMode(copy._texEnvMode), _textureUnit(copy._textureUnit), _textureSizeHint(copy._textureSizeHint), + _overlayClearColor(copy._overlayClearColor), _continuousUpdate(copy._continuousUpdate) { setNumChildrenRequiringUpdateTraversal(getNumChildrenRequiringUpdateTraversal()+1); init(); } +void OverlayNode::OverlayData::setThreadSafeRefUnref(bool threadSafe) +{ + if (_camera.valid()) _camera->setThreadSafeRefUnref(threadSafe); + if (_texgenNode.valid()) _texgenNode->setThreadSafeRefUnref(threadSafe); + if (_mainSubgraphStateSet.valid()) _mainSubgraphStateSet->setThreadSafeRefUnref(threadSafe); + if (_texture.valid()) _texture->setThreadSafeRefUnref(threadSafe); +} + +void OverlayNode::OverlayData::resizeGLObjectBuffers(unsigned int maxSize) +{ + if (_camera.valid()) _camera->resizeGLObjectBuffers(maxSize); + if (_texgenNode.valid()) _texgenNode->resizeGLObjectBuffers(maxSize); + if (_mainSubgraphStateSet.valid()) _mainSubgraphStateSet->resizeGLObjectBuffers(maxSize); + if (_texture.valid()) _texture->resizeGLObjectBuffers(maxSize); +} + +void OverlayNode::OverlayData::releaseGLObjects(osg::State* state) const +{ + if (_camera.valid()) _camera->releaseGLObjects(state); + if (_texgenNode.valid()) _texgenNode->releaseGLObjects(state); + if (_mainSubgraphStateSet.valid()) _mainSubgraphStateSet->releaseGLObjects(state); + if (_texture.valid()) _texture->releaseGLObjects(state); +} + void OverlayNode::setThreadSafeRefUnref(bool threadSafe) { osg::Group::setThreadSafeRefUnref(threadSafe); - if (_camera.valid()) _camera->setThreadSafeRefUnref(threadSafe); if (_overlaySubgraph.valid()) _overlaySubgraph->setThreadSafeRefUnref(threadSafe); - if (_texgenNode.valid()) _texgenNode->setThreadSafeRefUnref(threadSafe); - if (_mainSubgraphStateSet.valid()) _mainSubgraphStateSet->setThreadSafeRefUnref(threadSafe); - if (_texture.valid()) _texture->setThreadSafeRefUnref(threadSafe); + + for(OverlayDataMap::iterator itr = _overlayDataMap.begin(); + itr != _overlayDataMap.end(); + ++itr) + { + itr->second.setThreadSafeRefUnref(threadSafe); + } } void OverlayNode::resizeGLObjectBuffers(unsigned int maxSize) { osg::Group::resizeGLObjectBuffers(maxSize); - if (_camera.valid()) _camera->resizeGLObjectBuffers(maxSize); if (_overlaySubgraph.valid()) _overlaySubgraph->resizeGLObjectBuffers(maxSize); - if (_texgenNode.valid()) _texgenNode->resizeGLObjectBuffers(maxSize); - if (_mainSubgraphStateSet.valid()) _mainSubgraphStateSet->resizeGLObjectBuffers(maxSize); - if (_texture.valid()) _texture->resizeGLObjectBuffers(maxSize); + + for(OverlayDataMap::iterator itr = _overlayDataMap.begin(); + itr != _overlayDataMap.end(); + ++itr) + { + itr->second.resizeGLObjectBuffers(maxSize); + } } void OverlayNode::releaseGLObjects(osg::State* state) const { osg::Group::releaseGLObjects(state); - if (_camera.valid()) _camera->releaseGLObjects(state); if (_overlaySubgraph.valid()) _overlaySubgraph->releaseGLObjects(state); - if (_texgenNode.valid()) _texgenNode->releaseGLObjects(state); - if (_mainSubgraphStateSet.valid()) _mainSubgraphStateSet->releaseGLObjects(state); - if (_texture.valid()) _texture->releaseGLObjects(state); + + for(OverlayDataMap::const_iterator itr = _overlayDataMap.begin(); + itr != _overlayDataMap.end(); + ++itr) + { + itr->second.releaseGLObjects(state); + } } void OverlayNode::setOverlayTechnique(OverlayTechnique technique) @@ -116,11 +151,15 @@ void OverlayNode::init_OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY() { osg::notify(osg::NOTICE)<<"OverlayNode::init() - OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY"<setTextureSize(tex_width, tex_height); texture->setInternalFormat(GL_RGBA); @@ -128,34 +167,36 @@ void OverlayNode::init_OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY() 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,0.0f)); - _texture = texture; + texture->setBorderColor(osg::Vec4(_overlayClearColor)); + overlayData._texture = texture; } // set up the render to texture camera. - if (!_camera) + if (!overlayData._camera) { + osg::notify(osg::NOTICE)<<" setting up camera"<setClearColor(osg::Vec4(0.0f,0.0f,0.0f,0.0f)); + overlayData._camera->setClearColor(_overlayClearColor); // set viewport - _camera->setViewport(0,0,tex_width,tex_height); + overlayData._camera->setViewport(0,0,tex_width,tex_height); // set the camera to render before the main camera. - _camera->setRenderOrder(osg::Camera::PRE_RENDER); + overlayData._camera->setRenderOrder(osg::Camera::PRE_RENDER); // tell the camera to use OpenGL frame buffer object where supported. - _camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); + overlayData._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()); + overlayData._camera->attach(osg::Camera::COLOR_BUFFER, overlayData._texture.get()); } - if (!_texgenNode) _texgenNode = new osg::TexGenNode; + if (!overlayData._texgenNode) overlayData._texgenNode = new osg::TexGenNode; - if (!_mainSubgraphStateSet) _mainSubgraphStateSet = new osg::StateSet; + if (!overlayData._mainSubgraphStateSet) overlayData._mainSubgraphStateSet = new osg::StateSet; setOverlayTextureUnit(_textureUnit); } @@ -188,19 +229,23 @@ void OverlayNode::traverse(osg::NodeVisitor& nv) void OverlayNode::traverse_OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeVisitor& nv) { + OverlayData& overlayData = getOverlayData(0); + osg::Camera* camera = overlayData._camera.get(); + if (nv.getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR) { - Group::traverse(nv); if (_continuousUpdate || _updateCamera) { + + // 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) + for(unsigned int i=0; igetNumChildren(); ++i) { - bs.expandBy(_camera->getChild(i)->getBound()); + bs.expandBy(camera->getChild(i)->getBound()); } if (bs.valid()) @@ -215,7 +260,7 @@ void OverlayNode::traverse_OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeV csn = dynamic_cast(*itr); } - _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); + camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); if (csn) { @@ -230,8 +275,8 @@ void OverlayNode::traverse_OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeV double top = (bs.radius()/centerDistance)*znear; double right = top; - _camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar); - _camera->setViewMatrixAsLookAt(eyePoint, bs.center(), osg::Vec3(0.0f,1.0f,0.0f)); + camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar); + camera->setViewMatrixAsLookAt(eyePoint, bs.center(), osg::Vec3(0.0f,1.0f,0.0f)); } else { @@ -248,26 +293,26 @@ void OverlayNode::traverse_OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeV float top = bs.radius(); float right = top; - _camera->setProjectionMatrixAsOrtho(-right,right,-top,top,znear,zfar); - _camera->setViewMatrixAsLookAt(eyePoint,center,upDirection); + 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 MVP = _camera->getViewMatrix() * - _camera->getProjectionMatrix(); + osg::Matrix MVP = camera->getViewMatrix() * + camera->getProjectionMatrix(); osg::Matrix MVPT = MVP * osg::Matrix::translate(1.0,1.0,1.0) * osg::Matrix::scale(0.5,0.5,0.5); - _texgenNode->getTexGen()->setMode(osg::TexGen::EYE_LINEAR); - _texgenNode->getTexGen()->setPlanesFromMatrix(MVPT); + overlayData._texgenNode->getTexGen()->setMode(osg::TexGen::EYE_LINEAR); + overlayData._texgenNode->getTexGen()->setPlanesFromMatrix(MVPT); - _textureFrustum.setToUnitFrustum(false,false); - _textureFrustum.transformProvidingInverse(MVP); + overlayData._textureFrustum.setToUnitFrustum(false,false); + overlayData._textureFrustum.transformProvidingInverse(MVP); } _updateCamera = false; } @@ -294,7 +339,8 @@ void OverlayNode::traverse_OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeV // if we need to redraw then do cull traversal on camera. if (!_textureObjectValidList[contextID] || _continuousUpdate) { - _camera->accept(*cv); + camera->setClearColor(_overlayClearColor); + camera->accept(*cv); _textureObjectValidList[contextID] = 1; } @@ -315,14 +361,14 @@ void OverlayNode::traverse_OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY(osg::NodeV #endif { - _texgenNode->accept(*cv); + overlayData._texgenNode->accept(*cv); const osg::Matrix modelView = *(cv->getModelViewMatrix()); osg::Polytope viewTextureFrustum; - viewTextureFrustum.setAndTransformProvidingInverse(_textureFrustum, osg::Matrix::inverse(modelView)); + viewTextureFrustum.setAndTransformProvidingInverse(overlayData._textureFrustum, osg::Matrix::inverse(modelView)); - cv->getProjectionCullingStack().back().addStateFrustum(_mainSubgraphStateSet.get(), viewTextureFrustum); - cv->getCurrentCullingSet().addStateFrustum(_mainSubgraphStateSet.get(), _textureFrustum); + cv->getProjectionCullingStack().back().addStateFrustum(overlayData._mainSubgraphStateSet.get(), viewTextureFrustum); + cv->getCurrentCullingSet().addStateFrustum(overlayData._mainSubgraphStateSet.get(), overlayData._textureFrustum); // push the stateset. // cv->pushStateSet(_mainSubgraphStateSet.get()); @@ -496,12 +542,19 @@ void OverlayNode::setOverlaySubgraph(osg::Node* node) _overlaySubgraph = node; - if (_camera.valid()) + for(OverlayDataMap::iterator itr = _overlayDataMap.begin(); + itr != _overlayDataMap.end(); + ++itr) { - _camera->removeChildren(0, _camera->getNumChildren()); - _camera->addChild(node); + osg::Camera* camera = itr->second._camera.get(); + if (camera) + { + camera->removeChildren(0, camera->getNumChildren()); + camera->addChild(node); + } } + dirtyOverlayTexture(); } @@ -511,16 +564,6 @@ void OverlayNode::dirtyOverlayTexture() _updateCamera = true; } -void OverlayNode::setOverlayClearColor(const osg::Vec4& color) -{ - if (_camera.valid()) _camera->setClearColor(color); -} - -osg::Vec4 OverlayNode::getOverlayClearColor() const -{ - return _camera.valid() ? _camera->getClearColor() : osg::Vec4(1.0f,1.0f,1.0f,1.0f); -} - void OverlayNode::setTexEnvMode(GLenum mode) { @@ -533,7 +576,13 @@ void OverlayNode::setOverlayTextureUnit(unsigned int unit) { _textureUnit = unit; - if (_texgenNode.valid()) _texgenNode->setTextureUnit(_textureUnit); + for(OverlayDataMap::iterator itr = _overlayDataMap.begin(); + itr != _overlayDataMap.end(); + ++itr) + { + osg::TexGenNode* texgenNode = itr->second._texgenNode.get(); + if (texgenNode) texgenNode->setTextureUnit(_textureUnit); + } updateMainSubgraphStateSet(); } @@ -543,24 +592,41 @@ void OverlayNode::setOverlayTextureSizeHint(unsigned int size) if (_textureSizeHint == size) return; _textureSizeHint = size; + + + for(OverlayDataMap::iterator itr = _overlayDataMap.begin(); + itr != _overlayDataMap.end(); + ++itr) + { + if (itr->second._texture.valid()) itr->second._texture->setTextureSize(_textureSizeHint, _textureSizeHint); + if (itr->second._camera.valid()) itr->second._camera->setViewport(0,0,_textureSizeHint,_textureSizeHint); + } + //_texture->dirtyTextureObject(); - if (_texture.valid()) _texture->setTextureSize(_textureSizeHint, _textureSizeHint); - if (_camera.valid()) _camera->setViewport(0,0,_textureSizeHint,_textureSizeHint); } void OverlayNode::updateMainSubgraphStateSet() { - if (!_mainSubgraphStateSet) return; + osg::notify(osg::NOTICE)<<"OverlayNode::updateMainSubgraphStateSet()"<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); - - if (_texEnvMode!=GL_NONE) + for(OverlayDataMap::iterator itr = _overlayDataMap.begin(); + itr != _overlayDataMap.end(); + ++itr) { - _mainSubgraphStateSet->setTextureAttribute(_textureUnit, new osg::TexEnv((osg::TexEnv::Mode)_texEnvMode)); + osg::StateSet* mainSubgraphStateSet = itr->second._mainSubgraphStateSet.get(); + if (mainSubgraphStateSet) + { + mainSubgraphStateSet->clear(); + mainSubgraphStateSet->setTextureAttributeAndModes(_textureUnit, itr->second._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); + + if (_texEnvMode!=GL_NONE) + { + mainSubgraphStateSet->setTextureAttribute(_textureUnit, new osg::TexEnv((osg::TexEnv::Mode)_texEnvMode)); + } + } } } diff --git a/src/osgWrappers/osgSim/OverlayNode.cpp b/src/osgWrappers/osgSim/OverlayNode.cpp index afd1a04ff..4319b97b5 100644 --- a/src/osgWrappers/osgSim/OverlayNode.cpp +++ b/src/osgWrappers/osgSim/OverlayNode.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -124,9 +123,9 @@ BEGIN_OBJECT_REFLECTOR(osgSim::OverlayNode) __void__setOverlayClearColor__C5_osg_Vec4_R1, "Set the clear color to use when rendering the overlay subgraph. ", ""); - I_Method0(osg::Vec4, getOverlayClearColor, + I_Method0(const osg::Vec4 &, getOverlayClearColor, Properties::NON_VIRTUAL, - __osg_Vec4__getOverlayClearColor, + __C5_osg_Vec4_R1__getOverlayClearColor, "Get the clear color to use when rendering the overlay subgraph. ", ""); I_Method1(void, setTexEnvMode, IN, GLenum, mode, @@ -159,16 +158,6 @@ BEGIN_OBJECT_REFLECTOR(osgSim::OverlayNode) __unsigned_int__getOverlayTextureSizeHint, "Get the texture size hint. ", ""); - I_Method0(osg::Camera *, getCamera, - Properties::NON_VIRTUAL, - __osg_Camera_P1__getCamera, - "Get the camera used to implement the render to texture of the overlay subgraph. ", - ""); - I_Method0(const osg::Camera *, getCamera, - Properties::NON_VIRTUAL, - __C5_osg_Camera_P1__getCamera, - "Get the const camera used to implement the render to texture of the overlay subgraph. ", - ""); I_Method1(void, setThreadSafeRefUnref, IN, bool, threadSafe, Properties::VIRTUAL, __void__setThreadSafeRefUnref__bool, @@ -232,14 +221,11 @@ BEGIN_OBJECT_REFLECTOR(osgSim::OverlayNode) __void__updateMainSubgraphStateSet, "", ""); - I_SimpleProperty(osg::Camera *, Camera, - __osg_Camera_P1__getCamera, - 0); I_SimpleProperty(bool, ContinuousUpdate, __bool__getContinuousUpdate, __void__setContinuousUpdate__bool); - I_SimpleProperty(osg::Vec4, OverlayClearColor, - __osg_Vec4__getOverlayClearColor, + I_SimpleProperty(const osg::Vec4 &, OverlayClearColor, + __C5_osg_Vec4_R1__getOverlayClearColor, __void__setOverlayClearColor__C5_osg_Vec4_R1); I_SimpleProperty(osg::Node *, OverlaySubgraph, __osg_Node_P1__getOverlaySubgraph, diff --git a/src/osgWrappers/osgUtil/CullVisitor.cpp b/src/osgWrappers/osgUtil/CullVisitor.cpp index d09d146d5..0b2057a61 100644 --- a/src/osgWrappers/osgUtil/CullVisitor.cpp +++ b/src/osgWrappers/osgUtil/CullVisitor.cpp @@ -266,6 +266,11 @@ BEGIN_OBJECT_REFLECTOR(osgUtil::CullVisitor) __void__addPositionedTextureAttribute__unsigned_int__osg_RefMatrix_P1__C5_osg_StateAttribute_P1, "Add an attribute which is positioned relative to the modelview matrix. ", ""); + I_Method0(void, computeNearPlane, + Properties::NON_VIRTUAL, + __void__computeNearPlane, + "compute near plane based on the polgon intersection of primtives in near plane candidate list of drawables. ", + "Note, you have to set ComputeNearFarMode to COMPUTE_NEAR_FAR_USING_PRIMITIVES to be able to near plane candidate drawables to be recorded by the cull traversal. "); I_Method0(void, popProjectionMatrix, Properties::VIRTUAL, __void__popProjectionMatrix,