/// <summary> /// Updates the HMD. /// </summary> private void UpdateHMD() { CVRSystem hmd = Hmd; if (renderPoses.Length > 0) { ETrackingResult result = renderPoses[0].eTrackingResult; VRInitializing = result == ETrackingResult.Uninitialized; VRCalibrating = result == ETrackingResult.Calibrating_InProgress || result == ETrackingResult.Calibrating_OutOfRange; VROutOfRange = result == ETrackingResult.Running_OutOfRange || result == ETrackingResult.Calibrating_OutOfRange; if (result == ETrackingResult.Running_OK) { // Get poses for each eye (left, right, center) renderPoses[0].ToMatrix(out Matrix mCenter); mCenter.ToVRPose(out VRPose center); EyesProperties[2].Pose = center; for (int i = 0; i < 2; i++) { VREye eye = EyesProperties[i]; VREyeTexture texture = eye.Texture; hmd.GetProjectionMatrix((EVREye)i, texture.NearPlane, texture.FarPlane).ToMatrix(out Matrix projection); projection.Invert(); eye.Projection = projection; hmd.GetEyeToHeadTransform((EVREye)i).ToMatrix(out Matrix mOffset); mOffset *= mCenter; mOffset.ToVRPose(out VRPose pose); eye.Pose = pose; } } } }
/// <summary> /// Gets the projection for an eye view point. /// </summary> /// <param name="lefteye">Left or right.</param> /// <param name="znear">Near plane.</param> /// <param name="zfar">Far plane.</param> /// <returns>Eye projection.</returns> public Matrix4 GetProjection(bool lefteye, float znear, float zfar) { HmdMatrix44_t temp = VR.GetProjectionMatrix(!lefteye ? EVREye.Eye_Left : EVREye.Eye_Right, znear, zfar, EGraphicsAPIConvention.API_OpenGL); Matrix4 proj = new Matrix4(temp.m0, temp.m1, temp.m2, temp.m3, temp.m4, temp.m5, temp.m6, temp.m7, temp.m8, temp.m9, temp.m10, temp.m11, temp.m12, temp.m13, temp.m14, temp.m15); proj.Transpose(); return(proj); }
public override void Evaluate(int SpreadMax, CVRSystem system) { FTexSizeOut[0] = OpenVRManager.RecommendedRenderTargetSize; if (OpenVRManager.RenderPoses == null) { return; } //camera properties var projL = system.GetProjectionMatrix(EVREye.Eye_Left, FNearPlane[0], FFarPlane[0]); var projR = system.GetProjectionMatrix(EVREye.Eye_Right, FNearPlane[0], FFarPlane[0]); FProjectionOut.SliceCount = 2; FProjectionOut[0] = projL.ToProjectionMatrix(); FProjectionOut[1] = projR.ToProjectionMatrix(); var eyeL = system.GetEyeToHeadTransform(EVREye.Eye_Left).ToEyeMatrix(); var eyeR = system.GetEyeToHeadTransform(EVREye.Eye_Right).ToEyeMatrix(); FEyeToHeadOut.SliceCount = 2; FEyeToHeadOut[0] = eyeL; FEyeToHeadOut[1] = eyeR; //view FViewOut.SliceCount = 2; FViewOut[0] = Matrix.Invert(eyeL * OpenVRManager.RenderPoses[0].mDeviceToAbsoluteTracking.ToMatrix()); FViewOut[1] = Matrix.Invert(eyeR * OpenVRManager.RenderPoses[0].mDeviceToAbsoluteTracking.ToMatrix()); //hidden pixels mesh var meshLeft = system.GetHiddenAreaMesh(EVREye.Eye_Left, EHiddenAreaMeshType.k_eHiddenAreaMesh_Standard); var meshRight = system.GetHiddenAreaMesh(EVREye.Eye_Right, EHiddenAreaMeshType.k_eHiddenAreaMesh_Standard); if (meshLeft.unTriangleCount > 0 && meshRight.unTriangleCount > 0) { GetMeshData(meshLeft, FVerticesLeftOut); GetMeshData(meshRight, FVerticesRightOut); } else { FVerticesLeftOut.SliceCount = 0; FVerticesRightOut.SliceCount = 0; } FHMDPoseOut[0] = OpenVRManager.GamePoses[0].mDeviceToAbsoluteTracking.ToMatrix(); }
private OpenVRScene(float nearClip, float farClip, CVRSystem hmd, int leftIndex, int rightIndex) { // set up the hmd this.hmd = hmd; NearClip = nearClip; FarClip = farClip; leftEyeProj = hmd.GetProjectionMatrix(EVREye.Eye_Left, nearClip, farClip, EGraphicsAPIConvention.API_OpenGL).ToGLMatrix4(); rightEyeProj = hmd.GetProjectionMatrix(EVREye.Eye_Right, nearClip, farClip, EGraphicsAPIConvention.API_OpenGL).ToGLMatrix4(); leftEyeView = hmd.GetEyeToHeadTransform(EVREye.Eye_Left).ToGLMatrix4().Inverted(); rightEyeView = hmd.GetEyeToHeadTransform(EVREye.Eye_Right).ToGLMatrix4().Inverted(); leftHandControllerIndex = leftIndex; rightHandControllerIndex = rightIndex; OpenVRInput = new OpenVRInputObservable(hmd); }
public override void Evaluate(int SpreadMax, CVRSystem system) { if (IsInit || FInit[0]) { FTexSizeOut[0] = OpenVRManager.RecommendedRenderTargetSize; var projL = system.GetProjectionMatrix(EVREye.Eye_Left, 0.05f, 100, EGraphicsAPIConvention.API_DirectX); var projR = system.GetProjectionMatrix(EVREye.Eye_Right, 0.05f, 100, EGraphicsAPIConvention.API_DirectX); FProjectionOut.SliceCount = 2; FProjectionOut[0] = projL.ToProjectionMatrix(); FProjectionOut[1] = projR.ToProjectionMatrix(); EyeL = system.GetEyeToHeadTransform(EVREye.Eye_Left).ToEyeMatrix(); EyeR = system.GetEyeToHeadTransform(EVREye.Eye_Right).ToEyeMatrix(); FEyeToHeadOut.SliceCount = 2; FEyeToHeadOut[0] = EyeL; FEyeToHeadOut[1] = EyeR; IsInit = false; var meshLeft = system.GetHiddenAreaMesh(EVREye.Eye_Left); var meshRight = system.GetHiddenAreaMesh(EVREye.Eye_Right); //hidden pixels mesh if (meshLeft.unTriangleCount > 0 && meshRight.unTriangleCount > 0) { GetMeshData(meshLeft, FVerticesLeftOut); GetMeshData(meshRight, FVerticesRightOut); } else { FVerticesLeftOut.SliceCount = 0; FVerticesRightOut.SliceCount = 0; } } //view FViewOut.SliceCount = 2; FViewOut[0] = Matrix.Invert(EyeL * OpenVRManager.RenderPoses[0].mDeviceToAbsoluteTracking.ToMatrix()); FViewOut[1] = Matrix.Invert(EyeR * OpenVRManager.RenderPoses[0].mDeviceToAbsoluteTracking.ToMatrix()); FHMDPoseOut[0] = OpenVRManager.GamePoses[0].mDeviceToAbsoluteTracking.ToMatrix(); }
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)); }
private void setupCameras() { 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; } 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")) { O_Interior = camera; } if (cameraName.Equals("GalaxyCamera")) { O_Galaxy = camera; } if (cameraName.Equals("Camera ScaledSpace")) { O_SclaledSpace = camera; log("sky cam rot = " + camera.transform.rotation.eulerAngles.ToString()); } } } } //Instantiate Cameras for all Layers 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); //copy Properties from Original Cameras leftSky.CopyFrom(O_SclaledSpace); rightSky.CopyFrom(O_SclaledSpace); leftStars.CopyFrom(O_Galaxy); rightStars.CopyFrom(O_Galaxy); camRight_Near.CopyFrom(O_Near); camLeft_Near.CopyFrom(O_Near); camLeft_Interior.CopyFrom(O_Interior); camRight_Interior.CopyFrom(O_Interior); camRight_Far.CopyFrom(O_Far); camLeft_Far.CopyFrom(O_Far); //set RenderTextures for Cameras setRenderTexturesTo(hmdLeftEyeRenderTexture, hmdRightEyeRenderTexture); //create left slave leftSlave = camLeft_Interior.gameObject.AddOrGetComponent <RenderSlave>(); leftSlave.left = true; //create right slave rightSlave = camRight_Interior.gameObject.AddOrGetComponent <RenderSlave>(); rightSlave.left = false; //Set Projectsions for all Cameras 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); camLeft_Interior.SetStereoProjectionMatrix(Camera.StereoscopicEye.Left, MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft2)); camLeft_Interior.SetStereoProjectionMatrix(Camera.StereoscopicEye.Right, MathUtils.Matrix4x4_OpenVr2UnityFormat(ref projLeft2)); 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); //disable All Cameras to increase Performance O_SclaledSpace.enabled = false; O_Galaxy.enabled = false; O_Near.enabled = false; O_Far.enabled = false; O_Interior.enabled = false; camLeft_Near.enabled = false; camRight_Near.enabled = false; camLeft_Far.enabled = false; camRight_Far.enabled = false; leftSky.enabled = false; rightSky.enabled = false; leftStars.enabled = false; rightStars.enabled = false; camLeft_Interior.enabled = false; camRight_Interior.enabled = false; //activate slaves posTracker.HmdOn = true; leftSlave.HmdOn = true; rightSlave.HmdOn = true; //initialize active kerbal: activeKerbal = CameraManager.Instance.IVACameraActiveKerbal; lastKerbalID = CameraManager.Instance.IVACameraActiveKerbalIndex; }
/// <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); }
/*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; } } }
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); }); } }
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]; 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); }
public override Matrix GetProjectionMatrix(int eye) { var mat = m_System.GetProjectionMatrix((EVREye)eye, 0.1f, 1000.0f); return(mat.ToXNA()); }