Skip to main content
Up and Coming
June 23, 2013

OpenSceneGraph

I've started working on an integration with OpenSceneGraph (http://www.openscenegraph.org/) and although I don't have a Rift to test with yet what I've done looks pretty close to the Oculus World demo so I'm hoping I've done it right. If there are any OSG developers out there who could test out my code I'd really appreciate it. I found GLSL versions of the shaders in the OpenHMD project (http://openhmd.net/) which are referenced as vertexShaderSource and fragmentShaderSource. I based my work on the night vision effect example from the OpenSceneGraph Cookbook (http://www.packtpub.com/openscenegrap-3-for-advanced-3d-programming-using-api-cookbook/book) and my code uses the functions from that example to create the RTT & HUD cameras as well as the quads. The source is available at https://github.com/xarray/osgRecipes. I have pseudocode where the scene is added to the cameras (step five in the cookbook) and where the cameras are added to the root node (step 7 in the cookbook) because I'm also integrating with a derived type of renderer but you should be able to replace them with what's in the example.




// Because I don't have a Rift yet I just made a OVR::HMDInfo and OVR::Util::Render::StereoConfig and guessed at some values.
myHMDInfo.HResolution = 1280;
myHMDInfo.VResolution = 800;
myHMDInfo.HScreenSize = 0.14976;
myHMDInfo.VScreenSize = 0.0935;
myHMDInfo.VScreenCenter = myHMDInfo.VScreenSize / 2;
myHMDInfo.EyeToScreenDistance = 0.05; //????
myHMDInfo.LensSeparationDistance = 0.03; //????
myHMDInfo.InterpupillaryDistance = 0.025; //?????????

myStereoConfig.SetHMDInfo(myHMDInfo);


const int textureWidth = myHMDInfo.HResolution / 2;
const int textureHeight = myHMDInfo.VResolution;

// Setup textures for the RTT cameras
osg::ref_ptr<osg::Texture2D> leftEyeTex2D = new osg::Texture2D;
leftEyeTex2D->setTextureSize( textureWidth, textureHeight );
leftEyeTex2D->setInternalFormat( GL_RGBA );
osg::ref_ptr<osg::Texture2D> rightEyeTex2D = new osg::Texture2D;
rightEyeTex2D->setTextureSize( textureWidth, textureHeight );
rightEyeTex2D->setInternalFormat( GL_RGBA );

// Initialize RTT cameras for each eye
osg::ref_ptr<osg::Camera> leftEyeRTTCamera = osgCookBook::createRTTCamera(
osg::Camera::COLOR_BUFFER, leftEyeTex2D.get());
OVR::Util::Render::StereoEyeParams leftEyeParams =
myStereoConfig.GetEyeRenderParams(OVR::Util::Render::StereoEye_Left);
osg::Matrixf leftEyeTranslation = osg::Matrixf::translate(
leftEyeParams.ViewAdjust.M[0][3], leftEyeParams.ViewAdjust.M[2][3],
leftEyeParams.ViewAdjust.M[2][3]);
leftEyeRTTCamera->setViewMatrix(leftEyeTranslation);
leftEyeRTTCamera->setProjectionMatrixAsPerspective(
myStereoConfig.GetYFOVDegrees(), myStereoConfig.GetAspect(), 0.3, 5000);
osg::ref_ptr<osg::Camera> rightEyeRTTCamera = osgCookBook::createRTTCamera(
osg::Camera::COLOR_BUFFER, rightEyeTex2D.get());
OVR::Util::Render::StereoEyeParams rightEyeParams =
myStereoConfig.GetEyeRenderParams(OVR::Util::Render::StereoEye_Right);
osg::Matrixf rightEyeTranslation = osg::Matrixf::translate(
rightEyeParams.ViewAdjust.M[0][3], rightEyeParams.ViewAdjust.M[2][3],
rightEyeParams.ViewAdjust.M[2][3]);
rightEyeRTTCamera->setViewMatrix(rightEyeTranslation);
rightEyeRTTCamera->setProjectionMatrixAsPerspective(
myStereoConfig.GetYFOVDegrees(), myStereoConfig.GetAspect(), 0.3, 5000);

// add your scene to the camera, should be something like:
// leftEyeRTTCamera->addChild( scene.get() );
// rightEyeRTTCamera->addChild( scene.get() );

// Create HUD cameras for each eye
osg::ref_ptr<osg::Camera> leftEyeHUDCamera =
osgCookBook::createHUDCamera(0.0, 1.0, 0.0, 1.0);
osg::ref_ptr<osg::Camera> rightEyeHUDCamera =
osgCookBook::createHUDCamera(0.0, 1.0, 0.0, 1.0);

// Create quads on each camera
leftEyeHUDCamera->addChild( osgCookBook::createScreenQuad(
1.0f, 1.0f) );
leftEyeHUDCamera->setViewport(
new osg::Viewport(0, 0, myHMDInfo.HResolution / 2, myHMDInfo.VResolution));
rightEyeHUDCamera->addChild( osgCookBook::createScreenQuad(
1.0f, 1.0f) );
rightEyeHUDCamera->setViewport(
new osg::Viewport(myHMDInfo.HResolution / 2, 0, myHMDInfo.HResolution / 2, myHMDInfo.VResolution));

// Set up shaders (from the OpenHMD project)
osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader( new osg::Shader(osg::Shader::VERTEX,
vertexShaderSource) );
program->addShader( new osg::Shader(osg::Shader::FRAGMENT,
fragmentShaderSource) );

// Configure state sets for both eyes
osg::StateSet* leftEyeStateSet = leftEyeHUDCamera->getOrCreateStateSet();
leftEyeStateSet->setTextureAttributeAndModes( 0, leftEyeTex2D.get() );
leftEyeStateSet->setAttributeAndModes( program.get() );
leftEyeStateSet->addUniform( new osg::Uniform("warpTexture", 0) );

osg::StateSet* rightEyeStateSet = rightEyeHUDCamera->getOrCreateStateSet();
rightEyeStateSet->setTextureAttributeAndModes( 0, rightEyeTex2D.get() );
rightEyeStateSet->setAttributeAndModes( program.get() );
rightEyeStateSet->addUniform( new osg::Uniform("warpTexture", 0) );


// Add everything to the root, should be something like:
//osg::ref_ptr<osg::Group> root = ?;
//root->addChild( leftEyeRTTCamera.get().get() );
//root->addChild( leftEyeHUDCamera.get().get() );
//root->addChild( rightEyeRTTCamera.get().get() );
//root->addChild( rightEyeHUDCamera.get().get() );
//root->addChild( hudCamera.get() );
//root->addChild( scene.get() );

    54 replies

    Up and Coming
    August 9, 2015
    I am happy to report that I am finally flicker free.

    The problem was that the FBO's where never set to the new swap texture set. This is the reason that only even frame id's worked.

    The solution was to get the FBO id for each FBO and make sure that they where set to the correct swap texture before each new frame.

    The latest develoment have been pushed to github:
    https://github.com/bjornblissing/osgocu ... e/sdk-v0.6
    Up and Coming
    August 9, 2015
    Did you update to 0.6.0.1 and if so what's performance like for you? I'm still having pretty serious problems, even with the Oculus OpenGL examples. Hopefully 0.7 will be a happier place.
    Up and Coming
    August 10, 2015
    "JeffBail" wrote:
    Did you update to 0.6.0.1 and if so what's performance like for you? I'm still having pretty serious problems, even with the Oculus OpenGL examples. Hopefully 0.7 will be a happier place.


    I have only tested my code with 0.6.0.1. And I have not made any performance test yet, but I have not seen anything getting obviously worse (yet). But I will try to do some tests during the day.

    If you are still running with your camRenderer->setCameraRequiresSetUp(true) solution, I would recommend to take a look at my code instead. Since calling setCameraRequiresSetUp() function each frame would probably affect performance negatively, since it forces OSG to completely rebuild the FBO setup each frame.
    Up and Coming
    August 13, 2015
    I am happy to report that support for Oculus SDK 0.6.0.1 is now complete. This has now been merged into the master branch at GitHub.

    The Oculus SDK v0.5, which is the last version supporting MacOS and Linux has been branched to:
    https://github.com/bjornblissing/osgocu ... e/sdk-v0.5
    Up and Coming
    August 23, 2015
    "pixelminer" wrote:
    If you are still running with your camRenderer->setCameraRequiresSetUp(true) solution, I would recommend to take a look at my code instead. Since calling setCameraRequiresSetUp() function each frame would probably affect performance negatively, since it forces OSG to completely rebuild the FBO setup each frame.


    Thanks for that; your solution for the FBO's is indeed much faster. Although performance seems much improved over setCameraRequiresSetUp() I'm still seeing missed frames according to the Oculus performance HUD even in very simple scenes. Are you seeing those as well? I'm not sure there's much we can do; as reported in the OpenGL performance thread even the Oculus "Tiny" example drops frames. Let's hope things will be better with 0.7.
    Up and Coming
    August 28, 2015
    I am happy to report that support for Oculus SDK 0.7.0.0 is added and merged into the master branch.

    The latest Oculus SDK v0.6 development has been merged back into the 0.6 branch:
    https://github.com/bjornblissing/osgocu ... e/sdk-v0.6
    Up and Coming
    October 22, 2015
    I have made the small changes needed to support Oculus SDK 0.8.0.0.

    The latest Oculus SDK v0.7 development is can be found in the 0.7 branch:
    https://github.com/bjornblissing/osgocu ... e/sdk-v0.7
    Participant
    March 17, 2016
    Hi, I'm coming into OSG pretty cold to try to add Oculus integration, and I can't figure out how to update the clipping planes after the initial setup. Could you give any assistance?
    Up and Coming
    March 17, 2016
    "JonathanVB" wrote:
    Hi, I'm coming into OSG pretty cold to try to add Oculus integration, and I can't figure out how to update the clipping planes after the initial setup. Could you give any assistance?


    Well, I guess that you desire a dynamic projection matrix, which since the Oculus SDK already supplies all other values means defining new near/far planes...

    Right now I only do a setup of the projection matrix in the init phase of the integration:
    https://github.com/bjornblissing/osgocu ... #L691-L709

    But there is nothing stopping you from updating the projection matrix in each frame. What you need to do is to calculate the new projection matrix in the updateSlave callback function and then apply this projection matrix to the slave camera.
    Participant
    March 17, 2016
    Thanks, I got it working.