Hi all,

I have a multiple render target setup where a texture is attached to an FBO on 
GL_COLOR_ATTACHMENT2. The other target is simply the frame buffer on 
GL_COLOR_ATTACHMENT0. Both targets are the same size and format. 

A fragment shader uses glFragData[0] and glFragData[2] to write to the targets 
and I'm getting the expected onscreen data from glFragData[0]. The problem 
comes in when I try to use a PostDrawCallback to read from GL_COLOR_ATTACHMENT2 
so I can move it to an image and manipulate the data on the CPU. 

In the code below, if I have glReadBuffer(GL_COLOR_ATTACHMENT2) then I get an 
"Warning: detected OpenGL error 'invalid enumerant' at end of 
SceneView::draw()".  glReadBuffer(GL_BACK) works fine but that's not the data I 
want. 

Is this because the FBO is already detached when the callback is invoked? Is 
there another place I can 'hook in' to do this? I've tried simply attaching an 
osg::image as the secondary render target but I don't need to do this on every 
frame and it's too big of a performance hit.

Callback code:

Code:

virtual void operator()(osg::RenderInfo& renderInfo) const {
osg::GraphicsContext* gc = renderInfo.getCurrentCamera()->getGraphicsContext();
osg::GLBufferObject::Extensions* ext = osg::GLBufferObject::getExtensions(
     gc->getState()->getContextID(),true);
int width = gc->getTraits()->width;
int height = gc->getTraits()->height;

if( m_starMapImage->s() != width || m_starMapImage->t() != height ) {
     m_starMapImage->allocateImage(width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE);
     if( m_pbo ) {
          ext->glDeleteBuffers (1, &m_pbo);
          m_pbo = 0;
     }
}

if( !m_pbo ) {
     ext->glGenBuffers(1, &m_pbo);
     ext->glBindBuffer(GL_PIXEL_PACK_BUFFER, m_pbo);
     ext->glBufferData(GL_PIXEL_PACK_BUFFER, m_starMapImage-   
>getTotalSizeInBytes(), 0, GL_STREAM_READ);
}
else
     ext->glBindBuffer( GL_PIXEL_PACK_BUFFER, m_pbo );

glReadBuffer(GL_COLOR_ATTACHMENT2);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);

GLubyte* src = (GLubyte*)ext->glMapBuffer( GL_PIXEL_PACK_BUFFER, GL_READ_ONLY );

if(src) {
     memcpy( m_starMapImage->data(), src, m_starMapImage->getTotalSizeInBytes() 
);   
     ext->glUnmapBuffer( GL_PIXEL_PACK_BUFFER );
}

osgDB::writeImageFile(*m_starMapImage, std::string("test.png"));
ext->glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 );
}




Camera Setup:

Code:

osg::TextureRectangle* starMap = new osg::TextureRectangle;
starMap->setTextureSize( width, height );
starMap->setInternalFormat( GL_RGBA );
starMap->setSourceFormat( GL_RGBA );
osg::ref_ptr<osg::Camera> stars3d = new osg::Camera;
stars3d->setClearMask( GL_DEPTH_BUFFER_BIT );
stars3d->setGraphicsContext(gc);
stars3d->setAllowEventFocus( false );
stars3d->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
stars3d->attach(osg::Camera::COLOR_BUFFER0, &renderTarget);
stars3d->attach(osg::Camera::COLOR_BUFFER2, starMap);




Cheers,
Trystan

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





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

Reply via email to