Skip to content

Commit

Permalink
Updated the deprecated example (for OSG 3.0) with latest changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Björn Blissing committed Jun 25, 2014
1 parent 1bb855a commit 43dbeee
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 84 deletions.
157 changes: 90 additions & 67 deletions src/hmdcamera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@

HMDCamera::HMDCamera(osgViewer::View* view, osg::ref_ptr<OculusDevice> dev) : osg::Group(),
m_configured(false),
m_chromaticAberrationCorrection(false),
m_useChromaticAberrationCorrection(false),
m_view(view),
m_dev(dev)
m_device(dev)
{
}

Expand All @@ -40,54 +40,58 @@ void HMDCamera::traverse(osg::NodeVisitor& nv)
}

// Get orientation from oculus sensor
osg::Quat orient = m_dev->getOrientation();
osg::Quat orient = m_device->getOrientation();
// Nasty hack to update the view offset for each of the slave cameras
// There doesn't seem to be an accessor for this, fortunately the offsets are public
m_view->findSlaveForCamera(m_l_rtt.get())->_viewOffset.setRotate(orient);
m_view->findSlaveForCamera(m_r_rtt.get())->_viewOffset.setRotate(orient);
m_view->findSlaveForCamera(m_cameraRTTLeft.get())->_viewOffset.setRotate(orient);
m_view->findSlaveForCamera(m_cameraRTTRight.get())->_viewOffset.setRotate(orient);
osg::Group::traverse(nv);
}

osg::Camera* HMDCamera::createRTTCamera(osg::Camera::BufferComponent buffer, osg::Texture* tex)
osg::Camera* HMDCamera::createRTTCamera(osg::Texture* texture, osg::GraphicsContext* gc) const
{
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f));
camera->setClearMask( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT );
camera->setDrawBuffer(GL_FRONT);
camera->setReadBuffer(GL_FRONT);
camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
camera->setRenderOrder( osg::Camera::PRE_RENDER );
camera->setGraphicsContext(m_view->getCamera()->getGraphicsContext());
camera->setRenderOrder(osg::Camera::PRE_RENDER);
camera->setAllowEventFocus(false);
camera->setGraphicsContext(gc);
camera->setReferenceFrame(osg::Camera::RELATIVE_RF);

if ( tex ) {
tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR );
tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR );
camera->setViewport( 0, 0, tex->getTextureWidth(), tex->getTextureHeight() );
camera->attach( buffer, tex, 0, 0, false, 4, 4);
if ( texture ) {
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
camera->setViewport(0, 0, texture->getTextureWidth(), texture->getTextureHeight());
camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, 0, false, 4, 4);
}

return camera.release();
}

osg::Camera* HMDCamera::createHUDCamera(double left, double right, double bottom, double top)
osg::Camera* HMDCamera::createHUDCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const
{
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setGraphicsContext(m_view->getCamera()->getGraphicsContext());
camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f));
camera->setClearMask( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
camera->setRenderOrder( osg::Camera::POST_RENDER );
camera->setAllowEventFocus( false );
camera->setProjectionMatrix( osg::Matrix::ortho2D(left, right, bottom, top) );
camera->setRenderOrder(osg::Camera::POST_RENDER);
camera->setAllowEventFocus(false);
camera->setGraphicsContext(gc);
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setProjectionMatrix(osg::Matrix::ortho2D(left, right, bottom, top));
camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
return camera.release();
}

osg::Geode* HMDCamera::createHUDQuad( float width, float height, float scale )
osg::Geode* HMDCamera::createHUDQuad( float width, float height, float scale ) const
{
osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(),
osg::Vec3(width, 0.0f, 0.0f),
osg::Vec3(0.0f, height, 0.0f),
0.0f, 0.0f, width*scale, height*scale );
osg::Vec3(width, 0.0f, 0.0f),
osg::Vec3(0.0f, height, 0.0f),
0.0f, 0.0f, width*scale, height*scale );
osg::ref_ptr<osg::Geode> quad = new osg::Geode;
quad->addDrawable( geom );
int values = osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED;
Expand All @@ -96,74 +100,93 @@ osg::Geode* HMDCamera::createHUDQuad( float width, float height, float scale )
return quad.release();
}

void HMDCamera::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program,
osg::Texture2D* texture, OculusDevice::EyeSide eye) const {
stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
stateSet->setAttributeAndModes( program, osg::StateAttribute::ON );
stateSet->addUniform( new osg::Uniform("WarpTexture", 0) );
stateSet->addUniform( new osg::Uniform("LensCenter", m_device->lensCenter(eye)));
stateSet->addUniform( new osg::Uniform("ScreenCenter", m_device->screenCenter()));
stateSet->addUniform( new osg::Uniform("Scale", m_device->scale()));
stateSet->addUniform( new osg::Uniform("ScaleIn", m_device->scaleIn()));
stateSet->addUniform( new osg::Uniform("HmdWarpParam", m_device->warpParameters()));
stateSet->addUniform( new osg::Uniform("ChromAbParam", m_device->chromAbParameters()));
}

