Hi,
In the frame of mixed geometry/volume rendering, i would like to create 
depthtexture for a subgraph..this texture is used to stop forward raycast of 
the volume.
In order to do that i would like to:
1)Render subgraph in a fbo with 3 attachements
-depth to renderbuffer
-depth to texture
-color to renderbuffer
2)Copy back  depth and color render buffers from the fbo to the frame buffer 
(using glblitframebuffer)


Here my current code

Code:

class OSGMULTIGRID_EXPORT RenderDepth2Texture : public osg::Group{
        public:
virtual         bool addChild(osg::Node*n);
                RenderDepth2Texture(); 
                /** Copy constructor using CopyOp to manage deep vs shallow 
copy.*/
         
         
                inline osg::Texture2D*getDepthTexture()const{ return 
_depthtexture; }
                inline osg::Uniform*getDepthResolutionUniform()const{ return 
_rdx; }
                void setRasterizationResolution(const osg::Vec2ui&);
                const osg::Vec2ui & getRasterizationResolution()const { return 
_resolution; }
        
                virtual void traverse(osg::NodeVisitor &nv);
                 osg::ref_ptr<osg::Texture2D> _depthtexture,_colortexture;
                osg::Vec2ui _resolution;
                osg::ref_ptr<osg::Camera> _camera;
                osg::ref_ptr<osg::Uniform > _rdx; 
        };
class PreDrawFBOCallback : public osg::Camera::DrawCallback
{
public:
        PreDrawFBOCallback(osg::FrameBufferObject* fbo, osg::FrameBufferObject* 
source_fbo, unsigned int width, unsigned int height, osg::Texture2D *dt, 
osg::Texture2D *ct) :
                _fbo(fbo), _source_fbo(source_fbo), _depthTexture(dt), 
_colorTexture(ct), _width(width), _height(height) {}

        virtual void operator () (osg::RenderInfo& renderInfo) const
        {
                cerr << "PreDrawFBOCallback" << endl;
                // switching only the frame buffer attachments is actually 
faster than switching the framebuffer
#ifdef USE_PACKED_DEPTH_STENCIL
#ifdef USE_TEXTURE_RECTANGLE
                _fbo->setAttachment(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER, 
osg::FrameBufferAttachment((osg::TextureRectangle*)(_depthTexture.get())));
#else
                _fbo->setAttachment(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER, 
osg::FrameBufferAttachment((osg::Texture2D*)(_depthTexture.get())));
                _fbo->setAttachment(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER, 
osg::FrameBufferAttachment(new osg::RenderBuffer(_width, _height, 
GL_DEPTH24_STENCIL8_EXT)));// A16)));
#endif
#else
#ifdef USE_TEXTURE_RECTANGLE
                _fbo->setAttachment(osg::Camera::DEPTH_BUFFER, 
osg::FrameBufferAttachment((osg::TextureRectangle*)(_depthTexture.get())));
#else
                _fbo->setAttachment(osg::Camera::DEPTH_BUFFER, 
osg::FrameBufferAttachment(_depthTexture.get()));// 
osg::FrameBufferAttachment(new osg::RenderBuffer(_width, _height, GL_RGBA16)));
#endif
#endif
#ifdef USE_TEXTURE_RECTANGLE
                _fbo->setAttachment(osg::Camera::COLOR_BUFFER0, 
osg::FrameBufferAttachment((osg::TextureRectangle*)(_colorTexture.get())));
#else
                _fbo->setAttachment(osg::Camera::COLOR_BUFFER0, 
osg::FrameBufferAttachment((_colorTexture.get())));// 
osg::FrameBufferAttachment(new osg::RenderBuffer(_width, _height, 
GL_DEPTH_COMPONENT16_ARB)));

                _fbo->setAttachment(osg::Camera::COLOR_BUFFER, 
osg::FrameBufferAttachment(new osg::RenderBuffer(_width, _height, GL_RGBA)));// 
A16)));
#endif
                /*
                // check if we need to do some depth buffer copying from a 
source FBO into the current FBO
                if (_source_fbo.get() != NULL)
                {
                osg::FBOExtensions* fbo_ext = 
osg::FBOExtensions::instance(renderInfo.getContextID(), true);
                bool fbo_supported = fbo_ext && fbo_ext->isSupported();
                if (fbo_supported && fbo_ext->glBlitFramebuffer)
                {
                // blit the depth buffer from the solid geometry fbo into the 
current transparency fbo
                (_fbo.get())->apply(*renderInfo.getState(), 
osg::FrameBufferObject::DRAW_FRAMEBUFFER);
                (_source_fbo.get())->apply(*renderInfo.getState(), 
osg::FrameBufferObject::READ_FRAMEBUFFER);

                //             glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); // only 
needed to blit the color buffer
                //             glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); // only 
needed to blit the color buffer
                fbo_ext->glBlitFramebuffer(
                0, 0, static_cast<GLint>(_width), static_cast<GLint>(_height),
                0, 0, static_cast<GLint>(_width), static_cast<GLint>(_height),
                #ifdef USE_PACKED_DEPTH_STENCIL
                GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
                #else
                GL_DEPTH_BUFFER_BIT, GL_NEAREST);
                #endif
                (_fbo.get())->apply(*renderInfo.getState(), 
osg::FrameBufferObject::READ_FRAMEBUFFER);
                (_fbo.get())->apply(*renderInfo.getState(), 
osg::FrameBufferObject::DRAW_FRAMEBUFFER);
                }
                }*/
                // switch to this fbo, if it isn't already bound
                (_fbo.get())->apply(*renderInfo.getState());// , 
