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

Reply via email to