diff --git a/examples/osghud/osghud.cpp b/examples/osghud/osghud.cpp index 3cedf6959..4eed583c6 100644 --- a/examples/osghud/osghud.cpp +++ b/examples/osghud/osghud.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -36,17 +37,6 @@ osg::Node* createHUD() osg::StateSet* stateset = geode->getOrCreateStateSet(); stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF); -#if 0 - // to ensure the hud appears on top we can either use osg::Depth to force the - // depth fragments to be placed at the front of the screen. - stateset->setAttribute(new osg::Depth(osg::Depth::LESS,0.0,0.0001)); -#else - // or disable depth test, and make sure that the hud is drawn after everything - // else so that it always appears ontop. - stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF); - stateset->setRenderBinDetails(11,"RenderBin"); -#endif - osg::Vec3 position(150.0f,800.0f,0.0f); osg::Vec3 delta(0.0f,-120.0f,0.0f); @@ -146,6 +136,42 @@ osg::Node* createHUD() geode->addDrawable(geom); } +#if 1 + + osg::CameraNode* camera = new osg::CameraNode; + + // 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::CameraNode::POST_RENDER); + + camera->addChild(geode); + + return camera; + +#else + +#if 0 + // to ensure the hud appears on top we can either use osg::Depth to force the + // depth fragments to be placed at the front of the screen. + stateset->setAttribute(new osg::Depth(osg::Depth::LESS,0.0,0.0001)); +#else + // or disable depth test, and make sure that the hud is drawn after everything + // else so that it always appears ontop. + stateset->setMode(GL_DEPTH_TEST,osg::StateAttribute::OFF); + stateset->setRenderBinDetails(11,"RenderBin"); +#endif + + + // create the hud. osg::MatrixTransform* modelview_abs = new osg::MatrixTransform; modelview_abs->setReferenceFrame(osg::Transform::ABSOLUTE_RF); @@ -157,6 +183,7 @@ osg::Node* createHUD() projection->addChild(modelview_abs); return projection; +#endif } diff --git a/examples/osgprerender/osgprerender.cpp b/examples/osgprerender/osgprerender.cpp index 37e3fdac0..3d0abe27d 100644 --- a/examples/osgprerender/osgprerender.cpp +++ b/examples/osgprerender/osgprerender.cpp @@ -23,180 +23,186 @@ #include -class MyUpdateCallback : public osg::NodeCallback -{ - public: - - MyUpdateCallback(osg::Node* subgraph): - _subgraph(subgraph) {} +#define USE_CAMERA_NODE - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) - { - // traverse the subgraph to update any nodes. - if (_subgraph.valid()) _subgraph->accept(*nv); - - // must traverse the Node's subgraph - traverse(node,nv); - } - - osg::ref_ptr _subgraph; -}; +#ifndef USE_CAMERA_NODE -class MyCullCallback : public osg::NodeCallback -{ - public: - - MyCullCallback(osg::Node* subgraph,osg::Texture2D* texture): - _subgraph(subgraph), - _texture(texture), - _localState(new osg::StateSet) {} + class MyUpdateCallback : public osg::NodeCallback + { + public: - MyCullCallback(osg::Node* subgraph,osg::Image* image): - _subgraph(subgraph), - _image(image), - _localState(new osg::StateSet) {} - - virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) - { + MyUpdateCallback(osg::Node* subgraph): + _subgraph(subgraph) {} - osgUtil::CullVisitor* cullVisitor = dynamic_cast(nv); - if (cullVisitor && (_texture.valid()|| _image.valid()) && _subgraph.valid()) - { - doPreRender(*node,*cullVisitor); - - // must traverse the subgraph - traverse(node,nv); - - } - else + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { - // must traverse the subgraph + // traverse the subgraph to update any nodes. + if (_subgraph.valid()) _subgraph->accept(*nv); + + // must traverse the Node's subgraph traverse(node,nv); } + + osg::ref_ptr _subgraph; + }; + + + class MyCullCallback : public osg::NodeCallback + { + public: + + MyCullCallback(osg::Node* subgraph,osg::Texture2D* texture): + _subgraph(subgraph), + _texture(texture), + _localState(new osg::StateSet) {} + + MyCullCallback(osg::Node* subgraph,osg::Image* image): + _subgraph(subgraph), + _image(image), + _localState(new osg::StateSet) {} + + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + { + + osgUtil::CullVisitor* cullVisitor = dynamic_cast(nv); + if (cullVisitor && (_texture.valid()|| _image.valid()) && _subgraph.valid()) + { + doPreRender(*node,*cullVisitor); + + // must traverse the subgraph + traverse(node,nv); + + } + else + { + // must traverse the subgraph + traverse(node,nv); + } + } + + void doPreRender(osg::Node& node, osgUtil::CullVisitor& cv); + + osg::ref_ptr _subgraph; + osg::ref_ptr _texture; + osg::ref_ptr _image; + osg::ref_ptr _localState; + + }; + + void MyCullCallback::doPreRender(osg::Node&, osgUtil::CullVisitor& cv) + { + const osg::BoundingSphere& bs = _subgraph->getBound(); + if (!bs.valid()) + { + osg::notify(osg::WARN) << "bb invalid"<<_subgraph.get()< _subgraph; - osg::ref_ptr _texture; - osg::ref_ptr _image; - osg::ref_ptr _localState; - -}; - -void MyCullCallback::doPreRender(osg::Node&, osgUtil::CullVisitor& cv) -{ - const osg::BoundingSphere& bs = _subgraph->getBound(); - if (!bs.valid()) - { - osg::notify(osg::WARN) << "bb invalid"<<_subgraph.get()< rtts = new osgUtil::RenderToTextureStage; - - // set up lighting. - // currently ignore lights in the scene graph itself.. - // will do later. - osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage(); - - // set up the background color and clear mask. - rtts->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f)); - rtts->setClearMask(previous_stage->getClearMask()); - - // set up to charge the same RenderStageLighting is the parent previous stage. - rtts->setRenderStageLighting(previous_stage->getRenderStageLighting()); - // record the render bin, to be restored after creation - // of the render to text - osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin(); + // create the render to texture stage. + osg::ref_ptr rtts = new osgUtil::RenderToTextureStage; - // set the current renderbin to be the newly created stage. - cv.setCurrentRenderBin(rtts.get()); + // set up lighting. + // currently ignore lights in the scene graph itself.. + // will do later. + osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage(); + + // set up the background color and clear mask. + rtts->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f)); + rtts->setClearMask(previous_stage->getClearMask()); + + // set up to charge the same RenderStageLighting is the parent previous stage. + rtts->setRenderStageLighting(previous_stage->getRenderStageLighting()); - float znear = 1.0f*bs.radius(); - float zfar = 3.0f*bs.radius(); - - // 2:1 aspect ratio as per flag geomtry below. - float top = 0.25f*znear; - float right = 0.5f*znear; + // record the render bin, to be restored after creation + // of the render to text + osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin(); - znear *= 0.9f; - zfar *= 1.1f; + // set the current renderbin to be the newly created stage. + cv.setCurrentRenderBin(rtts.get()); - // set up projection. - osg::RefMatrix* projection = new osg::RefMatrix; - projection->makeFrustum(-right,right,-top,top,znear,zfar); - cv.pushProjectionMatrix(projection); + float znear = 1.0f*bs.radius(); + float zfar = 3.0f*bs.radius(); - osg::RefMatrix* matrix = new osg::RefMatrix; - matrix->makeLookAt(bs.center()+osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); + // 2:1 aspect ratio as per flag geomtry below. + float top = 0.25f*znear; + float right = 0.5f*znear; - cv.pushModelViewMatrix(matrix); + znear *= 0.9f; + zfar *= 1.1f; - cv.pushStateSet(_localState.get()); + // set up projection. + osg::RefMatrix* projection = new osg::RefMatrix; + projection->makeFrustum(-right,right,-top,top,znear,zfar); - { + cv.pushProjectionMatrix(projection); - // traverse the subgraph - _subgraph->accept(cv); + osg::RefMatrix* matrix = new osg::RefMatrix; + matrix->makeLookAt(bs.center()+osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); + + cv.pushModelViewMatrix(matrix); + + cv.pushStateSet(_localState.get()); + + { + + // traverse the subgraph + _subgraph->accept(cv); + + } + + cv.popStateSet(); + + // restore the previous model view matrix. + cv.popModelViewMatrix(); + + // restore the previous model view matrix. + cv.popProjectionMatrix(); + + // restore the previous renderbin. + cv.setCurrentRenderBin(previousRenderBin); + + if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0) + { + // getting to this point means that all the subgraph has been + // culled by small feature culling or is beyond LOD ranges. + return; + } + + + + int height = 256; + int width = 512; + + + const osg::Viewport& viewport = *cv.getViewport(); + + // offset the impostor viewport from the center of the main window + // viewport as often the edges of the viewport might be obscured by + // other windows, which can cause image/reading writing problems. + int center_x = viewport.x()+viewport.width()/2; + int center_y = viewport.y()+viewport.height()/2; + + osg::Viewport* new_viewport = new osg::Viewport; + new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height); + rtts->setViewport(new_viewport); + + _localState->setAttribute(new_viewport); + + // and the render to texture stage to the current stages + // dependancy list. + cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get()); + + // if one exist attach texture to the RenderToTextureStage. + if (_texture.valid()) rtts->setTexture(_texture.get()); + + // if one exist attach image to the RenderToTextureStage. + if (_image.valid()) rtts->setImage(_image.get()); } - - cv.popStateSet(); - - // restore the previous model view matrix. - cv.popModelViewMatrix(); - - // restore the previous model view matrix. - cv.popProjectionMatrix(); - - // restore the previous renderbin. - cv.setCurrentRenderBin(previousRenderBin); - - if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0) - { - // getting to this point means that all the subgraph has been - // culled by small feature culling or is beyond LOD ranges. - return; - } - - - - int height = 256; - int width = 512; - - - const osg::Viewport& viewport = *cv.getViewport(); - - // offset the impostor viewport from the center of the main window - // viewport as often the edges of the viewport might be obscured by - // other windows, which can cause image/reading writing problems. - int center_x = viewport.x()+viewport.width()/2; - int center_y = viewport.y()+viewport.height()/2; - - osg::Viewport* new_viewport = new osg::Viewport; - new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height); - rtts->setViewport(new_viewport); - - _localState->setAttribute(new_viewport); - - // and the render to texture stage to the current stages - // dependancy list. - cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get()); - - // if one exist attach texture to the RenderToTextureStage. - if (_texture.valid()) rtts->setTexture(_texture.get()); - - // if one exist attach image to the RenderToTextureStage. - if (_image.valid()) rtts->setImage(_image.get()); - -} +#endif // call back which cretes a deformation field to oscilate the model. class MyGeometryCallback : @@ -352,6 +358,8 @@ osg::Node* createPreRenderSubGraph(osg::Node* subgraph) osg::Geode* geode = new osg::Geode(); geode->addDrawable(polyGeom); +#ifndef USE_CAMERA_NODE + osg::Group* parent = new osg::Group; parent->setUpdateCallback(new MyUpdateCallback(subgraph)); @@ -361,6 +369,63 @@ osg::Node* createPreRenderSubGraph(osg::Node* subgraph) parent->addChild(geode); return parent; + +#else + + + osg::CameraNode* camera = new osg::CameraNode; + + // set up the background color and clear mask. + camera->setClearColor(osg::Vec4(0.1f,0.1f,0.3f,1.0f)); + camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + const osg::BoundingSphere& bs = subgraph->getBound(); + if (!bs.valid()) + { + return subgraph; + } + + float znear = 1.0f*bs.radius(); + float zfar = 3.0f*bs.radius(); + + // 2:1 aspect ratio as per flag geomtry below. + float proj_top = 0.25f*znear; + float proj_right = 0.5f*znear; + + znear *= 0.9f; + zfar *= 1.1f; + + // set up projection. + camera->setProjectionMatrixAsFrustum(-proj_right,proj_right,-proj_top,proj_top,znear,zfar); + + // set view + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + camera->setViewMatrixAsLookAt(bs.center()+osg::Vec3(0.0f,2.0f,0.0f)*bs.radius(),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); + + // set viewport + camera->setViewport(0,0,1024,512); + + camera->getOrCreateStateSet()->setAttribute(camera->getViewport()); + + // set the camera to render before the main camera. + camera->setRenderOrder(osg::CameraNode::PRE_RENDER); + + camera->attach(osg::CameraNode::COLOR_BUFFER,texture); + + // add subgraph to render + camera->addChild(subgraph); + + + // create a group to contain the flag and the pre rendering camera. + osg::Group* parent = new osg::Group; + + parent->addChild(camera); + parent->addChild(geode); + + + return parent; + +#endif } int main( int argc, char **argv ) diff --git a/include/osg/CameraNode b/include/osg/CameraNode index a985c1728..4ccf69a6f 100644 --- a/include/osg/CameraNode +++ b/include/osg/CameraNode @@ -16,12 +16,15 @@ #include #include +#include +#include +#include namespace osg { /** CameraNode - is a subclass of Transform which represents encapsulates the settings of a Camera. */ -class OSG_EXPORT CameraNode : public Transform +class OSG_EXPORT CameraNode : public Transform, public CullSettings { public : @@ -34,20 +37,6 @@ class OSG_EXPORT CameraNode : public Transform META_Node(osg, CameraNode); - /** Sets the clear color. */ - inline void setClearColor(const Vec4& color) { _clearColor = color; } - - /** Returns the clear color. */ - inline const Vec4& getClearColor() const { return _clearColor; } - - /** Set the clear mask used in glClear(..). - * Defaults to GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */ - inline void setClearMask(GLbitfield mask) { _clearMask = mask; } - - /** Get the clear mask.*/ - inline GLbitfield getClearMask() const { return _clearMask; } - - /** Set the viewport of the scene view to use specified osg::Viewport. */ void setViewport(osg::Viewport* viewport) @@ -151,7 +140,76 @@ class OSG_EXPORT CameraNode : public Transform + /** Sets the clear color. */ + inline void setClearColor(const Vec4& color) { _clearColor = color; } + /** Returns the clear color. */ + inline const Vec4& getClearColor() const { return _clearColor; } + + /** Set the clear mask used in glClear(..). + * Defaults to GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */ + inline void setClearMask(GLbitfield mask) { _clearMask = mask; } + + /** Get the clear mask.*/ + inline GLbitfield getClearMask() const { return _clearMask; } + + + + enum RenderOrder + { + PRE_RENDER, + NESTED_RENDER, + POST_RENDER + }; + + /** Set the rendering order of this camera's subgraph relative to any camera that this subgraph is nested within. + * For rendering to a texture, one typically uses PRE_RENDER. + * For Head Up Displays, one would typically use POST_RENDER.*/ + void setRenderOrder(RenderOrder order) { _renderOrder = order; } + + /** Get the rendering order of this camera's subgraph relative to any camera that this subgraph is nested within.*/ + RenderOrder getRenderOrder() const { return _renderOrder; } + + enum RenderTargetImplementation + { + FRAME_BUFFER_OBJECT, + PIXEL_BUFFER, + FRAME_BUFFER + }; + + void setRenderTargetImplmentation(RenderTargetImplementation impl) { _renderTargetImplementation = impl; } + RenderTargetImplementation getRenderTargetImplmentation() const { return _renderTargetImplementation; } + + enum BufferComponent + { + COLOR_BUFFER, + DEPTH_BUFFER, + STENCIL_BUFFER + }; + + void attach(BufferComponent buffer, GLenum internalFormat); + + void attach(BufferComponent buffer, osg::Texture* texture, unsigned int face=0); + + void attach(BufferComponent buffer, osg::Image* image); + + void detach(BufferComponent buffer); + + struct Attachment + { + GLenum _internalFormat; + ref_ptr _image; + ref_ptr _texture; + unsigned int _face; + }; + + typedef std::map< BufferComponent, Attachment> BufferAttachmentMap; + + BufferAttachmentMap& getBufferAttachmentMap() { return _bufferAttachmentMap; } + const BufferAttachmentMap& getBufferAttachmentMap() const { return _bufferAttachmentMap; } + + + public: /** Transform method that must be defined to provide generic interface for scene graph traversals.*/ @@ -164,11 +222,16 @@ class OSG_EXPORT CameraNode : public Transform virtual ~CameraNode(); - Vec4 _clearColor; - GLbitfield _clearMask; - ref_ptr _viewport; - Matrixd _projectionMatrix; - Matrixd _viewMatrix; + Vec4 _clearColor; + GLbitfield _clearMask; + ref_ptr _viewport; + Matrixd _projectionMatrix; + Matrixd _viewMatrix; + + RenderOrder _renderOrder; + + RenderTargetImplementation _renderTargetImplementation; + BufferAttachmentMap _bufferAttachmentMap; }; diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index 0ee229ee8..b3b9502cc 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -75,6 +76,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac virtual void apply(osg::Switch& node); virtual void apply(osg::LOD& node); virtual void apply(osg::ClearNode& node); + virtual void apply(osg::CameraNode& node); virtual void apply(osg::OccluderNode& node); void setClearNode(const osg::ClearNode* earthSky) { _clearNode = earthSky; } diff --git a/include/osgUtil/RenderStage b/include/osgUtil/RenderStage index 4114ba4c3..3328dd241 100644 --- a/include/osgUtil/RenderStage +++ b/include/osgUtil/RenderStage @@ -127,9 +127,14 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin virtual void draw(osg::State& state,RenderLeaf*& previous); + virtual void drawPostRenderStages(osg::State& state,RenderLeaf*& previous); + virtual void drawImplementation(osg::State& state,RenderLeaf*& previous); - void addToDependencyList(RenderStage* rs); + void addToDependencyList(RenderStage* rs) { addPreRenderStage(rs); } + + void addPreRenderStage(RenderStage* rs); + void addPostRenderStage(RenderStage* rs); /** Extract stats for current draw list. */ bool getStats(Statistics* primStats); @@ -138,10 +143,11 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin virtual ~RenderStage(); - typedef std::vector< osg::ref_ptr > DependencyList; + typedef std::vector< osg::ref_ptr > RenderStageList; bool _stageDrawnThisFrame; - DependencyList _dependencyList; + RenderStageList _preRenderList; + RenderStageList _postRenderList; // viewport x,y,width,height. osg::ref_ptr _viewport; diff --git a/src/osg/CameraNode.cpp b/src/osg/CameraNode.cpp index 4d027a0cd..96e291bfa 100644 --- a/src/osg/CameraNode.cpp +++ b/src/osg/CameraNode.cpp @@ -18,17 +18,24 @@ using namespace osg; CameraNode::CameraNode(): _clearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f)), - _clearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + _clearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT), + _renderOrder(POST_RENDER), + _renderTargetImplementation(FRAME_BUFFER) { } CameraNode::CameraNode(const CameraNode& camera,const CopyOp& copyop): Transform(camera,copyop), + CullSettings(camera), _clearColor(camera._clearColor), _clearMask(camera._clearMask), _viewport(camera._viewport), _projectionMatrix(camera._projectionMatrix), - _viewMatrix(camera._viewMatrix) + _viewMatrix(camera._viewMatrix), + _renderOrder(camera._renderOrder), + _renderTargetImplementation(camera._renderTargetImplementation), + _bufferAttachmentMap(camera._bufferAttachmentMap) + { } @@ -109,6 +116,29 @@ void CameraNode::getViewMatrixAsLookAt(Vec3& eye,Vec3& center,Vec3& up,float loo _viewMatrix.getLookAt(eye,center,up,lookDistance); } + +void CameraNode::attach(BufferComponent buffer, GLenum internalFormat) +{ + _bufferAttachmentMap[buffer]._internalFormat = internalFormat; +} + +void CameraNode::attach(BufferComponent buffer, osg::Texture* texture, unsigned int face) +{ + _bufferAttachmentMap[buffer]._texture = texture; + _bufferAttachmentMap[buffer]._face = face; +} + +void CameraNode::attach(BufferComponent buffer, osg::Image* image) +{ + _bufferAttachmentMap[buffer]._image = image; +} + +void CameraNode::detach(BufferComponent buffer) +{ + _bufferAttachmentMap.erase(buffer); +} + + bool CameraNode::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const { if (_referenceFrame==RELATIVE_RF) diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index 366616c85..966460d28 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -1023,6 +1023,100 @@ void CullVisitor::apply(osg::ClearNode& node) } +void CullVisitor::apply(osg::CameraNode& camera) +{ + // push the node's state. + StateSet* node_state = camera.getStateSet(); + if (node_state) pushStateSet(node_state); + + // use render to texture stage. + { + // create the render to texture stage. + osg::ref_ptr rtts = new osgUtil::RenderToTextureStage; + + // set up lighting. + // currently ignore lights in the scene graph itself.. + // will do later. + osgUtil::RenderStage* previous_stage = getCurrentRenderBin()->getStage(); + + // set up the background color and clear mask. + rtts->setClearColor(camera.getClearColor()); + rtts->setClearMask(camera.getClearMask()); + + // set up the viewport. + rtts->setViewport( camera.getViewport()!=0 ? camera.getViewport() : previous_stage->getViewport()); + + // set up to charge the same RenderStageLighting is the parent previous stage. + rtts->setRenderStageLighting(previous_stage->getRenderStageLighting()); + + // record the render bin, to be restored after creation + // of the render to text + osgUtil::RenderBin* previousRenderBin = getCurrentRenderBin(); + + // set the current renderbin to be the newly created stage. + setCurrentRenderBin(rtts.get()); + + pushProjectionMatrix(new osg::RefMatrix(camera.getProjectionMatrix())); + + pushModelViewMatrix(new osg::RefMatrix(camera.getViewMatrix())); + + // traverse the subgraph + { + handle_cull_callbacks_and_traverse(camera); + } + + // restore the previous model view matrix. + popModelViewMatrix(); + + // restore the previous model view matrix. + popProjectionMatrix(); + + // restore the previous renderbin. + setCurrentRenderBin(previousRenderBin); + + if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0) + { + // getting to this point means that all the subgraph has been + // culled by small feature culling or is beyond LOD ranges. + } + + + // and the render to texture stage to the current stages + // dependancy list. + switch(camera.getRenderOrder()) + { + case osg::CameraNode::PRE_RENDER : + getCurrentRenderBin()->getStage()->addPreRenderStage(rtts.get()); + break; + case osg::CameraNode::NESTED_RENDER : + getCurrentRenderBin()->getStage()->addPostRenderStage(rtts.get()); + break; + case osg::CameraNode::POST_RENDER : + getCurrentRenderBin()->getStage()->addPostRenderStage(rtts.get()); + break; + } + + osg::CameraNode::BufferAttachmentMap& bufferAttachements = camera.getBufferAttachmentMap(); + for(osg::CameraNode::BufferAttachmentMap::iterator itr = bufferAttachements.begin(); + itr != bufferAttachements.end(); + ++itr) + { + + // if one exist attach texture to the RenderToTextureStage. + osg::Texture2D* texture2D = dynamic_cast(itr->second._texture.get()); + if (texture2D) rtts->setTexture(texture2D); + + // if one exist attach image to the RenderToTextureStage. + if (itr->second._image.valid()) rtts->setImage(itr->second._image.get()); + } + + } + + // pop the node's state off the render graph stack. + if (node_state) popStateSet(); + +} + void CullVisitor::apply(osg::OccluderNode& node) { // need to check if occlusion node is in the occluder diff --git a/src/osgUtil/RenderBin.cpp b/src/osgUtil/RenderBin.cpp index 7f143a6f8..7492f15de 100644 --- a/src/osgUtil/RenderBin.cpp +++ b/src/osgUtil/RenderBin.cpp @@ -322,7 +322,7 @@ RenderBin* RenderBin::find_or_insert(int binNum,const std::string& binName) rs->_binNum = binNum; rs->_parent = NULL; rs->_stage = rs; - _stage->addToDependencyList(rs); + _stage->addPreRenderStage(rs); } else { diff --git a/src/osgUtil/RenderStage.cpp b/src/osgUtil/RenderStage.cpp index b89a015bb..f22cf24ea 100644 --- a/src/osgUtil/RenderStage.cpp +++ b/src/osgUtil/RenderStage.cpp @@ -56,7 +56,8 @@ RenderStage::RenderStage(SortMode mode): RenderStage::RenderStage(const RenderStage& rhs,const osg::CopyOp& copyop): RenderBin(rhs,copyop), _stageDrawnThisFrame(false), - _dependencyList(rhs._dependencyList), + _preRenderList(rhs._preRenderList), + _postRenderList(rhs._postRenderList), _viewport(rhs._viewport), _clearMask(rhs._clearMask), _colorMask(rhs._colorMask), @@ -77,7 +78,7 @@ RenderStage::~RenderStage() void RenderStage::reset() { - _dependencyList.clear(); + _preRenderList.clear(); _stageDrawnThisFrame = false; if (_renderStageLighting.valid()) _renderStageLighting->reset(); @@ -85,18 +86,23 @@ void RenderStage::reset() RenderBin::reset(); } -void RenderStage::addToDependencyList(RenderStage* rs) +void RenderStage::addPreRenderStage(RenderStage* rs) { - if (rs) _dependencyList.push_back(rs); + if (rs) _preRenderList.push_back(rs); +} + +void RenderStage::addPostRenderStage(RenderStage* rs) +{ + if (rs) _postRenderList.push_back(rs); } void RenderStage::drawPreRenderStages(osg::State& state,RenderLeaf*& previous) { - if (_dependencyList.empty()) return; + if (_preRenderList.empty()) return; //cout << "Drawing prerendering stages "<x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<draw(state,previous); @@ -115,6 +121,10 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous) //drawPreRenderStages(state,previous); RenderBin::draw(state,previous); + + // place the post draw here temprorarily while we figure out how + // best to do SceneView. + drawPostRenderStages(state,previous); } void RenderStage::drawImplementation(osg::State& state,RenderLeaf*& previous) @@ -182,6 +192,21 @@ void RenderStage::drawImplementation(osg::State& state,RenderLeaf*& previous) } } + +void RenderStage::drawPostRenderStages(osg::State& state,RenderLeaf*& previous) +{ + if (_postRenderList.empty()) return; + + //cout << "Drawing prerendering stages "<x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<draw(state,previous); + } + //cout << "Done Drawing prerendering stages "<x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<