diff --git a/components/streams/src/renderers/openvr_render.cpp b/components/streams/src/renderers/openvr_render.cpp
index 1827e3f248574f54ea5c822c3a69a83e46df3da3..add3c24c2428a653912bb792990037b7d03a4aa2 100644
--- a/components/streams/src/renderers/openvr_render.cpp
+++ b/components/streams/src/renderers/openvr_render.cpp
@@ -17,15 +17,17 @@ using ftl::render::OpenVRRender;
 using ftl::codecs::Channel;
 using ftl::rgbd::Capability;
 
+#ifdef HAVE_OPENVR
+static vr::IVRSystem *HMD = nullptr;
+#endif
+
 
 OpenVRRender::OpenVRRender(ftl::render::Source *host, ftl::stream::Feed *feed)
 : ftl::render::BaseSourceImpl(host), feed_(feed), my_id_(0) {
-	/*host->restore("device:render", {
-		"renderer",
-		"source",
-		"intrinsics",
-		"name"
-	});*/
+	#ifdef HAVE_OPENVR
+	if (HMD) throw FTL_Error("Can only have one OpenVR device");
+	#endif
+	initVR();
 
 	renderer_ = std::unique_ptr<ftl::render::CUDARender>(
 		ftl::create<ftl::render::CUDARender>(host_, "renderer")
@@ -58,6 +60,36 @@ OpenVRRender::OpenVRRender(ftl::render::Source *host, ftl::stream::Feed *feed)
 OpenVRRender::~OpenVRRender() {
 	if (filter_) filter_->remove();
 	delete intrinsics_;
+
+	#ifdef HAVE_OPENVR
+	if (HMD != nullptr) {
+		vr::VR_Shutdown();
+	}
+	#endif
+}
+
+bool OpenVRRender::initVR() {
+	#ifdef HAVE_OPENVR
+	if (!vr::VR_IsHmdPresent()) {
+		return false;
+	}
+
+	if (HMD) return true;
+
+	vr::EVRInitError eError = vr::VRInitError_None;
+	HMD = vr::VR_Init( &eError, vr::VRApplication_Scene );
+	
+	if (eError != vr::VRInitError_None)
+	{
+		HMD = nullptr;
+		LOG(ERROR) << "Unable to init VR runtime: " << vr::VR_GetVRInitErrorAsEnglishDescription(eError);
+		return false;
+	}
+
+	return true;
+	#else
+	return false;
+	#endif
 }
 
 bool OpenVRRender::supported() {
@@ -69,14 +101,44 @@ bool OpenVRRender::supported() {
 }
 
 bool OpenVRRender::isReady() {
-	return true;
+	#ifdef HAVE_OPENVR
+	return HMD != nullptr;
+	#else
+	return false;
+	#endif
 }
 
 bool OpenVRRender::capture(int64_t ts) {
 	return true;
 }
 
+#ifdef HAVE_OPENVR
+static inline Eigen::Matrix4d ConvertSteamVRMatrixToMatrix4( const vr::HmdMatrix34_t &matPose )
+{
+	Eigen::Matrix4d matrixObj;
+	matrixObj <<
+		matPose.m[0][0], matPose.m[0][1], matPose.m[0][2], matPose.m[0][3],
+		matPose.m[1][0], matPose.m[1][1], matPose.m[1][2], matPose.m[1][3],
+		matPose.m[2][0], matPose.m[2][1], matPose.m[2][2], matPose.m[2][3],
+					0.0,			 0.0,			  0.0,			   1.0;
+	return matrixObj;
+}
+
+static inline Eigen::Matrix4d ConvertSteamVRMatrixToMatrix4( const vr::HmdMatrix44_t &matPose )
+{
+	Eigen::Matrix4d matrixObj;
+	matrixObj <<
+		matPose.m[0][0], matPose.m[0][1], matPose.m[0][2], matPose.m[0][3],
+		matPose.m[1][0], matPose.m[1][1], matPose.m[1][2], matPose.m[1][3],
+		matPose.m[2][0], matPose.m[2][1], matPose.m[2][2], matPose.m[2][3],
+		matPose.m[3][0], matPose.m[3][1], matPose.m[3][2], matPose.m[3][3];
+	return matrixObj;
+}
+#endif
+
 bool OpenVRRender::retrieve(ftl::data::Frame &frame_out) {
+
+	#ifdef HAVE_OPENVR
 	//auto input = std::atomic_load(&input_);
 
 	my_id_ = frame_out.frameset();
@@ -109,6 +171,60 @@ bool OpenVRRender::retrieve(ftl::data::Frame &frame_out) {
 
 		int width = rgbdframe.getLeft().width;
 		int height = rgbdframe.getLeft().height;
+
+		vr::VRCompositor()->SetTrackingSpace(vr::TrackingUniverseStanding);
+		vr::VRCompositor()->WaitGetPoses(rTrackedDevicePose_, vr::k_unMaxTrackedDeviceCount, NULL, 0 );
+
+		if (rTrackedDevicePose_[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid ) {
+			Eigen::Matrix4d eye_l = ConvertSteamVRMatrixToMatrix4(
+				vr::VRSystem()->GetEyeToHeadTransform(vr::Eye_Left));
+
+			//Eigen::Matrix4d eye_r = ConvertSteamVRMatrixToMatrix4(
+			//	vr::VRSystem()->GetEyeToHeadTransform(vr::Eye_Left));
+
+			float baseline_in = 2.0 * eye_l(0, 3);
+
+			if (baseline_in != baseline_) {
+				baseline_ = baseline_in;
+				//src_->set("baseline", baseline_);
+				state_.getLeft().baseline = baseline_;
+				state_.getRight().baseline = baseline_;
+			}
+			Eigen::Matrix4d pose = ConvertSteamVRMatrixToMatrix4(rTrackedDevicePose_[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking);
+			Eigen::Vector3d ea = pose.block<3, 3>(0, 0).eulerAngles(0, 1, 2);
+
+			Eigen::Vector3d vreye;
+			vreye[0] = pose(0, 3);
+			vreye[1] = -pose(1, 3);
+			vreye[2] = -pose(2, 3);
+
+			// NOTE: If modified, should be verified with VR headset!
+			Eigen::Matrix3d R;
+			R =		Eigen::AngleAxisd(ea[0], Eigen::Vector3d::UnitX()) *
+					Eigen::AngleAxisd(-ea[1], Eigen::Vector3d::UnitY()) *
+					Eigen::AngleAxisd(-ea[2], Eigen::Vector3d::UnitZ());
+
+			//double rd = 180.0 / 3.141592;
+			//LOG(INFO) << "rotation x: " << ea[0] *rd << ", y: " << ea[1] * rd << ", z: " << ea[2] * rd;
+			// pose.block<3, 3>(0, 0) = R;
+
+			rotmat_.block(0, 0, 3, 3) = R;
+
+			// TODO: Apply a rotation to orient also
+
+			eye_[0] += (neye_[0] - eye_[0]) * lerpSpeed_ * delta_;
+			eye_[1] += (neye_[1] - eye_[1]) * lerpSpeed_ * delta_;
+			eye_[2] += (neye_[2] - eye_[2]) * lerpSpeed_ * delta_;
+
+			Eigen::Translation3d trans(eye_ + vreye);
+			Eigen::Affine3d t(trans);
+			auto viewPose = t.matrix() * rotmat_;
+
+			rgbdframe.setPose() = viewPose;
+
+		} else {
+			//LOG(ERROR) << "No VR Pose";
+		}
 		
 		// FIXME: Create opengl buffers here and map to cuda?
 		rgbdframe.create<cv::cuda::GpuMat>(Channel::Colour).create(height, width, CV_8UC4);
@@ -137,9 +253,27 @@ bool OpenVRRender::retrieve(ftl::data::Frame &frame_out) {
 		} catch (const ftl::exception &e) {
 			LOG(ERROR) << "Render exception: " << e.what();
 		}
-		return true;
+		//return true;
 	} else {
 		//LOG(INFO) << "Render fail";
-		return true;
+		//return true;
 	}
+
+	//if (HMD) {
+		//glBindTexture(GL_TEXTURE_2D, leftEye_);
+		vr::Texture_t leftEyeTexture = {(void*)(uintptr_t)leftEye_, vr::TextureType_OpenGL, vr::ColorSpace_Gamma };
+		vr::VRCompositor()->Submit(vr::Eye_Left, &leftEyeTexture );
+
+		//glBindTexture(GL_TEXTURE_2D, rightEye_);
+		vr::Texture_t rightEyeTexture = {(void*)(uintptr_t)rightEye_, vr::TextureType_OpenGL, vr::ColorSpace_Gamma };
+		vr::VRCompositor()->Submit(vr::Eye_Right, &rightEyeTexture );
+
+		glFlush();
+	//}
+
+	return true;
+
+	#else
+	return false;
+	#endif
 }
diff --git a/components/streams/src/renderers/openvr_render.hpp b/components/streams/src/renderers/openvr_render.hpp
index 9462141314485cfed81c28af31ffae7113acd3d3..3b4b4891b84ceabf944605f0c91ff0efbbe95244 100644
--- a/components/streams/src/renderers/openvr_render.hpp
+++ b/components/streams/src/renderers/openvr_render.hpp
@@ -31,6 +31,8 @@ class OpenVRRender : public ftl::render::BaseSourceImpl {
 	std::unique_ptr<ftl::render::CUDARender> renderer_;
 	ftl::Configurable *intrinsics_;
 	uint32_t my_id_;
+
+	bool initVR();
 };
 
 }