--- /dev/null
+#include <openvr.h>
+#include "openvrcombiner.h"
+#include "openvrdevice.h"
+
+namespace Msp {
+namespace VR {
+
+struct OpenVRCombiner::Private
+{
+ static Frustum get_projection(vr::EVREye);
+};
+
+
+OpenVRCombiner::OpenVRCombiner(OpenVRDevice &d):
+ device(d)
+{
+ vr::IVRSystem *vr_sys = vr::VRSystem();
+ uint32_t w, h;
+ vr_sys->GetRecommendedRenderTargetSize(&w, &h);
+ target_width = w;
+ target_height = h;
+
+ Frustum left_frustum = Private::get_projection(vr::Eye_Left);
+ Frustum right_frustum = Private::get_projection(vr::Eye_Right);
+ configure_eye_frustums(left_frustum, right_frustum);
+}
+
+void OpenVRCombiner::prepare() const
+{
+ device.update_pose_matrices();
+}
+
+void OpenVRCombiner::render(const GL::Texture2D &left, const GL::Texture2D &right) const
+{
+ vr::Texture_t tex;
+ tex.eType = vr::API_OpenGL;
+ tex.eColorSpace = vr::ColorSpace_Gamma;
+
+ vr::IVRCompositor *compositor = vr::VRCompositor();
+ tex.handle = reinterpret_cast<void *>(left.get_id());
+ compositor->Submit(vr::Eye_Left, &tex);
+ tex.handle = reinterpret_cast<void *>(right.get_id());
+ compositor->Submit(vr::Eye_Right, &tex);
+}
+
+
+StereoCombiner::Frustum OpenVRCombiner::Private::get_projection(vr::EVREye eye)
+{
+ Frustum frustum;
+ /* The parameter order is documented as left, right, top, bottom; however
+ the third parameter is actually negative and fourth one positive. */
+ vr::VRSystem()->GetProjectionRaw(eye, &frustum.left, &frustum.right, &frustum.bottom, &frustum.top);
+ return frustum;
+}
+
+} // namespace VR
+} // namespace Msp