[osg-users] How do cameras handle the render target?

399 views
Skip to first unread message

Werner Modenbach

unread,
Mar 15, 2017, 5:56:53 AM3/15/17
to osg-...@lists.openscenegraph.org
Hi all.

I have a problem understanding how cameras handle render targets.
My special case:
I have a standard camera on a view.
The root node of the scene is a group with the following children:

- my model
- hud camera for wallpaper
- hud camera for text
- more cameras for special cases

All the cameras are children of the group node and do POST_RENDER operation.

I need snapshots of the complete scene from various camera positions.
What I do:

osg::ref_ptr<osg::Camera> camera = view->getCamera();
osg::ref_ptr<osg::Image> fbImage = new osg::Image;
fbImage->allocateImage(width,height,1,GL_RGBA,GL_UNSIGNED_BYTE, 1);

osg::Camera::RenderTargetImplementation rti = camera->getRenderTargetImplementation();
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
camera->attach( osg::Camera::COLOR_BUFFER, fbImage.get(), 0, 0);
camera->dirtyAttachmentMap();

Then I do snapshots with the modified projection matrix of the camera.
After each snapshot I read the contents of the fbImage.

I reset everything to the initial status by:

camera->setRenderTargetImplementation(rti);
camera->detach( osg::Camera::COLOR_BUFFER);
camera->dirtyAttachmentMap();

    
Unfortunately the fbImage always only contains my model but not the child cameras renderings.
Attaching the fbImage to the child cameras as well gives me just a black fbImage.
Of course the child cameras do not clear the color buffer.

What is the proper way of receiving the complete rendering? I also tried already
installing a slave camera to the main camera but that also gives me only the rendered model.
And rendering to the fbImage by installing an additional child camera with POST_RENDER instead
of a slave camera leads to the same result.

Rendering to screen is perfect, but to fbImage is not.
It seems I'm blind on some basic functionality and all my research doesn't open my eyes.

I instantly hope for some help.

Thanks

- Werner -

Sebastian Messerschmidt

unread,
Mar 15, 2017, 6:29:07 AM3/15/17
to OpenSceneGraph Users

Hi Werner,


from diagonal reading:

You could make all cameras composing to the same FBO and get the texture
in a final pass that can either put the image to Framebuffer or read
back the texture. Also take a look at the screenshot example (using
pbuffer) and the various draw callbacks.

Cheers
Sebastian


> Hi all.
>
> I have a problem understanding how cameras handle render targets.
> My special case:
> I have a standard camera on a view.
> The root node of the scene is a group with the following children:
>
> - my model
> - hud camera for wallpaper
> - hud camera for text
> - more cameras for special cases
>
> All the cameras are children of the group node and do POST_RENDER operation.
>
> I need snapshots of the complete scene from various camera positions.
> What I do:
>
> osg::ref_ptr<osg::Camera>camera=view->getCamera();
>
> osg::ref_ptr<osg::Image>fbImage=newosg::Image;
>
> fbImage->allocateImage(width,height,1,GL_RGBA,GL_UNSIGNED_BYTE,1);
>
> osg::Camera::RenderTargetImplementationrti=camera->getRenderTargetImplementation();
> camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
> camera->attach(osg::Camera::COLOR_BUFFER,fbImage.get(),0,0);
> camera->dirtyAttachmentMap();
>
> Then I do snapshots with the modified projection matrix of the camera.
> After each snapshot I read the contents of the fbImage.
>
> I reset everything to the initial status by:
>
> camera->setRenderTargetImplementation(rti);
>
> camera->detach(osg::Camera::COLOR_BUFFER);
>
> camera->dirtyAttachmentMap();
>
>
> Unfortunately the fbImage always only contains my model but not the
> child cameras renderings.
> Attaching the fbImage to the child cameras as well gives me just a black
> fbImage.
> Of course the child cameras do not clear the color buffer.
>
> What is the proper way of receiving the complete rendering? I also tried
> already
> installing a slave camera to the main camera but that also gives me only
> the rendered model.
> And rendering to the fbImage by installing an additional child camera
> with POST_RENDER instead
> of a slave camera leads to the same result.
>
> Rendering to screen is perfect, but to fbImage is not.
> It seems I'm blind on some basic functionality and all my research
> doesn't open my eyes.
>
> I instantly hope for some help.
>
> Thanks
>
> - Werner -
>
>
> _______________________________________________
> osg-users mailing list
> osg-...@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Werner Modenbach

unread,
Mar 15, 2017, 7:56:58 AM3/15/17
to OpenSceneGraph Users
Hi Sebastion,

thanks for the quick reply.
What do you mean by composing to the same FBO? As i wrote attaching the
FBO to the child cameras the same way as with the main camera just delivers a black fbImage.

Concerning the screen capture example:
I remember an easier version where a slave camera was created with a pbuffer context and then
an image attached like thgat:

