public override uint[] GetRenderTargetSize() { uint width = 0; uint height = 0; m_System.GetRecommendedRenderTargetSize(ref width, ref height); return(new[] { width, height }); }
public static Size2 GetRecommendedRenderTargetSize(this CVRSystem system) { uint pnWidth = 0, pnHeight = 0; system.GetRecommendedRenderTargetSize(ref pnWidth, ref pnHeight); return(new Size2((int)pnWidth, (int)pnHeight)); }
public override RenderTarget2D CreateRenderTargetForEye(int eye) { uint width = 0; uint height = 0; _hmd.GetRecommendedRenderTargetSize(ref width, ref height); var renderTarget = new RenderTarget2D(Game.GraphicsDevice, (int)width, (int)height, false, SurfaceFormat.ColorSRgb, DepthFormat.Depth24Stencil8, 2, RenderTargetUsage.PreserveContents); _textures[eye] = new Texture_t(); #if WINDOWS var info = typeof(RenderTarget2D).GetField("_texture", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); var handle = info.GetValue(renderTarget) as SharpDX.Direct3D11.Resource; _textures[eye].handle = handle.NativePointer; _textures[eye].eType = ETextureType.DirectX; #else var info = typeof(RenderTarget2D).GetField("glTexture", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); var glTexture = (int)info.GetValue(renderTarget); _textures[eye].handle = new IntPtr(glTexture); _textures[eye].eType = ETextureType.OpenGL; #endif _textures[eye].eColorSpace = EColorSpace.Auto; _textureBounds[eye].uMin = 0; _textureBounds[eye].uMax = 1; _textureBounds[eye].vMin = 0; _textureBounds[eye].vMax = 1; return(renderTarget); }
/// <summary> /// Internal start call for VR setup. /// </summary> public void Start() { uint w = 0; uint h = 0; VR.GetRecommendedRenderTargetSize(ref w, ref h); if (w <= 0 || h <= 0) { throw new Exception("Failed to start VR: Invalid render target size!"); } w *= 2; TheClient.Engine3D.MainView.Generate(TheClient.Engine3D, (int)w, (int)h); TheClient.Engine3D.MainView.GenerateFBO(); StringBuilder val = new StringBuilder(256); ETrackedPropertyError errx = ETrackedPropertyError.TrackedProp_Success; VR.GetStringTrackedDeviceProperty(OpenVR.k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty.Prop_TrackingSystemName_String, val, 256, ref errx); SysConsole.Output(OutputType.INIT, "Switching to VR mode: " + w + "/" + h + "... " + val.ToString()); VRModel = val.ToString(); Compositor = OpenVR.Compositor; Compositor.SetTrackingSpace(ETrackingUniverseOrigin.TrackingUniverseStanding); Compositor.CompositorBringToFront(); LeftTexture = new VRControllerTextureEngine(); RightTexture = new VRControllerTextureEngine(); LeftTexture.BaseTexture = TheClient.Textures.GetTexture("vr/controller/vive_circle_left"); RightTexture.BaseTexture = TheClient.Textures.GetTexture("vr/controller/vive_circle_right"); LeftTexture.GenerateFirst(); RightTexture.GenerateFirst(); RightControllerModel = TheClient.Models.GetModel("vr/controller/vive"); LeftControllerModel = TheClient.Models.GetModel("vr/controller/vive"); }
public Tuple <int, int> GetRenderTarget() { uint uRenderWidth = 0; uint uRenderHeight = 0; hmd.GetRecommendedRenderTargetSize(ref uRenderWidth, ref uRenderHeight); return(Tuple.Create((int)uRenderWidth, (int)uRenderHeight)); }
internal VRSystem() { if (!OpenVR.IsRuntimeInstalled()) { throw new Exception("VR Runtime not installed"); } if (!OpenVR.IsHmdPresent()) { throw new Exception("HMD not found"); } EVRInitError error = EVRInitError.None; vrContext = OpenVR.Init(ref error); if (error != EVRInitError.None) { Console.WriteLine(error); } compositor = OpenVR.Compositor; RenderModel = OpenVR.GetGenericInterface(OpenVR.IVRRenderModels_Version, ref error); if (RenderModel == IntPtr.Zero) { ; } { Console.WriteLine(error); } controllerSystem = new VRControllerSystem(vrContext); leftTexture = new Texture_t(); leftTexture.eType = ETextureType.OpenGL; leftTexture.eColorSpace = EColorSpace.Gamma; rightTexture = new Texture_t(); rightTexture.eType = ETextureType.OpenGL; rightTexture.eColorSpace = EColorSpace.Gamma; vrContext.GetRecommendedRenderTargetSize(ref height, ref width); bound = new VRTextureBounds_t(); bound.uMin = 0; bound.vMin = 0; bound.vMax = 1; bound.uMax = 1; /* * var errProp = new ETrackedPropertyError(); * var str = new StringBuilder(); * vrContext.GetStringTrackedDeviceProperty(OpenVR.k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty.Prop_TrackingSystemName_String, str, 100, ref errProp); */ }
public VrHandler() { _vrControls = new VrControls(); _vrSystem = OpenVR.System; _vrCompositor = OpenVR.Compositor; _vrSystem.GetRecommendedRenderTargetSize(ref _width, ref _height); _renderPose = new TrackedDevicePose_t[1]; _gamePose = new TrackedDevicePose_t[1]; //var error = default(ETrackedPropertyError); //var displayFrequency = _vrSystem.GetFloatTrackedDeviceProperty(0, ETrackedDeviceProperty.Prop_DisplayFrequency_Float, ref error); //Check(error); //_frameDuration = 1.0f / displayFrequency; //_vsyncToPhotons = _vrSystem.GetFloatTrackedDeviceProperty(0, ETrackedDeviceProperty.Prop_SecondsFromVsyncToPhotons_Float, ref error); //Check(error); }
//Called when mod is loading public override void OnLoad() { ModConsole.Print("Initializing OpenVR"); if (!OpenVRInit()) { return; } mainCamera = Camera.main; /*ModConsole.Print(mainCamera.cullingMask); * mainCamera.cullingMask = ~mainCamera.cullingMask; * * mainCamera.enabled = false;*/ ModConsole.Print(SystemInfo.graphicsDeviceVersion); System.Diagnostics.Trace.WriteLine("Initializing our own D3D11 device"); d3d11Device = new SharpDX.Direct3D11.Device(SharpDX.Direct3D.DriverType.Hardware, SharpDX.Direct3D11.DeviceCreationFlags.Debug); hook = new D3D11Hook(); hook.Create(); System.Diagnostics.Trace.WriteLine("Getting RenderTarget Size"); uint w = 0, h = 0; vrSystem.GetRecommendedRenderTargetSize(ref w, ref h); vrRig = new VRRig((int)w, (int)h); System.Diagnostics.Trace.WriteLine("Fetching Unity D3D11 Device"); var devChild = vrRig.leftTexture.QueryInterface <SharpDX.Direct3D11.DeviceChild>(); unityRenderer = devChild.Device; devChild.Dispose(); ModConsole.Print(unityRenderer.CreationFlags & SharpDX.Direct3D11.DeviceCreationFlags.SingleThreaded); vrRenderer = new VRRenderer(d3d11Device, unityRenderer, vrRig); hook.OnRender += HookRender; System.Diagnostics.Trace.WriteLine("All done"); ModConsole.Print("MSCVR initialized"); }
public override void Initialize(GraphicsDevice gd) { _gd = gd; StringBuilder sb = new StringBuilder(512); ETrackedPropertyError error = ETrackedPropertyError.TrackedProp_Success; uint ret = _vrSystem.GetStringTrackedDeviceProperty( OVR.k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty.Prop_TrackingSystemName_String, sb, 512u, ref error); if (error != ETrackedPropertyError.TrackedProp_Success) { _deviceName = "<Unknown OpenVR Device>"; } else { _deviceName = sb.ToString(); } uint eyeWidth = 0; uint eyeHeight = 0; _vrSystem.GetRecommendedRenderTargetSize(ref eyeWidth, ref eyeHeight); _leftEyeFB = CreateFramebuffer(eyeWidth, eyeHeight); _rightEyeFB = CreateFramebuffer(eyeWidth, eyeHeight); Matrix4x4 eyeToHeadLeft = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left)); Matrix4x4.Invert(eyeToHeadLeft, out _headToEyeLeft); Matrix4x4 eyeToHeadRight = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right)); Matrix4x4.Invert(eyeToHeadRight, out _headToEyeRight); _projLeft = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Left, 0.1f, 1000f)); _projRight = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Right, 0.1f, 1000f)); }
public void Start() { uint w = 0; uint h = 0; VR.GetRecommendedRenderTargetSize(ref w, ref h); if (w <= 0 || h <= 0) { throw new Exception("Failed to start VR: Invalid render target size!"); } w *= 2; TheClient.MainWorldView.Generate(TheClient, (int)w, (int)h); TheClient.MainWorldView.GenerateFBO(); SysConsole.Output(OutputType.INFO, "Switching to VR mode: " + w + "/" + h); Compositor = OpenVR.Compositor; Compositor.SetTrackingSpace(ETrackingUniverseOrigin.TrackingUniverseStanding); Compositor.CompositorBringToFront(); LeftTexture = new VRControllerTextureEngine(); RightTexture = new VRControllerTextureEngine(); LeftTexture.BaseTexture = TheClient.Textures.GetTexture("vr/controller/vive_circle_left"); RightTexture.BaseTexture = TheClient.Textures.GetTexture("vr/controller/vive_circle_right"); LeftTexture.GenerateFirst(); RightTexture.GenerateFirst(); }
void Update() { //increase prediction if (Input.GetKeyDown(KeyCode.KeypadPlus)) { predict += 0.01f; log("predict interval set to: " + predict); } //decrease prediction if (Input.GetKeyDown(KeyCode.KeypadMinus)) { predict -= 0.01f; log("predict interval set to: " + predict); } //If Hmd is initialised and key is pressed -> reset position if (Input.GetKeyDown(KeyCode.Keypad0) && HmdOn) { vrSystem.ResetSeatedZeroPose(); log("Seated pose reset!"); } //If Hmd is not initialised and key is pressed -> initialise everything if (Input.GetKeyDown(KeyCode.Keypad0) && !HmdOn) { //get Active Vessel activeVessel = FlightGlobals.ActiveVessel; HmdOn = true; //setup OpenVR setup(); uint renderTextureWidth = 0; uint renderTextureHeight = 0; vrSystem.GetRecommendedRenderTargetSize(ref renderTextureWidth, ref renderTextureHeight); HmdMatrix34_t vrLeftEyeTransform = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left); HmdMatrix34_t vrRightEyeTransform = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right); //eyeDiference = (int)(Camera.main.WorldToScreenPoint(new Utils.RigidTransform(vrLeftEyeTransform).pos) - Camera.main.WorldToScreenPoint(new Utils.RigidTransform(vrRightEyeTransform).pos)).magnitude; // skyTexture = new RenderTexture((int)(renderTextureWidth + eyeDiference), (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32); // skyTexture.Create(); hmdLeftEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32); hmdLeftEyeRenderTexture.Create(); hmdRightEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32); hmdRightEyeRenderTexture.Create(); setupCameras(); //add on vesselchange callback GameEvents.onVesselChange.Add(onVesselChange); } if (HmdOn) { if (!CameraManager.Instance.currentCameraMode.Equals(activeCameraMode)) { if (CameraManager.Instance.currentCameraMode.Equals(CameraManager.CameraMode.Flight) || CameraManager.Instance.currentCameraMode.Equals(CameraManager.CameraMode.External)) { // Camera.main.enabled = true; setRenderTexturesTo(null, null); O_SclaledSpace.enabled = true; O_Galaxy.enabled = true; O_Near.enabled = true; O_Far.enabled = true; //O_Interior.enabled = false; } else { setRenderTexturesTo(null, null); O_SclaledSpace.enabled = false; O_Galaxy.enabled = false; O_Near.enabled = false; O_Far.enabled = false; O_Interior.enabled = false; } } if (CameraManager.Instance.currentCameraMode.Equals(CameraManager.CameraMode.IVA)) { leftStars.Render(); leftSky.Render(); camLeft_Far.Render(); camLeft_Near.Render(); camLeft_Interior.Render(); rightStars.Render(); rightSky.Render(); camRight_Far.Render(); camRight_Near.Render(); camRight_Interior.Render(); } //if someone knows how to fix the other cameras corectly please tell me! else if (CameraManager.Instance.currentCameraMode.Equals(CameraManager.CameraMode.Map)) { O_Galaxy.Render(); O_SclaledSpace.Render(); } else { O_Galaxy.Render(); O_SclaledSpace.Render(); O_Far.Render(); O_Near.Render(); } } }
private SteamVR(System.IntPtr pHmd, System.IntPtr pCompositor, System.IntPtr pOverlay) { hmd = new CVRSystem(pHmd); Debug.Log("Connected to " + hmd_TrackingSystemName + ":" + hmd_SerialNumber); compositor = new CVRCompositor(pCompositor); overlay = new CVROverlay(pOverlay); // Setup render values uint w = 0, h = 0; hmd.GetRecommendedRenderTargetSize(ref w, ref h); sceneWidth = (float)w; sceneHeight = (float)h; 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); tanHalfFov = new Vector2( Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -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; Unity.SetSubmitParams(textureBounds[0], textureBounds[1], EVRSubmitFlags.Submit_Default); // Grow the recommended size to account for the overlapping fov sceneWidth = sceneWidth / Mathf.Max(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); sceneHeight = sceneHeight / Mathf.Max(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); aspect = tanHalfFov.x / tanHalfFov.y; fieldOfView = 2.0f * Mathf.Atan(tanHalfFov.y) * Mathf.Rad2Deg; eyes = new SteamVR_Utils.RigidTransform[] { new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(EVREye.Eye_Left)), new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(EVREye.Eye_Right)) }; if (SystemInfo.graphicsDeviceVersion.StartsWith("OpenGL")) { graphicsAPI = EGraphicsAPIConvention.API_OpenGL; } else { graphicsAPI = EGraphicsAPIConvention.API_DirectX; } SteamVR_Utils.Event.Listen("initializing", OnInitializing); SteamVR_Utils.Event.Listen("calibrating", OnCalibrating); SteamVR_Utils.Event.Listen("out_of_range", OnOutOfRange); SteamVR_Utils.Event.Listen("device_connected", OnDeviceConnected); SteamVR_Utils.Event.Listen("new_poses", OnNewPoses); }
/// <summary> /// Initialize HMD using OpenVR API calls. /// </summary> /// <returns>True on success, false otherwise. Errors logged.</returns> bool InitHMD() { bool retVal = false; // return if HMD has already been initialized if (hmdIsInitialized) { return(true); } bool is64bit = (IntPtr.Size == 8); string mypath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); log("OpenVR path set to " + Path.Combine(mypath, is64bit ? "win64" : "win32")); SetDllDirectory(Path.Combine(mypath, is64bit ? "win64" : "win32")); // check if HMD is connected on the system retVal = OpenVR.IsHmdPresent(); if (!retVal) { err("HMD not found on this system."); return(retVal); } // check if SteamVR runtime is installed. // For this plugin, MAKE SURE IT IS ALREADY RUNNING. retVal = OpenVR.IsRuntimeInstalled(); if (!retVal) { err("SteamVR runtime not found on this system."); return(retVal); } // initialize HMD EVRInitError hmdInitErrorCode = EVRInitError.None; vrSystem = OpenVR.Init(ref hmdInitErrorCode, EVRApplicationType.VRApplication_Scene); // return if failure retVal = (hmdInitErrorCode == EVRInitError.None); if (!retVal) { err("Failed to initialize HMD. Init returned: " + OpenVR.GetStringForHmdError(hmdInitErrorCode)); return(retVal); } else { log("OpenVR.Init passed."); } // reset "seated position" and capture initial position. this means you should hold the HMD in // the position you would like to consider "seated", before running this code. ResetInitialHmdPosition(); // initialize Compositor vrCompositor = OpenVR.Compositor; // initialize render textures (for displaying on HMD) uint renderTextureWidth = 0; uint renderTextureHeight = 0; vrSystem.GetRecommendedRenderTargetSize(ref renderTextureWidth, ref renderTextureHeight); //renderTextureWidth /= 2; //renderTextureHeight /= 2; log("Render Texture size: " + renderTextureWidth + " x " + renderTextureHeight); hmdLeftEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32); hmdLeftEyeRenderTexture.Create(); hmdRightEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32); hmdRightEyeRenderTexture.Create(); hmdLeftEyeTexture.handle = hmdLeftEyeRenderTexture.GetNativeTexturePtr(); hmdLeftEyeTexture.eColorSpace = EColorSpace.Auto; hmdRightEyeTexture.handle = hmdRightEyeRenderTexture.GetNativeTexturePtr(); hmdRightEyeTexture.eColorSpace = EColorSpace.Auto; switch (SystemInfo.graphicsDeviceType) { case UnityEngine.Rendering.GraphicsDeviceType.OpenGL2: case UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore: case UnityEngine.Rendering.GraphicsDeviceType.OpenGLES2: case UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3: hmdLeftEyeTexture.eType = EGraphicsAPIConvention.API_OpenGL; hmdRightEyeTexture.eType = EGraphicsAPIConvention.API_OpenGL; break; //doesnt work in unity 5.4 with current SteamVR (12/2016) case UnityEngine.Rendering.GraphicsDeviceType.Direct3D9: throw (new Exception("DirectX9 not supported")); case UnityEngine.Rendering.GraphicsDeviceType.Direct3D11: hmdLeftEyeTexture.eType = EGraphicsAPIConvention.API_DirectX; hmdRightEyeTexture.eType = EGraphicsAPIConvention.API_DirectX; break; default: throw (new Exception(SystemInfo.graphicsDeviceType.ToString() + " not supported")); } // Set rendering bounds on texture to render? // I assume min=0.0 and max=1.0 renders to the full extent of the texture hmdTextureBounds.uMin = 0.0f; hmdTextureBounds.uMax = 1.0f; hmdTextureBounds.vMin = 0.0f; hmdTextureBounds.vMax = 1.0f; // TODO: Need to understand better how to create render targets and incorporate hidden area mask mesh foreach (Camera camera in Camera.allCameras) { log("KSP Camera: " + camera.name); } // search for camera objects to render foreach (string cameraName in cameraNamesToRender) { foreach (Camera camera in Camera.allCameras) { if (cameraName.Equals(camera.name)) { float nearClipPlane = (camera.name.Equals(cameraNames[3])) ? 0.05f : camera.nearClipPlane; HmdMatrix44_t projLeft = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, nearClipPlane, camera.farClipPlane, EGraphicsAPIConvention.API_OpenGL); HmdMatrix44_t projRight = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, nearClipPlane, camera.farClipPlane, EGraphicsAPIConvention.API_OpenGL); //HmdMatrix44_t projLeft = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, nearClipPlane, camera.farClipPlane, EGraphicsAPIConvention.API_DirectX); // this doesn't seem to work //HmdMatrix44_t projRight = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, nearClipPlane, camera.farClipPlane, EGraphicsAPIConvention.API_DirectX); // this doesn't seem to work camerasToRender.Add(new CameraProperties(camera, camera.projectionMatrix, MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft), MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight))); break; } } } // detect controllers for (uint idx = 0; idx < OpenVR.k_unMaxTrackedDeviceCount; idx++) { if ((ctrlIndexLeft == 0) && (vrSystem.GetTrackedDeviceClass(idx) == ETrackedDeviceClass.Controller)) { ctrlIndexLeft = idx; } else if ((ctrlIndexRight == 0) && (vrSystem.GetTrackedDeviceClass(idx) == ETrackedDeviceClass.Controller)) { ctrlIndexRight = idx; } } bool ctrlFocusCaptured = vrSystem.CaptureInputFocus(); if (!ctrlFocusCaptured) { warn("Controller input focus was not captured"); } initTmr.Start(); return(retVal); }
public MyOpenVR() { if (true) { m_viewHMD = Matrix.Identity; m_headsetPosD = MatrixD.Identity; m_c1pos = Matrix.Identity; m_c2pos = Matrix.Identity; //IntPtr Handle = MyRender11.LoadLibrary(@"D:\KeenSWH.VR\Sandbox\Sources\SpaceEngineers\bin\x64\Debug\Bin64\openvr_api.dll"); //IntPtr Handle = LoadLibrary(@"C:\Program Files (x86)\Steam\SteamApps\common\SteamVR\bin\win64\openvr_api.dll"); IntPtr Handle = LoadLibrary(@"openvr_api.dll"); //IntPtr Handle = MyRender11.LoadLibrary(@"c:\Program Files (x86)\Steam\bin\openvr_api.dll");//err code 193 - not a valid Win32 application //Assembly.LoadFile(@"D:\KeenSWH\Sandbox\Sources\SpaceEngineers\bin\x64\Debug\Bin64\openvr_api.dll"); if (Handle == IntPtr.Zero) { int errorCode = Marshal.GetLastWin32Error(); throw new Exception(string.Format("Failed to load library (ErrorCode: {0})", errorCode)); } EVRInitError error = EVRInitError.None; IntPtr ptr = OpenVR.Init(ref error, EVRApplicationType.VRApplication_Scene); if (error == EVRInitError.None) { m_vrSystem = new CVRSystem(ptr); uint sizeX = 0, sizeY = 0; m_vrSystem.GetRecommendedRenderTargetSize(ref sizeX, ref sizeY); m_vrSystem.SetDisplayVisibility(true); ETrackedPropertyError pError = 0; m_ipd_2 = 0.5f * m_vrSystem.GetFloatTrackedDeviceProperty(0, ETrackedDeviceProperty.Prop_UserIpdMeters_Float, ref pError); SetIPD(m_ipd_2 * 2); IntPtr pointer = OpenVR.GetGenericInterface(OpenVR.IVRCompositor_Version, ref error); if (error == EVRInitError.None) { m_vrCompositor = new CVRCompositor(pointer); m_vrCompositor.CompositorBringToFront(); m_vrCompositor.ShowMirrorWindow(); m_openVR = this; } else { var errString = OpenVR.GetStringForHmdError(error); Log.WriteLineAndConsole(errString); Debug.Fail("No compositor interface"); throw new Exception(errString); } } else { var errString = OpenVR.GetStringForHmdError(error); Log.WriteLineAndConsole(errString); //Debug.Fail("OpenVR init failed"); throw new Exception(errString); } InitOverlays(); } }
protected override void Render() { EnsureDllsLoaded(); Lock = true; EVRInitError initError = EVRInitError.None; Valve.VR.OpenVR.Init(ref initError); if (initError != EVRInitError.None) { throw new Exception("OpenVR init error " + initError + ": " + Valve.VR.OpenVR.GetStringForHmdError(initError)); } CVRSystem hmd = Valve.VR.OpenVR.System; CVRCompositor compositor = Valve.VR.OpenVR.Compositor; uint targetWidth = 0, targetHeight = 0; hmd.GetRecommendedRenderTargetSize(ref targetWidth, ref targetHeight); float sceneWidth = (float)targetWidth; float sceneHeight = (float)targetHeight; 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); Vector2 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)) ); VRTextureBounds_t[] 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; float aspect = tanHalfFov.X / tanHalfFov.Y; float lookFov = (float)(2.0f * Math.Atan(tanHalfFov.Y) * 180 / Math.PI); Texture2DDescription eyeTextureDescription = new Texture2DDescription() { Format = Format.R8G8B8A8_UNorm_SRgb, ArraySize = 1, MipLevels = 1, Width = (int)targetWidth, Height = (int)targetHeight, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; Texture2DDescription eyeDepthTextureDescription = new Texture2DDescription() { Format = Format.D32_Float_S8X24_UInt, ArraySize = 1, MipLevels = 1, Width = (int)targetWidth, Height = (int)targetHeight, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; ///// CUBE //var cubeEffect = new SharpDX.Toolkit.Graphics.BasicEffect(_gd) //{ // //PreferPerPixelLighting = false, // //TextureEnabled = false, // LightingEnabled = true, // //DiffuseColor = new Vector4(0.5f,0.5f,0.5f,1f), // Sampler = _gd.SamplerStates.AnisotropicClamp //}; //cubeEffect.EnableDefaultLighting(); //var cube = SharpDX.Toolkit.Graphics.GeometricPrimitive.Teapot.New(_gd, 1, 8, false); ///// END using (_device = new Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport, new FeatureLevel[] { FeatureLevel.Level_10_0 })) using (DeviceContext context = _device.ImmediateContext) using (_gd = SharpDX.Toolkit.Graphics.GraphicsDevice.New(_device)) //using (SharpDX.Toolkit.Graphics.GeometricPrimitive primitive = GraphicTools.CreateGeometry(_projection, _gd, false)) using (customEffectL = GetCustomEffect(_gd)) using (customEffectR = GetCustomEffect(_gd)) using (Texture2D leftEye = new Texture2D(_device, eyeTextureDescription)) using (RenderTargetView leftEyeView = new RenderTargetView(_device, leftEye)) using (Texture2D leftEyeDepth = new Texture2D(_device, eyeDepthTextureDescription)) using (DepthStencilView leftEyeDepthView = new DepthStencilView(_device, leftEyeDepth)) using (Texture2D rightEye = new Texture2D(_device, eyeTextureDescription)) using (RenderTargetView rightEyeView = new RenderTargetView(_device, rightEye)) using (Texture2D rightEyeDepth = new Texture2D(_device, eyeDepthTextureDescription)) using (DepthStencilView rightEyeDepthView = new DepthStencilView(_device, rightEyeDepth)) using (vrui = new VRUI(_device, _gd)) { //primitive = GraphicTools.CreateGeometry(Projection, _gd, false); Stopwatch stopwatch = new Stopwatch(); Texture_t leftEyeTex = new Texture_t() { eColorSpace = EColorSpace.Gamma, eType = EGraphicsAPIConvention.API_DirectX, handle = leftEye.NativePointer }; Texture_t rightEyeTex = new Texture_t() { eColorSpace = EColorSpace.Gamma, eType = EGraphicsAPIConvention.API_DirectX, handle = rightEye.NativePointer }; TrackedDevicePose_t[] renderPoseArray = new TrackedDevicePose_t[16]; TrackedDevicePose_t[] gamePoseArray = new TrackedDevicePose_t[16]; TrackedDevicePose_t pose = new TrackedDevicePose_t(); try { // Start with default background SetDefaultScene(); while (!abort) { UpdateContentIfRequested(); float deltaTime = (float)stopwatch.Elapsed.TotalSeconds; stopwatch.Restart(); compositor.WaitGetPoses(renderPoseArray, gamePoseArray); if (renderPoseArray[Valve.VR.OpenVR.k_unTrackedDeviceIndex_Hmd].bPoseIsValid) { pose = gamePoseArray[Valve.VR.OpenVR.k_unTrackedDeviceIndex_Hmd]; } foreach (EVREye eye in new EVREye[] { EVREye.Eye_Left, EVREye.Eye_Right }) { DepthStencilView currentEyeDepthView = (eye == EVREye.Eye_Left) ? leftEyeDepthView : rightEyeDepthView; RenderTargetView currentEyeView = (eye == EVREye.Eye_Left) ? leftEyeView : rightEyeView; // Setup targets and viewport for rendering context.OutputMerger.SetTargets(currentEyeDepthView, currentEyeView); context.ClearDepthStencilView(currentEyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); context.ClearRenderTargetView(currentEyeView, Color.Black); context.Rasterizer.SetViewport(new Viewport(0, 0, (int)targetWidth, (int)targetHeight, 0.0f, 1.0f)); Quaternion lookRotation; // = pose.mDeviceToAbsoluteTracking.GetRotation(); Vector3 lookPosition; // = pose.mDeviceToAbsoluteTracking.GetPosition(); Vector3 scale; Matrix eyePose = hmd.GetEyeToHeadTransform(eye).RebuildTRSMatrix() * pose.mDeviceToAbsoluteTracking.RebuildTRSMatrix(); eyePose.Decompose(out scale, out lookRotation, out lookPosition); Matrix rotationMatrix = Matrix.RotationQuaternion(lookRotation); Vector3 lookUp = Vector3.Transform(Vector3.Up, rotationMatrix).ToVector3(); Vector3 lookAt = Vector3.Transform(Vector3.ForwardRH, rotationMatrix).ToVector3(); //Console.WriteLine($"OpenVR {eye} up: {lookUp:00.00} at: {lookAt:00.00} position:{lookPosition:00.00}"); Matrix viewMatrix = Matrix.LookAtRH(lookPosition, lookPosition + lookAt, lookUp); Matrix pm1 = Matrix.PerspectiveFovLH(lookFov * ((float)Math.PI / 180f), aspect, 0.001f, 100.0f); //Matrix pm2 = hmd.GetProjectionMatrix(eye, 0.001f, 100f, EGraphicsAPIConvention.API_DirectX).ToProjMatrix(); Matrix projectionMatrix = pm1; Matrix worldMatrix = Matrix.Translation(lookPosition); if (Logic.Instance.settings.OpenVRReverse) { worldMatrix = Matrix.RotationY(180) * worldMatrix; } Matrix MVP = worldMatrix * viewMatrix * projectionMatrix; customEffectL.Parameters["WorldViewProj"].SetValue(MVP); customEffectR.Parameters["WorldViewProj"].SetValue(MVP); lock (localCritical) { if (eye == EVREye.Eye_Left) { primitive?.Draw(customEffectL); } if (eye == EVREye.Eye_Right) { primitive?.Draw(customEffectR); } } if (eye == EVREye.Eye_Left) { Vector3 fixedLookPosition = Vector3.Transform(lookPosition, MVP).ToVector3(); Vector3 fixedLookAt = Vector3.Transform(lookPosition + Vector3.ForwardLH, MVP).ToVector3() - fixedLookPosition; Vector3 fixedLookUp = Vector3.Transform(lookPosition + Vector3.Up, MVP).ToVector3() - fixedLookPosition; fixedLookAt.Normalize(); fixedLookUp.Normalize(); Quaternion fixedLookRotation = Quaternion.LookAtRH(Vector3.Zero, fixedLookAt, fixedLookUp); //fixedLookRotation.X *= -1; //fixedLookRotation.Y *= -1; fixedLookRotation.Z *= -1; //if(eye == EVREye.Eye_Left) // fixedLookRotation.Invert(); //Mirror effect of rotation along z axis by flipping x and y elements of the quaternion. //http://stackoverflow.com/a/32482386/785171 //float t = fixedLookRotation.X; //fixedLookRotation.X = fixedLookRotation.Y; //fixedLookRotation.Y = t; //fixedLookRotation = new Quaternion(1, 0, 0, 0) * fixedLookRotation; //fixedLookRotation = new Quaternion(0, 0, 1, 0) * fixedLookRotation; LoggerManager.Publish("openvr.forward", fixedLookAt); LoggerManager.Publish("openvr.up", fixedLookUp); // TODO: normalize ProvideLook?.Invoke(fixedLookPosition, fixedLookRotation, lookFov); } // reset UI position every frame if it is not visible if (vrui.isUIHidden) { vrui.SetWorldPosition(viewMatrix.Forward, lookPosition, false); } vrui.Draw(Media, currentTime, Duration); vrui.Render(deltaTime, viewMatrix, projectionMatrix, lookPosition, ShouldShowVRUI); //// controllers: //cubeEffect.View = viewMatrix; //cubeEffect.Projection = projectionMatrix; //for (uint controller = 1 /*skip hmd*/; controller < Valve.VR.OpenVR.k_unMaxTrackedDeviceCount; controller++) //{ // VRControllerState_t controllerState = default(VRControllerState_t); // //var controllerPose = renderPoseArray[controller]; // //if (hmd.GetControllerState(controller, ref controllerState)) { // Vector3 pos = renderPoseArray[controller].mDeviceToAbsoluteTracking.GetPosition(); // Quaternion rot = renderPoseArray[controller].mDeviceToAbsoluteTracking.GetRotation(); // rot = rot * new Quaternion(0, 1, 0, 0); // float s = controllerState.ulButtonPressed > 0 ? 0.5f : 0.1f; // cubeEffect.World = Matrix.Scaling(s) * Matrix.RotationQuaternion(rot) * Matrix.Translation(pos); // cube.Draw(cubeEffect); // //} //} } // RENDER TO HMD EVRCompositorError errorLeft = compositor.Submit( EVREye.Eye_Left, ref leftEyeTex, ref textureBounds[0], EVRSubmitFlags.Submit_Default ); EVRCompositorError errorRight = compositor.Submit( EVREye.Eye_Right, ref rightEyeTex, ref textureBounds[1], EVRSubmitFlags.Submit_Default ); if (errorLeft != EVRCompositorError.None) { throw new HeadsetError("VR Compositor failure (left): " + errorLeft); } if (errorRight != EVRCompositorError.None) { throw new HeadsetError("VR Compositor failure (right): " + errorRight); } } ; } finally { Valve.VR.OpenVR.Shutdown(); primitive?.Dispose(); context.ClearState(); context.Flush(); } } }
/*void LateUpdate() * { * if (HmdOn) * { * foreach (int id in leftCameras) * { * * //Left camera position:########################################################## * Camera.allCameras[id].transform.localRotation = hmdTransform.rot; * * // translate the camera to match the position of the left eye, from origin * Camera.allCameras[id].transform.localPosition = new Vector3(0f, 0f, 0f); * Camera.allCameras[id].transform.Translate(hmdLeftEyeTransform.pos); * * // translate the camera to match the position of the HMD * Camera.allCameras[id].transform.localPosition += hmdTransform.pos; * * } * } * }*/ void Update() { if (Input.GetKeyDown(KeyCode.KeypadPlus)) { predict += 0.01f; log("predict interval set to: " + predict); } if (Input.GetKeyDown(KeyCode.KeypadMinus)) { predict -= 0.01f; log("predict interval set to: " + predict); } /* if (Input.GetKeyDown(KeyCode.Keypad5)) * { * log("cameras:"); * foreach (Camera c in Camera.allCameras) * { * log(" " + c.name); * } * }*/ if (Input.GetKeyDown(KeyCode.Keypad0) && HmdOn) { vrSystem.ResetSeatedZeroPose(); log("Seated pose reset!"); } if (Input.GetKeyDown(KeyCode.KeypadMultiply)) { camLeft_Near.cullingMask = camLeft_Near.cullingMask << 1; camRight_Near.cullingMask = camLeft_Near.cullingMask; log(Convert.ToString(camLeft_Near.cullingMask, 2)); if (camLeft_Near.cullingMask == 0) { camLeft_Near.cullingMask = 1; camRight_Near.cullingMask = 1; } } if (Input.GetKeyDown(KeyCode.KeypadDivide)) { camLeft_Near.cullingMask = camLeft_Near.cullingMask >> 1; camRight_Near.cullingMask = camLeft_Near.cullingMask; log(Convert.ToString(camLeft_Near.cullingMask, 2)); if (camLeft_Near.cullingMask == 0) { camLeft_Near.cullingMask = 1; camRight_Near.cullingMask = 1; } } if (Input.GetKeyDown(KeyCode.Keypad2)) { log(" ScaledSpace rot = " + ScaledSpace.Instance.transform.rotation.eulerAngles.ToString()); log(" GalaxyCubeControl rot = " + GalaxyCubeControl.Instance.transform.rotation.eulerAngles.ToString()); log("GalaxyCubeControl tgt rot = " + GalaxyCubeControl.Instance.tgt.transform.rotation.eulerAngles.ToString()); log(" GalaxyCameraControl rot = " + GalaxyCameraControl.Instance.transform.rotation.eulerAngles.ToString()); log(" ScaledCamera rot = " + ScaledCamera.Instance.transform.rotation.eulerAngles.ToString()); } if (HmdOn) { if (Input.GetKeyDown(KeyCode.Keypad1)) { log("L:" + Convert.ToString(camLeft_Near.cullingMask, 2)); log("R:" + Convert.ToString(camRight_Near.cullingMask, 2)); } int tmp = 0; if (Input.GetKey(KeyCode.LeftShift)) { tmp = 10; } else if (Input.GetKey(KeyCode.RightShift)) { tmp = 20; } else if (Input.GetKey(KeyCode.RightControl)) { tmp = 30; } if (Input.GetKeyDown(KeyCode.Alpha0)) { camLeft_Near.cullingMask ^= (1 << 0 + tmp); } if (Input.GetKeyDown(KeyCode.Alpha1)) { camLeft_Near.cullingMask ^= (1 << 1 + tmp); } if (Input.GetKeyDown(KeyCode.Alpha2)) { camLeft_Near.cullingMask ^= (1 << 2 + tmp); } if (Input.GetKeyDown(KeyCode.Alpha3)) { camLeft_Near.cullingMask ^= (1 << 3 + tmp); } if (Input.GetKeyDown(KeyCode.Alpha4)) { camLeft_Near.cullingMask ^= (1 << 4 + tmp); } if (Input.GetKeyDown(KeyCode.Alpha5)) { camLeft_Near.cullingMask ^= (1 << 5 + tmp); } if (Input.GetKeyDown(KeyCode.Alpha6)) { camLeft_Near.cullingMask ^= (1 << 6 + tmp); } if (Input.GetKeyDown(KeyCode.Alpha7)) { camLeft_Near.cullingMask ^= (1 << 7 + tmp); } if (Input.GetKeyDown(KeyCode.Alpha8)) { camLeft_Near.cullingMask ^= (1 << 8 + tmp); } if (Input.GetKeyDown(KeyCode.Alpha9)) { camLeft_Near.cullingMask ^= (1 << 9 + tmp); } camRight_Near.cullingMask = camLeft_Near.cullingMask; if (Input.GetKeyDown(KeyCode.Keypad7)) { if (camRight_Near.transparencySortMode == TransparencySortMode.Default) { camRight_Near.transparencySortMode = TransparencySortMode.Orthographic; camLeft_Near.transparencySortMode = TransparencySortMode.Orthographic; } if (camRight_Near.transparencySortMode == TransparencySortMode.Orthographic) { camRight_Near.transparencySortMode = TransparencySortMode.Perspective; camLeft_Near.transparencySortMode = TransparencySortMode.Perspective; } if (camRight_Near.transparencySortMode == TransparencySortMode.Perspective) { camRight_Near.transparencySortMode = TransparencySortMode.Default; camLeft_Near.transparencySortMode = TransparencySortMode.Default; } } if (Input.GetKeyDown(KeyCode.Keypad8)) { if (camRight_Near.opaqueSortMode == UnityEngine.Rendering.OpaqueSortMode.Default) { camRight_Near.opaqueSortMode = UnityEngine.Rendering.OpaqueSortMode.FrontToBack; camLeft_Near.opaqueSortMode = UnityEngine.Rendering.OpaqueSortMode.FrontToBack; } if (camRight_Near.opaqueSortMode == UnityEngine.Rendering.OpaqueSortMode.FrontToBack) { camRight_Near.opaqueSortMode = UnityEngine.Rendering.OpaqueSortMode.NoDistanceSort; camLeft_Near.opaqueSortMode = UnityEngine.Rendering.OpaqueSortMode.NoDistanceSort; } if (camRight_Near.opaqueSortMode == UnityEngine.Rendering.OpaqueSortMode.NoDistanceSort) { camRight_Near.opaqueSortMode = UnityEngine.Rendering.OpaqueSortMode.Default; camLeft_Near.opaqueSortMode = UnityEngine.Rendering.OpaqueSortMode.Default; } } } if (Input.GetKeyDown(KeyCode.Keypad0) && !HmdOn) { activeVessel = FlightGlobals.ActiveVessel; var goArray = FindObjectsOfType <GameObject>(); /*GameObject tmp = new GameObject(); * tmp.transform.position = activeVessel.transform.position; * tmp.transform.SetParent(activeVessel.transform); * for (var i = 0; i < goArray.Length; i++) * { * if (goArray[i].layer == 16 | goArray[i].layer == 20) * { * log(goArray[i].name); * //Vector3 tmp = goArray[i].transform.position; * * * goArray[i].transform.SetParent(tmp.transform); * interiorModelList.Add(goArray[i]); * } * } * tmp.transform.rotation = activeVessel.transform.rotation; */ HmdOn = true; log("TEST!!!!!!!!!!!!!!!!!!"); log(ScaledSpace.Instance.transform.rotation.eulerAngles.ToString()); //setup OpenVR setup(); int mask = 0; Camera pit = Camera.main; uint renderTextureWidth = 0; uint renderTextureHeight = 0; vrSystem.GetRecommendedRenderTargetSize(ref renderTextureWidth, ref renderTextureHeight); HmdMatrix34_t vrLeftEyeTransform = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left); HmdMatrix34_t vrRightEyeTransform = vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right); int widthDiference = (int)(Camera.main.WorldToScreenPoint(new Utils.RigidTransform(vrLeftEyeTransform).pos) - Camera.main.WorldToScreenPoint(new Utils.RigidTransform(vrRightEyeTransform).pos)).magnitude; widthDiference = 100; //TODO calculate corectly skyTexture = new RenderTexture((int)(renderTextureWidth + widthDiference), (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32); skyTexture.Create(); hmdLeftEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32); hmdLeftEyeRenderTexture.Create(); hmdRightEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32); hmdRightEyeRenderTexture.Create(); float max = 0; float[] distances = new float[32]; foreach (string cameraName in cameraNamesToRender) { foreach (Camera camera in Camera.allCameras) { if (cameraName.Equals(camera.name)) { switch (camera.name) { case "GalaxyCamera": O_Galaxy = camera; break; case "Camera ScaledSpace": O_SclaledSpace = camera; break; case "Camera 01": O_Far = camera; break; case "Camera 00": O_Near = camera; break; default: break; } mask |= camera.cullingMask; max = Math.Max(camera.farClipPlane, max); string bitMask = Convert.ToString(camera.cullingMask, 2); for (int i = 0; i < distances.Length; i++) { distances[i] = Math.Max(distances[i], Math.Max(camera.layerCullDistances[i], camera.farClipPlane)); } camera.gameObject.AddOrGetComponent <posTracker>(); log("Camera:"); log(" Name: " + camera.name); log(" mask: " + Convert.ToString(camera.cullingMask, 2)); log(" depth: " + camera.depth); log(""); if (cameraName.Equals("InternalCamera")) { pit = camera; camLeft_Near = camera; //camRight = camera; leftCameras.Add(camera); O_Interior = camera; } if (cameraName.Equals("GalaxyCamera")) { O_Galaxy = camera; } if (cameraName.Equals("Camera ScaledSpace")) { // sky = camera; O_SclaledSpace = camera; log("sky cam rot = " + camera.transform.rotation.eulerAngles.ToString()); } } } } // camRight_Interior = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation); // camLeft_Interior = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation); camRight_Near = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation); camLeft_Near = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation); camRight_Far = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation); camLeft_Far = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation); leftSky = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation); rightSky = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation); leftStars = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation); rightStars = (Camera)Camera.Instantiate(Camera.main, Camera.main.transform.position + new Vector3(0, 0, 0), Camera.main.transform.rotation); leftSky.CopyFrom(O_SclaledSpace); rightSky.CopyFrom(O_SclaledSpace); leftSky.transform.SetParent(activeVessel.transform); rightSky.transform.SetParent(activeVessel.transform); leftStars.CopyFrom(O_Galaxy); rightStars.CopyFrom(O_Galaxy); leftStars.transform.SetParent(activeVessel.transform); rightStars.transform.SetParent(activeVessel.transform); camRight_Near.CopyFrom(O_Near); camLeft_Near.CopyFrom(O_Near); camRight_Near.transform.SetParent(activeVessel.transform); camLeft_Near.transform.SetParent(activeVessel.transform); // camLeft_Interior.CopyFrom(O_Interior); // camRight_Interior.CopyFrom(O_Interior); // camLeft_Interior.transform.SetParent(activeVessel.transform); // camRight_Interior.transform.SetParent(activeVessel.transform); camRight_Far.CopyFrom(O_Far); camLeft_Far.CopyFrom(O_Far); camRight_Far.transform.SetParent(activeVessel.transform); camLeft_Far.transform.SetParent(activeVessel.transform); // stars.clearFlags = CameraClearFlags.Depth; // stars.cullingMask = (1 << 18); //sky.cullingMask = (1 << 9); leftStars.targetTexture = hmdLeftEyeRenderTexture; rightStars.targetTexture = hmdRightEyeRenderTexture; // leftSky.targetTexture = hmdLeftEyeRenderTexture; rightSky.targetTexture = hmdRightEyeRenderTexture; //skyCopySlave = rightSky.gameObject.AddComponent<copySlave>(); // skyCopySlave.leftTarget = hmdLeftEyeRenderTexture; // skyCopySlave.rightTarget = hmdRightEyeRenderTexture; //skyCopySlave.difrence = widthDiference; camLeft_Near.targetTexture = hmdLeftEyeRenderTexture; camRight_Near.targetTexture = hmdRightEyeRenderTexture; // camLeft_Interior.targetTexture = hmdLeftEyeRenderTexture; // camRight_Interior.targetTexture = hmdRightEyeRenderTexture; camLeft_Far.targetTexture = hmdLeftEyeRenderTexture; camRight_Far.targetTexture = hmdRightEyeRenderTexture; leftStars.depth += 4; leftSky.depth += 4; camLeft_Near.depth += 4; camLeft_Far.depth += 4; // camLeft_Interior.depth += 4; // camRight_Interior.depth += 4; //rightSky.depth = -5; // camRight.targetTexture = sky.targetTexture; // camLeft.targetTexture = sky.targetTexture; // camera.targetTexture = hmdLeftEyeRenderTexture; // camRight.cullingMask = (1 << 0) | (1 << 4) | (1 << 10) | (1 << 15) | (1 << 16) | (1 << 20) | (1 << 23); // camLeft.cullingMask = (1 << 0) | (1 << 4) | (1 << 10) | (1 << 15) | (1 << 16) | (1 << 20) | (1 << 23); // 0: ship exterior //15: ground //16: ship interior //TODO change to |= //camRight_Near.cullingMask = 1 << 20 | (1 << 16); //camLeft_Near.cullingMask = 1 << 20 | (1 << 16); // camLeft.clearFlags = CameraClearFlags.Depth; // camRight.clearFlags = CameraClearFlags.Depth; // camLeft_Near.layerCullDistances = distances; // camRight_Near.layerCullDistances = distances; // camLeft.depthTextureMode = DepthTextureMode.Depth; // camRight.depthTextureMode = DepthTextureMode.Depth; //camRight.transparencySortMode = TransparencySortMode.Perspective; //create left slave leftSlave = camLeft_Near.gameObject.AddOrGetComponent <RenderSlave>(); //leftSlave = sky.gameObject.AddOrGetComponent<RenderSlave>(); leftSlave.left = true; // camLeft.cullingMask = (1 << 0) | (1 << 4) | (1 << 9) | (1 << 10) | (1 << 15) | (1 << 16) | (1 << 18) | (1 << 20) | (1 << 23); //camLeft.cullingMask = (1 << 9) | (1 << 15) | (1 << 16) | (1 << 20) | (1 << 32); //camLeft.cullingMask = 0; // camLeft.ResetCullingMatrix(); //camLeft_Near.useOcclusionCulling = true; //camLeft_Near.nearClipPlane = 0.01f; //camLeft_Near.farClipPlane = max; //create right slave rightSlave = camRight_Near.gameObject.AddOrGetComponent <RenderSlave>(); rightSlave.left = false; // camRight.cullingMask = (1 << 0) | (1 << 4) | (1 << 9) | (1 << 10) | (1 << 15) | (1 << 16) | (1 << 18) | (1 << 20) | (1 << 23); // camRight.cullingMask = (1 << 9) | (1 << 15) | (1 << 16) | (1 << 20) | (1 << 32); // camRight.cullingMask = 0; //camRight.ResetCullingMatrix(); // camRight_Near.useOcclusionCulling = true; // // camRight_Near.nearClipPlane = 0.01f; // camRight_Near.farClipPlane = max; //set camera projections: //TODO rewrite HmdMatrix44_t projLeft = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, camLeft_Near.nearClipPlane, camLeft_Near.farClipPlane); HmdMatrix44_t projRight = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, camRight_Near.nearClipPlane, camRight_Near.farClipPlane); camLeft_Near.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft); camRight_Near.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight); // HmdMatrix44_t projLeft2 = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, camLeft_Interior.nearClipPlane, camLeft_Interior.farClipPlane); // HmdMatrix44_t projRight2 = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, camRight_Interior.nearClipPlane, camRight_Interior.farClipPlane); // // camLeft_Interior.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft2); // camRight_Interior.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight2); HmdMatrix44_t projLeft3 = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, camLeft_Far.nearClipPlane, camLeft_Far.farClipPlane); HmdMatrix44_t projRight3 = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, camRight_Far.nearClipPlane, camRight_Far.farClipPlane); camLeft_Far.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft3); camRight_Far.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight3); HmdMatrix44_t projLeft4 = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, leftSky.nearClipPlane, leftSky.farClipPlane); HmdMatrix44_t projRight4 = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, rightSky.nearClipPlane, rightSky.farClipPlane); leftSky.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft4); rightSky.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight4); HmdMatrix44_t projLeft5 = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, leftStars.nearClipPlane, leftStars.farClipPlane); HmdMatrix44_t projRight5 = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, rightStars.nearClipPlane, rightStars.farClipPlane); leftStars.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft5); rightStars.projectionMatrix = MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight5); // camLeft_Interior.depth = 0; // camLeft_Interior.clearFlags = CameraClearFlags.Skybox; // camLeft_Near.depth = 0; // camLeft_Near.clearFlags = CameraClearFlags.Nothing; // camLeft_Far.depth = -1; // camLeft_Far.clearFlags = CameraClearFlags.Nothing; // leftSky.depth = -2; // leftSky.clearFlags = CameraClearFlags.Nothing; // leftStars.depth = -3; // leftStars.clearFlags = CameraClearFlags.Skybox; // // // // camRight_Interior.depth = 5; // // camRight_Interior.clearFlags = CameraClearFlags.Skybox; // camRight_Near.depth =0; // camRight_Near.clearFlags = CameraClearFlags.Nothing; // camRight_Far.depth = -1; // camRight_Far.clearFlags = CameraClearFlags.Nothing; // rightSky.depth = -2; // rightSky.clearFlags = CameraClearFlags.Nothing; // rightStars.depth = -3; // rightStars.clearFlags = CameraClearFlags.Skybox; //activate slaves posTracker.HmdOn = true; leftSlave.HmdOn = true; rightSlave.HmdOn = true; } }
public void InitRendering(UI ui) { lock (_drawLock) { if (ui == null) { return; } _ui = ui; ResizeRedraw = true; var initError = EVRInitError.None; system = OpenVR.Init(ref initError); if (initError != EVRInitError.None) { throw new Exception("Not Available"); } compositor = OpenVR.Compositor; compositor.CompositorBringToFront(); compositor.FadeGrid(5.0f, false); count = OpenVR.k_unMaxTrackedDeviceCount; currentPoses = new TrackedDevicePose_t[count]; nextPoses = new TrackedDevicePose_t[count]; controllers = new List <uint>(); controllerModels = new RenderModel_t[count]; controllerTextures = new RenderModel_TextureMap_t[count]; controllerTextureViews = new ShaderResourceView[count]; controllerVertexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerIndexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerVertexBufferBindings = new VertexBufferBinding[count]; for (uint device = 0; device < count; device++) { var deviceClass = system.GetTrackedDeviceClass(device); switch (deviceClass) { case ETrackedDeviceClass.HMD: headset = device; break; case ETrackedDeviceClass.Controller: controllers.Add(device); break; } } uint width = 0; uint height = 0; system.GetRecommendedRenderTargetSize(ref width, ref height); headsetSize = new Size((int)width, (int)height); windowSize = new Size(UI.GameWidth, UI.GameHeight); leftEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f)); rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f)); leftEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left)); rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right)); foreach (var controller in controllers) { var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); controllerModels[controller] = renderModel; break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); controllerTextures[controller] = texture; break; } } } } int adapterIndex = 0; system.GetDXGIOutputInfo(ref adapterIndex); using (var factory = new SharpDX.DXGI.Factory4()) { var adapter = factory.GetAdapter(adapterIndex); var swapChainDescription = new SwapChainDescription { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription { Format = Format.B8G8R8A8_UNorm, Width = windowSize.Width, Height = windowSize.Height, RefreshRate = new Rational(60, 1) }, OutputHandle = this.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain); factory.MakeWindowAssociation(this.Handle, WindowAssociationFlags.None); context = device.ImmediateContext; using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) backBufferView = new RenderTargetView(device, backBuffer); var depthBufferDescription = new Texture2DDescription { Format = Format.D16_UNorm, ArraySize = 1, MipLevels = 1, Width = windowSize.Width, Height = windowSize.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; using (var depthBuffer = new Texture2D(device, depthBufferDescription)) depthStencilView = new DepthStencilView(device, depthBuffer); // Create Eye Textures var eyeTextureDescription = new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, Format = Format.B8G8R8A8_UNorm, Width = headsetSize.Width, Height = headsetSize.Height, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; leftEyeTexture = new Texture2D(device, eyeTextureDescription); rightEyeTexture = new Texture2D(device, eyeTextureDescription); leftEyeTextureView = new RenderTargetView(device, leftEyeTexture); rightEyeTextureView = new RenderTargetView(device, rightEyeTexture); // Create Eye Depth Buffer eyeTextureDescription.BindFlags = BindFlags.DepthStencil; eyeTextureDescription.Format = Format.D32_Float; eyeDepth = new Texture2D(device, eyeTextureDescription); eyeDepthView = new DepthStencilView(device, eyeDepth); Shapes.Cube.Load(device); Shapes.Sphere.Load(device); Shaders.Normal.Load(device); Shaders.NormalTexture.Load(device); // Load Controller Models foreach (var controller in controllers) { var model = controllerModels[controller]; controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)model.unVertexCount * 32 }); controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0); controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription { BindFlags = BindFlags.IndexBuffer, SizeInBytes = (int)model.unTriangleCount * 3 * 2 }); var texture = controllerTextures[controller]; using (var texture2d = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, Format = Format.R8G8B8A8_UNorm, Width = texture.unWidth, Height = texture.unHeight, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4))) controllerTextureViews[controller] = new ShaderResourceView(device, texture2d); } shaderParameterBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Shaders.Parameters>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); var rasterizerStateDescription = RasterizerStateDescription.Default(); //rasterizerStateDescription.FillMode = FillMode.Wireframe; rasterizerStateDescription.IsFrontCounterClockwise = true; //rasterizerStateDescription.CullMode = CullMode.None; rasterizerState = new RasterizerState(device, rasterizerStateDescription); var blendStateDescription = BlendStateDescription.Default(); blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDescription.RenderTarget[0].IsBlendEnabled = false; blendState = new BlendState(device, blendStateDescription); var depthStateDescription = DepthStencilStateDescription.Default(); depthStateDescription.DepthComparison = Comparison.LessEqual; depthStateDescription.IsDepthEnabled = true; depthStateDescription.IsStencilEnabled = false; depthStencilState = new DepthStencilState(device, depthStateDescription); var samplerStateDescription = SamplerStateDescription.Default(); samplerStateDescription.Filter = Filter.MinMagMipLinear; samplerStateDescription.AddressU = TextureAddressMode.Wrap; samplerStateDescription.AddressV = TextureAddressMode.Wrap; samplerState = new SamplerState(device, samplerStateDescription); startTime = DateTime.Now; frame = 0; //windowSize = ClientSize; backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1); head = Matrix.Identity; _ui.ready = true; } } }
protected void setupScene() { mScene = new Scene(ref mDoc, ref mHMD); mScene.setWindowSize(this.Width, this.Height); mScene.mIsLefty = mIsLefty; if (mStrDriver.Contains("oculus")) { mScene.isOculus = true; } else { mScene.isOculus = false; } if (mHMD != null) { mHMD.GetRecommendedRenderTargetSize(ref mRenderWidth, ref mRenderHeight); } //visualizing axises OpenTK.Vector3 x0 = UtilOld.platformToVRPoint(ref mScene, new OpenTK.Vector3(-240, 0, 0)); OpenTK.Vector3 x1 = UtilOld.platformToVRPoint(ref mScene, new OpenTK.Vector3(240, 0, 0)); OpenTK.Vector3 y0 = UtilOld.platformToVRPoint(ref mScene, new OpenTK.Vector3(0, -240, 0)); OpenTK.Vector3 y1 = UtilOld.platformToVRPoint(ref mScene, new OpenTK.Vector3(0, 240, 0)); OpenTK.Vector3 z0 = UtilOld.platformToVRPoint(ref mScene, new OpenTK.Vector3(0, 0, -240)); OpenTK.Vector3 z1 = UtilOld.platformToVRPoint(ref mScene, new OpenTK.Vector3(0, 0, 240)); Geometry.Geometry xAxis_g = new Geometry.GeometryStroke(ref mScene); Material.Material xAxis_m = new Material.SingleColorMaterial(1, 1, 1, 0); ((Geometry.GeometryStroke)xAxis_g).addPoint(x0); ((Geometry.GeometryStroke)xAxis_g).addPoint(x1); mScene.xAxis = new SceneNode("xAxis", ref xAxis_g, ref xAxis_m); mScene.staticGeometry.add(ref mScene.xAxis); Geometry.Geometry yAxis_g = new Geometry.GeometryStroke(ref mScene); Material.Material yAxis_m = new Material.SingleColorMaterial(1, 1, 1, 0); ((Geometry.GeometryStroke)yAxis_g).addPoint(y0); ((Geometry.GeometryStroke)yAxis_g).addPoint(y1); mScene.yAxis = new SceneNode("yAxis", ref yAxis_g, ref yAxis_m); mScene.staticGeometry.add(ref mScene.yAxis); Geometry.Geometry zAxis_g = new Geometry.GeometryStroke(ref mScene); Material.Material zAxis_m = new Material.SingleColorMaterial(1, 1, 1, 0); ((Geometry.GeometryStroke)zAxis_g).addPoint(z0); ((Geometry.GeometryStroke)zAxis_g).addPoint(z1); mScene.zAxis = new SceneNode("zAxis", ref zAxis_g, ref zAxis_m); mScene.staticGeometry.add(ref mScene.zAxis); // LeftController Point and Laser //g = new Geometry.Geometry("C:/workspace/Kestrel/resources/meshes/bunny.obj"); //m = new Material.RGBNormalMaterial(1); Geometry.Geometry controllerL_g = new Geometry.PointMarker(new Vector3(0, 0, 0)); Material.Material controllerL_m = new Material.SingleColorMaterial(1, 0, 0, 1); SceneNode controllerL_p = new SceneNode("Left Cursor", ref controllerL_g, ref controllerL_m); mScene.leftControllerNode.add(ref controllerL_p); controllerL_p.transform = new Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);//mScene.mLeftControllerOffset; Geometry.Geometry controllerR_g = new Geometry.PointMarker(new Vector3(0, 0, 0)); Material.Material controllerR_m = new Material.SingleColorMaterial(1, 0, 0, 1); SceneNode controllerR_p = new SceneNode("Right Cursor", ref controllerR_g, ref controllerR_m); mScene.rightControllerNode.add(ref controllerR_p); controllerR_p.transform = new Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); Geometry.Geometry controllerLRay_g = new Geometry.GeometryStroke(ref mScene); Material.Material controllerLRay_m = new Material.SingleColorMaterial(1, 0, 0, 1); ((Geometry.GeometryStroke)controllerLRay_g).addPoint(new Vector3(0, 0, 0)); ((Geometry.GeometryStroke)controllerLRay_g).addPoint(new Vector3(0, 0, -1)); SceneNode rayTraceL = new SceneNode("ControllerRay", ref controllerLRay_g, ref controllerLRay_m); if (mIsLefty) { mScene.leftControllerNode.add(ref rayTraceL); } else { mScene.rightControllerNode.add(ref rayTraceL); } rayTraceL.transform = new Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);//mScene.mLeftControllerOffset; UtilOld.showLaser(ref mScene, false); mScene.xzPlane = new DesignPlane(ref mScene, XYZPlanes.XZ); mScene.xyPlane = new DesignPlane(ref mScene, XYZPlanes.XY); mScene.yzPlane = new DesignPlane(ref mScene, XYZPlanes.YZ); }
private void setup() { //init VR System and check for errors var error = EVRInitError.None; vrSystem = OpenVR.Init(ref error, EVRApplicationType.VRApplication_Scene); if ((int)error != (int)EVRInitError.None) { log("KerbalVrPlugin started."); } else { err(error.ToString()); } //rendervalues ######################################################### // Setup render values uint w = 0, h = 0; vrSystem.GetRecommendedRenderTargetSize(ref w, ref h); float sceneWidth = (float)w; float sceneHeight = (float)h; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; vrSystem.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; vrSystem.GetProjectionRaw(EVREye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); Vector2 tanHalfFov = new Vector2(Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -r_top, r_bottom)); //Setup rendertextures hmdLeftEyeTexture = new Texture_t(); hmdLeftEyeTexture.eColorSpace = EColorSpace.Auto; hmdRightEyeTexture = new Texture_t(); hmdRightEyeTexture.eColorSpace = EColorSpace.Auto; //select Texture Type depending on RenderAPI (Currently only DirectX11 is tested) switch (SystemInfo.graphicsDeviceType) { case UnityEngine.Rendering.GraphicsDeviceType.OpenGL2: log("OpenGL2"); hmdLeftEyeTexture.eType = ETextureType.OpenGL; hmdRightEyeTexture.eType = ETextureType.OpenGL; break; case UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore: log("OpenCore"); hmdLeftEyeTexture.eType = ETextureType.OpenGL; hmdRightEyeTexture.eType = ETextureType.OpenGL; break; case UnityEngine.Rendering.GraphicsDeviceType.OpenGLES2: log("OpenGLES2"); hmdLeftEyeTexture.eType = ETextureType.OpenGL; hmdRightEyeTexture.eType = ETextureType.OpenGL; break; case UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3: log("OpenGLES3"); hmdLeftEyeTexture.eType = ETextureType.OpenGL; hmdRightEyeTexture.eType = ETextureType.OpenGL; break; case UnityEngine.Rendering.GraphicsDeviceType.Direct3D9: log("Direct3D9"); warn("DirectX 9 mode not Supported! There be Dragons!"); hmdLeftEyeTexture.eType = ETextureType.DirectX; hmdRightEyeTexture.eType = ETextureType.DirectX; break; case UnityEngine.Rendering.GraphicsDeviceType.Direct3D11: log("Direct3D11"); hmdLeftEyeTexture.eType = ETextureType.DirectX; hmdRightEyeTexture.eType = ETextureType.DirectX; break; case UnityEngine.Rendering.GraphicsDeviceType.Direct3D12: log("Direct3D12"); warn("DirectX 12 mode not implemented! There be Dragons!"); hmdLeftEyeTexture.eType = ETextureType.DirectX12; hmdRightEyeTexture.eType = ETextureType.DirectX12; break; default: throw (new Exception(SystemInfo.graphicsDeviceType.ToString() + " not supported")); } vrCompositor = OpenVR.Compositor; if (!vrCompositor.CanRenderScene()) { err("can not render scene"); } }
public override void Initialize() { StringBuilder sb = new StringBuilder(512); ETrackedPropertyError error = ETrackedPropertyError.TrackedProp_Success; uint ret = _vrSystem.GetStringTrackedDeviceProperty( OVR.k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty.Prop_TrackingSystemName_String, sb, 512u, ref error); if (error != ETrackedPropertyError.TrackedProp_Success) { _deviceName = "<Unknown OpenVR Device>"; } else { _deviceName = sb.ToString(); } uint eyeWidth = 0; uint eyeHeight = 0; _vrSystem.GetRecommendedRenderTargetSize(ref eyeWidth, ref eyeHeight); _leftEyeGT = GPUDevice.CreateTexture(); var descLeftEye = GPUTextureDescription.New2D((int)eyeWidth, (int)eyeHeight, 1, PixelFormat.R8G8B8A8_UNorm, msaaLevel: _options.EyeRenderTargetSampleCount); _leftEyeGT.Init(ref descLeftEye); _rightEyeGT = GPUDevice.CreateTexture(); var descRightEye = GPUTextureDescription.New2D((int)eyeWidth, (int)eyeHeight, 1, PixelFormat.R8G8B8A8_UNorm, msaaLevel: _options.EyeRenderTargetSampleCount); _rightEyeGT.Init(ref descRightEye); Matrix eyeToHeadLeft = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left)); Matrix.Invert(ref eyeToHeadLeft, out _headToEyeLeft); Matrix eyeToHeadRight = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right)); Matrix.Invert(ref eyeToHeadRight, out _headToEyeRight); // Default RH matrices /*_projLeft = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Left, 0.1f, 10000f)); * _projRight = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Right, 0.1f, 10000f));*/ // Build LH projection matrices (https://github.com/ValveSoftware/openvr/wiki/IVRSystem::GetProjectionRaw) float pLeft = 0; float pRight = 0; float pTop = 0; float pBottom = 0; // Default values float zNear = 0.1f; float zFar = 20000f; _vrSystem.GetProjectionRaw(EVREye.Eye_Left, ref pLeft, ref pRight, ref pTop, ref pBottom); _projLeft = Matrix.PerspectiveOffCenter(pLeft * zNear, pRight * zNear, pBottom * zNear * -1f, pTop * zNear * -1f, zNear, zFar); _vrSystem.GetProjectionRaw(EVREye.Eye_Right, ref pLeft, ref pRight, ref pTop, ref pBottom); _projRight = Matrix.PerspectiveOffCenter(pLeft * zNear, pRight * zNear, pBottom * zNear * -1f, pTop * zNear * -1f, zNear, zFar); }
static void Main() { var initError = EVRInitError.None; system = OpenVR.Init(ref initError); if (initError != EVRInitError.None) { return; } compositor = OpenVR.Compositor; compositor.CompositorBringToFront(); compositor.FadeGrid(5.0f, false); count = OpenVR.k_unMaxTrackedDeviceCount; currentPoses = new TrackedDevicePose_t[count]; nextPoses = new TrackedDevicePose_t[count]; controllers = new List <uint>(); controllerModels = new RenderModel_t[count]; controllerTextures = new RenderModel_TextureMap_t[count]; controllerTextureViews = new ShaderResourceView[count]; controllerVertexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerIndexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerVertexBufferBindings = new VertexBufferBinding[count]; controllerEmitters = new Emitter[count]; controllerVoices = new SourceVoice[count]; for (uint device = 0; device < count; device++) { var deviceClass = system.GetTrackedDeviceClass(device); switch (deviceClass) { case ETrackedDeviceClass.HMD: headset = device; break; case ETrackedDeviceClass.Controller: controllers.Add(device); break; } } uint width = 0; uint height = 0; system.GetRecommendedRenderTargetSize(ref width, ref height); headsetSize = new Size((int)width, (int)height); windowSize = new Size(960, 540); var leftEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f)); var rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f)); var leftEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left)); var rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right)); foreach (var controller in controllers) { var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); controllerModels[controller] = renderModel; break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); controllerTextures[controller] = texture; break; } } } } int adapterIndex = 0; system.GetDXGIOutputInfo(ref adapterIndex); using (var form = new Form()) using (var factory = new Factory4()) { form.ClientSize = windowSize; var adapter = factory.GetAdapter(adapterIndex); var swapChainDescription = new SwapChainDescription { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription { Format = Format.B8G8R8A8_UNorm, Width = form.ClientSize.Width, Height = form.ClientSize.Height, RefreshRate = new Rational(60, 1) }, OutputHandle = form.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain); factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.None); context = device.ImmediateContext; using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) backBufferView = new RenderTargetView(device, backBuffer); var depthBufferDescription = new Texture2DDescription { Format = Format.D16_UNorm, ArraySize = 1, MipLevels = 1, Width = form.ClientSize.Width, Height = form.ClientSize.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; using (var depthBuffer = new Texture2D(device, depthBufferDescription)) depthStencilView = new DepthStencilView(device, depthBuffer); // Create Eye Textures var eyeTextureDescription = new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, Format = Format.B8G8R8A8_UNorm, Width = headsetSize.Width, Height = headsetSize.Height, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; var leftEyeTexture = new Texture2D(device, eyeTextureDescription); var rightEyeTexture = new Texture2D(device, eyeTextureDescription); var leftEyeTextureView = new RenderTargetView(device, leftEyeTexture); var rightEyeTextureView = new RenderTargetView(device, rightEyeTexture); // Create Eye Depth Buffer eyeTextureDescription.BindFlags = BindFlags.DepthStencil; eyeTextureDescription.Format = Format.D32_Float; var eyeDepth = new Texture2D(device, eyeTextureDescription); var eyeDepthView = new DepthStencilView(device, eyeDepth); Shapes.Cube.Load(device); Shapes.Sphere.Load(device); Shaders.Load(device); // Load Controller Models foreach (var controller in controllers) { var model = controllerModels[controller]; controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)model.unVertexCount * 32 }); controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0); controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription { BindFlags = BindFlags.IndexBuffer, SizeInBytes = (int)model.unTriangleCount * 3 * 2 }); var texture = controllerTextures[controller]; using (var texture2d = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, Format = Format.R8G8B8A8_UNorm, Width = texture.unWidth, Height = texture.unHeight, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4))) controllerTextureViews[controller] = new ShaderResourceView(device, texture2d); } var controllerVertexShaderByteCode = SharpDX.D3DCompiler.ShaderBytecode.Compile(Properties.Resources.NormalTextureShader, "VS", "vs_5_0"); controllerVertexShader = new VertexShader(device, controllerVertexShaderByteCode); controllerPixelShader = new PixelShader(device, SharpDX.D3DCompiler.ShaderBytecode.Compile(Properties.Resources.NormalTextureShader, "PS", "ps_5_0")); var controllerLayout = new InputLayout(device, SharpDX.D3DCompiler.ShaderSignature.GetInputSignature(controllerVertexShaderByteCode), new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 24, 0) }); worldViewProjectionBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); var rasterizerStateDescription = RasterizerStateDescription.Default(); //rasterizerStateDescription.FillMode = FillMode.Wireframe; rasterizerStateDescription.IsFrontCounterClockwise = true; //rasterizerStateDescription.CullMode = CullMode.None; rasterizerState = new RasterizerState(device, rasterizerStateDescription); var blendStateDescription = BlendStateDescription.Default(); blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDescription.RenderTarget[0].IsBlendEnabled = false; blendState = new BlendState(device, blendStateDescription); var depthStateDescription = DepthStencilStateDescription.Default(); depthStateDescription.DepthComparison = Comparison.LessEqual; depthStateDescription.IsDepthEnabled = true; depthStateDescription.IsStencilEnabled = false; depthStencilState = new DepthStencilState(device, depthStateDescription); var samplerStateDescription = SamplerStateDescription.Default(); samplerStateDescription.Filter = Filter.MinMagMipLinear; samplerStateDescription.AddressU = TextureAddressMode.Wrap; samplerStateDescription.AddressV = TextureAddressMode.Wrap; samplerState = new SamplerState(device, samplerStateDescription); startTime = DateTime.Now; frame = 0; windowSize = form.ClientSize; backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1); var vrEvent = new VREvent_t(); var eventSize = (uint)Utilities.SizeOf <VREvent_t>(); head = Matrix.Identity; // Initialize Audio audio = new XAudio2(); var voice = new MasteringVoice(audio); audio3d = new X3DAudio(Speakers.Stereo); foreach (var controller in controllers) { controllerEmitters[controller] = new Emitter { ChannelCount = 1, CurveDistanceScaler = 0.15f, OrientFront = Vector3.ForwardLH, OrientTop = Vector3.Up, Position = new Vector3(0, 0, 1000), //Velocity = Vector3.Zero }; } listener = new Listener { OrientFront = Vector3.ForwardLH, OrientTop = Vector3.Up, Position = new Vector3(0, 0, 1000) }; var audioFormat = new WaveFormat(44100, 32, 1); //var audioSource = new SourceVoice(audio, audioFormat); var audioBufferSize = audioFormat.ConvertLatencyToByteSize(1000); var audioStream = new DataStream(audioBufferSize, true, true); var audioSamples = audioBufferSize / audioFormat.BlockAlign; var random = new Random(); for (var sample = 0; sample < audioSamples; sample++) { audioStream.Write((float)random.NextFloat(-1, 1)); } audioStream.Position = 0; var audioBuffer = new AudioBuffer { Stream = audioStream, AudioBytes = audioBufferSize, LoopCount = 255 }; var audioSettings = new DspSettings(1, 2); foreach (var controller in controllers) { var audioSource = new SourceVoice(audio, audioFormat); audioSource.SubmitSourceBuffer(audioBuffer, null); audio3d.Calculate(listener, controllerEmitters[controller], CalculateFlags.Matrix, audioSettings); audioSource.SetOutputMatrix(1, 2, audioSettings.MatrixCoefficients); audioSource.Start(); controllerVoices[controller] = audioSource; } RenderLoop.Run(form, () => { while (system.PollNextEvent(ref vrEvent, eventSize)) { switch ((EVREventType)vrEvent.eventType) { case EVREventType.VREvent_TrackedDeviceActivated: var controller = vrEvent.trackedDeviceIndex; controllers.Add(controller); var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); controllerModels[controller] = renderModel; // Load Controller Model var model = controllerModels[controller]; controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)model.unVertexCount * 32 }); controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0); controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription { BindFlags = BindFlags.IndexBuffer, SizeInBytes = (int)model.unTriangleCount * 3 * 2 }); break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var textureMap = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); controllerTextures[controller] = textureMap; using (var texture2d = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, Format = Format.R8G8B8A8_UNorm, Width = textureMap.unWidth, Height = textureMap.unHeight, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(textureMap.rubTextureMapData, textureMap.unWidth * 4))) controllerTextureViews[controller] = new ShaderResourceView(device, texture2d); break; } } controllerEmitters[controller] = new Emitter { ChannelCount = 1, CurveDistanceScaler = 0.15f, OrientFront = Vector3.ForwardLH, OrientTop = Vector3.Up, Position = new Vector3(0, 0, 1000), //Velocity = Vector3.Zero }; var audioSource = new SourceVoice(audio, audioFormat); audioSource.SubmitSourceBuffer(audioBuffer, null); audio3d.Calculate(listener, controllerEmitters[controller], CalculateFlags.Matrix, audioSettings); audioSource.SetOutputMatrix(1, 2, audioSettings.MatrixCoefficients); audioSource.Start(); controllerVoices[controller] = audioSource; } break; case EVREventType.VREvent_TrackedDeviceDeactivated: controllers.RemoveAll(c => c == vrEvent.trackedDeviceIndex); break; default: System.Diagnostics.Debug.WriteLine((EVREventType)vrEvent.eventType); break; } } if (form.ClientSize != windowSize) { Utilities.Dispose(ref backBufferView); if (form.ClientSize.Width != 0 && form.ClientSize.Height != 0) { swapChain.ResizeBuffers(1, form.ClientSize.Width, form.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None); using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) backBufferView = new RenderTargetView(device, backBuffer); } windowSize = form.ClientSize; } // Update Device Tracking compositor.WaitGetPoses(currentPoses, nextPoses); if (currentPoses[headset].bPoseIsValid) { Convert(ref currentPoses[headset].mDeviceToAbsoluteTracking, ref head); // Update Audio Listener listener.Position = head.TranslationVector * new Vector3(1, 1, -1); listener.OrientFront = head.Forward * new Vector3(1, 1, -1); listener.OrientTop = head.Up * new Vector3(1, 1, -1); } foreach (var controller in controllers) { var controllerMatrix = Matrix.Identity; Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref controllerMatrix); var position = controllerMatrix.TranslationVector * new Vector3(1, 1, -1); controllerEmitters[controller].Position = position; audio3d.Calculate(listener, controllerEmitters[controller], CalculateFlags.Matrix, audioSettings); controllerVoices[controller].SetOutputMatrix(1, 2, audioSettings.MatrixCoefficients); } // Render Left Eye context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height); context.OutputMerger.SetTargets(eyeDepthView, leftEyeTextureView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(leftEyeTextureView, backgroundColor); context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); var ratio = (float)headsetSize.Width / (float)headsetSize.Height; var projection = leftEyeProjection; var view = Matrix.Invert(leftEyeView * head); var world = Matrix.Scaling(0.5f) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.InputLayout = controllerLayout; context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; context.VertexShader.Set(controllerVertexShader); context.PixelShader.Set(controllerPixelShader); context.GeometryShader.Set(null); context.DomainShader.Set(null); context.HullShader.Set(null); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } var texture = new Texture_t { eType = ETextureType.DirectX, eColorSpace = EColorSpace.Gamma, handle = leftEyeTextureView.Resource.NativePointer }; var bounds = new VRTextureBounds_t { uMin = 0.0f, uMax = 1.0f, vMin = 0.0f, vMax = 1.0f, }; var submitError = compositor.Submit(EVREye.Eye_Left, ref texture, ref bounds, EVRSubmitFlags.Submit_Default); if (submitError != EVRCompositorError.None) { System.Diagnostics.Debug.WriteLine(submitError); } // Render Right Eye context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height); context.OutputMerger.SetTargets(eyeDepthView, rightEyeTextureView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(rightEyeTextureView, backgroundColor); context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); projection = rightEyeProjection; view = Matrix.Invert(rightEyeView * head); world = Matrix.Scaling(0.5f) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.InputLayout = controllerLayout; context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; context.VertexShader.Set(controllerVertexShader); context.PixelShader.Set(controllerPixelShader); context.GeometryShader.Set(null); context.DomainShader.Set(null); context.HullShader.Set(null); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } texture.handle = rightEyeTextureView.Resource.NativePointer; submitError = compositor.Submit(EVREye.Eye_Right, ref texture, ref bounds, EVRSubmitFlags.Submit_Default); if (submitError != EVRCompositorError.None) { System.Diagnostics.Debug.WriteLine(submitError); } // Render Window context.Rasterizer.SetViewport(0, 0, windowSize.Width, windowSize.Height); context.OutputMerger.SetTargets(depthStencilView, backBufferView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(backBufferView, backgroundColor); context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); ratio = (float)form.ClientSize.Width / (float)form.ClientSize.Height; projection = Matrix.PerspectiveFovRH(3.14F / 3.0F, ratio, 0.01f, 1000); view = Matrix.Invert(head); world = Matrix.Scaling(0.5f) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.InputLayout = controllerLayout; context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; context.VertexShader.Set(controllerVertexShader); context.PixelShader.Set(controllerPixelShader); context.GeometryShader.Set(null); context.DomainShader.Set(null); context.HullShader.Set(null); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } // Show Backbuffer swapChain.Present(0, PresentFlags.None); }); audio.Dispose(); } }
/// <summary> /// Initialize HMD using OpenVR API calls. /// </summary> /// <returns>True on success, false otherwise. Errors logged.</returns> bool InitHMD() { bool retVal = false; // return if HMD has already been initialized if (hmdIsInitialized) { return(true); } // check if HMD is connected on the system retVal = OpenVR.IsHmdPresent(); if (!retVal) { Debug.Log("[KerbalVR] HMD not found on this system."); return(retVal); } // check if SteamVR runtime is installed. // For this plugin, MAKE SURE IT IS ALREADY RUNNING. retVal = OpenVR.IsRuntimeInstalled(); if (!retVal) { Debug.Log("[KerbalVR] SteamVR runtime not found on this system."); return(retVal); } // initialize HMD EVRInitError hmdInitErrorCode = EVRInitError.None; vrSystem = OpenVR.Init(ref hmdInitErrorCode, EVRApplicationType.VRApplication_Scene); // return if failure retVal = (hmdInitErrorCode == EVRInitError.None); if (!retVal) { Debug.Log("[KerbalVR] Failed to initialize HMD. Init returned: " + OpenVR.GetStringForHmdError(hmdInitErrorCode)); return(retVal); } else { Debug.Log("[KerbalVR] OpenVR.Init passed."); } // reset "seated position" and capture initial position. this means you should hold the HMD in // the position you would like to consider "seated", before running this code. hmdIsInitialized = true; ResetInitialHmdPosition(); // initialize Compositor vrCompositor = OpenVR.Compositor; // initialize render textures (for displaying on HMD) uint renderTextureWidth = 0; uint renderTextureHeight = 0; vrSystem.GetRecommendedRenderTargetSize(ref renderTextureWidth, ref renderTextureHeight); //renderTextureWidth /= 2; //renderTextureHeight /= 2; Debug.Log("[KerbalVR] Render Texture size: " + renderTextureWidth + " x " + renderTextureHeight); hmdLeftEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32); hmdLeftEyeRenderTexture.antiAliasing = 1; hmdLeftEyeRenderTexture.Create(); hmdRightEyeRenderTexture = new RenderTexture((int)renderTextureWidth, (int)renderTextureHeight, 24, RenderTextureFormat.ARGB32); hmdRightEyeRenderTexture.Create(); hmdLeftEyeTexture.handle = hmdLeftEyeRenderTexture.GetNativeTexturePtr(); hmdLeftEyeTexture.eType = EGraphicsAPIConvention.API_OpenGL; //hmdLeftEyeTexture.eType = EGraphicsAPIConvention.API_DirectX; // this doesn't seem to work hmdLeftEyeTexture.eColorSpace = EColorSpace.Auto; hmdRightEyeTexture.handle = hmdRightEyeRenderTexture.GetNativeTexturePtr(); hmdRightEyeTexture.eType = EGraphicsAPIConvention.API_OpenGL; //hmdRightEyeTexture.eType = EGraphicsAPIConvention.API_DirectX; // this doesn't seem to work hmdRightEyeTexture.eColorSpace = EColorSpace.Auto; // Set rendering bounds on texture to render? // I assume min=0.0 and max=1.0 renders to the full extent of the texture hmdTextureBounds.uMin = 0.0f; hmdTextureBounds.uMax = 1.0f; hmdTextureBounds.vMin = 0.0f; hmdTextureBounds.vMax = 1.0f; // create the hidden area mask meshes HiddenAreaMesh_t vrHiddenAreaMesh = vrSystem.GetHiddenAreaMesh(EVREye.Eye_Left); hmdHiddenAreaMeshLeft = SteamVR_Utils.CreateHiddenAreaMesh(vrHiddenAreaMesh, hmdTextureBounds); vrHiddenAreaMesh = vrSystem.GetHiddenAreaMesh(EVREye.Eye_Right); hmdHiddenAreaMeshRight = SteamVR_Utils.CreateHiddenAreaMesh(vrHiddenAreaMesh, hmdTextureBounds); // TODO: Need to understand better how to create render targets and incorporate hidden area mask mesh // search for camera objects to render foreach (string cameraName in cameraNamesToRender) { foreach (Camera camera in Camera.allCameras) { if (cameraName.Equals(camera.name)) { float nearClipPlane = (camera.name.Equals(cameraNames[3])) ? 0.05f : camera.nearClipPlane; HmdMatrix44_t projLeft = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, nearClipPlane, camera.farClipPlane, EGraphicsAPIConvention.API_OpenGL); HmdMatrix44_t projRight = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, nearClipPlane, camera.farClipPlane, EGraphicsAPIConvention.API_OpenGL); //HmdMatrix44_t projLeft = vrSystem.GetProjectionMatrix(EVREye.Eye_Left, nearClipPlane, camera.farClipPlane, EGraphicsAPIConvention.API_DirectX); // this doesn't seem to work //HmdMatrix44_t projRight = vrSystem.GetProjectionMatrix(EVREye.Eye_Right, nearClipPlane, camera.farClipPlane, EGraphicsAPIConvention.API_DirectX); // this doesn't seem to work camerasToRender.Add(new CameraProperties(camera, camera.projectionMatrix, MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft), MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projRight))); break; } } } foreach (Camera camera in Camera.allCameras) { if (cameraNames[5].Equals(camera.name)) { uiCamera = camera; } } // detect controllers for (uint idx = 0; idx < OpenVR.k_unMaxTrackedDeviceCount; idx++) { if ((ctrlIndexLeft == 0) && (vrSystem.GetTrackedDeviceClass(idx) == ETrackedDeviceClass.Controller)) { ctrlIndexLeft = idx; } else if ((ctrlIndexRight == 0) && (vrSystem.GetTrackedDeviceClass(idx) == ETrackedDeviceClass.Controller)) { ctrlIndexRight = idx; } } bool ctrlFocusCaptured = vrSystem.CaptureInputFocus(); if (!ctrlFocusCaptured) { Debug.LogWarning("[KerbalVR] Controller input focus was not captured"); } return(retVal); }
internal static void Enable() { var initError = EVRInitError.None; System = OpenVR.Init(ref initError); if (initError != EVRInitError.None) { return; } Compositor = OpenVR.Compositor; Compositor.CompositorBringToFront(); Compositor.FadeGrid(5.0f, false); var count = OpenVR.k_unMaxTrackedDeviceCount; CurrentPoses = new TrackedDevicePose_t[count]; NextPoses = new TrackedDevicePose_t[count]; Controllers = new List <uint>(); ControllerModels = new RenderModel_t[count]; ControllerTextures = new RenderModel_TextureMap_t[count]; ControllerTextureViews = new ShaderResourceView[count]; ControllerVertexBuffers = new SharpDX.Direct3D11.Buffer[count]; ControllerIndexBuffers = new SharpDX.Direct3D11.Buffer[count]; ControllerVertexBufferBindings = new VertexBufferBinding[count]; ControllerEmitters = new Emitter[count]; ControllerVoices = new SourceVoice[count]; for (uint device = 0; device < count; device++) { var deviceClass = System.GetTrackedDeviceClass(device); switch (deviceClass) { case ETrackedDeviceClass.HMD: Headset = device; break; case ETrackedDeviceClass.Controller: Controllers.Add(device); break; } } uint width = 0; uint height = 0; System.GetRecommendedRenderTargetSize(ref width, ref height); headsetSize = new Size((int)width, (int)height); windowSize = new Size(960, 540); var leftEyeProjection = Convert(System.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f)); var rightEyeProjection = Convert(System.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f)); var leftEyeView = Convert(System.GetEyeToHeadTransform(EVREye.Eye_Left)); var rightEyeView = Convert(System.GetEyeToHeadTransform(EVREye.Eye_Right)); foreach (var controller in Controllers) { var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = System.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = global::System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); ControllerModels[controller] = renderModel; break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(ControllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var texture = global::System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); ControllerTextures[controller] = texture; break; } } } } int adapterIndex = 0; System.GetDXGIOutputInfo(ref adapterIndex); Thread = new Thread(Run); Thread.Start(); }
static void Main() { var initError = EVRInitError.None; system = OpenVR.Init(ref initError); if (initError != EVRInitError.None) { return; } compositor = OpenVR.Compositor; compositor.CompositorBringToFront(); compositor.FadeGrid(5.0f, false); count = OpenVR.k_unMaxTrackedDeviceCount; currentPoses = new TrackedDevicePose_t[count]; nextPoses = new TrackedDevicePose_t[count]; controllers = new List <uint>(); controllerModels = new RenderModel_t[count]; controllerTextures = new RenderModel_TextureMap_t[count]; controllerTextureViews = new ShaderResourceView[count]; controllerVertexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerIndexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerVertexBufferBindings = new VertexBufferBinding[count]; for (uint device = 0; device < count; device++) { var deviceClass = system.GetTrackedDeviceClass(device); switch (deviceClass) { case ETrackedDeviceClass.HMD: headset = device; break; case ETrackedDeviceClass.Controller: controllers.Add(device); break; } } uint width = 0; uint height = 0; system.GetRecommendedRenderTargetSize(ref width, ref height); headsetSize = new Size((int)width, (int)height); windowSize = new Size(960, 540); var leftEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f)); var rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f)); var leftEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left)); var rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right)); foreach (var controller in controllers) { var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); controllerModels[controller] = renderModel; break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); controllerTextures[controller] = texture; break; } } } } int adapterIndex = 0; system.GetDXGIOutputInfo(ref adapterIndex); using (var form = new Form()) using (var factory = new Factory4()) { form.ClientSize = windowSize; var adapter = factory.GetAdapter(adapterIndex); var swapChainDescription = new SwapChainDescription { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription { Format = Format.B8G8R8A8_UNorm, Width = form.ClientSize.Width, Height = form.ClientSize.Height, RefreshRate = new Rational(60, 1) }, OutputHandle = form.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain); factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.None); context = device.ImmediateContext; using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) backBufferView = new RenderTargetView(device, backBuffer); var depthBufferDescription = new Texture2DDescription { Format = Format.D16_UNorm, ArraySize = 1, MipLevels = 1, Width = form.ClientSize.Width, Height = form.ClientSize.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; using (var depthBuffer = new Texture2D(device, depthBufferDescription)) depthStencilView = new DepthStencilView(device, depthBuffer); // Create Eye Textures var eyeTextureDescription = new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, Format = Format.B8G8R8A8_UNorm, Width = headsetSize.Width, Height = headsetSize.Height, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; var leftEyeTexture = new Texture2D(device, eyeTextureDescription); var rightEyeTexture = new Texture2D(device, eyeTextureDescription); var leftEyeTextureView = new RenderTargetView(device, leftEyeTexture); var rightEyeTextureView = new RenderTargetView(device, rightEyeTexture); // Create Eye Depth Buffer eyeTextureDescription.BindFlags = BindFlags.DepthStencil; eyeTextureDescription.Format = Format.D32_Float; var eyeDepth = new Texture2D(device, eyeTextureDescription); var eyeDepthView = new DepthStencilView(device, eyeDepth); Shapes.Cube.Load(device); Shapes.Sphere.Load(device); Shaders.Position.Load(device); Shaders.Normal.Load(device); Shaders.NormalTexture.Load(device); // Load Controller Models foreach (var controller in controllers) { var model = controllerModels[controller]; controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)model.unVertexCount * 32 }); controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0); controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription { BindFlags = BindFlags.IndexBuffer, SizeInBytes = (int)model.unTriangleCount * 3 * 2 }); var texture = controllerTextures[controller]; using (var texture2d = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, Format = Format.R8G8B8A8_UNorm, Width = texture.unWidth, Height = texture.unHeight, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4))) controllerTextureViews[controller] = new ShaderResourceView(device, texture2d); } worldViewProjectionBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); var rasterizerStateDescription = RasterizerStateDescription.Default(); //rasterizerStateDescription.FillMode = FillMode.Wireframe; rasterizerStateDescription.IsFrontCounterClockwise = true; //rasterizerStateDescription.CullMode = CullMode.None; rasterizerState = new RasterizerState(device, rasterizerStateDescription); var blendStateDescription = BlendStateDescription.Default(); blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDescription.RenderTarget[0].IsBlendEnabled = false; blendState = new BlendState(device, blendStateDescription); var depthStateDescription = DepthStencilStateDescription.Default(); depthStateDescription.DepthComparison = Comparison.LessEqual; depthStateDescription.IsDepthEnabled = true; depthStateDescription.IsStencilEnabled = false; depthStencilState = new DepthStencilState(device, depthStateDescription); var samplerStateDescription = SamplerStateDescription.Default(); samplerStateDescription.Filter = Filter.MinMagMipLinear; samplerStateDescription.AddressU = TextureAddressMode.Wrap; samplerStateDescription.AddressV = TextureAddressMode.Wrap; samplerState = new SamplerState(device, samplerStateDescription); startTime = DateTime.Now; frame = 0; windowSize = form.ClientSize; backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1); var vrEvent = new VREvent_t(); var eventSize = (uint)Utilities.SizeOf <VREvent_t>(); head = Matrix.Identity; // Initialize Audio var audioSamples = 1024; var audioDevices = DirectSoundCapture.GetDevices(); //var audioCapture = new DirectSoundCapture(devices.OrderByDescending(d => d.Description.Contains("Mic")).First().DriverGuid); var audioCapture = new DirectSoundCapture(audioDevices.OrderByDescending(d => d.Description.Contains("Mix")).First().DriverGuid); var audioFormat = new WaveFormat(); var audioLength = audioFormat.ConvertLatencyToByteSize(24); var audioData = new byte[audioLength]; var audioPosition = 0; var leftWaveForm = new float[1024 * 8]; var rightWaveForm = new float[1024 * 8]; for (var sample = 0; sample < 1024; sample++) { leftWaveForm[(sample * 8) + 0] = -1.0f + ((float)sample / 512.0f); rightWaveForm[(sample * 8) + 0] = -1.0f + ((float)sample / 512.0f); } var audioBuffer = new CaptureBuffer(audioCapture, new CaptureBufferDescription { BufferBytes = audioLength, Format = audioFormat }); audioBuffer.Start(true); var waveFormBufferDescription = new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = leftWaveForm.Length * sizeof(float), CpuAccessFlags = CpuAccessFlags.Write, Usage = ResourceUsage.Dynamic }; var leftWaveFormVertexBuffer = SharpDX.Direct3D11.Buffer.Create(device, leftWaveForm, waveFormBufferDescription); var rightWaveFormVertexBuffer = SharpDX.Direct3D11.Buffer.Create(device, rightWaveForm, waveFormBufferDescription); var leftWaveFormVertexBufferBinding = new VertexBufferBinding(leftWaveFormVertexBuffer, 8 * sizeof(float), 0); var rightWaveFormVertexBufferBinding = new VertexBufferBinding(rightWaveFormVertexBuffer, 8 * sizeof(float), 0); RenderLoop.Run(form, () => { if (audioBuffer.CurrentCapturePosition != audioBuffer.CurrentRealPosition) { audioBuffer.Read(audioData, 0, audioData.Length, 0, LockFlags.None); for (var sample = 0; sample < 1024; sample++) { leftWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, sample * 4) / (float)short.MinValue; rightWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, (sample * 4) + 2) / (float)short.MinValue; } DataStream stream; context.MapSubresource(leftWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); stream.WriteRange(leftWaveForm); context.UnmapSubresource(leftWaveFormVertexBuffer, 0); stream.Dispose(); context.MapSubresource(rightWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); stream.WriteRange(rightWaveForm); context.UnmapSubresource(rightWaveFormVertexBuffer, 0); stream.Dispose(); } audioPosition += 8; if (audioPosition >= leftWaveForm.Length) { audioPosition = 0; } while (system.PollNextEvent(ref vrEvent, eventSize)) { switch ((EVREventType)vrEvent.eventType) { case EVREventType.VREvent_TrackedDeviceActivated: var controller = vrEvent.trackedDeviceIndex; controllers.Add(controller); var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); controllerModels[controller] = renderModel; // Load Controller Model var model = controllerModels[controller]; controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)model.unVertexCount * 32 }); controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0); controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription { BindFlags = BindFlags.IndexBuffer, SizeInBytes = (int)model.unTriangleCount * 3 * 2 }); break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var textureMap = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); controllerTextures[controller] = textureMap; using (var texture2d = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, Format = Format.R8G8B8A8_UNorm, Width = textureMap.unWidth, Height = textureMap.unHeight, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(textureMap.rubTextureMapData, textureMap.unWidth * 4))) controllerTextureViews[controller] = new ShaderResourceView(device, texture2d); break; } } } break; case EVREventType.VREvent_TrackedDeviceDeactivated: controllers.RemoveAll(c => c == vrEvent.trackedDeviceIndex); break; default: System.Diagnostics.Debug.WriteLine((EVREventType)vrEvent.eventType); break; } } if (form.ClientSize != windowSize) { Utilities.Dispose(ref backBufferView); if (form.ClientSize.Width != 0 && form.ClientSize.Height != 0) { swapChain.ResizeBuffers(1, form.ClientSize.Width, form.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None); using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) backBufferView = new RenderTargetView(device, backBuffer); } windowSize = form.ClientSize; } // Update Device Tracking compositor.WaitGetPoses(currentPoses, nextPoses); if (currentPoses[headset].bPoseIsValid) { Convert(ref currentPoses[headset].mDeviceToAbsoluteTracking, ref head); } foreach (var controller in controllers) { var controllerMatrix = Matrix.Identity; Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref controllerMatrix); } // Render Left Eye context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height); context.OutputMerger.SetTargets(eyeDepthView, leftEyeTextureView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(leftEyeTextureView, backgroundColor); context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Normal.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); var ratio = (float)headsetSize.Width / (float)headsetSize.Height; var projection = leftEyeProjection; var view = Matrix.Invert(leftEyeView * head); var world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Shaders.NormalTexture.Apply(context); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world; worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } // Draw Waveforms Shaders.Position.Apply(context); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip; context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding); context.Draw(1024, 0); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding); context.Draw(1024, 0); // Present Left Eye var texture = new Texture_t { eType = ETextureType.DirectX, eColorSpace = EColorSpace.Gamma, handle = leftEyeTextureView.Resource.NativePointer }; var bounds = new VRTextureBounds_t { uMin = 0.0f, uMax = 1.0f, vMin = 0.0f, vMax = 1.0f, }; var submitError = compositor.Submit(EVREye.Eye_Left, ref texture, ref bounds, EVRSubmitFlags.Submit_Default); if (submitError != EVRCompositorError.None) { System.Diagnostics.Debug.WriteLine(submitError); } // Render Right Eye context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height); context.OutputMerger.SetTargets(eyeDepthView, rightEyeTextureView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(rightEyeTextureView, backgroundColor); context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Normal.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); projection = rightEyeProjection; view = Matrix.Invert(rightEyeView * head); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Shaders.NormalTexture.Apply(context); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world; worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } // Draw Waveforms Shaders.Position.Apply(context); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip; context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding); context.Draw(1024, 0); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding); context.Draw(1024, 0); // Present Right Eye texture.handle = rightEyeTextureView.Resource.NativePointer; submitError = compositor.Submit(EVREye.Eye_Right, ref texture, ref bounds, EVRSubmitFlags.Submit_Default); if (submitError != EVRCompositorError.None) { System.Diagnostics.Debug.WriteLine(submitError); } // Render Window context.Rasterizer.SetViewport(0, 0, windowSize.Width, windowSize.Height); context.OutputMerger.SetTargets(depthStencilView, backBufferView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(backBufferView, backgroundColor); context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Normal.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); ratio = (float)form.ClientSize.Width / (float)form.ClientSize.Height; projection = Matrix.PerspectiveFovRH(3.14f / 3.0f, ratio, 0.01f, 1000); view = Matrix.Invert(head); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Shaders.NormalTexture.Apply(context); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world; worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } // Draw Waveforms Shaders.Position.Apply(context); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip; context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding); context.Draw(1024, 0); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding); context.Draw(1024, 0); // Show Backbuffer swapChain.Present(0, PresentFlags.None); }); } }
private SteamVR(System.IntPtr pHmd, System.IntPtr pCompositor, System.IntPtr pOverlay) { hmd = new CVRSystem(pHmd); Debug.Log("Connected to " + hmd_TrackingSystemName + ":" + hmd_SerialNumber); compositor = new CVRCompositor(pCompositor); overlay = new CVROverlay(pOverlay); var capacity = compositor.GetLastError(null, 0); if (capacity > 1) { var result = new System.Text.StringBuilder((int)capacity); compositor.GetLastError(result, capacity); Debug.Log("Compositor - " + result); } // Hook up the render thread event. var error = HmdError.None; SetUnityRenderCallback(OpenVR.GetGenericInterface(IVRHmdDistortPresent_Version, ref error)); // Setup render values uint w = 0, h = 0; hmd.GetRecommendedRenderTargetSize(ref w, ref h); sceneWidth = (float)w; sceneHeight = (float)h; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; hmd.GetProjectionRaw(Hmd_Eye.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(Hmd_Eye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); tanHalfFov = new Vector2( Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -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; // Grow the recommended size to account for the overlapping fov sceneWidth = sceneWidth / Mathf.Max(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); sceneHeight = sceneHeight / Mathf.Max(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); aspect = tanHalfFov.x / tanHalfFov.y; fieldOfView = 2.0f * Mathf.Atan(tanHalfFov.y) * Mathf.Rad2Deg; eyes = new SteamVR_Utils.RigidTransform[] { new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(Hmd_Eye.Eye_Left)), new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(Hmd_Eye.Eye_Right)) }; if (SystemInfo.graphicsDeviceVersion.StartsWith("OpenGL")) { graphicsAPI = GraphicsAPIConvention.API_OpenGL; } else { graphicsAPI = GraphicsAPIConvention.API_DirectX; } SteamVR_Utils.Event.Listen("initializing", OnInitializing); SteamVR_Utils.Event.Listen("calibrating", OnCalibrating); SteamVR_Utils.Event.Listen("out_of_range", OnOutOfRange); SteamVR_Utils.Event.Listen("device_connected", OnDeviceConnected); SteamVR_Utils.Event.Listen("new_poses", OnNewPoses); }
private SteamVR(System.IntPtr pHmd, System.IntPtr pCompositor, System.IntPtr pOverlay) { hmd = new CVRSystem(pHmd); Debug.Log("Connected to " + hmd_TrackingSystemName + ":" + hmd_SerialNumber); compositor = new CVRCompositor(pCompositor); overlay = new CVROverlay(pOverlay); var device = new UnityGraphicsDevice(); GetUnityGraphicsDevice(ref device); switch (device.type) { case GfxDeviceRenderer.kGfxRendererD3D11: compositor.SetGraphicsDevice(Compositor_DeviceType.D3D11, device.ptr); break; case GfxDeviceRenderer.kGfxRendererOpenGL: compositor.SetGraphicsDevice(Compositor_DeviceType.OpenGL, device.ptr); break; default: throw new System.Exception("Unsupported device type."); } var capacity = compositor.GetLastError(null, 0); if (capacity > 1) { var result = new System.Text.StringBuilder((int)capacity); compositor.GetLastError(result, capacity); Debug.Log("Compositor - " + result); } // Register for a callback if our graphics device goes away, so we can properly clean up. var resetDelegate = new UnityResetDelegate(SteamVR.SafeDispose); callbackHandle = GCHandle.Alloc(resetDelegate); SetUnityResetCallback(Marshal.GetFunctionPointerForDelegate(resetDelegate)); // Hook up the render thread present event just in case we wind up needing to use this. var error = HmdError.None; SetUnityRenderCallback(OpenVR.GetGenericInterface(IVRHmdDistortPresent_Version, ref error)); // Setup render values uint w = 0, h = 0; hmd.GetRecommendedRenderTargetSize(ref w, ref h); sceneWidth = (float)w; sceneHeight = (float)h; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; hmd.GetProjectionRaw(Hmd_Eye.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(Hmd_Eye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); tanHalfFov = new Vector2( Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -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; // Grow the recommended size to account for the overlapping fov sceneWidth = sceneWidth / Mathf.Max(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); sceneHeight = sceneHeight / Mathf.Max(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); aspect = tanHalfFov.x / tanHalfFov.y; fieldOfView = 2.0f * Mathf.Atan(tanHalfFov.y) * Mathf.Rad2Deg; eyes = new SteamVR_Utils.RigidTransform[] { new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(Hmd_Eye.Eye_Left)), new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(Hmd_Eye.Eye_Right)) }; SteamVR_Utils.Event.Listen("initializing", OnInitializing); SteamVR_Utils.Event.Listen("calibrating", OnCalibrating); SteamVR_Utils.Event.Listen("out_of_range", OnOutOfRange); SteamVR_Utils.Event.Listen("device_connected", OnDeviceConnected); SteamVR_Utils.Event.Listen("new_poses", OnNewPoses); }