Discussion:
[osg-users] Render multiple PRE_RENDER cameras to FBO
ivar out
2018-11-13 15:42:03 UTC
Permalink
Hi,

I'm having trouble properly rendering a couple of cameras to an FBO. I have two PRE_RENDER cameras that use a FBO and render to a texture. The color buffer seems to be reset before rendering the second camera though. This is my code:

Code:

osg::Group* root = new osg::Group;

osg::Camera* backgroundCamera = new osg::Camera;
osg::Camera* sceneCamera = new osg::Camera;
osg::Camera* finalCamera = new osg::Camera;

root->addChild(backgroundCamera);
root->addChild(sceneCamera);
root->addChild(finalCamera);

//-----------------------------------------
// create texture to render to
//-----------------------------------------
osg::ref_ptr<osg::Texture2D> tex = new osg:
tex->setSourceType(GL_FLOAT);
tex->setSourceFormat(GL_RGBA);
tex->setInternalFormat(GL_RGBA);
tex->setTextureSize(512, 512);

//-------------------------------------------------------------------
// add geometry to background camera
//-------------------------------------------------------------------
osg::Geometry* background = osg::createTexturedQuadGeometry(osg::Vec3(), osg::Vec3(0, 1.0f, 0), osg::Vec3(1.0f, 0, 0));
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0));
colors->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0));
colors->push_back(osg::Vec4(0, 0, 0, 1.0f));
colors->push_back(osg::Vec4(0, 0, 0, 1.0));
background->setColorArray(colors.get());
background->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
osg::Geode* geode = new osg::Geode;
geode->addChild(background);
backgroundCamera->addChild(geode);

backgroundCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
backgroundCamera->setViewport(0, 0, tex->getTextureWidth(), tex->getTextureHeight());
backgroundCamera->attach(osg::Camera::COLOR_BUFFER, tex.get(), 0, 0, true, 512, 512);
backgroundCamera->setRenderOrder(osg::Camera::PRE_RENDER, 0);
backgroundCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
backgroundCamera->setProjectionMatrixAsOrtho2D(0.0f, 1.0f, 0.0f, 1.0f);
backgroundCamera->getOrCreateStateSet()->setMode(GL_LIGHTING, FALSE);
backgroundCamera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
backgroundCamera->setClearColor(osg::Vec4(0, 0, 0, 1));

//-------------------------------------------------------------------
// CREATE Camera to display scene
//-------------------------------------------------------------------
sceneCamera->setRenderOrder(osg::Camera::PRE_RENDER, 1);
osg::Node* node = osgDB::readNodeFile("C:\\Software\\OpenSceneGraph-3.6.0\\Models\\cessna.osg");
sceneCamera->addChild(node);
sceneCamera->setViewMatrixAsLookAt(osg::Vec3(100, 0, 0), osg::Vec3(), osg::Vec3(0, 0, 1));
sceneCamera->setClearMask(GL_DEPTH_BUFFER_BIT); //don't clear color buffer please
sceneCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
sceneCamera->attach(osg::Camera::COLOR_BUFFER, tex.get(), 0, 0, true, 512, 512);
sceneCamera->setViewport(0, 0, tex->getTextureWidth(), tex->getTextureHeight());

//-------------------------------------------------------------------
// CREATE Camera to display texture
//-------------------------------------------------------------------
finalCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
finalCamera->setProjectionMatrix(osg::Matrix::ortho2D(0, 1.0f, 0, 1.0f));
osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(), osg::Vec3(1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 1.0f, 0.0f));
osg::ref_ptr<osg::Geode> quad = new osg::Geode;
quad->addDrawable(geom);
finalCamera->addChild(quad.get());

// add shaders that draw the texture on the quad
osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader(osgDB::readShaderFile("shader.frag"));
program->addShader(osgDB::readShaderFile("shader.vert"));
osg::StateSet* stateset = finalCamera->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0, tex.get());
stateset->setAttributeAndModes(program.get());
stateset->addUniform(new osg::Uniform("myTexture", 0));

osgViewer::Viewer viewer;
viewer.setSceneData(root);
return viewer.run();




Either the background or scene camera can correctly be rendered to the FBO (by commenting the other out) but not both at the same time. Does anyone understand why this doesn't work? When I render to FRAME_BUFFER it works perfectly fine, but I figured since I don't want the texture rendered on screen an FBO would be a more efficient option perhaps?

Thanks!

Cheers,
ivar

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75191#75191
Voerman, L.
2018-11-14 09:36:16 UTC
Permalink
Hi Ivar,
Your call to Camera::attach is wrong, requesting anything other than 0 for
multisampleSamples will cause the setup to fail.

backgroundCamera->attach(osg::Camera::COLOR_BUFFER, tex.get(), 0, 0, false,
0, 0);
sceneCamera->attach(osg::Camera::COLOR_BUFFER, tex.get(), 0, 0, false, 0,
0);

