diff --git a/include/osgUtil/RenderStage b/include/osgUtil/RenderStage index 6841a2505..410968785 100644 --- a/include/osgUtil/RenderStage +++ b/include/osgUtil/RenderStage @@ -119,9 +119,14 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin /** Get the clear color.*/ int getClearStencil() const { return _clearStencil; } - - void setCameraNode(const osg::CameraNode* camera) { _camera = camera; } + void setCameraNode(osg::CameraNode* camera) { if (_camera!=camera) { _camera = camera; _cameraRequiresSetUp = true; } } + osg::CameraNode* getCameraNode() { return _camera; } const osg::CameraNode* getCameraNode() const { return _camera; } + + void setCameraRequiresSetUp(bool flag) { _cameraRequiresSetUp = true; } + bool getCameraRequiresSetUp() const { return _cameraRequiresSetUp; } + + void runCameraSetUp(osg::State& state); void setTexture(osg::Texture* texture, unsigned int level = 0, unsigned int face=0) { _texture = texture; _level = level; _face = face; } osg::Texture* getTexture() { return _texture.get(); } @@ -216,7 +221,8 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin double _clearDepth; int _clearStencil; - const osg::CameraNode* _camera; + bool _cameraRequiresSetUp; + osg::CameraNode* _camera; osg::ref_ptr _texture; unsigned int _level; diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index d49e2d325..70c2a5a68 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -1205,212 +1205,6 @@ void CullVisitor::apply(osg::CameraNode& camera) break; } - osg::CameraNode::BufferAttachmentMap& bufferAttachements = camera.getBufferAttachmentMap(); - for(osg::CameraNode::BufferAttachmentMap::iterator itr = bufferAttachements.begin(); - itr != bufferAttachements.end(); - ++itr) - { - // assign the texture... pro - if (itr->second._texture.valid()) rtts->setTexture(itr->second._texture.get(), itr->second._level, itr->second._face); - - // if one exist attach image to the RenderToTextureStage. - if (itr->second._image.valid()) rtts->setImage(itr->second._image.get()); - } - - if (camera.getRenderTargetImplementation()==osg::CameraNode::FRAME_BUFFER_OBJECT) - { - osg::ref_ptr fbo = rtts->getFrameBufferObject(); - - if (!fbo) - { - fbo = new osg::FrameBufferObject; - rtts->setFrameBufferObject(fbo.get()); - - rtts->setDrawBuffer(GL_BACK); - rtts->setReadBuffer(GL_BACK); - - bool colorAttached = false; - bool depthAttached = false; - bool stencilAttached = false; - for(osg::CameraNode::BufferAttachmentMap::iterator itr = bufferAttachements.begin(); - itr != bufferAttachements.end(); - ++itr) - { - - osg::CameraNode::BufferComponent buffer = itr->first; - osg::CameraNode::Attachment& attachment = itr->second; - switch(buffer) - { - case(osg::CameraNode::DEPTH_BUFFER): - { - fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(attachment)); - depthAttached = true; - break; - } - case(osg::CameraNode::STENCIL_BUFFER): - { - fbo->setAttachment(GL_STENCIL_ATTACHMENT_EXT, osg::FrameBufferAttachment(attachment)); - stencilAttached = true; - break; - } - default: - { - fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT+(buffer-osg::CameraNode::COLOR_BUFFER0), osg::FrameBufferAttachment(attachment)); - colorAttached = true; - break; - } - - } - } - - if (!depthAttached) - { - fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(viewport->width(), viewport->height(), GL_DEPTH_COMPONENT24))); - } - - if (!colorAttached) - { - fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(viewport->width(), viewport->height(), GL_RGB))); - } - } - } - else if (camera.getRenderTargetImplementation()==osg::CameraNode::PIXEL_BUFFER_RTT || - camera.getRenderTargetImplementation()==osg::CameraNode::PIXEL_BUFFER || - camera.getRenderTargetImplementation()==osg::CameraNode::SEPERATE_WINDOW ) - { - osg::ref_ptr context = rtts->getGraphicsContext(); - if (!context) - { - osg::Texture* pBufferTexture = 0; - - // set up the traits of the graphics context that we want - osg::ref_ptr traits = new osg::GraphicsContext::Traits; - - traits->_width = viewport->width(); - traits->_height = viewport->height(); - traits->_pbuffer = (camera.getRenderTargetImplementation()==osg::CameraNode::PIXEL_BUFFER || camera.getRenderTargetImplementation()==osg::CameraNode::PIXEL_BUFFER_RTT); - traits->_windowDecoration = (camera.getRenderTargetImplementation()==osg::CameraNode::SEPERATE_WINDOW); - traits->_doubleBuffer = (camera.getRenderTargetImplementation()==osg::CameraNode::SEPERATE_WINDOW); - - rtts->setDrawBuffer(GL_FRONT); - rtts->setReadBuffer(GL_FRONT); - - GLenum bufferFormat = GL_NONE; - - bool colorAttached = false; - bool depthAttached = false; - bool stencilAttached = false; - for(osg::CameraNode::BufferAttachmentMap::iterator itr = bufferAttachements.begin(); - itr != bufferAttachements.end(); - ++itr) - { - - osg::CameraNode::BufferComponent buffer = itr->first; - osg::CameraNode::Attachment& attachment = itr->second; - switch(buffer) - { - case(osg::CameraNode::DEPTH_BUFFER): - { - traits->_depth = 24; - depthAttached = true; - break; - } - case(osg::CameraNode::STENCIL_BUFFER): - { - traits->_stencil = 8; - stencilAttached = true; - break; - } - case(osg::CameraNode::COLOR_BUFFER): - { - if (attachment._internalFormat!=GL_NONE) - { - bufferFormat = attachment._internalFormat; - } - else - { - if (attachment._texture.valid()) - { - pBufferTexture = attachment._texture.get(); - bufferFormat = attachment._texture->getInternalFormat(); - } - else if (attachment._image.valid()) - { - bufferFormat = attachment._image->getInternalTextureFormat(); - } - else - { - bufferFormat = GL_RGBA; - } - } - - if (camera.getRenderTargetImplementation()==osg::CameraNode::PIXEL_BUFFER_RTT) - { - traits->_target = bufferFormat; - traits->_level = attachment._level; - traits->_face = attachment._face; - traits->_mipMapGeneration = attachment._mipMapGeneration; - } - break; - } - default: - { - if (camera.getRenderTargetImplementation()==osg::CameraNode::SEPERATE_WINDOW) - osg::notify(osg::NOTICE)<<"Warning: Window "; - else - osg::notify(osg::NOTICE)<<"Warning: Pbuffer "; - - osg::notify(osg::NOTICE)<<"does not support multiple color outputs."<_depth = 24; - } - - if (!colorAttached) - { - if (bufferFormat == GL_NONE) bufferFormat = GL_RGB; - - traits->_red = 8; - traits->_green = 8; - traits->_blue = 8; - traits->_alpha = (bufferFormat==GL_RGBA) ? 8 : 0; - } - - // share OpenGL objects if possible... - if (_state.valid() && _state->getGraphicsContext()) - { - traits->_sharedContext = _state->getGraphicsContext(); - } - - // create the graphics context according to these traits. - context = osg::GraphicsContext::createGraphicsContext(traits.get()); - - if (!context) - { - osg::notify(osg::NOTICE)<<"Failed to aquire Graphics Context"<setGraphicsContext(context.get()); - - if (pBufferTexture && camera.getRenderTargetImplementation()==osg::CameraNode::PIXEL_BUFFER_RTT) - { - pBufferTexture->setReadPBuffer(context.get()); - } -#if 0 - context->createGraphicsThread(); -#else - context->realize(); -#endif - } - } - - } // restore the previous model view matrix. diff --git a/src/osgUtil/RenderStage.cpp b/src/osgUtil/RenderStage.cpp index 5ae64d893..645408a58 100644 --- a/src/osgUtil/RenderStage.cpp +++ b/src/osgUtil/RenderStage.cpp @@ -143,6 +143,231 @@ void RenderStage::drawPreRenderStages(osg::State& state,RenderLeaf*& previous) //cout << "Done Drawing prerendering stages "<x()<<","<< _viewport->y()<<","<< _viewport->width()<<","<< _viewport->height()<getRenderTargetImplementation(); + + osg::CameraNode::BufferAttachmentMap& bufferAttachements = _camera->getBufferAttachmentMap(); + for(osg::CameraNode::BufferAttachmentMap::iterator itr = bufferAttachements.begin(); + itr != bufferAttachements.end(); + ++itr) + { + // assign the texture... pro + if (itr->second._texture.valid()) setTexture(itr->second._texture.get(), itr->second._level, itr->second._face); + + // if one exist attach image to the RenderToTextureStage. + if (itr->second._image.valid()) setImage(itr->second._image.get()); + } + + if (renderTargetImplemntation==osg::CameraNode::FRAME_BUFFER_OBJECT) + { + osg::FBOExtensions* fbo_ext = osg::FBOExtensions::instance(state.getContextID()); + bool fbo_supported = fbo_ext && fbo_ext->isSupported(); + + if (!fbo_supported) + { + // fallback to using pbuffer + osg::notify(osg::NOTICE)<<"Using fallback to Pbuffer"<first; + osg::CameraNode::Attachment& attachment = itr->second; + switch(buffer) + { + case(osg::CameraNode::DEPTH_BUFFER): + { + _fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(attachment)); + depthAttached = true; + break; + } + case(osg::CameraNode::STENCIL_BUFFER): + { + _fbo->setAttachment(GL_STENCIL_ATTACHMENT_EXT, osg::FrameBufferAttachment(attachment)); + stencilAttached = true; + break; + } + default: + { + _fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT+(buffer-osg::CameraNode::COLOR_BUFFER0), osg::FrameBufferAttachment(attachment)); + colorAttached = true; + break; + } + + } + } + + if (!depthAttached) + { + _fbo->setAttachment(GL_DEPTH_ATTACHMENT_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(_viewport->width(), _viewport->height(), GL_DEPTH_COMPONENT24))); + } + + if (!colorAttached) + { + _fbo->setAttachment(GL_COLOR_ATTACHMENT0_EXT, osg::FrameBufferAttachment(new osg::RenderBuffer(_viewport->width(), _viewport->height(), GL_RGB))); + } + } + } + + if (renderTargetImplemntation==osg::CameraNode::PIXEL_BUFFER_RTT || + renderTargetImplemntation==osg::CameraNode::PIXEL_BUFFER || + renderTargetImplemntation==osg::CameraNode::SEPERATE_WINDOW ) + { + osg::ref_ptr context = getGraphicsContext(); + if (!context) + { + osg::Texture* pBufferTexture = 0; + + // set up the traits of the graphics context that we want + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + + traits->_width = _viewport->width(); + traits->_height = _viewport->height(); + traits->_pbuffer = (renderTargetImplemntation==osg::CameraNode::PIXEL_BUFFER || renderTargetImplemntation==osg::CameraNode::PIXEL_BUFFER_RTT); + traits->_windowDecoration = (renderTargetImplemntation==osg::CameraNode::SEPERATE_WINDOW); + traits->_doubleBuffer = (renderTargetImplemntation==osg::CameraNode::SEPERATE_WINDOW); + + setDrawBuffer(GL_FRONT); + setReadBuffer(GL_FRONT); + + GLenum bufferFormat = GL_NONE; + + bool colorAttached = false; + bool depthAttached = false; + bool stencilAttached = false; + for(osg::CameraNode::BufferAttachmentMap::iterator itr = bufferAttachements.begin(); + itr != bufferAttachements.end(); + ++itr) + { + + osg::CameraNode::BufferComponent buffer = itr->first; + osg::CameraNode::Attachment& attachment = itr->second; + switch(buffer) + { + case(osg::CameraNode::DEPTH_BUFFER): + { + traits->_depth = 24; + depthAttached = true; + break; + } + case(osg::CameraNode::STENCIL_BUFFER): + { + traits->_stencil = 8; + stencilAttached = true; + break; + } + case(osg::CameraNode::COLOR_BUFFER): + { + if (attachment._internalFormat!=GL_NONE) + { + bufferFormat = attachment._internalFormat; + } + else + { + if (attachment._texture.valid()) + { + pBufferTexture = attachment._texture.get(); + bufferFormat = attachment._texture->getInternalFormat(); + } + else if (attachment._image.valid()) + { + bufferFormat = attachment._image->getInternalTextureFormat(); + } + else + { + bufferFormat = GL_RGBA; + } + } + + if (renderTargetImplemntation==osg::CameraNode::PIXEL_BUFFER_RTT) + { + traits->_target = bufferFormat; + traits->_level = attachment._level; + traits->_face = attachment._face; + traits->_mipMapGeneration = attachment._mipMapGeneration; + } + break; + } + default: + { + if (renderTargetImplemntation==osg::CameraNode::SEPERATE_WINDOW) + osg::notify(osg::NOTICE)<<"Warning: Window "; + else + osg::notify(osg::NOTICE)<<"Warning: Pbuffer "; + + osg::notify(osg::NOTICE)<<"does not support multiple color outputs."<_depth = 24; + } + + if (!colorAttached) + { + if (bufferFormat == GL_NONE) bufferFormat = GL_RGB; + + traits->_red = 8; + traits->_green = 8; + traits->_blue = 8; + traits->_alpha = (bufferFormat==GL_RGBA) ? 8 : 0; + } + + // share OpenGL objects if possible... + if (state.getGraphicsContext()) + { + traits->_sharedContext = state.getGraphicsContext(); + } + + // create the graphics context according to these traits. + context = osg::GraphicsContext::createGraphicsContext(traits.get()); + + if (!context) + { + osg::notify(osg::NOTICE)<<"Failed to aquire Graphics Context"<setReadPBuffer(context.get()); + } +#if 0 + context->createGraphicsThread(); +#else + bool result = context.valid() ? context->realize() : false; + + osg::notify(osg::NOTICE)<<"Context has been realized "<