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

Sebastian Messerschmidt sebastian.messerschmidt at gmx.de
Wed Mar 15 05:13:09 PDT 2017



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

>
> Thanks again
>
> - Werner -
>
> Am 15.03.2017 um 11:28 schrieb Sebastian Messerschmidt:
>>
>> 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-users at lists.openscenegraph.org
>>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>>
>>>
>> _______________________________________________
>> osg-users mailing list
>> osg-users at lists.openscenegraph.org
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
> --
> *TEXION Software Solutions, Rotter Bruch 26a, D-52068 Aachen*
> Phone: +49 241 475757-0
> Fax: +49 241 475757-29
> Web: http://texion.eu
> eMail: info at texion.eu
>
>
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>



More information about the osg-users mailing list