osg::FrameBufferObject::READ_FRAMEBUFFER);
                //(_fbo.get())->apply(*renderInfo.getState(), 
osg::FrameBufferObject::DRAW_FRAMEBUFFER);
        }
protected:
        osg::ref_ptr<osg::FrameBufferObject> _fbo;
        osg::ref_ptr<osg::FrameBufferObject> _source_fbo;
        osg::ref_ptr<osg::Texture2D> _depthTexture;
        osg::ref_ptr<osg::Texture2D> _colorTexture;
        unsigned int _width;
        unsigned int _height;
};


class PostDrawFBOCallback : public osg::Camera::DrawCallback
{
public:
        PostDrawFBOCallback(osg::FrameBufferObject* fbo, 
osg::FrameBufferObject* source_fbo, unsigned int width, unsigned int height, 
osg::Texture *dt, osg::Texture *ct) :
                _fbo(fbo), _width(width), _height(height) {
// in order to select FrameBuffer instead of FBO
                _dummyfbo = new osg::FrameBufferObject();
        }
        virtual void operator () (osg::RenderInfo& renderInfo) const
        {
                cerr << "PostDrawFBOCallback" << endl;
                osg::FBOExtensions* fbo_ext = 
osg::FBOExtensions::instance(renderInfo.getContextID(), false);

                

                (_fbo.get())->apply(*renderInfo.getState(), 
osg::FrameBufferObject::READ_FRAMEBUFFER);
                (_dummyfbo.get())->apply(*renderInfo.getState(), 
osg::FrameBufferObject::DRAW_FRAMEBUFFER);
                //same as glBind(GL_DRAW_FRAMEBUFFER,0);

                fbo_ext->glBlitFramebuffer(
                        0, 0, static_cast<GLint>(_width), 
static_cast<GLint>(_height),
                        0, 0, static_cast<GLint>(_width), 
static_cast<GLint>(_height),
                        GL_COLOR_BUFFER_BIT, GL_NEAREST);

                fbo_ext->glBlitFramebuffer(
                        0, 0, static_cast<GLint>(_width), 
static_cast<GLint>(_height),
                        0, 0, static_cast<GLint>(_width), 
static_cast<GLint>(_height),
#ifdef USE_PACKED_DEPTH_STENCIL
                        GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, 
GL_NEAREST);
#else
                        GL_DEPTH_BUFFER_BIT, GL_NEAREST);
#endif

                ///restore fbo 
                (_dummyfbo.get())->apply(*renderInfo.getState(), 
osg::FrameBufferObject::READ_FRAMEBUFFER);

                
        }
protected:
        bool _restore;
protected:
        osg::ref_ptr<osg::FrameBufferObject> _fbo, _dummyfbo;
 
        unsigned int _width;
        unsigned int _height;
};
 
