[osg-users] Render multiple PRE_RENDER cameras to FBO

ivar out ivarout at gmail.com
Tue Nov 13 07:42:03 PST 2018


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







More information about the osg-users mailing list