using Godot; public partial class Main : Node3D { [Signal] public delegate void FocusLostEventHandler(); [Signal] public delegate void FocusGainedEventHandler(); [Signal] public delegate void PoseRecenteredEventHandler(); [Export] public int MaximumRefreshRate { get; set; } = 90; private OpenXRInterface _xrInterface; private bool _xrIsFocused; public override void _Ready() { _xrInterface = (OpenXRInterface)XRServer.FindInterface("OpenXR"); if (_xrInterface != null && _xrInterface.IsInitialized()) { GD.Print("OpenXR instantiated successfully."); Viewport vp = GetViewport(); vp.UseXR = true; DisplayServer.WindowSetVsyncMode(DisplayServer.VSyncMode.Disabled); if (RenderingServer.GetRenderingDevice() != null) vp.VrsMode = Viewport.VrsModeEnum.XR; _xrInterface.SessionBegun += OnSessionBegun; _xrInterface.SessionVisible += OnSessionVisible; _xrInterface.SessionFocussed += OnSessionFocussed; _xrInterface.SessionStopping += OnSessionStopping; _xrInterface.PoseRecentered += OnPoseRecentered; } else { GD.PushWarning("OpenXR not instantiated, running in flat preview mode. Check headset and XR runtime."); } } private void OnSessionBegun() { float currentRefreshRate = _xrInterface.DisplayRefreshRate; GD.Print(currentRefreshRate > 0.0f ? $"OpenXR: refresh rate reported as {currentRefreshRate}" : "OpenXR: no refresh rate given by XR runtime"); float newRate = currentRefreshRate; var availableRates = _xrInterface.GetAvailableDisplayRefreshRates(); if (availableRates.Count == 0) GD.Print("OpenXR: target does not support refresh rate extension"); else if (availableRates.Count == 1) newRate = (float)availableRates[0]; else { foreach (float rate in availableRates) { if (rate > newRate && rate <= MaximumRefreshRate) newRate = rate; } } if (currentRefreshRate != newRate) { GD.Print($"OpenXR: setting refresh rate to {newRate}"); _xrInterface.DisplayRefreshRate = newRate; currentRefreshRate = newRate; } Engine.PhysicsTicksPerSecond = (int)currentRefreshRate; } private void OnSessionVisible() { if (_xrIsFocused) { GD.Print("OpenXR lost focus"); _xrIsFocused = false; GetTree().Paused = true; EmitSignal(SignalName.FocusLost); } } private void OnSessionFocussed() { GD.Print("OpenXR gained focus"); _xrIsFocused = true; GetTree().Paused = false; EmitSignal(SignalName.FocusGained); } private void OnSessionStopping() { GD.Print("OpenXR is stopping"); } private void OnPoseRecentered() { EmitSignal(SignalName.PoseRecentered); } }