void HMDCamera::configure()
{
const int textureWidth = m_dev->scaleFactor() * m_dev->hScreenResolution()/2;
const int textureHeight = m_dev->scaleFactor() * m_dev->vScreenResolution();
const int textureWidth = m_device->scaleFactor() * m_device->hScreenResolution()/2;
const int textureHeight = m_device->scaleFactor() * m_device->vScreenResolution();

// master projection matrix
m_view->getCamera()->setProjectionMatrix(m_dev->projectionCenterMatrix());
osg::ref_ptr<osg::Texture2D> l_tex = new osg::Texture2D;
l_tex->setTextureSize( textureWidth, textureHeight );
l_tex->setInternalFormat( GL_RGBA );
osg::ref_ptr<osg::Texture2D> r_tex = new osg::Texture2D;
r_tex->setTextureSize( textureWidth, textureHeight );
r_tex->setInternalFormat( GL_RGBA );
osg::ref_ptr<osg::Camera> l_rtt = createRTTCamera(osg::Camera::COLOR_BUFFER, l_tex);
m_l_rtt = l_rtt;
osg::ref_ptr<osg::Camera> r_rtt = createRTTCamera(osg::Camera::COLOR_BUFFER, r_tex);
m_r_rtt = r_rtt;
m_view->getCamera()->setProjectionMatrix(m_device->projectionCenterMatrix());
m_view->setName("Oculus");
osg::ref_ptr<osg::Camera> mainCamera = m_view->getCamera();
mainCamera->setName("Main");
// Disable scene rendering for main camera
mainCamera->setCullMask(~m_sceneNodeMask);

osg::ref_ptr<osg::Texture2D> textureLeft = new osg::Texture2D;
textureLeft->setTextureSize( textureWidth, textureHeight );
textureLeft->setInternalFormat( GL_RGBA );
osg::ref_ptr<osg::Texture2D> textureRight = new osg::Texture2D;
textureRight->setTextureSize( textureWidth, textureHeight );
textureRight->setInternalFormat( GL_RGBA );

osg::ref_ptr<osg::GraphicsContext> gc = mainCamera->getGraphicsContext();
// Create render to texture cameras
m_cameraRTTLeft = createRTTCamera(textureLeft, gc.get());
m_cameraRTTRight = createRTTCamera(textureRight, gc.get());
m_cameraRTTLeft->setName("LeftRTT");
m_cameraRTTRight->setName("RightRTT");
m_cameraRTTLeft->setCullMask(m_sceneNodeMask);
m_cameraRTTRight->setCullMask(m_sceneNodeMask);


// Create HUD cameras for each eye
osg::ref_ptr<osg::Camera> l_hud = createHUDCamera(0.0, 1.0, 0.0, 1.0);
l_hud->setViewport(new osg::Viewport(0, 0, m_dev->hScreenResolution() / 2.0f, m_dev->vScreenResolution()));
osg::ref_ptr<osg::Camera> r_hud = createHUDCamera(0.0, 1.0, 0.0, 1.0);
r_hud->setViewport(new osg::Viewport(m_dev->hScreenResolution() / 2.0f, 0,
m_dev->hScreenResolution() / 2.0f, m_dev->vScreenResolution()));
osg::ref_ptr<osg::Camera> cameraHUDLeft = createHUDCamera(0.0, 1.0, 0.0, 1.0, gc.get());
cameraHUDLeft->setName("LeftHUD");
cameraHUDLeft->setViewport(new osg::Viewport(0, 0, m_device->hScreenResolution() / 2.0f, m_device->vScreenResolution()));
osg::ref_ptr<osg::Camera> cameraHUDRight = createHUDCamera(0.0, 1.0, 0.0, 1.0, gc.get());
cameraHUDRight->setName("RightHUD");
cameraHUDRight->setViewport(new osg::Viewport(m_device->hScreenResolution() / 2.0f, 0,
m_device->hScreenResolution() / 2.0f, m_device->vScreenResolution()));
// Create quads on each camera
osg::ref_ptr<osg::Geode> leftQuad = createHUDQuad(1.0f, 1.0f);
l_hud->addChild(leftQuad);
cameraHUDLeft->addChild(leftQuad);
osg::ref_ptr<osg::Geode> rightQuad = createHUDQuad(1.0f, 1.0f);
r_hud->addChild(rightQuad);
cameraHUDRight->addChild(rightQuad);

// Set up shaders from the Oculus SDK documentation
osg::ref_ptr<osg::Program> program = new osg::Program;
osg::ref_ptr<osg::Shader> vertexShader = new osg::Shader(osg::Shader::VERTEX);
vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp.vert"));
osg::ref_ptr<osg::Shader> fragmentShader = new osg::Shader(osg::Shader::FRAGMENT);

// Fragment shader with or without correction for chromatic aberration
if (m_chromaticAberrationCorrection) {
if (m_useChromaticAberrationCorrection) {
fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warpWithChromeAb.frag"));
} else {
fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warpWithoutChromeAb.frag"));
}

program->addShader(vertexShader);
program->addShader(fragmentShader);
// Configure state sets for both eyes

// Attach shaders to each HUD
osg::StateSet* leftEyeStateSet = leftQuad->getOrCreateStateSet();
leftEyeStateSet->setTextureAttributeAndModes(0, l_tex, osg::StateAttribute::ON);
leftEyeStateSet->setAttributeAndModes( program, osg::StateAttribute::ON );
leftEyeStateSet->addUniform( new osg::Uniform("WarpTexture", 0) );
leftEyeStateSet->addUniform( new osg::Uniform("LensCenter", m_dev->lensCenter(OculusDevice::LEFT_EYE)));
leftEyeStateSet->addUniform( new osg::Uniform("ScreenCenter", m_dev->screenCenter()));
leftEyeStateSet->addUniform( new osg::Uniform("Scale", m_dev->scale()));
leftEyeStateSet->addUniform( new osg::Uniform("ScaleIn", m_dev->scaleIn()));
leftEyeStateSet->addUniform( new osg::Uniform("HmdWarpParam", m_dev->warpParameters()));
leftEyeStateSet->addUniform( new osg::Uniform("ChromAbParam", m_dev->chromAbParameters()));
osg::StateSet* rightEyeStateSet = rightQuad->getOrCreateStateSet();
rightEyeStateSet->setTextureAttributeAndModes(0, r_tex, osg::StateAttribute::ON);
rightEyeStateSet->setAttributeAndModes( program, osg::StateAttribute::ON );
rightEyeStateSet->addUniform( new osg::Uniform("WarpTexture", 0) );
rightEyeStateSet->addUniform( new osg::Uniform("LensCenter", m_dev->lensCenter(OculusDevice::RIGHT_EYE)));
rightEyeStateSet->addUniform( new osg::Uniform("ScreenCenter", m_dev->screenCenter()));
rightEyeStateSet->addUniform( new osg::Uniform("Scale", m_dev->scale()));
rightEyeStateSet->addUniform( new osg::Uniform("ScaleIn", m_dev->scaleIn()));
rightEyeStateSet->addUniform( new osg::Uniform("HmdWarpParam", m_dev->warpParameters()));
rightEyeStateSet->addUniform( new osg::Uniform("ChromAbParam", m_dev->chromAbParameters()));
applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::LEFT_EYE);
applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::RIGHT_EYE);

