]> git.tdb.fi Git - libs/vr.git/blob - source/ovr/oculusriftdevice.cpp
Automatically configure the window to cover the Rift's monitor
[libs/vr.git] / source / ovr / oculusriftdevice.cpp
1 #include <msp/graphics/display.h>
2 #include <msp/vr/stereoview.h>
3 #include "oculusriftdevice.h"
4 #include "oculusriftdevice_private.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace VR {
10
11 unsigned OculusRiftDevice::n_instances = 0;
12
13 OculusRiftDevice::OculusRiftDevice():
14         priv(new Private),
15         frame_index(0)
16 {
17         if(!n_instances)
18                 ovr_Initialize();
19         ++n_instances;
20
21         priv->ovr_hmd = ovrHmd_Create(0);
22         if(!priv->ovr_hmd)
23         {
24                 delete priv;
25                 throw runtime_error("rift hmd not found");
26         }
27 }
28
29 OculusRiftDevice::~OculusRiftDevice()
30 {
31         ovrHmd_Destroy(priv->ovr_hmd);
32         delete priv;
33
34         --n_instances;
35         if(!n_instances)
36                 ovr_Shutdown();
37 }
38
39 void OculusRiftDevice::configure_window(Graphics::Window &window) const
40 {
41         Graphics::WindowOptions win_opts = window.get_options();
42         win_opts.width = priv->ovr_hmd->Resolution.w;
43         win_opts.height = priv->ovr_hmd->Resolution.h;
44
45         const list<Graphics::Monitor> &monitors = window.get_display().get_monitors();
46         string hmd_name = priv->ovr_hmd->ProductName;
47         for(list<Graphics::Monitor>::const_iterator i=monitors.begin(); i!=monitors.end(); ++i)
48                 if(hmd_name.find(i->name)!=string::npos)
49                 {
50                         win_opts.fullscreen = true;
51                         win_opts.fullscreen_monitor = &*i;
52                         win_opts.fullscreen_exclusive = false;
53                 }
54
55         window.reconfigure(win_opts);
56 }
57
58 void OculusRiftDevice::configure_view(StereoView &view) const
59 {
60         ovrEyeRenderDesc left_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Left, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]);
61         ovrEyeRenderDesc right_desc = ovrHmd_GetRenderDesc(priv->ovr_hmd, ovrEye_Right, priv->ovr_hmd->DefaultEyeFov[ovrEye_Left]);
62         view.set_eye_spacing(left_desc.HmdToEyeViewOffset.x-right_desc.HmdToEyeViewOffset.x);
63 }
64
65 OculusRiftCamera *OculusRiftDevice::create_camera(const GL::Camera &bc)
66 {
67         return new OculusRiftCamera(*this, bc);
68 }
69
70 OculusRiftCombiner *OculusRiftDevice::create_combiner(GL::View &view)
71 {
72         return new OculusRiftCombiner(*this, view);
73 }
74
75 void OculusRiftDevice::begin_frame()
76 {
77         priv->frame_timing = ovrHmd_BeginFrameTiming(priv->ovr_hmd, ++frame_index);
78         timing_active = true;
79 }
80
81 void OculusRiftDevice::end_frame()
82 {
83         glFinish();
84         ovrHmd_EndFrameTiming(priv->ovr_hmd);
85         timing_active = false;
86 }
87
88 double OculusRiftDevice::get_tracking_time() const
89 {
90         if(!timing_active)
91                 throw logic_error("timing not active");
92         return priv->frame_timing.ScanoutMidpointSeconds;
93 }
94
95 double OculusRiftDevice::get_timewarp_time() const
96 {
97         if(!timing_active)
98                 throw logic_error("timing not active");
99         return priv->frame_timing.TimewarpPointSeconds;
100 }
101
102 double OculusRiftDevice::get_current_time() const
103 {
104         return ovr_GetTimeInSeconds();
105 }
106
107 } // namespace VR
108 } // namespace Msp