Hi Trystan You can attach texture instead(it'll work much faster), and when you need data - get it from texture with image->readImageFromCurrentTexture(..). You will need to bind your texture before call.
Cheers, Sergey. 21.05.2012, 23:14, "Trystan Larey-Williams" <[email protected]>: > 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 _______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