// Add cameras as slaves, specifying offsets for the projection
// View takes ownership of our cameras, that's why we keep only weak pointers to them
m_view->addSlave(l_rtt, m_dev->projectionOffsetMatrix(OculusDevice::LEFT_EYE), m_dev->viewMatrix(OculusDevice::LEFT_EYE), true);
m_view->addSlave(r_rtt, m_dev->projectionOffsetMatrix(OculusDevice::RIGHT_EYE), m_dev->viewMatrix(OculusDevice::RIGHT_EYE), true);
m_view->addSlave(l_hud, false);
m_view->addSlave(r_hud, false);
m_view->addSlave(m_cameraRTTLeft.get(), m_device->projectionOffsetMatrix(OculusDevice::LEFT_EYE),
m_device->viewMatrix(OculusDevice::LEFT_EYE),
true);
m_view->addSlave(m_cameraRTTRight.get(), m_device->projectionOffsetMatrix(OculusDevice::RIGHT_EYE),
m_device->viewMatrix(OculusDevice::RIGHT_EYE),
true);
m_view->addSlave(cameraHUDLeft, false);
m_view->addSlave(cameraHUDRight, false);
m_configured = true;
}
23 changes: 13 additions & 10 deletions src/hmdcamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

#include <osg/Group>

// Forward declarations
class OculusDevice;
#include "oculusdevice.h"

