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