RenderDepth2Texture::RenderDepth2Texture() :osg::Group()
{
         
        _camera = new osg::Camera();
        _camera->setClearColor(osg::Vec4(0, 1, 0, 1));
        _camera->setClearDepth(1);
         
        _camera->setAllowEventFocus(false);

        setCullingActive(false);


        _rdx = new osg::Uniform();
        _rdx->setName("rviewport");
        _rdx->setType(osg::Uniform::FLOAT_VEC2);

        _resolution = osg::Vec2ui(0, 0);
        _rdx->set(osg::Vec2f(1.0f / (float)_resolution.x(), 1.0f / 
(float)_resolution.y()));
        _colortexture = new osg::Texture2D();

        _colortexture->setInternalFormat(GL_RGBA);// GL_DEPTH_COMPONENT32_ARB 
perhaps ARB should be cool
        _colortexture->setSourceFormat(GL_RGBA);//RGBA
        _colortexture->setSourceType(GL_UNSIGNED_BYTE);//don give a shit cause 
its not  client data

        _colortexture->setDataVariance(osg::Texture2D::DYNAMIC);
        _colortexture->setFilter(osg::Texture2D::MIN_FILTER, 
osg::Texture2D::NEAREST);
        _colortexture->setFilter(osg::Texture2D::MAG_FILTER, 
osg::Texture2D::NEAREST);

        _depthtexture = new osg::Texture2D();

        _depthtexture->setInternalFormat(GL_DEPTH_COMPONENT16_ARB);// 
GL_DEPTH_COMPONENT32_ARB perhaps ARB should be cool
        _depthtexture->setSourceFormat(GL_DEPTH_COMPONENT);//RGBA
        _depthtexture->setSourceType(GL_UNSIGNED_BYTE);//don give a shit cause 
its not  client data

        _depthtexture->setDataVariance(osg::Texture2D::DYNAMIC);
        _depthtexture->setFilter(osg::Texture2D::MIN_FILTER, 
osg::Texture2D::NEAREST);
        _depthtexture->setFilter(osg::Texture2D::MAG_FILTER, 
osg::Texture2D::NEAREST);
#ifdef USE_PACKED_DEPTH_STENCIL
        _depthtexture->setInternalFormat(GL_DEPTH24_STENCIL8_EXT);
        _depthtexture->setSourceFormat(GL_DEPTH_STENCIL_EXT);
        _depthtexture->setSourceType(GL_UNSIGNED_INT_24_8_EXT);
#else
        _depthtexture->setInternalFormat(GL_DEPTH_COMPONENT);
#endif

 

}


void RenderDepth2Texture::setRasterizationResolution(const osg::Vec2ui& size)
{
        _resolution = size; _rdx->set(osg::Vec2f(1.0f / (float)_resolution.x(), 
1.0f / (float)_resolution.y()));
        _rdx->dirty();
 
        _depthtexture->setTextureSize(_resolution.x(), _resolution.y());
        _colortexture->setTextureSize(_resolution.x(), _resolution.y());
        _colortexture->dirtyTextureObject();
        _depthtexture->dirtyTextureObject();
 

}
bool RenderDepth2Texture::addChild(osg::Node*n){
        osg::Group::addChild(n);//dummy node for serialisaetion
        return _camera->addChild(n);//real one
}
void RenderDepth2Texture::traverse(osg::NodeVisitor &nv)
{
        // record the traversal mask on entry so we can reapply it later.
        unsigned int traversalMask = nv.getTraversalMask();
        if (nv.getVisitorType() == osg::NodeVisitor::CULL_VISITOR)
        {
                osgUtil::CullVisitor* cv = 
dynamic_cast<osgUtil::CullVisitor*>(&nv);
                osg::Camera*cam = cv->getCurrentCamera();
                osg::Camera::Attachment attach = 
cam->getBufferAttachmentMap()[osg::Camera::DEPTH_BUFFER];

                unsigned int w, h;
                w = cam->getViewport()->width();
                h = cam->getViewport()->height();

                if (getRasterizationResolution() != osg::Vec2ui(w, h)){
                        //no texture resoltuion changes fuck the stuff..        
_resolution
                        setRasterizationResolution
                                (osg::Vec2ui(w, h));
                        //_camera = 
(osg::Camera*)cam->clone(osg::CopyOp::DEEP_COPY_ALL);
                        osg::ref_ptr<osg::FrameBufferObject> fbo = new 
osg::FrameBufferObject();
                        _camera->setViewport(cam->getViewport());
                         
                        _camera->setClearColor(osg::Vec4(0, 1, 0, 0));
                        _camera->setClearDepth(1.0f);
#ifndef USE_PACKED_DEPTH_STENCIL
                        _camera->setClearMask(GL_DEPTH_BUFFER_BIT | 
GL_COLOR_BUFFER_BIT);
#else
                        _camera->setClearMask(GL_DEPTH_BUFFER_BIT | 
GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
#endif
                        _camera->setPreDrawCallback(new PreDrawFBOCallback(fbo, 
0, w, h, _depthtexture, _colortexture));
                        _camera->setFinalDrawCallback(new 
PostDrawFBOCallback(fbo, 0, w, h, 0, 0)); 
 

                        cam->getView()->addSlave(_camera, false);
                        /*for (int i = 0; i < getNumChildren(); i++)
                        _camera->addChild(getChild(i));
                        */
                 
                        _camera->dirtyBound();
                        this->dirtyBound(); std::cerr << "ATTACHING DEPTH 
TARGET TO CAMERA" << _camera->getNumChildren() << endl;
                 
                }

         

                nv.apply(*_camera.get()); 

         

        }
        else nv.apply(*_camera.get());  

}



I took osgdepthpeeling as an example but i may missed something because it s no 
working....I only getback the FBO clearColor to  FrameBuffer as if _camera 
haven't any children drawn ...
Note that I overload Group and delegate traversal to _camera...It's the only 
way i found to retrieve the main view...
It's the first time I use a slave camera ...is there something i missed
All help is welcome

Thank you!

Cheers,
Julien [/code]

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=61914#61914





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to