namespace osgViewer {
class View;
class NodeVisitor;
Expand All @@ -21,20 +21,23 @@ class HMDCamera: public osg::Group {
public:
HMDCamera(osgViewer::View* view, osg::ref_ptr<OculusDevice> dev);
virtual void traverse(osg::NodeVisitor& nv);
void setChromaticAberrationCorrection(bool correctionEnabled) { m_chromaticAberrationCorrection = correctionEnabled; }
void setChromaticAberrationCorrection(bool correctionEnabled) { m_useChromaticAberrationCorrection = correctionEnabled; }
void setSceneNodeMask(osg::Node::NodeMask nodeMask) { m_sceneNodeMask = nodeMask; }
protected:
~HMDCamera();
virtual void configure();

osg::Camera* createRTTCamera(osg::Camera::BufferComponent buffer, osg::Texture* tex);
osg::Camera* createHUDCamera(double left, double right, double bottom, double top);
osg::Geode* createHUDQuad( float width, float height, float scale = 1.0f );

osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc) const;
osg::Camera* createHUDCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const;
osg::Geode* createHUDQuad(float width, float height, float scale = 1.0f) const;
void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program,
osg::Texture2D* texture, OculusDevice::EyeSide eye) const;
bool m_configured;
bool m_chromaticAberrationCorrection;
bool m_useChromaticAberrationCorrection;
osg::observer_ptr<osgViewer::View> m_view;
osg::observer_ptr<osg::Camera> m_l_rtt, m_r_rtt;
osg::observer_ptr<OculusDevice> m_dev;
osg::observer_ptr<osg::Camera> m_cameraRTTLeft, m_cameraRTTRight;
osg::observer_ptr<OculusDevice> m_device;
osg::Node::NodeMask m_sceneNodeMask;
};

#endif /* _OSG_HMDCAMERA_H_ */
41 changes: 34 additions & 7 deletions src/osgoculusviewer_deprecated.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <osgDB/ReadFile>
#include <osgGA/TrackballManipulator>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include "oculusdevice.h"
#include "hmdcamera.h"
Expand Down Expand Up @@ -49,27 +50,47 @@ int main( int argc, char** argv )
// Open the HMD
osg::ref_ptr<OculusDevice> oculusDevice = new OculusDevice();
oculusDevice->setCustomScaleFactor(1.25f);

// Create screen with match the Oculus Rift resolution
osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();

if (!wsi) {
osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
return 1;
}

// Get the screen identifiers set in environment variable DISPLAY
osg::GraphicsContext::ScreenIdentifier si;
si.readDISPLAY();

// If displayNum has not been set, reset it to 0.
if (si.displayNum < 0) si.displayNum = 0;

// If screenNum has not been set, reset it to 0.
if (si.screenNum < 0) si.screenNum = 0;

unsigned int width, height;
wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);
wsi->getScreenResolution(si, width, height);

osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->hostName = si.hostName;
traits->screenNum = si.screenNum;
traits->displayNum = si.displayNum;
traits->windowDecoration = false;
traits->x = 0;
traits->y = 0;
traits->width = oculusDevice->hScreenResolution();
traits->height = oculusDevice->vScreenResolution();
traits->doubleBuffer = true;
traits->sharedContext = 0;
traits->sampleBuffers = true;
traits->samples = 4;
traits->vsync = true;
traits->vsync = true; // VSync should always be enabled for Oculus Rift applications

// Create a graphic context based on our desired traits
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits);
if (!gc) {
osg::notify(osg::NOTICE) << "Error, GraphicsWindow has not been created successfully" << std::endl;
return 1;
}

if (gc.valid()) {
gc->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f));
Expand All @@ -79,17 +100,23 @@ int main( int argc, char** argv )
osgViewer::Viewer viewer(arguments);
viewer.getCamera()->setGraphicsContext(gc);
viewer.getCamera()->setViewport(0, 0, traits->width, traits->height);

// Disable automatic computation of near and far plane
viewer.getCamera()->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR );
viewer.setCameraManipulator(cameraManipulator);
viewer.realize();

// Subtract at least one bit of the node mask to disable rendering for main camera
osg::Node::NodeMask sceneNodeMask = loadedModel->getNodeMask() & ~0x1;
loadedModel->setNodeMask(sceneNodeMask);

osg::ref_ptr<HMDCamera> hmd_camera = new HMDCamera(&viewer, oculusDevice);
hmd_camera->setChromaticAberrationCorrection(true);
hmd_camera->setSceneNodeMask(sceneNodeMask);
hmd_camera->addChild(loadedModel);
viewer.setSceneData(hmd_camera);
// Create matrix for camera position and orientation (from HMD)
osg::Matrix cameraManipulatorViewMatrix;
osg::Matrix orientationMatrix;
// Add statistics handler
viewer.addEventHandler(new osgViewer::StatsHandler);
// Start Viewer
viewer.run();
return 0;
Expand Down

0 comments on commit 43dbeee

Please sign in to comment.