OK, this is what I've done. I've Subclassed osg::Camera::DrawCallback and read 
from the texture in the operator() using osg::Image::readPixels, with an 
applied FBO with the texture i want to read from attached. The retrieved value 
seems to be correct. The callback object is set as "final draw callback" in a 
camera I create and add to the root of my scene graph.

Even though I am able to get the data I need this way, it seems to me that this 
is not a good solution. The only reason why I create a "dummy" camera which 
doesn't render anything is to get a valid osg::State object to apply the FBO in 
operator(). There must be a better way to do this? This way I have to request a 
value and wait untill the next frame to collect it (??) because readPixels is 
called in the operator() which I can't call in the update traversal were I need 
the value. "Warning: detected OpenGL error 'invalid enumerant' at after 
RenderBin::draw(..)" is printed each frame when the camera in the scene graph.  


class ReadBufferCallback: public osg::Camera::DrawCallback
        {
        public:
                osg::Texture2D* tex;
                osg::Image* image;
                osg::FrameBufferObject* fbo;
                osg::FrameBufferAttachment *fba;
                        

                ReadBufferCallback(osg::Texture2D *_tex){
                        tex = _tex;
                        image = new osg::Image;
                        fbo = new osg::FrameBufferObject();
                        fba = new osg::FrameBufferAttachment(tex);
                        fbo->setAttachment(osg::Camera::COLOR_BUFFER, *fba);
                
                }

                virtual void operator() (osg::RenderInfo& renderInfo) const
                {
                        fbo->apply(*(renderInfo.getState()), 
osg::FrameBufferObject::READ_FRAMEBUFFER);
                        image->readPixels(500, 500, 1, 1, GL_LUMINANCE, 
GL_FLOAT);
                        float* height = (float*)image->data();
                        cout << "height: " << *height << endl;
                }
        };


//Added to root of scene graph
osg::Camera* HeightTile::getHeightSampleCamera()
{
        osg::Camera* cam = new osg::Camera;
        cam->setRenderOrder(osg::Camera::PRE_RENDER);
        cam->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
        cam->setFinalDrawCallback(new ReadBufferCallback(m_elevation_tex));
        return cam;
}

Any help is much appreciated!

Cheers,
Martin

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





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

Reply via email to