Laurens.
Post by ivar out
Hi,
I'm having trouble properly rendering a couple of cameras to an FBO. I
have two PRE_RENDER cameras that use a FBO and render to a texture. The
color buffer seems to be reset before rendering the second camera though.
osg::Group* root = new osg::Group;
osg::Camera* backgroundCamera = new osg::Camera;
osg::Camera* sceneCamera = new osg::Camera;
osg::Camera* finalCamera = new osg::Camera;
root->addChild(backgroundCamera);
root->addChild(sceneCamera);
root->addChild(finalCamera);
//-----------------------------------------
// create texture to render to
//-----------------------------------------
tex->setSourceType(GL_FLOAT);
tex->setSourceFormat(GL_RGBA);
tex->setInternalFormat(GL_RGBA);
tex->setTextureSize(512, 512);
//-------------------------------------------------------------------
// add geometry to background camera
//-------------------------------------------------------------------
osg::Geometry* background = osg::createTexturedQuadGeometry(osg::Vec3(),
osg::Vec3(0, 1.0f, 0), osg::Vec3(1.0f, 0, 0));
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0));
colors->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0));
colors->push_back(osg::Vec4(0, 0, 0, 1.0f));
colors->push_back(osg::Vec4(0, 0, 0, 1.0));
background->setColorArray(colors.get());
background->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
osg::Geode* geode = new osg::Geode;
geode->addChild(background);
backgroundCamera->addChild(geode);
backgroundCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
backgroundCamera->setViewport(0, 0, tex->getTextureWidth(),
tex->getTextureHeight());
backgroundCamera->attach(osg::Camera::COLOR_BUFFER, tex.get(), 0, 0, true, 512, 512);
backgroundCamera->setRenderOrder(osg::Camera::PRE_RENDER, 0);
backgroundCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
backgroundCamera->setProjectionMatrixAsOrtho2D(0.0f, 1.0f, 0.0f, 1.0f);
backgroundCamera->getOrCreateStateSet()->setMode(GL_LIGHTING, FALSE);
backgroundCamera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
backgroundCamera->setClearColor(osg::Vec4(0, 0, 0, 1));
//-------------------------------------------------------------------
// CREATE Camera to display scene
//-------------------------------------------------------------------
sceneCamera->setRenderOrder(osg::Camera::PRE_RENDER, 1);
osg::Node* node =
osgDB::readNodeFile("C:\\Software\\OpenSceneGraph-3.6.0\\Models\\cessna.osg");
sceneCamera->addChild(node);
sceneCamera->setViewMatrixAsLookAt(osg::Vec3(100, 0, 0), osg::Vec3(), osg::Vec3(0, 0, 1));
sceneCamera->setClearMask(GL_DEPTH_BUFFER_BIT); //don't clear color buffer please
sceneCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
sceneCamera->attach(osg::Camera::COLOR_BUFFER, tex.get(), 0, 0, true, 512, 512);
sceneCamera->setViewport(0, 0, tex->getTextureWidth(),
tex->getTextureHeight());
//-------------------------------------------------------------------
// CREATE Camera to display texture
//-------------------------------------------------------------------
finalCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
finalCamera->setProjectionMatrix(osg::Matrix::ortho2D(0, 1.0f, 0, 1.0f));
osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(),
osg::Vec3(1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 1.0f, 0.0f));
osg::ref_ptr<osg::Geode> quad = new osg::Geode;
quad->addDrawable(geom);
finalCamera->addChild(quad.get());
// add shaders that draw the texture on the quad
osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader(osgDB::readShaderFile("shader.frag"));
program->addShader(osgDB::readShaderFile("shader.vert"));
osg::StateSet* stateset = finalCamera->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0, tex.get());
stateset->setAttributeAndModes(program.get());
stateset->addUniform(new osg::Uniform("myTexture", 0));
osgViewer::Viewer viewer;
viewer.setSceneData(root);
return viewer.run();
Either the background or scene camera can correctly be rendered to the FBO
(by commenting the other out) but not both at the same time. Does anyone
understand why this doesn't work? When I render to FRAME_BUFFER it works
perfectly fine, but I figured since I don't want the texture rendered on
screen an FBO would be a more efficient option perhaps?
Thanks!
Cheers,
ivar
------------------
http://forum.openscenegraph.org/viewtopic.php?p=75191#75191
_______________________________________________
osg-users mailing list
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
ivar out
2018-11-14 09:59:37 UTC
Permalink
Hi Laurens,

You're right, wow that was a silly mistake. Thank you so much, it works now!

Thank you!

Cheers,
ivar

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75194#75194

Continue reading on narkive:
Search results for '[osg-users] Render multiple PRE_RENDER cameras to FBO' (Questions and Answers)
7
replies
What's your experience with Windows Vista?
started 2007-04-11 07:05:00 UTC
desktops
Loading...