Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OpenVR] Handle custom resolution specified by the user through VR settings #2000

Merged
merged 1 commit into from Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -14,6 +14,14 @@ public class VRDeviceDescription
[DataMember(10)]
public VRApi Api { get; set; }

/// <summary>
/// Scales the render resolution,
/// note that this compounds with the user-specified resolution multiplier
/// </summary>
/// <userdoc>
/// Scales the render resolution,
/// note that this compounds with the user-specified resolution multiplier
/// </userdoc>
[DataMember(20)]
public float ResolutionScale { get; set; } = 1.0f;
}
Expand Down
6 changes: 6 additions & 0 deletions sources/engine/Stride.VirtualReality/OpenVR/OpenVR.cs
Expand Up @@ -435,6 +435,12 @@ public static Texture GetMirrorTexture(GraphicsDevice device, int eyeIndex)
return tex;
}

public static void GetRecommendedRenderTargetSize(out (uint x, uint y) size)
{
size = default;
Valve.VR.OpenVR.System.GetRecommendedRenderTargetSize(ref size.x, ref size.y);
}

public static ulong CreateOverlay()
{
var layerKeyName = Guid.NewGuid().ToString();
Expand Down
51 changes: 36 additions & 15 deletions sources/engine/Stride.VirtualReality/OpenVR/OpenVrHmd.cs
Expand Up @@ -25,41 +25,55 @@ internal class OpenVRHmd : VRDevice
private Vector3 currentHeadLinearVelocity;
private Vector3 currentHeadAngularVelocity;
private Quaternion currentHeadRot;
private (uint x, uint y) recommendedSize;
private GraphicsDevice device;

public override bool CanInitialize => OpenVR.InitDone || OpenVR.Init();

public OpenVRHmd()
{
VRApi = VRApi.OpenVR;
SupportsOverlays = true;
recommendedSize = (2160, 1200);
}

public override void Enable(GraphicsDevice device, GraphicsDeviceManager graphicsDeviceManager, bool requireMirror, int mirrorWidth, int mirrorHeight)
{
var width = (int)(OptimalRenderFrameSize.Width * RenderFrameScaling);
this.device = device;
needsMirror = requireMirror;
OpenVR.GetRecommendedRenderTargetSize(out recommendedSize);
RebuildRenderTargets();
leftEyeMirror = OpenVR.GetMirrorTexture(device, 0);
rightEyeMirror = OpenVR.GetMirrorTexture(device, 1);

leftHandController = new OpenVRTouchController(TouchControllerHand.Left);
rightHandController = new OpenVRTouchController(TouchControllerHand.Right);

trackedDevices = new OpenVRTrackedDevice[Valve.VR.OpenVR.k_unMaxTrackedDeviceCount];
for (int i=0; i<trackedDevices.Length; i++)
trackedDevices[i] = new OpenVRTrackedDevice(i);
}

private void RebuildRenderTargets()
{
var width = (int)(recommendedSize.x * RenderFrameScaling);
width += width % 2;
var height = (int)(OptimalRenderFrameSize.Height * RenderFrameScaling);
var height = (int)(recommendedSize.y * RenderFrameScaling);
height += height % 2;

ActualRenderFrameSize = new Size2(width, height);

needsMirror = requireMirror;

bothEyesMirror?.Dispose();
if (needsMirror)
{
bothEyesMirror = Texture.New2D(device, width, height, PixelFormat.R8G8B8A8_UNorm_SRgb, TextureFlags.RenderTarget | TextureFlags.ShaderResource);
}
else
{
bothEyesMirror = null;
}

leftEyeMirror = OpenVR.GetMirrorTexture(device, 0);
rightEyeMirror = OpenVR.GetMirrorTexture(device, 1);
MirrorTexture = bothEyesMirror;

leftHandController = new OpenVRTouchController(TouchControllerHand.Left);
rightHandController = new OpenVRTouchController(TouchControllerHand.Right);

trackedDevices = new OpenVRTrackedDevice[Valve.VR.OpenVR.k_unMaxTrackedDeviceCount];
for (int i=0; i<trackedDevices.Length; i++)
trackedDevices[i] = new OpenVRTrackedDevice(i);
}

public override VROverlay CreateOverlay(int width, int height, int mipLevels, int sampleCount)
Expand All @@ -70,6 +84,13 @@ public override VROverlay CreateOverlay(int width, int height, int mipLevels, in

public override void Draw(GameTime gameTime)
{
OpenVR.GetRecommendedRenderTargetSize(out var newSize);
if (recommendedSize != newSize)
{
recommendedSize = newSize;
RebuildRenderTargets();
}

OpenVR.UpdatePoses();
state = OpenVR.GetHeadPose(out currentHead, out currentHeadLinearVelocity, out currentHeadAngularVelocity);
Vector3 scale;
Expand Down Expand Up @@ -152,11 +173,11 @@ public override void SetTrackingSpace(TrackingSpace space)

public override Texture MirrorTexture { get; protected set; }

public override float RenderFrameScaling { get; set; } = 1.4f;
public override float RenderFrameScaling { get; set; } = 1f;

public override Size2 ActualRenderFrameSize { get; protected set; }

public override Size2 OptimalRenderFrameSize => new Size2(2160, 1200);
public override Size2 OptimalRenderFrameSize => new Size2((int)recommendedSize.x, (int)recommendedSize.y);

public override void Dispose()
{
Expand Down