]> git.tdb.fi Git - libs/vr.git/blobdiff - source/ovr/oculusriftsystem.cpp
Rename DisplayDevice to System
[libs/vr.git] / source / ovr / oculusriftsystem.cpp
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