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