Skip to content
Permalink
Browse files

WIP OpenVR support (black screen, but SteamVR connection is OK)

  • Loading branch information
Yannick
Yannick committed Mar 6, 2017
1 parent 0964886 commit 3339355c84125295fd0d54479352bc282f7ab4d5
Showing with 4,995 additions and 7 deletions.
  1. +6 −0 C3DE.Demo/Scenes/HeightmapDemo.cs
  2. +2 −0 C3DE/C3DE.csproj
  3. +8 −7 C3DE/Rendering/VRRenderer.cs
  4. +135 −0 C3DE/VR/OpenVRService.cs
  5. +4,844 −0 C3DE/VR/openvr_api.cs
@@ -3,6 +3,7 @@
using C3DE.Materials;
using C3DE.Prefabs;
using C3DE.Rendering;
using C3DE.VR;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

@@ -62,6 +63,11 @@ public override void Initialize()
// And fog
RenderSettings.FogDensity = 0.0085f;
RenderSettings.FogMode = FogMode.Exp2;

var openVRDevice = new OpenVRService(Application.Engine);
var vrRenderer = new VRRenderer(Application.GraphicsDevice, openVRDevice);

Application.Engine.Renderer = vrRenderer;
}
}
}
@@ -130,6 +130,8 @@
<Compile Include="VR\IVRDevice.cs" />
<Compile Include="VR\OculusRift.cs" />
<Compile Include="VR\OculusRiftService.cs" />
<Compile Include="VR\OpenVRService.cs" />
<Compile Include="VR\openvr_api.cs" />
</ItemGroup>
<!--
<ItemGroup>
@@ -11,22 +11,23 @@ namespace C3DE.Rendering
{
public class VRRenderer : Renderer
{
private IVRDevice vrDevice;
private IVRDevice _vrDevice;
private RenderTarget2D[] renderTargetEye = new RenderTarget2D[2];
private Matrix playerMatrix = Matrix.CreateScale(1);

public VRRenderer(GraphicsDevice graphics, IVRDevice device)
public VRRenderer(GraphicsDevice graphics, IVRDevice vrDevice)
: base(graphics)
{
Application.Engine.IsFixedTimeStep = false;
_vrDevice = vrDevice;
}

public override void Initialize(ContentManager content)
{
base.Initialize(content);

for (int eye = 0; eye < 2; eye++)
renderTargetEye[eye] = vrDevice.CreateRenderTargetForEye(eye);
renderTargetEye[eye] = _vrDevice.CreateRenderTargetForEye(eye);
}

public override void Render(Scene scene)
@@ -38,16 +39,16 @@ public override void Render(Scene scene)
m_graphicsDevice.SetRenderTarget(renderTargetEye[eye]);
m_graphicsDevice.Clear(Color.Black);

camera.projection = vrDevice.GetProjectionMatrix(eye);
camera.view = vrDevice.GetViewMatrix(eye, playerMatrix);
camera.projection = _vrDevice.GetProjectionMatrix(eye);
camera.view = _vrDevice.GetViewMatrix(eye, playerMatrix);

RenderShadowMaps(scene);
RenderObjects(scene, camera);
//renderPostProcess(scene.postProcessPasses);
//RenderUI(scene.Behaviours);
}

vrDevice.SubmitRenderTargets(renderTargetEye[0], renderTargetEye[1]);
_vrDevice.SubmitRenderTargets(renderTargetEye[0], renderTargetEye[1]);

// show left eye view also on the monitor screen
DrawEyeViewIntoBackbuffer(0);
@@ -69,7 +70,7 @@ private void DrawEyeViewIntoBackbuffer(int eye)
var pp = m_graphicsDevice.PresentationParameters;

int height = pp.BackBufferHeight;
int width = Math.Min(pp.BackBufferWidth, (int)(height * vrDevice.GetRenderTargetAspectRatio(eye)));
int width = Math.Min(pp.BackBufferWidth, (int)(height * _vrDevice.GetRenderTargetAspectRatio(eye)));
int offset = (pp.BackBufferWidth - width) / 2;

m_spriteBatch.Begin();
@@ -0,0 +1,135 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Valve.VR;

namespace C3DE.VR
{
public class OpenVRService : GameComponent, IVRDevice
{
private CVRSystem _hmd;
private TrackedDevicePose_t[] _trackedDevices;
private TrackedDevicePose_t[] _gamePose;
private VRTextureBounds_t[] textureBounds;

public OpenVRService(Game game)
: base(game)
{
var error = EVRInitError.None;
_hmd = OpenVR.Init(ref error);

_trackedDevices = new TrackedDevicePose_t[OpenVR.k_unMaxTrackedDeviceCount];
_gamePose = new TrackedDevicePose_t[OpenVR.k_unMaxTrackedDeviceCount];

var strDriver = "No Driver";
var strDisplay = "No Display";

strDriver = GetTrackedDeviceString(OpenVR.k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty.Prop_TrackingSystemName_String);
strDisplay = GetTrackedDeviceString(OpenVR.k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty.Prop_SerialNumber_String);

Debug.Log("Driver: {0} - Display {1}", strDriver, strDisplay);

float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f;
_hmd.GetProjectionRaw(EVREye.Eye_Left, ref l_left, ref l_right, ref l_top, ref l_bottom);

float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f;
_hmd.GetProjectionRaw(EVREye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom);

var tanHalfFov = new Vector2(Math.Max(Math.Max(-l_left, l_right), Math.Max(-r_left, r_right)), Math.Max(Math.Max(-l_top, l_bottom), Math.Max(-r_top, r_bottom)));
textureBounds = new VRTextureBounds_t[2];

textureBounds[0].uMin = 0.5f + 0.5f * l_left / tanHalfFov.X;
textureBounds[0].uMax = 0.5f + 0.5f * l_right / tanHalfFov.X;
textureBounds[0].vMin = 0.5f - 0.5f * l_bottom / tanHalfFov.Y;
textureBounds[0].vMax = 0.5f - 0.5f * l_top / tanHalfFov.Y;

textureBounds[1].uMin = 0.5f + 0.5f * r_left / tanHalfFov.X;
textureBounds[1].uMax = 0.5f + 0.5f * r_right / tanHalfFov.X;
textureBounds[1].vMin = 0.5f - 0.5f * r_bottom / tanHalfFov.Y;
textureBounds[1].vMax = 0.5f - 0.5f * r_top / tanHalfFov.Y;

game.Components.Add(this);
}

public RenderTarget2D CreateRenderTargetForEye(int eye)
{
uint width = 0;
uint height = 0;
_hmd.GetRecommendedRenderTargetSize(ref width, ref height);

return new RenderTarget2D(Game.GraphicsDevice, (int)width, (int)height);
}

public Matrix GetProjectionMatrix(int eye)
{
var mat = _hmd.GetProjectionMatrix((EVREye)eye, 0.1f, 1000.0f);

var matrix = Matrix44ToXNA(ref mat);
return Matrix.Transpose(matrix);
}

public float GetRenderTargetAspectRatio(int eye)
{
return 1.0f;
}

public Matrix GetViewMatrix(int eye, Matrix playerScale)
{
var mat = _hmd.GetEyeToHeadTransform((EVREye)eye);
var matrix = Matrix34ToXNA(ref mat);
return Matrix.Transpose(matrix);
}

public int SubmitRenderTargets(RenderTarget2D leftRT, RenderTarget2D rightRT)
{
Texture_t texture0;
texture0.handle = leftRT.GetSharedHandle();
texture0.eType = ETextureType.DirectX;
texture0.eColorSpace = EColorSpace.Auto;

OpenVR.Compositor.Submit(EVREye.Eye_Left, ref texture0, ref textureBounds[0], EVRSubmitFlags.Submit_Default);

Texture_t texture1;
texture1.handle = leftRT.GetSharedHandle();
texture1.eType = ETextureType.DirectX;
texture1.eColorSpace = EColorSpace.Auto;

OpenVR.Compositor.Submit(EVREye.Eye_Right, ref texture1, ref textureBounds[1], EVRSubmitFlags.Submit_Default);

OpenVR.Compositor.WaitGetPoses(_trackedDevices, _gamePose);

return 0;
}

public string GetTrackedDeviceString(uint deviceIndex, ETrackedDeviceProperty prop)
{
ETrackedPropertyError error = ETrackedPropertyError.TrackedProp_Success;
var bufferSize = _hmd.GetStringTrackedDeviceProperty(deviceIndex, prop, null, 0, ref error);
if (bufferSize == 0)
return string.Empty;

var buffer = new System.Text.StringBuilder((int)bufferSize);
bufferSize = _hmd.GetStringTrackedDeviceProperty(deviceIndex, prop, buffer, bufferSize, ref error);

return buffer.ToString();
}

private Matrix Matrix34ToXNA(ref HmdMatrix34_t mat)
{
return new Matrix(
mat.m0, mat.m1, mat.m2, mat.m3,
mat.m4, mat.m5, mat.m6, mat.m7,
mat.m8, mat.m9, mat.m10, mat.m11,
0.0f, 0.0f, 0.0f, 1.0f);
}

private Matrix Matrix44ToXNA(ref HmdMatrix44_t mat)
{
return new Matrix(
mat.m0, mat.m1, mat.m2, mat.m3,
mat.m4, mat.m5, mat.m6, mat.m7,
mat.m8, mat.m9, mat.m10, mat.m11,
mat.m12, mat.m13, mat.m14, mat.m15);
}
}
}

0 comments on commit 3339355

Please sign in to comment.
You can’t perform that action at this time.