Rename DisplayDevice to System
authorMikko Rasa <tdb@tdb.fi>
Mon, 3 Oct 2016 12:35:38 +0000 (15:35 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 3 Oct 2016 12:48:49 +0000 (15:48 +0300)
Motion controllers are going to be supported too so the top-level class
shouldn't be tied to display.

22 files changed:
source/displaydevice.cpp [deleted file]
source/displaydevice.h [deleted file]
source/openvr/openvrcamera.cpp
source/openvr/openvrcamera.h
source/openvr/openvrcombiner.cpp
source/openvr/openvrcombiner.h
source/openvr/openvrdevice.cpp [deleted file]
source/openvr/openvrdevice.h [deleted file]
source/openvr/openvrsystem.cpp [new file with mode: 0644]
source/openvr/openvrsystem.h [new file with mode: 0644]
source/ovr/oculusriftcamera.cpp
source/ovr/oculusriftcamera.h
source/ovr/oculusriftcombiner.cpp
source/ovr/oculusriftcombiner.h
source/ovr/oculusriftdevice.cpp [deleted file]
source/ovr/oculusriftdevice.h [deleted file]
source/ovr/oculusriftdevice_private.h [deleted file]
source/ovr/oculusriftsystem.cpp [new file with mode: 0644]
source/ovr/oculusriftsystem.h [new file with mode: 0644]
source/ovr/oculusriftsystem_private.h [new file with mode: 0644]
source/system.cpp [new file with mode: 0644]
source/system.h [new file with mode: 0644]

diff --git a/source/displaydevice.cpp b/source/displaydevice.cpp
deleted file mode 100644 (file)
index 5e11266..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#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
diff --git a/source/displaydevice.h b/source/displaydevice.h
deleted file mode 100644 (file)
index 46dfbae..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#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
index 6166d3ad30f4191b2b7da9d128d5dfa3a62895e8..d6a0fe69ea54cc24aa9500b7fa5c26af533c3a6f 100644 (file)
@@ -1,11 +1,11 @@
 #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)
 { }
index ff86817e9c950fd4bc8ab94bb725b11584a006f0..ab14d3d18fe4ee35b5ebc950c71702950497e2c2 100644 (file)
@@ -6,15 +6,15 @@
 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();
index 9bdf4b01a8151755a7f1ca3fa715c6dd96de9045..fa5a8ac45edb9daba2398c04b68107c8041be485 100644 (file)
@@ -1,6 +1,6 @@
 #include <openvr.h>
 #include "openvrcombiner.h"
-#include "openvrdevice.h"
+#include "openvrsystem.h"
 
 namespace Msp {
 namespace VR {
@@ -11,7 +11,7 @@ struct OpenVRCombiner::Private
 };
 
 
-OpenVRCombiner::OpenVRCombiner(OpenVRDevice &d, GL::View &v):
+OpenVRCombiner::OpenVRCombiner(OpenVRSystem &d, GL::View &v):
        device(d),
        view(v)
 {
index 58a24c9c9f2708eebac8c2f048e7e762ec4dada7..94ccce36be99b597bf05f9fd7c23406eee88cd6d 100644 (file)
@@ -7,18 +7,18 @@
 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;
diff --git a/source/openvr/openvrdevice.cpp b/source/openvr/openvrdevice.cpp
deleted file mode 100644 (file)
index b4ff20b..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-#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
diff --git a/source/openvr/openvrdevice.h b/source/openvr/openvrdevice.h
deleted file mode 100644 (file)
index ee00942..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#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
diff --git a/source/openvr/openvrsystem.cpp b/source/openvr/openvrsystem.cpp
new file mode 100644 (file)
index 0000000..ec6b418
--- /dev/null
@@ -0,0 +1,94 @@
+#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
diff --git a/source/openvr/openvrsystem.h b/source/openvr/openvrsystem.h
new file mode 100644 (file)
index 0000000..98ad556
--- /dev/null
@@ -0,0 +1,35 @@
+#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
index 713ae3cec5a480f5bc943fb1572856e4507c6fda..4da732b29251056255529e9df321ba28940b3090 100644 (file)
@@ -1,11 +1,11 @@
 #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)
 {
index b6acae1691648786aaf76dacb51b292c1596f7c5..6abb11651290fb037c0315b97a53e63377f09afb 100644 (file)
@@ -6,15 +6,15 @@
 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();
index 2d40ea95c1ff0e00b2231c94d812874f675ba11e..e0c2c4d0ffc9146106d0d999191973b0daa7d05d 100644 (file)
@@ -1,8 +1,8 @@
 #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;
 
@@ -81,7 +81,7 @@ struct OculusRiftCombiner::Frustum: StereoCombiner::Frustum
 };
 
 
-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)),
index 14f0e4cdc7c3603d8100f3aaf984991a9b57d39a..418c569cc382f55317fb291a3b964c6d7699680b 100644 (file)
@@ -10,7 +10,7 @@
 namespace Msp {
 namespace VR {
 
-class OculusRiftDevice;
+class OculusRiftSystem;
 
 /**
 Presents a stereo view in a way suitable for an Oculus Rift HMD.  All distances
@@ -21,7 +21,7 @@ class OculusRiftCombiner: public StereoCombiner
 private:
        struct Frustum;
 
-       OculusRiftDevice &device;
+       OculusRiftSystem &device;
        GL::View &view;
        GL::Mesh left_mesh;
        GL::Mesh right_mesh;
@@ -30,7 +30,7 @@ private:
        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;
diff --git a/source/ovr/oculusriftdevice.cpp b/source/ovr/oculusriftdevice.cpp
deleted file mode 100644 (file)
index 38fd20e..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-#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
diff --git a/source/ovr/oculusriftdevice.h b/source/ovr/oculusriftdevice.h
deleted file mode 100644 (file)
index 02f8016..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#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
diff --git a/source/ovr/oculusriftdevice_private.h b/source/ovr/oculusriftdevice_private.h
deleted file mode 100644 (file)
index 26587ff..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#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
diff --git a/source/ovr/oculusriftsystem.cpp b/source/ovr/oculusriftsystem.cpp
new file mode 100644 (file)
index 0000000..4a85383
--- /dev/null
@@ -0,0 +1,110 @@
+#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
diff --git a/source/ovr/oculusriftsystem.h b/source/ovr/oculusriftsystem.h
new file mode 100644 (file)
index 0000000..20a4a5e
--- /dev/null
@@ -0,0 +1,45 @@
+#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
diff --git a/source/ovr/oculusriftsystem_private.h b/source/ovr/oculusriftsystem_private.h
new file mode 100644 (file)
index 0000000..2f91fdf
--- /dev/null
@@ -0,0 +1,19 @@
+#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
diff --git a/source/system.cpp b/source/system.cpp
new file mode 100644 (file)
index 0000000..436862e
--- /dev/null
@@ -0,0 +1,29 @@
+#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
diff --git a/source/system.h b/source/system.h
new file mode 100644 (file)
index 0000000..0610e29
--- /dev/null
@@ -0,0 +1,33 @@
+#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