osg::ref_ptr<osg::PixelBufferObject> pbo= new osg::PixelBufferObject(image.get());
image->setPixelBufferObject(pbo.get());
image->allocateImage(width,height,1,GL_RGBA,GL_UNSIGNED_BYTE, 1);
camera->attach( osg::Camera::COLOR_BUFFER, image.get());
pbuffer->realize();

    This seams more convenient than fiddling with gl functions.
I still have that version but it also shows only the rendered model.
Is it possible that the rendering is just not completed after the viewer->frame() call?
Is it necessary having a finalDrawCallback instead?

Thanks again

- Werner -
--
TEXION Software Solutions, Rotter Bruch 26a, D-52068 Aachen
Phone: +49 241 475757-0
Fax: +49 241 475757-29
Web: http://texion.eu
eMail: in...@texion.eu

Sebastian Messerschmidt

unread,
Mar 15, 2017, 8:13:26 AM3/15/17
to OpenSceneGraph Users


Am 3/15/2017 um 12:56 PM schrieb Werner Modenbach:
> Hi Sebastion,
>
> thanks for the quick reply.
> What do you mean by composing to the same FBO? As i wrote attaching the
> FBO to the child cameras the same way as with the main camera just
> delivers a black fbImage.

Render everything(also the HUD cameras) with the FBO as target attaching
your target-texture and see below.
>
> Concerning the screen capture example:
> I remember an easier version where a slave camera was created with a
> pbuffer context and then
> an image attached like thgat:
>
> osg::ref_ptr<osg::PixelBufferObject>pbo=newosg::PixelBufferObject(image.get());
>
>
> image->setPixelBufferObject(pbo.get());
>
> image->allocateImage(width,height,1,GL_RGBA,GL_UNSIGNED_BYTE,1);
>
> camera->attach(osg::Camera::COLOR_BUFFER,image.get());
>
> pbuffer->realize();
>
> This seams more convenient than fiddling with gl functions.
> I still have that version but it also shows only the rendered model.
The slave most likely is rendered after the main camera but _before_ the
POST_RENDER. I once struggled with something similar and solved the
issue by explicitely setting the camera draw order (setRenderOrder) and
to PRE_ORDER to let the final camera be the one pushing everything to
the framebuffer. I guess adding the pbuffer-slave to the output will do
the trick.

Basically like this (ignore the MRT-stuff if you have a simple color
target):

osg::Camera* Helpers::createRenderTargetCamera( int view_port_width, int
view_port_height,
int pass,
osg::Texture2D* rttDepthTexture,
osg::Texture2D* rttColorTexture01 /*= 0*/,
osg::Texture2D* rttColorTexture02 /*= 0*/,
osg::Texture2D* rttColorTexture03 /*= 0*/
)
{

osg::Camera* camera = new osg::Camera();
camera->setCullingActive(false);
// Set the camera to render before the main camera.
camera->setRenderOrder(osg::Camera::PRE_RENDER, pass);

// Tell the camera to use OpenGL frame buffer object where supported.
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
// Attack RTT textures to Camera
if (rttDepthTexture)
{
camera->attach(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER,
rttDepthTexture );
}
if (rttColorTexture01)
{
if (rttColorTexture01->getUseHardwareMipMapGeneration())
{
camera->attach(osg::Camera::COLOR_BUFFER0, rttColorTexture01, 0,0,true);
}
else
{
camera->attach(osg::Camera::COLOR_BUFFER0,rttColorTexture01);
}

}
if (rttColorTexture02)
{
camera->attach(osg::Camera::COLOR_BUFFER1,rttColorTexture02);
}
if (rttColorTexture03)
{
camera->attach(osg::Camera::COLOR_BUFFER2,rttColorTexture03);
}
// Set up the background color and clear mask.
camera->setClearMask(0);

// Set viewport
camera->setViewport(0,0,view_port_width,view_port_height);
// Set view
camera->setReferenceFrame(osg::Transform::RELATIVE_RF);
// Camera hints
camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
return camera;
}

and for the output:

osg::Camera* Helpers::createOutCamera(int view_port_width, int
view_port_height)
{
osg::Camera* camera = new osg::Camera();
// Set clear color and mask
camera->setClearColor(osg::Vec4(0.4f,0.4f,0.4f,1.0f));
camera->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// Set viewport
camera->setViewport(0,0,view_port_width,view_port_height);
// Set projection
camera->setProjectionMatrixAsOrtho2D(0,view_port_width,0,view_port_height);
// Set view
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setViewMatrix(osg::Matrix::identity());
// Camera hints
camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
camera->setRenderOrder(osg::Camera::POST_RENDER, 100);

return camera;
}


> Is it possible that the rendering is just not completed after the
> viewer->frame() call?
If there is no glFlush somewhere I guess it simply means that all
commands are issued.
> Is it necessary having a finalDrawCallback instead?
I guess so. At least that worked for me, when I had to retrieve one of
the textures written to in my chain.

Cheers
Sebastian
> *TEXION Software Solutions, Rotter Bruch 26a, D-52068 Aachen*
> Phone: +49 241 475757-0
> Fax: +49 241 475757-29
> Web: http://texion.eu
> eMail: in...@texion.eu
>
>
Reply all
Reply to author
Forward
0 new messages