+++ /dev/null
-#include <msp/strings/format.h>
-#include "displaydevice.h"
-#ifdef WITH_OPENVR
-#include "openvr/openvrdevice.h"
-#endif
-#ifdef WITH_LIBOVR
-#include "ovr/oculusriftdevice.h"
-#endif
-
-using namespace std;
-
-namespace Msp {
-namespace VR {
-
-DisplayDevice *DisplayDevice::create_device(const string &type)
-{
-#ifdef WITH_OPENVR
- if(type=="openvr")
- return new OpenVRDevice;
-#endif
-#ifdef WITH_LIBOVR
- if(type=="libovr")
- return new OculusRiftDevice;
-#endif
- throw invalid_argument(format("device type '%s' not supported", type));
-}
-
-} // namespace VR
-} // namespace Msp
+++ /dev/null
-#ifndef MSP_VR_DISPLAYDEVICE_H_
-#define MSP_VR_DISPLAYDEVICE_H_
-
-#include <string>
-#include <msp/gl/camera.h>
-#include <msp/gl/view.h>
-
-namespace Msp {
-namespace VR {
-
-class HeadTrackingCamera;
-class StereoCombiner;
-class StereoView;
-
-class DisplayDevice
-{
-protected:
- DisplayDevice() { }
-public:
- virtual ~DisplayDevice() { }
-
- static DisplayDevice *create_device(const std::string &);
-
- virtual void configure_window(Graphics::Window &) const = 0;
- virtual void configure_view(StereoView &) const = 0;
- virtual HeadTrackingCamera *create_camera(const GL::Camera &) = 0;
- virtual StereoCombiner *create_combiner(GL::View &) = 0;
-};
-
-} // namespace VR
-} // namespace Msp
-
-#endif
#include <openvr.h>
#include "openvrcamera.h"
-#include "openvrdevice.h"
+#include "openvrsystem.h"
namespace Msp {
namespace VR {
-OpenVRCamera::OpenVRCamera(const OpenVRDevice &d, const GL::Camera &c):
+OpenVRCamera::OpenVRCamera(const OpenVRSystem &d, const GL::Camera &c):
HeadTrackingCamera(c),
device(d)
{ }
namespace Msp {
namespace VR {
-class OpenVRDevice;
+class OpenVRSystem;
class OpenVRCamera: public HeadTrackingCamera
{
private:
- const OpenVRDevice &device;
+ const OpenVRSystem &device;
public:
- OpenVRCamera(const OpenVRDevice &, const GL::Camera &);
+ OpenVRCamera(const OpenVRSystem &, const GL::Camera &);
virtual void reset_tracking();
virtual void update();
#include <openvr.h>
#include "openvrcombiner.h"
-#include "openvrdevice.h"
+#include "openvrsystem.h"
namespace Msp {
namespace VR {
};
-OpenVRCombiner::OpenVRCombiner(OpenVRDevice &d, GL::View &v):
+OpenVRCombiner::OpenVRCombiner(OpenVRSystem &d, GL::View &v):
device(d),
view(v)
{
namespace Msp {
namespace VR {
-class OpenVRDevice;
+class OpenVRSystem;
class OpenVRCombiner: public StereoCombiner
{
private:
struct Private;
- OpenVRDevice &device;
+ OpenVRSystem &device;
GL::View &view;
public:
- OpenVRCombiner(OpenVRDevice &, GL::View &);
+ OpenVRCombiner(OpenVRSystem &, GL::View &);
virtual void prepare() const;
virtual void render(const GL::Texture2D &, const GL::Texture2D &) const;
+++ /dev/null
-#include <openvr.h>
-#include <msp/vr/stereoview.h>
-#include "openvrdevice.h"
-
-using namespace std;
-
-namespace {
-
-Msp::GL::Matrix convert_matrix(const vr::HmdMatrix34_t &m)
-{
- Msp::GL::Matrix result;
- for(unsigned i=0; i<3; ++i)
- for(unsigned j=0; j<4; ++j)
- result(i, j) = m.m[i][j];
- return result;
-}
-
-}
-
-
-namespace Msp {
-namespace VR {
-
-unsigned OpenVRDevice::n_instances = 0;
-
-OpenVRDevice::OpenVRDevice()
-{
- if(!n_instances)
- {
- vr::EVRInitError init_err;
- vr::VR_Init(&init_err, vr::VRApplication_Scene);
- if(init_err!=vr::VRInitError_None)
- throw runtime_error("OpenVR initialization failed");
- }
- ++n_instances;
-
- vr::IVRCompositor *compositor = vr::VRCompositor();
- if(!compositor)
- throw runtime_error("OpenVR compositor initialization failed");
-
- vr::VRCompositor()->SetTrackingSpace(vr::TrackingUniverseSeated);
-}
-
-OpenVRDevice::~OpenVRDevice()
-{
- if(!--n_instances)
- vr::VR_Shutdown();
-}
-
-void OpenVRDevice::configure_view(StereoView &view) const
-{
- vr::IVRSystem *vr_sys = vr::VRSystem();
-
-#if defined(__GNUC__) && defined(_WIN32)
- /* Visual C++ passes the return value address as first stack parameter and
- the this pointer in ecx. MinGW does the other way around. This trick
- forces the function signature to match at machine code level. */
- typedef void (vr::IVRSystem::*FuncPtr)(vr::HmdMatrix34_t *, vr::EVREye);
- FuncPtr get_eye_to_head_transform = reinterpret_cast<FuncPtr>(&vr::IVRSystem::GetEyeToHeadTransform);
-
- vr::HmdMatrix34_t left, right;
- (vr_sys->*get_eye_to_head_transform)(&left, vr::Eye_Left);
- (vr_sys->*get_eye_to_head_transform)(&right, vr::Eye_Right);
-#else
- vr::HmdMatrix34_t left = vr_sys->GetEyeToHeadTransform(vr::Eye_Left);
- vr::HmdMatrix34_t right = vr_sys->GetEyeToHeadTransform(vr::Eye_Right);
-#endif
-
- view.set_eye_matrices(convert_matrix(left), convert_matrix(right));
-}
-
-OpenVRCamera *OpenVRDevice::create_camera(const GL::Camera &bc)
-{
- return new OpenVRCamera(*this, bc);
-}
-
-OpenVRCombiner *OpenVRDevice::create_combiner(GL::View &v)
-{
- return new OpenVRCombiner(*this, v);
-}
-
-void OpenVRDevice::update_pose_matrices()
-{
- vector<vr::TrackedDevicePose_t> poses;
- poses.resize(vr::k_unTrackedDeviceIndex_Hmd+1);
- vr::VRCompositor()->WaitGetPoses(&poses[0], poses.size(), 0, 0);
-
- vr::TrackedDevicePose_t &hmd_pose = poses[vr::k_unTrackedDeviceIndex_Hmd];
- if(hmd_pose.bPoseIsValid)
- hmd_matrix = convert_matrix(hmd_pose.mDeviceToAbsoluteTracking);
-}
-
-} // namespace VR
-} // namespace Msp
+++ /dev/null
-#ifndef MSP_VR_OPENVRDEVICE_H_
-#define MSP_VR_OPENVRDEVICE_H_
-
-#include <msp/gl/matrix.h>
-#include <msp/vr/displaydevice.h>
-#include "openvrcamera.h"
-#include "openvrcombiner.h"
-
-namespace Msp {
-namespace VR {
-
-class OpenVRDevice: public DisplayDevice
-{
-private:
- GL::Matrix hmd_matrix;
-
- static unsigned n_instances;
-
-public:
- OpenVRDevice();
- ~OpenVRDevice();
-
- virtual void configure_window(Graphics::Window &) const { }
- virtual void configure_view(StereoView &) const;
- virtual OpenVRCamera *create_camera(const GL::Camera &);
- virtual OpenVRCombiner *create_combiner(GL::View &);
-
- void update_pose_matrices();
- const GL::Matrix &get_hmd_matrix() const { return hmd_matrix; }
-};
-
-} // namespace VR
-} // namespace Msp
-
-#endif
--- /dev/null
+#include <openvr.h>
+#include <msp/vr/stereoview.h>
+#include "openvrsystem.h"
+
+using namespace std;
+
+namespace {
+
+Msp::GL::Matrix convert_matrix(const vr::HmdMatrix34_t &m)
+{
+ Msp::GL::Matrix result;
+ for(unsigned i=0; i<3; ++i)
+ for(unsigned j=0; j<4; ++j)
+ result(i, j) = m.m[i][j];
+ return result;
+}
+
+}
+
+
+namespace Msp {
+namespace VR {
+
+unsigned OpenVRSystem::n_instances = 0;
+
+OpenVRSystem::OpenVRSystem()
+{
+ if(!n_instances)
+ {
+ vr::EVRInitError init_err;
+ vr::VR_Init(&init_err, vr::VRApplication_Scene);
+ if(init_err!=vr::VRInitError_None)
+ throw runtime_error("OpenVR initialization failed");
+ }
+ ++n_instances;
+
+ vr::IVRCompositor *compositor = vr::VRCompositor();
+ if(!compositor)
+ throw runtime_error("OpenVR compositor initialization failed");
+
+ vr::VRCompositor()->SetTrackingSpace(vr::TrackingUniverseSeated);
+}
+
+OpenVRSystem::~OpenVRSystem()
+{
+ if(!--n_instances)
+ vr::VR_Shutdown();
+}
+
+void OpenVRSystem::configure_view(StereoView &view) const
+{
+ vr::IVRSystem *vr_sys = vr::VRSystem();
+
+#if defined(__GNUC__) && defined(_WIN32)
+ /* Visual C++ passes the return value address as first stack parameter and
+ the this pointer in ecx. MinGW does the other way around. This trick
+ forces the function signature to match at machine code level. */
+ typedef void (vr::IVRSystem::*FuncPtr)(vr::HmdMatrix34_t *, vr::EVREye);
+ FuncPtr get_eye_to_head_transform = reinterpret_cast<FuncPtr>(&vr::IVRSystem::GetEyeToHeadTransform);
+
+ vr::HmdMatrix34_t left, right;
+ (vr_sys->*get_eye_to_head_transform)(&left, vr::Eye_Left);
+ (vr_sys->*get_eye_to_head_transform)(&right, vr::Eye_Right);
+#else
+ vr::HmdMatrix34_t left = vr_sys->GetEyeToHeadTransform(vr::Eye_Left);
+ vr::HmdMatrix34_t right = vr_sys->GetEyeToHeadTransform(vr::Eye_Right);
+#endif
+
+ view.set_eye_matrices(convert_matrix(left), convert_matrix(right));
+}
+
+OpenVRCamera *OpenVRSystem::create_camera(const GL::Camera &bc)
+{
+ return new OpenVRCamera(*this, bc);
+}
+
+OpenVRCombiner *OpenVRSystem::create_combiner(GL::View &v)
+{
+ return new OpenVRCombiner(*this, v);
+}
+
+void OpenVRSystem::update_pose_matrices()
+{
+ vector<vr::TrackedDevicePose_t> poses;
+ poses.resize(vr::k_unTrackedDeviceIndex_Hmd+1);
+ vr::VRCompositor()->WaitGetPoses(&poses[0], poses.size(), 0, 0);
+
+ vr::TrackedDevicePose_t &hmd_pose = poses[vr::k_unTrackedDeviceIndex_Hmd];
+ if(hmd_pose.bPoseIsValid)
+ hmd_matrix = convert_matrix(hmd_pose.mDeviceToAbsoluteTracking);
+}
+
+} // namespace VR
+} // namespace Msp
--- /dev/null
+#ifndef MSP_VR_OPENVRSYSTEM_H_
+#define MSP_VR_OPENVRSYSTEM_H_
+
+#include <msp/gl/matrix.h>
+#include <msp/vr/system.h>
+#include "openvrcamera.h"
+#include "openvrcombiner.h"
+
+namespace Msp {
+namespace VR {
+
+class OpenVRSystem: public System
+{
+private:
+ GL::Matrix hmd_matrix;
+
+ static unsigned n_instances;
+
+public:
+ OpenVRSystem();
+ ~OpenVRSystem();
+
+ virtual void configure_window(Graphics::Window &) const { }
+ virtual void configure_view(StereoView &) const;
+ virtual OpenVRCamera *create_camera(const GL::Camera &);
+ virtual OpenVRCombiner *create_combiner(GL::View &);
+
+ void update_pose_matrices();
+ const GL::Matrix &get_hmd_matrix() const { return hmd_matrix; }
+};
+
+} // namespace VR
+} // namespace Msp
+
+#endif
#include "oculusriftcamera.h"
-#include "oculusriftdevice.h"
-#include "oculusriftdevice_private.h"
+#include "oculusriftsystem.h"
+#include "oculusriftsystem_private.h"
namespace Msp {
namespace VR {
-OculusRiftCamera::OculusRiftCamera(const OculusRiftDevice &d, const GL::Camera &c):
+OculusRiftCamera::OculusRiftCamera(const OculusRiftSystem &d, const GL::Camera &c):
HeadTrackingCamera(c),
device(d)
{
namespace Msp {
namespace VR {
-class OculusRiftDevice;
+class OculusRiftSystem;
class OculusRiftCamera: public HeadTrackingCamera
{
private:
- const OculusRiftDevice &device;
+ const OculusRiftSystem &device;
public:
- OculusRiftCamera(const OculusRiftDevice &, const GL::Camera &);
+ OculusRiftCamera(const OculusRiftSystem &, const GL::Camera &);
virtual void reset_tracking();
virtual void update();
#include <msp/gl/meshbuilder.h>
#include <msp/gl/texture2d.h>
#include "oculusriftcombiner.h"
-#include "oculusriftdevice.h"
-#include "oculusriftdevice_private.h"
+#include "oculusriftsystem.h"
+#include "oculusriftsystem_private.h"
using namespace std;
};
-OculusRiftCombiner::OculusRiftCombiner(OculusRiftDevice &d, GL::View &v):
+OculusRiftCombiner::OculusRiftCombiner(OculusRiftSystem &d, GL::View &v):
device(d),
view(v),
left_mesh((GL::VERTEX2, GL::TEXCOORD2,0, GL::TEXCOORD2,1, GL::TEXCOORD2,2, GL::TEXCOORD2,3)),
namespace Msp {
namespace VR {
-class OculusRiftDevice;
+class OculusRiftSystem;
/**
Presents a stereo view in a way suitable for an Oculus Rift HMD. All distances
private:
struct Frustum;
- OculusRiftDevice &device;
+ OculusRiftSystem &device;
GL::View &view;
GL::Mesh left_mesh;
GL::Mesh right_mesh;
mutable GL::ProgramData right_shdata;
public:
- OculusRiftCombiner(OculusRiftDevice &, GL::View &);
+ OculusRiftCombiner(OculusRiftSystem &, GL::View &);
virtual void prepare() const;
virtual void render(const GL::Texture2D &, const GL::Texture2D &) const;
+++ /dev/null
-#include <msp/graphics/display.h>
-#include <msp/vr/stereoview.h>
-#include "oculusriftdevice.h"
-#include "oculusriftdevice_private.h"
-
-using namespace std;
-
-namespace Msp {
-namespace VR {
-
-unsigned OculusRiftDevice::n_instances = 0;
-
-OculusRiftDevice::OculusRiftDevice():
- priv(new Private),
- frame_index(0)
-{
- if(!n_instances)
- ovr_Initialize();
- ++n_instances;
-
- priv->ovr_hmd = ovrHmd_Create(0);
- if(!priv->ovr_hmd)
- {
- delete priv;
- throw runtime_error("rift hmd not found");
- }
-}
-
-OculusRiftDevice::~OculusRiftDevice()
-{
- ovrHmd_Destroy(priv->ovr_hmd);
- delete priv;
-
- --n_instances;
- if(!n_instances)
- ovr_Shutdown();
-}
-
-void OculusRiftDevice::configure_window(Graphics::Window &window) const
-{
- Graphics::WindowOptions win_opts = window.get_options();
- win_opts.width = priv->ovr_hmd->Resolution.w;
- win_opts.height = priv->ovr_hmd->Resolution.h;
-
- const list<Graphics::Monitor> &monitors = window.get_display().get_monitors();
- string hmd_name = priv->ovr_hmd->ProductName;
- for(list<Graphics::Monitor>::const_iterator i=monitors.begin(); i!=monitors.end(); ++i)
- if(hmd_name.find(i->name)!=string::npos)
- {
- win_opts.fullscreen = true;
- win_opts.fullscreen_monitor = &*i;
- win_opts.fullscreen_exclusive = false;
- }
-
- window.reconfigure(win_opts);
-}
-
-void OculusRiftDevice::configure_view(StereoView &view) const
-{
- ovrEyeRenderDesc left_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Left, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]);
- ovrEyeRenderDesc right_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Right, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]);
- const ovrVector3f &l = left_desc.HmdToEyeViewOffset;
- const ovrVector3f &r = right_desc.HmdToEyeViewOffset;
- view.set_eye_matrices(GL::Matrix::translation(GL::Vector3(l.x, l.y, l.z)), GL::Matrix::translation(GL::Vector3(r.x, r.y, r.z)));
-}
-
-OculusRiftCamera *OculusRiftDevice::create_camera(const GL::Camera &bc)
-{
- return new OculusRiftCamera(*this, bc);
-}
-
-OculusRiftCombiner *OculusRiftDevice::create_combiner(GL::View &view)
-{
- return new OculusRiftCombiner(*this, view);
-}
-
-void OculusRiftDevice::begin_frame()
-{
- priv->frame_timing = ovrHmd_BeginFrameTiming(priv->ovr_hmd, ++frame_index);
- timing_active = true;
-}
-
-void OculusRiftDevice::end_frame()
-{
- glFinish();
- ovrHmd_EndFrameTiming(priv->ovr_hmd);
- timing_active = false;
-}
-
-double OculusRiftDevice::get_tracking_time() const
-{
- if(!timing_active)
- throw logic_error("timing not active");
- return priv->frame_timing.ScanoutMidpointSeconds;
-}
-
-double OculusRiftDevice::get_timewarp_time() const
-{
- if(!timing_active)
- throw logic_error("timing not active");
- return priv->frame_timing.TimewarpPointSeconds;
-}
-
-double OculusRiftDevice::get_current_time() const
-{
- return ovr_GetTimeInSeconds();
-}
-
-} // namespace VR
-} // namespace Msp
+++ /dev/null
-#ifndef MSP_VR_OCULUSRIFTDEVICE_H_
-#define MSP_VR_OCULUSRIFTDEVICE_H_
-
-#include <msp/vr/displaydevice.h>
-#include "oculusriftcamera.h"
-#include "oculusriftcombiner.h"
-
-namespace Msp {
-namespace VR {
-
-class OculusRiftDevice: public DisplayDevice
-{
-public:
- struct Private;
-
-private:
- Private *priv;
- unsigned frame_index;
- bool timing_active;
-
- static unsigned n_instances;
-
-public:
- OculusRiftDevice();
- virtual ~OculusRiftDevice();
-
- const Private &get_private() const { return *priv; }
-
- virtual void configure_window(Graphics::Window &) const;
- virtual void configure_view(StereoView &) const;
- virtual OculusRiftCamera *create_camera(const GL::Camera &);
- virtual OculusRiftCombiner *create_combiner(GL::View &);
-
- void begin_frame();
- void end_frame();
- bool is_timing_active() const { return timing_active; }
- double get_tracking_time() const;
- double get_timewarp_time() const;
- double get_current_time() const;
-};
-
-} // namespace VR
-} // namespace Msp
-
-#endif
+++ /dev/null
-#ifndef MSP_VR_OCULUSRIFTDEVICE_PRIVATE_H_
-#define MSP_VR_OCULUSRIFTDEVICE_PRIVATE_H_
-
-#include <OVR.h>
-#include "oculusriftdevice.h"
-
-namespace Msp {
-namespace VR {
-
-struct OculusRiftDevice::Private
-{
- ovrHmd ovr_hmd;
- ovrFrameTiming frame_timing;
-};
-
-} // namespace VR
-} // namespace Msp
-
-#endif
--- /dev/null
+#include <msp/graphics/display.h>
+#include <msp/vr/stereoview.h>
+#include "oculusriftsystem.h"
+#include "oculusriftsystem_private.h"
+
+using namespace std;
+
+namespace Msp {
+namespace VR {
+
+unsigned OculusRiftSystem::n_instances = 0;
+
+OculusRiftSystem::OculusRiftSystem():
+ priv(new Private),
+ frame_index(0)
+{
+ if(!n_instances)
+ ovr_Initialize();
+ ++n_instances;
+
+ priv->ovr_hmd = ovrHmd_Create(0);
+ if(!priv->ovr_hmd)
+ {
+ delete priv;
+ throw runtime_error("rift hmd not found");
+ }
+}
+
+OculusRiftSystem::~OculusRiftSystem()
+{
+ ovrHmd_Destroy(priv->ovr_hmd);
+ delete priv;
+
+ --n_instances;
+ if(!n_instances)
+ ovr_Shutdown();
+}
+
+void OculusRiftSystem::configure_window(Graphics::Window &window) const
+{
+ Graphics::WindowOptions win_opts = window.get_options();
+ win_opts.width = priv->ovr_hmd->Resolution.w;
+ win_opts.height = priv->ovr_hmd->Resolution.h;
+
+ const list<Graphics::Monitor> &monitors = window.get_display().get_monitors();
+ string hmd_name = priv->ovr_hmd->ProductName;
+ for(list<Graphics::Monitor>::const_iterator i=monitors.begin(); i!=monitors.end(); ++i)
+ if(hmd_name.find(i->name)!=string::npos)
+ {
+ win_opts.fullscreen = true;
+ win_opts.fullscreen_monitor = &*i;
+ win_opts.fullscreen_exclusive = false;
+ }
+
+ window.reconfigure(win_opts);
+}
+
+void OculusRiftSystem::configure_view(StereoView &view) const
+{
+ ovrEyeRenderDesc left_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Left, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]);
+ ovrEyeRenderDesc right_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Right, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]);
+ const ovrVector3f &l = left_desc.HmdToEyeViewOffset;
+ const ovrVector3f &r = right_desc.HmdToEyeViewOffset;
+ view.set_eye_matrices(GL::Matrix::translation(GL::Vector3(l.x, l.y, l.z)), GL::Matrix::translation(GL::Vector3(r.x, r.y, r.z)));
+}
+
+OculusRiftCamera *OculusRiftSystem::create_camera(const GL::Camera &bc)
+{
+ return new OculusRiftCamera(*this, bc);
+}
+
+OculusRiftCombiner *OculusRiftSystem::create_combiner(GL::View &view)
+{
+ return new OculusRiftCombiner(*this, view);
+}
+
+void OculusRiftSystem::begin_frame()
+{
+ priv->frame_timing = ovrHmd_BeginFrameTiming(priv->ovr_hmd, ++frame_index);
+ timing_active = true;
+}
+
+void OculusRiftSystem::end_frame()
+{
+ glFinish();
+ ovrHmd_EndFrameTiming(priv->ovr_hmd);
+ timing_active = false;
+}
+
+double OculusRiftSystem::get_tracking_time() const
+{
+ if(!timing_active)
+ throw logic_error("timing not active");
+ return priv->frame_timing.ScanoutMidpointSeconds;
+}
+
+double OculusRiftSystem::get_timewarp_time() const
+{
+ if(!timing_active)
+ throw logic_error("timing not active");
+ return priv->frame_timing.TimewarpPointSeconds;
+}
+
+double OculusRiftSystem::get_current_time() const
+{
+ return ovr_GetTimeInSeconds();
+}
+
+} // namespace VR
+} // namespace Msp
--- /dev/null
+#ifndef MSP_VR_OCULUSRIFTSYSTEM_H_
+#define MSP_VR_OCULUSRIFTSYSTEM_H_
+
+#include <msp/vr/system.h>
+#include "oculusriftcamera.h"
+#include "oculusriftcombiner.h"
+
+namespace Msp {
+namespace VR {
+
+class OculusRiftSystem: public System
+{
+public:
+ struct Private;
+
+private:
+ Private *priv;
+ unsigned frame_index;
+ bool timing_active;
+
+ static unsigned n_instances;
+
+public:
+ OculusRiftSystem();
+ virtual ~OculusRiftSystem();
+
+ const Private &get_private() const { return *priv; }
+
+ virtual void configure_window(Graphics::Window &) const;
+ virtual void configure_view(StereoView &) const;
+ virtual OculusRiftCamera *create_camera(const GL::Camera &);
+ virtual OculusRiftCombiner *create_combiner(GL::View &);
+
+ void begin_frame();
+ void end_frame();
+ bool is_timing_active() const { return timing_active; }
+ double get_tracking_time() const;
+ double get_timewarp_time() const;
+ double get_current_time() const;
+};
+
+} // namespace VR
+} // namespace Msp
+
+#endif
--- /dev/null
+#ifndef MSP_VR_OCULUSRIFTSYSTEM_PRIVATE_H_
+#define MSP_VR_OCULUSRIFTSYSTEM_PRIVATE_H_
+
+#include <OVR.h>
+#include "oculusriftsystem.h"
+
+namespace Msp {
+namespace VR {
+
+struct OculusRiftSystem::Private
+{
+ ovrHmd ovr_hmd;
+ ovrFrameTiming frame_timing;
+};
+
+} // namespace VR
+} // namespace Msp
+
+#endif
--- /dev/null
+#include <msp/strings/format.h>
+#include "system.h"
+#ifdef WITH_OPENVR
+#include "openvr/openvrsystem.h"
+#endif
+#ifdef WITH_LIBOVR
+#include "ovr/oculusriftsystem.h"
+#endif
+
+using namespace std;
+
+namespace Msp {
+namespace VR {
+
+System *System::create(const string &type)
+{
+#ifdef WITH_OPENVR
+ if(type=="openvr")
+ return new OpenVRSystem;
+#endif
+#ifdef WITH_LIBOVR
+ if(type=="libovr")
+ return new OculusRiftSystem;
+#endif
+ throw invalid_argument(format("system '%s' not supported", type));
+}
+
+} // namespace VR
+} // namespace Msp
--- /dev/null
+#ifndef MSP_VR_SYSTEM_H_
+#define MSP_VR_SYSTEM_H_
+
+#include <string>
+#include <msp/gl/camera.h>
+#include <msp/gl/view.h>
+
+namespace Msp {
+namespace VR {
+
+class HeadTrackingCamera;
+class StereoCombiner;
+class StereoView;
+
+class System
+{
+protected:
+ System() { }
+public:
+ virtual ~System() { }
+
+ static System *create(const std::string &);
+
+ virtual void configure_window(Graphics::Window &) const = 0;
+ virtual void configure_view(StereoView &) const = 0;
+ virtual HeadTrackingCamera *create_camera(const GL::Camera &) = 0;
+ virtual StereoCombiner *create_combiner(GL::View &) = 0;
+};
+
+} // namespace VR
+} // namespace Msp
+
+#endif